You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

333 lines
7.6 KiB

  1. require("luaScript.cc.functions")
  2. BindableArray = class("BindableArray")
  3. function BindableArray:pairs()
  4. return pairs(self.Datas)
  5. end
  6. function BindableArray:ipairs()
  7. return ipairs(self.Datas)
  8. end
  9. function BindableArray:__pairs()
  10. return pairs(self.Datas)
  11. end
  12. function BindableArray:__ipairs()
  13. return ipairs(self.Datas)
  14. end
  15. function BindableArray:len()
  16. return self:size();
  17. end
  18. function BindableArray:__len()
  19. return self:size();
  20. end
  21. -- 删除数据
  22. function BindableArray:clear()
  23. local datas = self.Datas;
  24. self.Datas = {}
  25. self.DataCount = 0
  26. for i , v in pairs(datas) do
  27. self:raiseEvent("__remove" , i , v);
  28. end
  29. end
  30. -- 排序Datas数据表,当然了,老规矩,排序的表只支持:insert进来的数据,即键是正整数
  31. function BindableArray:sort(func)
  32. table.sort(self.Datas , func);
  33. end
  34. -- 获得元素数量
  35. function BindableArray:size()
  36. return self.DataCount
  37. end
  38. -- 添加元素数量
  39. function BindableArray:insert(value)
  40. self[self:size() + 1] = value;
  41. end
  42. -- 绑定变量属性修改
  43. function BindableArray:bind(name , onChangeFunc)
  44. if self[name] == nil then
  45. error("找不到成员变量:" .. name)
  46. return;
  47. end
  48. local bindIndex = self:bindEvent(name , onChangeFunc);
  49. onChangeFunc(name , self[name]);
  50. return bindIndex;
  51. end
  52. -- 绑定一个事件
  53. function BindableArray:bindEvent(eventName , onAddFunc)
  54. if type(onAddFunc) ~= "function" then
  55. error("is not a function")
  56. return
  57. end
  58. local name = eventName
  59. if self.Binds[name] == nil then
  60. self.Binds[name] = {}
  61. self.Binds[name]._looping = 0
  62. self.Binds[name].funs = {}
  63. end
  64. local index = self.BindIndex;
  65. -- 如果正在遍历过程中
  66. local bindTable = self.Binds[name]
  67. if bindTable._looping > 0 then
  68. if self.AddBinds[name] == nil then
  69. self.AddBinds[name] = {}
  70. end
  71. -- 添加到临时列表
  72. self.AddBinds[name][index] = onAddFunc
  73. else
  74. -- 不在遍历过程中立马加入
  75. bindTable.funs[index] = onAddFunc;
  76. end
  77. self.BindsByIndex[index] = name;
  78. self.BindIndex = self.BindIndex + 1
  79. return index;
  80. end
  81. -- 解除数据绑定
  82. function BindableArray:unbind(bindIndex)
  83. local name = self.BindsByIndex[bindIndex]
  84. if name then
  85. -- 如果正在遍历过程中
  86. local bindTable = self.Binds[name];
  87. if bindTable._looping > 0 then
  88. if self.RemoveBinds[name] == nil then
  89. self.RemoveBinds[name] = {}
  90. end
  91. -- 添加到临时列表
  92. self.RemoveBinds[name][bindIndex] = true
  93. else
  94. -- 不在遍历过程中立马移除
  95. bindTable.funs[bindIndex] = nil;
  96. end
  97. self.BindsByIndex[bindIndex] = nil;
  98. end
  99. end
  100. function BindableArray:raiseEvent(eventName , key , value)
  101. local bindTable = self.Binds[eventName]
  102. if bindTable == nil then
  103. return
  104. end
  105. local funcs = bindTable.funs;
  106. if funcs then
  107. bindTable._looping = bindTable._looping + 1
  108. -- 这里需要判断回调是否失效
  109. local bindsIndex = self.BindsByIndex
  110. for i, v in pairs(funcs) do
  111. if bindsIndex[i] then
  112. v(key , value);
  113. end
  114. end
  115. bindTable._looping = bindTable._looping - 1
  116. -- 如果在遍历过程中则等执行完
  117. if bindTable._looping > 0 then
  118. print("raiseEvent在遍历的过程中,又触发了一次,当前遍历的次数", eventName, bindTable._looping)
  119. return
  120. end
  121. -- 处理新移除
  122. local addBindFunc = self.AddBinds[eventName]
  123. local removeBindFunc = self.RemoveBinds[eventName]
  124. if removeBindFunc then
  125. print("BindableArray:raiseEvent过程中需要删除的绑定事件", table.toString(self.RemoveBinds))
  126. for i, v in pairs(removeBindFunc) do
  127. -- 新增列表里面有则也要清掉
  128. if addBindFunc then
  129. addBindFunc[i] = nil
  130. end
  131. funcs[i] = nil
  132. end
  133. -- 清空临时列表
  134. self.RemoveBinds[eventName] = nil
  135. end
  136. -- 处理新增加
  137. if addBindFunc then
  138. print("BindableArray:raiseEvent过程中需要增加的绑定事件", table.toString(self.AddBinds))
  139. for i, v in pairs(addBindFunc) do
  140. funcs[i] = v
  141. end
  142. -- 清空临时列表
  143. self.AddBinds[eventName] = nil
  144. end
  145. end
  146. end
  147. -- 绑定添加元素事件
  148. function BindableArray:bindAdd(onAddFunc)
  149. return self:bindEvent("__add" , onAddFunc);
  150. end
  151. -- 绑定移除元素事件
  152. function BindableArray:bindRemove(onRemoveFunc)
  153. return self:bindEvent("__remove" , onRemoveFunc);
  154. end
  155. -- 绑定更新事件 (update)
  156. function BindableArray:bindUpdateTo(onUpdateFunc)
  157. return self:bindEvent("__updateTo" , onUpdateFunc);
  158. end
  159. -- 绑定每一个元素的更新事件
  160. function BindableArray:bindUpdate(onUpdateFunc)
  161. return self:bindEvent("__update" , onUpdateFunc);
  162. end
  163. -- 绑定设置元素事件
  164. function BindableArray:bindSet(onSetFunc)
  165. return self:bindEvent("__set" , onSetFunc);
  166. end
  167. -- 把类数据写入到流
  168. function BindableArray:write(stream)
  169. NetStream.writeNetVar(rawget(self , "NetVar") , stream , self);
  170. end
  171. -- 把类数据发送到服务器
  172. function BindableArray:send(moduleID , commandID, net)
  173. if not net then
  174. log(debug.traceback())
  175. assert(false);
  176. return
  177. end
  178. local stream = NetStream.new();
  179. self:write(stream);
  180. net:send(moduleID , commandID , stream);
  181. NetStream.delete(stream);
  182. end
  183. -- 获取属性回调
  184. function BindableArray:__index(key)
  185. local value = self.Datas[key];
  186. if value ~= nil then
  187. return value;
  188. else
  189. local value = BindableArray[key];
  190. if value then
  191. return value;
  192. else
  193. return nil;
  194. end
  195. end
  196. end
  197. -- 设置属性回调
  198. function BindableArray:__newindex(key , value)
  199. local eventName;
  200. local datas = self.Datas;
  201. local oldValue = datas[key];
  202. -- 新增
  203. if oldValue == nil and value ~= nil then
  204. datas[key] = value
  205. self.DataCount = self.DataCount + 1
  206. eventName = "__add"
  207. -- 删除
  208. elseif oldValue ~= nil and value == nil then
  209. datas[key] = value
  210. self.DataCount = self.DataCount - 1
  211. eventName = "__remove"
  212. -- 没修改
  213. elseif oldValue == value then
  214. return;
  215. -- 修改
  216. else
  217. datas[key] = value
  218. self:raiseEvent(key , key , value);
  219. eventName = "__set"
  220. end
  221. self:raiseEvent(eventName , key , value);
  222. -- 总是发生一个__update
  223. self:raiseEvent("__update" , key , value);
  224. end
  225. -- 用以处理数据绑定的更新数据
  226. function BindableArray:updateTo(target)
  227. if target == nil or type(target) ~= "table" then
  228. return self;
  229. end
  230. -- 处理新增和修改
  231. for i , v in self:pairs() do
  232. local updated = false;
  233. if type(v) == "table" then
  234. if type(v.updateTo) == "function" then
  235. if target[i] ~= nil then
  236. target[i] = v:updateTo(target[i])
  237. updated = true;
  238. end
  239. end
  240. end
  241. if not updated then
  242. target[i] = v;
  243. end
  244. end
  245. -- 处理删除
  246. for i , v in target:pairs() do
  247. if self[i] == nil then
  248. target[i] = nil;
  249. end
  250. end
  251. target:raiseEvent("__updateTo" , target);
  252. return target;
  253. end
  254. function BindableArray:cloneTo(target)
  255. for i , v in self:pairs() do
  256. local cloned = false;
  257. if type(v) == "table" then
  258. if type(v.clone) == "function" then
  259. target[i] = v:clone();
  260. cloned = true;
  261. end
  262. end
  263. if not cloned then
  264. target[i] = v;
  265. end
  266. end
  267. end
  268. -- 深度克隆对象
  269. function BindableArray:clone()
  270. local newArray = newBindableArray();
  271. self:cloneTo(newArray);
  272. return newArray;
  273. end
  274. -- 创建一个带数据绑定功能的对象
  275. function _newBindableArray(sourceTable)
  276. if type(sourceTable) ~= "table" then
  277. print(table.tostring(sourceTable))
  278. end
  279. local obj = {}
  280. obj.Binds = {}
  281. obj.AddBinds = {}
  282. obj.RemoveBinds = {}
  283. obj.BindsByIndex = {}
  284. obj.BindIndex = 0;
  285. if sourceTable then
  286. obj.Datas = sourceTable
  287. local size = 0;
  288. for i , v in pairs(sourceTable) do
  289. size = size + 1;
  290. end
  291. obj.DataCount = size;
  292. else
  293. obj.Datas = {}
  294. obj.DataCount = 0;
  295. end
  296. obj.NetVar = nil;
  297. return obj
  298. end
  299. -- 创建一个带数据绑定功能的对象
  300. local function newBindableArray(sourceTable)
  301. local obj = _newBindableArray(sourceTable)
  302. setmetatable(obj , BindableArray)
  303. return obj
  304. end
  305. return newBindableArray;