一个强大的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