一个强大的UI node 抽象

 

 

基于cocos2d -x的一个强大的 界面对象的基类

 

  1 ---@type uinode ui 对象的抽象
  2 --@usage
  3 --       界面打开的执行流程
  4 --       带*的是可选重写的函数,不带*的为必须实现的
  5 --       [定义一个对象]
  6 --       test = {}
  7 --       --------------------------------------------
  8 --       ---配置函数
  9 --       [返回CCBI的名字]
 10 --       function test:getBindUINodeStr() end
 11 --       [*显示模式,不实现是直接打开。不会居中]
 12 --       function test:getShowModel() end
 13 --       --------------------------------------------
 14 --       ---流程函数
 15 --       [*打开界面前要执行网络操作]
 16 --       function test:getCmdStr() end
 17 --       [*打开界面前要执行网络操作需要的数据]
 18 --       function test:getCmdData() end
 19 --       网络命令成功后会进行的操作
 20 --       function test:onRemoteAck(networkArgs) end
 21 --       [*初始化界面上的相关信息]
 22 --       function test:on_initUI(node,openArgs,networkArgs) end
 23 --       [*关闭界面前要进行网络通信]
 24 --       function test:before_close(ackfun) end
 25 --       -----------------------------------------------------------------
 26 --       PS:当有*函数的出现,只要*函数执行成功,才会调用之后的函数
 27 --
 28 --       usage: local obj = test.getInstance()
 29 --              obj:open(args)  --args 为要传送到on_initUI中的args数据
 30 uinode ={}
 31 
 32 require("base")
 33 require("userGuidelines")
 34 
 35 ---===============================================================
 36 ---IUiNode interface
 37 IUiNode = {}
 38 ---IUiNode interface
 39 createInterface(IUiNode,"IUiNode",function(self,openArgs) end)
 40 ---===============================================================
 41 
 42 ---@field 是否为中心显示
 43 uinode.isShowInCenterFlg = false
 44 ---@field 当前绑定的节点
 45 --@return #cc.Node cc.node节点
 46 uinode.node = nil
 47 uinode ,supper= inheritance(uinode,object)
 48 
 49 ------------------------------------------------------------------------
 50 --显示模式定义
 51 uinode.showModel = {
 52     NOTADDTO_CONTENT = -1,
 53     NONE = 0,
 54     NORMAL = 1,
 55     CENTER=2,
 56     DELAYED_SHUTDOWN=3,
 57     nil
 58 }
 59 
 60 ----------------------------------------------------------
 61 ---资源管理器
 62 local unloadResource =  {}
 63 
 64 function uinode:unloadCustomResources()
 65     local res = self:__getCustomResources()
 66     if res ~= nil and #res > 0 then
 67         xse.base.unloadTextures(res)
 68     end
 69 end
 70 
 71 function uinode:__getCustomResources()
 72     if self.getCustomResources ==  nil then return {} end
 73     local resources = self:getCustomResources()
 74     return resources or  {}
 75 end
 76 
 77 function uinode:starLoadResource()
 78     if self.mask == nil then
 79         self.mask = xse.base.loadCCBI("waitting.ccbi",false)
 80         xse.base.Scene:addChild(self.mask,999999999)
 81     end
 82 end
 83 
 84 function uinode:endLoadResource()
 85     xse.base.Scene:removeChild(self.mask)
 86     self.mask = nil
 87 end
 88 
 89 ---加载资源
 90 function uinode:loadResource(onloadComplate)
 91     if uinode.__getCustomResources ~= nil then
 92         local res =  self:__getCustomResources()
 93         if res == nil or #res == 0 then onloadComplate()
 94         else
 95             local __id = nil
 96             local __index  = 1
 97             local __timerCounter = 1
 98             self:starLoadResource()
 99             local loaded = false
100             __id = xse.base.timer.tick.add(function()
101                 if loaded ~= true then loaded = true
102                     for var=1, #res do
103                         cc.Director:getInstance():getTextureCache():addImageAsync(res[var],
104                             function()
105                                 log("set load command :"..res[var])
106                                 __index = __index + 1
107                             end)
108                     end
109                 end
110 
111                 __timerCounter = __timerCounter + 1
112                 if __index >=  #res and __timerCounter > 100 then
113                     onloadComplate()
114                     self:endLoadResource()
115                     xse.base.timer.tick.remove(__id)
116                 end
117             end)
118         end
119     elseif onloadComplate~= nil then
120         onloadComplate()
121     end
122 end
123 
124 -------------------------------------------------------------------------
125 --帮助函数私有成员函数
126 
127 ---加载CCBI文件
128 --@param nodestr string 要加载的资源名字,不包含后缀名
129 --@return #cc.Node 一个node节点
130 function uinode:loadCCBI(nodestr)
131     assert(nodestr~=nil and type(nodestr)=="string","param nodestr must a string type")
132 --    local node = xse.base.loadScene(nodestr,nil,self:getShowModel()== uinode.showModel.CENTER)
133     local node = xse.base.loadScene(nodestr,nil)
134     return node
135 end
136 
137 ---为当前对象绑定一个ccbi
138 --@param nodestr string 要加载的资源名字,不包含后缀名
139 --@return cc.Node 当前对象绑定的节点
140 function uinode:bindCCBI(nodestr)
141     if self.node~=nil then
142         local parent = self.node:getParent()
143         if parent then parent:removeChild(parent) end
144         self.node = nil
145     end
146 
147     if self.node == nil then
148         self:registeUICallBack()
149         self.node = self:loadCCBI(nodestr)
150         self.node.__bindToInstance = self
151     end
152     return self.node
153 end
154 
155 ---绑定脚本到ccbi上
156 function uinode:bindScriptToNode(node)
157     node.__bindToInstance = self
158 end
159 
160 ---卸载ccbi文件
161 --@param nodestr string 要卸载的资源名字,不包含后缀名
162 function uinode:unloadCCBI(nodestr)
163     assert("false","暂时不支持的方法")
164 end
165 
166 ---重新加载CCBI文件
167 --@param nodestr string 要加载的资源名字,不包含后缀名
168 function uinode:reloadCCBI()
169     local parent = self.node:getParent()
170     if parent ~= nil then parent:removeChild(self.node)end
171     self:bindCCBI(self:getBindUINodeStr())
172 end
173 
174 ---显示界面函数
175 function uinode:show(onshowComplate)
176     assert(onshowComplate,"callbakc is nil value")
177     switch(self:getShowModel(),{
178 
179             [uinode.showModel.NOTADDTO_CONTENT] = function()
180                 ---不设置为添加到窗口中,就直接调用aftershow
181                 self:afterShow()
182             end,
183 
184             [uinode.showModel.NORMAL] = function()
185                 ---添加到界面上
186                 xse.base.show(nil,self.node)
187                 ---显示动画
188                 xse.base.animal.show(
189                     self.node,
190                     nil,
191                     function() onshowComplate() ; self:afterShow() end
192                 )
193             end,
194 
195             [uinode.showModel.CENTER] = function()
196                 onshowComplate();
197                 xse.base.animal.showOnCenter(self.node,nil,
198                     function() self:close(); end,
199                     self,
200                     function ()
201                         self:afterShow();
202                     end)
203             end,
204 
205             [uinode.showModel.DELAYED_SHUTDOWN] = function()
206                 onshowComplate();
207                 xse.base.show(nil,self.node);
208             end,
209 
210             [uinode.showModel.NONE] = function()
211                 xse.base.animal.show(self.node,xse.base.Scene,
212                     function()
213                         onshowComplate();
214                         self:afterShow();
215                     end, false
216                 ) end,
217 
218             ["default"] = function()
219                 xse.base.animal.show(self.node,
220                     nil,
221                     function() onshowComplate();self:afterShow() end)
222             end,
223     })
224 
225     self:endLoadResource()
226 end
227 
228 function uinode:afterShow()
229 
230 end
231 
232 function uinode:processClose()
233     self.moreNode = nil
234     switch(self:getShowModel(),{
235         [uinode.showModel.NORMAL] = function()
236             xse.base.hide(nil,self.node,function()
237                 self:after_close()
238             end);
239             self.node = nil;
240         end,
241         [uinode.showModel.CENTER] = function()
242             xse.base.hide(nil,self.node,function()
243                 self:after_close()
244             end);
245             self.node = nil;
246         end,
247         [uinode.showModel.DELAYED_SHUTDOWN] = function()
248             local action = cc.Sequence:create(cc.DelayTime:create(1),cc.CallFunc:create(function()
249                 xse.base.hide(nil,self.node,function() self:after_close() end);
250                 self.node = nil;
251             end))
252             self.node:runAction(action)
253         end,
254         ["default"] = function()
255             xse.base.hide(nil,self.node,function()
256                 self:after_close()
257             end);
258             self.node = nil;
259         end,
260     })
261 
262 
263 end
264 
265 function uinode:after_close()
266     self:unloadCustomResources()
267 end
268 
269 ---关闭界面函数
270 function uinode:close(sender)
271     log("#close ".. tostring(self:getHashCode()))
272     ---在关闭前的回掉
273     if self.before_close ~=nil and type(self.before_close) == "function" then
274         self:before_close(function(rd,sn,sd)
275             if type(sender) == "function" then sender()end
276         end)
277         self:processClose()
278     else
279         if type(sender) == "function" then  sender() end
280         self:processClose()
281     end
282     self:unregisteUICallBack() --避免在关闭的时候还有操作造成无法处理的bug
283 end
284 
285 ---注册自己定义的ui回调事件
286 function uinode:setCustomUiCallBack()
287 ---不做任何事情,留给子类去处理
288 end
289 
290 ---注册当前node 的回调事件
291 function uinode:registeUICallBack()
292     ---自定义事件注册
293     self:setCustomUiCallBack()
294     ---
295     local name = self:getName()
296     if name ~="unkonw" then
297         for key, var in pairs(self) do
298             if type(var)== "function"then
299                 xse.base.addEventSupportA(name,key,
300                     function(sender)
301                         assert(sender~=nil,"sender is nil value")
302                         local __callinstance = nil
303                         local tempsender = sender
304                         local obj = sender
305                         while sender ~= nil and (type(sender)== "table" or  type(sender)== "userdata") do
306                             assert(not (__callinstance and sender.__bindToInstance),"子节点界面不应该单独绑定到uinode上")
307                             if sender.__bindToInstance~= nil then
308                                 __callinstance = sender.__bindToInstance
309                                 break;
310                             end
311                             sender = sender:getParent()
312                         end
313 
314                         if __callinstance~=nil then
315                             local fun = __callinstance[key]
316                             fun(__callinstance,tempsender)
317                             return
318                         end
319 
320                         assert(false,"Have not found the bound script logic in all parent nodes,")
321                     end)
322             end
323         end
324     end
325 end
326 
327 ---注册当前node ui 的回调事件
328 function uinode:unregisteUICallBack()
329     local name = self:getName()
330     if name ~="unkonw" then
331         for key, var in pairs(self) do
332             if type(var)== "function"then
333                 ---取消事件注册
334                 xse.base.addEventSupportA(name,key,nil)
335             end
336         end
337     end
338 end
339 
340 ---------------------------------------------------------------------------
341 --业务接口
342 
343 ---禁止重写这个函数®
344 function uinode:open(openArgs)
345     if self.UserGuidelineSupportConfig then
346         self.userGuideLineConfigKey =  xse.base.random()
347         userGuidelineManager:addUserGuidelineSupportA(self,self.userGuideLineConfigKey)
348     end
349 
350     self:loadResource(function()
351         local ccbstr = self:getBindUINodeStr()
352         assert(ccbstr,"self:getBindUINodeStr()返回的数据不合法")
353         self:bindCCBI(ccbstr)---绑定界面
354 
355         local function init(self)
356             self.__openArgs = openArgs
357             ---发送网络命令
358             if self.getCmdStr and type(self.getCmdStr) == "function" then
359                 local cmdstr = self:getCmdStr()
360                 local dt = self:getCmdData()
361                 ---发送网络通信
362                 local remoteTask,protocal,command = require "remoteTask",require "protocal",require "command"
363                 assert(cmdstr,"Rewrite getCmdStr function, but the data returned is empty.")
364                 protocal:adddt(command[cmdstr],dt)
365                 local sn = remoteTask.add(protocal,communication.type.tcp,function(rd,sn,sd,self)
366                     if self.onRemoteAck then self:onRemoteAck(rd) end
367                     self:show(function()
368                         self:on_initUI(self.node,self.__openArgs,rd)
369                     end)
370                 end,nil,self)
371 
372             else
373                 self:on_initUI(self.node,self.__openArgs,rd)
374                 self:show(function()
375                     --self:on_iniself:on_initUI(self.node,self.__openArgs,rd)tUI(self.node,self.__openArgs,rd)
376                     end)
377             end
378         end
379 
380         ---DEBUG模式下调用初始化一些必要的基础数据
381         debugCallFun(function()
382             require("tcpExt")
383             ---刷新全部依赖的数据
384             tcpTaskQueue({
385                 {cmd = "WORLD_INIT",dt = {},callback = function(rd,sn,sd) init(self) end,errfun = nil},
386                 {cmd = "COMPANY_INIT",dt = {},callback = function(rd,sn,sd) end,errfun = nil},
387             })
388         end,nil)
389 
390         releaseCallFun(init,self)
391     end)
392 end
393 
394 ---绑定界面函数 [可重写]
395 -- @return #string 要绑定的界面,不包含后缀名
396 function uinode:getBindUINodeStr()
397     assert(false,"必须实现要绑定的界面")
398     return nil
399 end
400 
401 ---显示模式 [可选函数]
402 --@return #uinode.showModel 现实的模式
403 --PS:[显示模式,不实现是直接打开。不会居中]
404 function uinode:getShowModel()
405     return uinode.showModel.NORMAL
406 end
407 
408 ---打开界面前要执行网络操作[可选函数]
409 --@return cmdstr string
410 --function uinode:getCmdStr()
411 --    return nil
412 --end
413 --uinode.getCmdStr = nil
414 
415 ---发送网络命令需要的数据
416 --@return table #table,加载界面前发送网络命令时需要的数据
417 function uinode:getCmdData()
418     return  {}
419 end
420 
421 --
422 
423 
424 ---初始化界面上的相关信息[可选函数]
425 --@param node cc.Node 界面已绑定好的节点
426 --@param openArgs unknow open方法穿过来的数据
427 --@param networkArgs unknow 没有使用网络函数为nil,使用了网络函数:就为网络返回的数据
428 --@return nil
429 function uinode:on_initUI(node,openArgs,networkArgs)
430 --    self:on_initUI(node, opendArgs, networkArgs);
431 end
432 
433 ---关闭界面前要进行网络通信 [可选函数]
434 --@param networkACKCallBack function(rd,sn,sd) 网络成功后的回掉函数
435 --@return nil
436 function uinode:before_close(networkACKCallBack)
437     return false
438 end
439 
440 uinode.before_close = nil
441 
442 return uinode

 使用DEMO

local story = {}

require("depend")
require("tableViewExt")
require("uinode")
local tabView = require "TabView"
local text = require("richtext")

inheritanceA(story,object,"object")
inheritanceA(story,uinode,"uinode")
--uinode abstract function
implementInterface(story,"getShowModel",function(self)  return uinode.showModel.NONE end )
implementInterface(story,"getBindUINodeStr",function(self)  return "start01" end )
implementInterface(story,"getName",function(self) return "message_layer" end )
implementInterface(story,"on_initUI",function(self,node,openArgs,networkArgs) self:init(node,openArgs,networkArgs) end )

function story:init()
    cc.SimpleAudioEngine:getInstance():stopMusic()
    cc.SimpleAudioEngine:getInstance():playMusic("storyBackgroudn.mp3",true)

    local daytime = cc.DelayTime:create(1)
    --TODO::增加语言
    self.fontConfig =  {{fontSize = 30,str="23世界末,第三次世界大战\"能源战\"爆发。\"联军\"为了维持庞大的军费开支,开始将阿波罗-188号飞船用于商用。一些富商为了躲避战火纷纷变卖资产换取船票前往“开普勒”,而您,曾经闻名于世的一代商业传奇人物,也随着这波人流,开启了一段新的征程。",color = xse.color.GREEN}}
    local funAction = cc.CallFunc:create(function()
        self.text = richtext.playMessage(self,self.node, self.fontConfig,function()
            local daytime2 = cc.DelayTime:create(1)
            local nextaction = cc.CallFunc:create(function()
                xse.base.setCCBottonOnClick(self.node:getChildByTag(200),function() self:swithNode() end,self)
                --self:swithNode()
                self.node:getChildByTag(200):setVisible(true)
            end)
            self.node:runAction(cc.Sequence:create(daytime2,nextaction))
        end)
    end)

    self.node:runAction(cc.Sequence:create(daytime,funAction))
    self.node:getChildByTag(200):setVisible(false)
--    self.text=richtext.playMessage(self,self.node, self.fontConfig)
--    xse.base.setCCBottonOnClick(self.node:getChildByTag(200),function() self:swithNode() end,self)
end

function story:swithNode()
    local layer = self.node:getParent()
    self.text:getParent():removeChild(self.text)
    layer:removeChild(self.node)
    self.node = xse.base.loadCCBI("start02.ccbi")
    xse.base.show(layer,self.node)

    local daytime2 = cc.DelayTime:create(8)
    local nextaction = cc.CallFunc:create(function()
        local instance = require("citadel")
        instance:new():open()
    end)
    self.node:runAction(cc.Sequence:create(daytime2,nextaction))
end

return story

 

posted @ 2015-06-04 17:45  czjone  阅读(1298)  评论(0编辑  收藏  举报