|
- require("luaScript.cc.functions")
- BindableArray = class("BindableArray")
- function BindableArray:pairs()
- return pairs(self.Datas)
- end
- function BindableArray:ipairs()
- return ipairs(self.Datas)
- end
- function BindableArray:__pairs()
- return pairs(self.Datas)
- end
- function BindableArray:__ipairs()
- return ipairs(self.Datas)
- end
- function BindableArray:len()
- return self:size();
- end
- function BindableArray:__len()
- return self:size();
- end
- -- 删除数据
- function BindableArray:clear()
- local datas = self.Datas;
- self.Datas = {}
- self.DataCount = 0
- for i , v in pairs(datas) do
- self:raiseEvent("__remove" , i , v);
- end
- end
-
- -- 排序Datas数据表,当然了,老规矩,排序的表只支持:insert进来的数据,即键是正整数
- function BindableArray:sort(func)
- table.sort(self.Datas , func);
- end
-
- -- 获得元素数量
- function BindableArray:size()
- return self.DataCount
- end
-
- -- 添加元素数量
- function BindableArray:insert(value)
- self[self:size() + 1] = value;
- end
-
- -- 绑定变量属性修改
- function BindableArray:bind(name , onChangeFunc)
- if self[name] == nil then
- error("找不到成员变量:" .. name)
- return;
- end
- local bindIndex = self:bindEvent(name , onChangeFunc);
- onChangeFunc(name , self[name]);
- return bindIndex;
- end
-
- -- 绑定一个事件
- function BindableArray:bindEvent(eventName , onAddFunc)
- if type(onAddFunc) ~= "function" then
- error("is not a function")
- return
- end
- local name = eventName
- if self.Binds[name] == nil then
- self.Binds[name] = {}
- self.Binds[name]._looping = 0
- self.Binds[name].funs = {}
- end
- local index = self.BindIndex;
-
- -- 如果正在遍历过程中
- local bindTable = self.Binds[name]
- if bindTable._looping > 0 then
- if self.AddBinds[name] == nil then
- self.AddBinds[name] = {}
- end
- -- 添加到临时列表
- self.AddBinds[name][index] = onAddFunc
- else
- -- 不在遍历过程中立马加入
- bindTable.funs[index] = onAddFunc;
- end
-
- self.BindsByIndex[index] = name;
- self.BindIndex = self.BindIndex + 1
- return index;
- end
-
- -- 解除数据绑定
- function BindableArray:unbind(bindIndex)
- local name = self.BindsByIndex[bindIndex]
- if name then
- -- 如果正在遍历过程中
- local bindTable = self.Binds[name];
- if bindTable._looping > 0 then
- if self.RemoveBinds[name] == nil then
- self.RemoveBinds[name] = {}
- end
- -- 添加到临时列表
- self.RemoveBinds[name][bindIndex] = true
- else
- -- 不在遍历过程中立马移除
- bindTable.funs[bindIndex] = nil;
- end
- self.BindsByIndex[bindIndex] = nil;
- end
- end
-
- function BindableArray:raiseEvent(eventName , key , value)
- local bindTable = self.Binds[eventName]
- if bindTable == nil then
- return
- end
-
- local funcs = bindTable.funs;
- if funcs then
- bindTable._looping = bindTable._looping + 1
- -- 这里需要判断回调是否失效
- local bindsIndex = self.BindsByIndex
- for i, v in pairs(funcs) do
- if bindsIndex[i] then
- v(key , value);
- end
- end
- bindTable._looping = bindTable._looping - 1
-
- -- 如果在遍历过程中则等执行完
- if bindTable._looping > 0 then
- print("raiseEvent在遍历的过程中,又触发了一次,当前遍历的次数", eventName, bindTable._looping)
- return
- end
-
- -- 处理新移除
- local addBindFunc = self.AddBinds[eventName]
- local removeBindFunc = self.RemoveBinds[eventName]
- if removeBindFunc then
- print("BindableArray:raiseEvent过程中需要删除的绑定事件", table.toString(self.RemoveBinds))
- for i, v in pairs(removeBindFunc) do
- -- 新增列表里面有则也要清掉
- if addBindFunc then
- addBindFunc[i] = nil
- end
- funcs[i] = nil
- end
- -- 清空临时列表
- self.RemoveBinds[eventName] = nil
- end
-
- -- 处理新增加
- if addBindFunc then
- print("BindableArray:raiseEvent过程中需要增加的绑定事件", table.toString(self.AddBinds))
- for i, v in pairs(addBindFunc) do
- funcs[i] = v
- end
- -- 清空临时列表
- self.AddBinds[eventName] = nil
- end
- end
- end
-
- -- 绑定添加元素事件
- function BindableArray:bindAdd(onAddFunc)
- return self:bindEvent("__add" , onAddFunc);
- end
-
- -- 绑定移除元素事件
- function BindableArray:bindRemove(onRemoveFunc)
- return self:bindEvent("__remove" , onRemoveFunc);
- end
-
- -- 绑定更新事件 (update)
- function BindableArray:bindUpdateTo(onUpdateFunc)
- return self:bindEvent("__updateTo" , onUpdateFunc);
- end
-
- -- 绑定每一个元素的更新事件
- function BindableArray:bindUpdate(onUpdateFunc)
- return self:bindEvent("__update" , onUpdateFunc);
- end
-
- -- 绑定设置元素事件
- function BindableArray:bindSet(onSetFunc)
- return self:bindEvent("__set" , onSetFunc);
- end
-
- -- 把类数据写入到流
- function BindableArray:write(stream)
- NetStream.writeNetVar(rawget(self , "NetVar") , stream , self);
- end
-
- -- 把类数据发送到服务器
- function BindableArray:send(moduleID , commandID, net)
- if not net then
- log(debug.traceback())
- assert(false);
- return
- end
- local stream = NetStream.new();
- self:write(stream);
- net:send(moduleID , commandID , stream);
- NetStream.delete(stream);
- end
-
- -- 获取属性回调
- function BindableArray:__index(key)
- local value = self.Datas[key];
- if value ~= nil then
- return value;
- else
- local value = BindableArray[key];
- if value then
- return value;
- else
- return nil;
- end
- end
- end
-
- -- 设置属性回调
- function BindableArray:__newindex(key , value)
- local eventName;
- local datas = self.Datas;
- local oldValue = datas[key];
- -- 新增
- if oldValue == nil and value ~= nil then
- datas[key] = value
- self.DataCount = self.DataCount + 1
- eventName = "__add"
- -- 删除
- elseif oldValue ~= nil and value == nil then
- datas[key] = value
- self.DataCount = self.DataCount - 1
- eventName = "__remove"
- -- 没修改
- elseif oldValue == value then
- return;
- -- 修改
- else
- datas[key] = value
- self:raiseEvent(key , key , value);
- eventName = "__set"
- end
- self:raiseEvent(eventName , key , value);
- -- 总是发生一个__update
- self:raiseEvent("__update" , key , value);
- end
-
- -- 用以处理数据绑定的更新数据
- function BindableArray:updateTo(target)
- if target == nil or type(target) ~= "table" then
- return self;
- end
- -- 处理新增和修改
- for i , v in self:pairs() do
- local updated = false;
- if type(v) == "table" then
- if type(v.updateTo) == "function" then
- if target[i] ~= nil then
- target[i] = v:updateTo(target[i])
- updated = true;
- end
- end
- end
- if not updated then
- target[i] = v;
- end
- end
- -- 处理删除
- for i , v in target:pairs() do
- if self[i] == nil then
- target[i] = nil;
- end
- end
-
- target:raiseEvent("__updateTo" , target);
- return target;
- end
-
- function BindableArray:cloneTo(target)
- for i , v in self:pairs() do
- local cloned = false;
- if type(v) == "table" then
- if type(v.clone) == "function" then
- target[i] = v:clone();
- cloned = true;
- end
- end
- if not cloned then
- target[i] = v;
- end
- end
- end
- -- 深度克隆对象
- function BindableArray:clone()
- local newArray = newBindableArray();
- self:cloneTo(newArray);
- return newArray;
- end
-
- -- 创建一个带数据绑定功能的对象
- function _newBindableArray(sourceTable)
- if type(sourceTable) ~= "table" then
- print(table.tostring(sourceTable))
- end
- local obj = {}
- obj.Binds = {}
- obj.AddBinds = {}
- obj.RemoveBinds = {}
- obj.BindsByIndex = {}
- obj.BindIndex = 0;
- if sourceTable then
- obj.Datas = sourceTable
- local size = 0;
- for i , v in pairs(sourceTable) do
- size = size + 1;
- end
- obj.DataCount = size;
- else
- obj.Datas = {}
- obj.DataCount = 0;
- end
- obj.NetVar = nil;
- return obj
- end
-
- -- 创建一个带数据绑定功能的对象
- local function newBindableArray(sourceTable)
- local obj = _newBindableArray(sourceTable)
- setmetatable(obj , BindableArray)
- return obj
- end
-
- return newBindableArray;
|