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.

404 lines
11 KiB

  1. -- 实现自动绑定数据的函数
  2. -- @netObject 需要绑定添加事件的对象
  3. -- @valueName 需要绑定哪个变量名
  4. -- @propertyNameOrFunc , 当添加事件发生时的回调或设置什么属性,回调格式是func(cc.Node , value);
  5. -- @return index , unbinder index是用来调用Ref:unbind函数的。unbinder是自动调用unbind函数
  6. function cc.Node:bind(netObject , valueName , propertyNameOrFunc)
  7. local onPropChange;
  8. local typeP = type(propertyNameOrFunc);
  9. if typeP == "function" then
  10. onPropChange = function(key , value)
  11. propertyNameOrFunc(self , value);
  12. end
  13. elseif typeP == "string" then
  14. local function onChange(key , value)
  15. self[propertyNameOrFunc](self , value);
  16. end
  17. onPropChange = onChange
  18. else
  19. error("绑定数据" .. tostring(valueName) .. "时第三个参数错误,必须是属性名或函数" .. tostring(propertyNameOrFunc))
  20. return;
  21. end
  22. local index = netObject:bind(valueName , onPropChange);
  23. local unbinder = self:_autoUnbind(netObject , valueName , index);
  24. return index , unbinder;
  25. end
  26. -- 跟bind一样,但第一次调用时不回调
  27. function cc.Node:bindOnUpdate(netObject , valueName , propertyNameOrFunc)
  28. local firstRun = true;
  29. local function callback(...)
  30. if firstRun then
  31. firstRun = false;
  32. return;
  33. end
  34. local onPropChange;
  35. local typeP = type(propertyNameOrFunc);
  36. if typeP == "function" then
  37. onPropChange = function(key , value)
  38. propertyNameOrFunc(self , value);
  39. end
  40. elseif typeP == "string" then
  41. onPropChange = function(key , value)
  42. self[propertyNameOrFunc](self , value);
  43. end
  44. else
  45. error("绑定数据" .. tostring(valueName) .. "时第三个参数错误,必须是属性名或函数" .. tostring(propertyNameOrFunc))
  46. return;
  47. end
  48. onPropChange(...);
  49. end
  50. return self:bind(netObject , valueName , callback)
  51. end
  52. function cc.Node:getLuaData(key)
  53. return self[key];
  54. end
  55. local function autoUnbindAll(binds)
  56. for i , v in pairs(binds) do
  57. for ii , vv in pairs(v) do
  58. for iii , vvv in pairs(vv) do
  59. vvv();
  60. end
  61. end
  62. end
  63. end
  64. function cc.Node:setLuaData(key , value)
  65. if self[key] == nil then
  66. if value ~= nil then
  67. local function onUnbind(node , eventType)
  68. if eventType == cc.NodeEvent.OnCleanup then
  69. local value = self[key];
  70. if value then
  71. autoUnbindAll(value);
  72. self[key] = nil;
  73. end
  74. end
  75. end
  76. self.UnbindListener = self:addNodeEventListener(onUnbind);
  77. end
  78. else
  79. if value == nil then
  80. if self.UnbindListener then
  81. --self:removeNodeEventListener(self.UnbindListener);
  82. self.UnbindListener = nil;
  83. end
  84. end
  85. end
  86. self[key] = value;
  87. end
  88. -- 解绑数据
  89. --[[
  90. 用法:
  91. -- 绑定,并返回这个对象的绑定索引
  92. local index = label:bind(game.actor , "level" , "String");
  93. -- 解绑
  94. label:unbind(game.actor , index);
  95. --]]
  96. function cc.Node:unbind(netObject , bindName, index)
  97. local allbinds = self:getLuaData("_autoBinds")
  98. if allbinds == nil then
  99. return false;
  100. end
  101. local bindsList = allbinds[netObject];
  102. if bindsList == nil then
  103. return false;
  104. end
  105. -- 如果已经绑定过,就解除绑定
  106. local binds = bindsList[bindName];
  107. if not binds then
  108. return false;
  109. end;
  110. local unbinder = binds[index];
  111. if unbinder then
  112. unbinder()
  113. return true;
  114. else
  115. return false;
  116. end
  117. end
  118. -- 解除所有绑定
  119. function cc.Node:unbindAll()
  120. local allbinds = self:getLuaData("_autoBinds")
  121. if allbinds == nil then
  122. return false;
  123. end
  124. for i , v in pairs(allbinds) do
  125. for ii , vv in pairs(v) do
  126. for iii , vvv in pairs(vv) do
  127. vvv();
  128. end;
  129. end
  130. end
  131. self:setLuaData("_autoBinds" , nil);
  132. end
  133. function cc.Node:__autoUnbind(object , bindName , bindIndex , unbind)
  134. local allbinds = self:getLuaData("_autoBinds")
  135. if allbinds == nil then
  136. allbinds = {}
  137. self:setLuaData("_autoBinds" , allbinds);
  138. end
  139. local bindsList = allbinds[object];
  140. if bindsList == nil then
  141. bindsList = {}
  142. allbinds[object] = bindsList
  143. end
  144. -- 如果已经绑定过,就先解除绑定
  145. bindsList[bindName] = bindsList[bindName] or {};
  146. local unbinder = bindsList[bindName][bindIndex];
  147. if unbinder then
  148. unbinder()
  149. end
  150. bindsList[bindName][bindIndex] = unbind;
  151. return unbind;
  152. end
  153. -- 自动在CCObject对象析构时解除绑定
  154. function cc.Node:_autoUnbind(netObject , bindName , bindIndex)
  155. local function unbind()
  156. netObject:unbind(bindIndex);
  157. end
  158. return self:__autoUnbind(netObject , bindName , bindIndex , unbind);
  159. end
  160. -- 实现自动绑定数据的函数
  161. -- @netObject , 需要绑定添加事件的对象
  162. -- @func , 当添加事件发生时的回调,回调格式是func(cc.Node , key , value);
  163. function cc.Node:bindAdd(netObject , func)
  164. local onAdd = function(key , value)
  165. func(self , key , value);
  166. end
  167. if type(func) ~= "function" then
  168. error("绑定添加事件时参数错误,必须是属性名或函数" .. tostring(func))
  169. return;
  170. end
  171. local index = netObject:bindAdd(onAdd);
  172. self:_autoUnbind(netObject , "__add" , index);
  173. return index;
  174. end
  175. -- 实现自动绑定数据的函数
  176. -- @netObject , 需要绑定元素移除事件的对象
  177. -- @func , 当元素移除事件发生时的回调,回调格式是func(cc.Node , key , value);
  178. function cc.Node:bindRemove(netObject , func)
  179. local onRemove = function(key , value)
  180. func(self , key , value);
  181. end
  182. if type(func) ~= "function" then
  183. error("绑定移除事件时参数错误,必须是属性名或函数" .. tostring(func))
  184. return;
  185. end
  186. local index = netObject:bindRemove(onRemove);
  187. self:_autoUnbind(netObject , "__remove" , index);
  188. return index;
  189. end
  190. -- 实现一个map下绑定某个key下的subKey的绑定,如果不传subKey就是绑定某个key
  191. -- 用例 ui:bindMapObject(app.storeHouse.Goods,goodsId,"num",updateGoodsNum);
  192. function cc.Node:bindMapObject(mapObject,key,subKey,func)
  193. if type(func) ~= "function" then
  194. error("绑定更新事件时参数错误,必须是属性名或函数" .. tostring(func))
  195. return;
  196. end
  197. if(mapObject[key])then
  198. if(subKey)then
  199. self:bind(mapObject[key],subKey,func);
  200. else
  201. self:bind(mapObject,key,func);
  202. end
  203. else
  204. func(self,0)
  205. end
  206. self:bindAdd(mapObject,function(ui,addKey,value)
  207. if(addKey==key)then
  208. if(subKey)then
  209. func(self,value[subKey]);
  210. self:bind(mapObject[key],subKey,func);
  211. else
  212. func(self,value);
  213. self:bind(mapObject,key,func);
  214. end
  215. end
  216. end)
  217. self:bindRemove(mapObject,function(ui,removeKey,value)
  218. if(removeKey==key)then
  219. func(self,0);
  220. end
  221. end)
  222. end
  223. -- 实现自定绑定updateTo的调用
  224. -- @netObject , 需要绑定被修改的对象
  225. -- @func , 当添加事件发生时的回调,回调格式是func(cc.Node , netObject);
  226. function cc.Node:bindUpdateTo(netObject , func)
  227. local onUpdate = function(netObject)
  228. func(self , netObject);
  229. end
  230. if type(func) ~= "function" then
  231. error("绑定更新事件时参数错误,必须是属性名或函数" .. tostring(func))
  232. return;
  233. end
  234. local index = netObject:bindUpdateTo(onUpdate);
  235. self:_autoUnbind(netObject , "__updateTo" , index);
  236. return index;
  237. end
  238. -- 实现自动绑定数据的函数
  239. -- @netObject , 需要绑定添加事件的对象
  240. -- @func , 当添加事件发生时的回调,回调格式是func(cc.Node , key , value);
  241. function cc.Node:bindUpdate(netObject , func)
  242. local onUpdate = function(key , value)
  243. func(self , key , value);
  244. end
  245. if type(func) ~= "function" then
  246. error("绑定添加事件时参数错误,必须是属性名或函数" .. tostring(func))
  247. return;
  248. end
  249. local index = netObject:bindUpdate(onUpdate);
  250. self:_autoUnbind(netObject , "__update" , index);
  251. return index;
  252. end
  253. -- 绑定到NetObject数组
  254. function cc.Node:initWithNetObject(netObject , createFunction)
  255. local items = {};
  256. self.Items = items;
  257. local function onAdd(self , key , value)
  258. local node = createFunction(key , value);
  259. if node then
  260. self:addChild(node);
  261. if node:hasClip("fadeIn") then
  262. node:playClip("fadeIn");
  263. end
  264. end
  265. items[key] = node;
  266. end
  267. self:bindAdd(netObject , onAdd);
  268. local function onRemove(self , key , value)
  269. local node = items[key];
  270. if node then
  271. if node:hasClip("fadeOut") then
  272. local function onPlayEnd()
  273. self:removeChild(node)
  274. end
  275. node:playClip("fadeOut" , onPlayEnd);
  276. else
  277. self:removeChild(node)
  278. end
  279. end
  280. end
  281. self:bindRemove(netObject , onRemove);
  282. self:removeAllChildren();
  283. for i , v in pairs(netObject) do
  284. onAdd(self , i , v);
  285. end
  286. end
  287. -- 绑定事件派发,并在当前对象释放时自动解绑
  288. function cc.Node:bindEvent(eventProtocol , eventName , listener)
  289. local handle = eventProtocol:addEventListener(eventName , listener);
  290. local function unbind()
  291. eventProtocol:removeEventListener(eventName , handle);
  292. end
  293. self:__autoUnbind(eventProtocol , eventName , handle , unbind);
  294. return handle
  295. end
  296. -- 绑定屏幕大小改变
  297. function cc.Node:bindScreenSize(listener)
  298. local function onChanged()
  299. local glView = cc.Director:getInstance():getOpenGLView();
  300. listener(glView:getFrameSize() , cc.Director:getInstance():getWinSize());
  301. end
  302. local lis = cc.EventListenerCustom:create("applicationScreenSizeChanged" , onChanged);
  303. cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(lis , 1);
  304. local function unbind()
  305. if not tolua.isnull(lis) then
  306. cc.Director:getInstance():getEventDispatcher():removeEventListener(lis);
  307. end
  308. end
  309. self:__autoUnbind(cc.Director:getInstance():getEventDispatcher() , "applicationScreenSizeChanged" , lis , unbind);
  310. onChanged();
  311. return lis;
  312. end
  313. -- 发送网络消息,并在当前对象释放时自动解绑
  314. -- 有四种用法:
  315. --[[
  316. 对于定义了sender的协议来说,这样用
  317. ui:sendMsg(app.hero , "addHeroExp" , { heroId = self.HeroInfo.heroId });
  318. ui:sendMsg(app.hero , "addHeroExp" , { heroId = self.HeroInfo.heroId } , function()showTooltip("升级成功")end);
  319. 对于没有定义sender的协议来说,这样用
  320. ui:sendMsg(app.hero , "getHeroList");
  321. ui:sendMsg(app.hero , "getHeroList" , function()showTooltip("拉取英雄列表成功")end);
  322. --]]
  323. function cc.Node:sendMsg(netProtocol , msgName , argsOrResponseFunction , responseFunction)
  324. local function onResponse(...)
  325. if type(argsOrResponseFunction) == "function" then
  326. argsOrResponseFunction(...);
  327. elseif responseFunction then
  328. responseFunction(...);
  329. end
  330. end
  331. if type(argsOrResponseFunction) == "function" or argsOrResponseFunction == nil then
  332. netProtocol[msgName](netProtocol , onResponse);
  333. else
  334. netProtocol[msgName](netProtocol , argsOrResponseFunction , onResponse);
  335. end
  336. do return end
  337. -- 界面析构时不再接受回调
  338. local function unbind()
  339. -- 这里不能关闭等待窗口,等网络消息返回时才可以关闭等待窗口
  340. --app.waitDialogManager:closeWaitDialog();
  341. argsOrResponseFunction = nil
  342. responseFunction = nil
  343. end
  344. self:__autoUnbind(netProtocol, msgName, onResponse, unbind);
  345. end