c1_lua/lua/app/userdata/base_data.lua
2023-04-03 10:59:13 +08:00

142 lines
3.0 KiB
Lua

---@class BaseData
local BaseData = class("BaseData")
function BaseData:ctor(...)
self.data = {}
self.data.__parent = self
local innerData = nil
innerData = {
__index = function (t, key)
return innerData[key]
end,
__newindex = function (t, key, value)
local preValue = innerData[key]
innerData[key] = value
t.__parent:invoke(key, preValue, value)
end
}
setmetatable(self.data, innerData)
self.bindList = {}
self.forceList = {}
self._baseInvokeCount = 0
end
function BaseData:invoke(name, preValue, value)
self._baseInvokeCount = self._baseInvokeCount + 1
if (self.forceList[name] or preValue ~= value) or type(preValue) == "table" then
self.forceList[name] = nil
if self.bindList[name] then
for _, info in ipairs(self.bindList[name]) do
info.bindFunc(info.binder, value)
end
end
end
self._baseInvokeCount = self._baseInvokeCount - 1
if self._baseInvokeCount > 0 then -- 说明还在递归中
return
end
if self._baseRemoveFlag then
self._baseRemoveFlag = false
if self._waitRemoveMap then
for key, v in pairs(self._waitRemoveMap) do
local list = self.bindList[key]
if list then
for i = #list, 1, -1 do
if list[i] and list[i].waitRemove then
table.remove(list, i)
end
end
end
self._waitRemoveMap[key] = nil
end
end
end
end
function BaseData:bind(name, binder, bindFunc, immediately)
if not self.bindList[name] then
self.bindList[name] = {}
end
local unique = true
for i, info in ipairs(self.bindList[name]) do
if info and binder and info.binder == binder then
self.bindList[name][i].bindFunc = bindFunc
unique = false
break
end
end
if unique then
table.insert(self.bindList[name], {binder = binder, bindFunc = bindFunc})
end
if immediately then
self:invoke(name, nil, self.data[name])
end
end
function BaseData:unBind(name, binder)
if self.bindList[name] then
for i, info in ipairs(self.bindList[name]) do
if info.binder == binder then
if self._baseInvokeCount > 0 then -- 正在invoke过程中
info.waitRemove = true
self._baseRemoveFlag = true
if self._waitRemoveMap == nil then
self._waitRemoveMap = {}
end
self._waitRemoveMap[name] = true
else
table.remove(self.bindList[name], i)
end
break
end
end
end
end
function BaseData:setForceInvoke(name, value)
self.forceList[name] = true
self.data[name] = value
end
function BaseData:clearBind(name)
if self.bindList[name] then
self.bindList[name] = nil
end
end
function BaseData:clearBindAll()
self.bindList = {}
end
function BaseData:clear()
end
if NOT_PUBLISH then
function BaseData:_typeValid(name)
local value = self.data[name]
local vt = type(value)
if vt == "string" or
vt == "number" or
vt == "nil" or
vt == "boolean" or
vt == "table" then
return true
end
return false
end
BaseData._releaseBind = BaseData.bind
function BaseData:bind(name, ...)
if not self:_typeValid(name) then
Logger.logFatal("%s:%s type is valid", self.__cname, name)
end
self:_releaseBind(name, ...)
end
end
return BaseData