组件的绑定
在stage的方法里面会出现像self:fixbanker(rule)这样的函数调用,但是在该类和父类里面都找不到显示的定义fixbanker这个方法的地方,原因是设计了一个组件绑定的机制。
总的来说就是,就是stage和Behavior各自用对方的引用,由于Behavior有统一个接口bind()等,stage会继承到父类的bindMethod()方法,过程很绕,拿对方的引用传入自己的方法(字段)作为参数来调用对方暴露的接口,让对方也拥有自己的方法,以便对方调用。有点像一个设计模式,我忘了是哪个了,策略模式还是哪个来着?
拿DingZhuangStage做来说,
继承关系:DingZhuangStage.lua--->GameStage.lua--->TGameObject.lua--->GameObject.lua
在TGameObject.lua的ctor中会调用initBehaviors(),根据GameConfig里面的配置来找到当前stage配置的是哪个behavior,比如DingZhuangStage对应的FixBankerBehavior
--GameConfig.lua local behaviorConfig = {}; behaviorConfig.LogicManager = {"DealCardBehavior",} behaviorConfig.PlayCardStage = { "GameRoundBehavior","GrapCardBehavior","OperationBehavior","DumpHandCardBehavior", } behaviorConfig.DingZhuangStage = {"FixBankerBehavior"}
--TGameObejct.lua function TGameObject:ctor( tableDB ) if tableDB then self.m_tableDB = tableDB; self:bindBehavior("LogBehavior"); self:bindBehavior("DAOBehavior"); self:initBehaviors(tableDB:queryBehavior(self.className__)); end self:initBehaviors(BehaviorFactory.behaviorConfig[self.className__]); end function TGameObject:initBehaviors( behaviors ) if behaviors then for _,v in ipairs(behaviors) do self:bindBehavior(v); end end end
有可能绑定多个behavior,所以在initBehavior()中遍历绑定所有Behavior。bindBehavior中,递归的绑定Behavior的依赖。
function TGameObject:bindBehavior( behaviorName ) ---检查是否已经绑定该行为 if not self.behaviorObjects_ then self.behaviorObjects_ = {} end if self.behaviorObjects_[behaviorName] then return end ---根据配置表创建行为 local behavior = BehaviorFactory.createBehavior(behaviorName, self.m_tableDB) ---获取行为依赖 for i, dependBehaviorName in pairs(behavior:getDepends()) do --绑定依赖行为 self:bindBehavior(dependBehaviorName) ---以依赖行为名为key,以需要此依赖的行为名做list,记录下来 if not self.behaviorDepends_ then self.behaviorDepends_ = {} end if not self.behaviorDepends_[dependBehaviorName] then self.behaviorDepends_[dependBehaviorName] = {} end table.insert(self.behaviorDepends_[dependBehaviorName], behaviorName) end ---将行为上的方法绑定至此object类上 behavior:bind(self) ---以行为名为key,行为的操作对像为vaule记录下来 self.behaviorObjects_[behaviorName] = behavior ---按优先级重置行为 self:resetAllBehaviors() end
具体的绑定就在behavior:bind(self)这句。每个Behavior都会有bind()这个方法,用这个方法来将stage和他配置的Behavior绑定起来。
function FixBankerBehavior:bind(object) for i,v in ipairs(exportInterface) do object:bindMethod(self, v, handler(self, self[v])); end end
Behavior的bind()方法会调用传进来的stage中的bindMethod()方法,在bindMethod方法中,就在当前stage中加入了Behavior中提供给stage中使用的方法。实现了绑定。
function GameObject:bindMethod(behavior, methodName, method, deprecatedOriginMethod, callOriginMethodLast) --取出之前的方法 local originMethod = self[methodName] if not originMethod then self[methodName] = method return end ..... ..... end