H33中的消息機(jī)制的使用和原理

H33中的消息機(jī)制的使用和原理

目前消息觸發(fā)分為三類:

  • object接口,使用objs_call觸發(fā),監(jiān)聽游戲中所有object的消息觸發(fā)。
  • 典型的觀察者模式,需要手動注冊到某個(gè)unit中。所有的object都可以通過這種方式監(jiān)聽任何一個(gè)unit上的消息。
  • action接口,自動監(jiān)聽所屬unit的IID消息,回調(diào)信息在action enter時(shí)開始生效。

后兩種都將消息函數(shù)信息存放在unity.ActionManager中,并都使用actions_call回調(diào)。

消息機(jī)制 監(jiān)聽范圍 觸發(fā)方式 監(jiān)聽信息存放位置 添加接口方式 自動注冊 可使用對象 可配置監(jiān)聽次數(shù)
object接口 全局游戲 objs_call() objMgr add_interface object 不可以
觀察者模式 某個(gè)unit actions_call(unit) actionMgr add_observer_interface object 可以
action接口 所屬unit actions_call(unit) actionMgr add_action_interfaces action 不可以

先說使用上的區(qū)別:

消息機(jī)制 監(jiān)聽范圍 觸發(fā)方式 監(jiān)聽信息存放位置 添加接口方式 自動注冊 可使用對象 可配置監(jiān)聽次數(shù)
object接口 全局游戲 objs_call() objMgr add_interface object 不可以
觀察者模式 某個(gè)unit actions_call(unit) actionMgr add_observer_interface object 可以
action接口 所屬unit actions_call(unit) actionMgr add_action_interfaces action 不可以

1 消息機(jī)制的概括介紹

以上三種消息機(jī)制,他們的實(shí)現(xiàn)都可以分為四個(gè)步驟:接口聲明,接口注冊,監(jiān)聽信息保存以及消息觸發(fā)。

接口聲明在ClientEventInterface中,聲明有那些接口以及每個(gè)接口有哪些消息處理函數(shù)。三種消息機(jī)制共用一套消息聲明。

接口注冊是將object或action添加的接口IID以及實(shí)現(xiàn)的接口函數(shù),保存到class中。在這里可以根據(jù)IID和funcID找到具體要調(diào)用的方法。

監(jiān)聽信息保存是將對監(jiān)聽信息保存到unit中的actionManager中或者全局的objMgr中,在這里可以通過消息的IID找到監(jiān)聽這個(gè)消息的所有object或action。

消息觸發(fā)是根據(jù)IID查找監(jiān)聽IID的unit,以及根據(jù)funcID去class中的接口信息中找到要調(diào)用的函數(shù)。

2 使用方法

2.1 添加消息處理函數(shù)以及接口類

在ClientEventInterface中預(yù)先聲明消息,消息處理函數(shù)和接口類如下所示

class IOnFuryButtonClick:#一個(gè)接口類可以存在多個(gè)消息處理函數(shù)
    def on_fury_button_click(self, stateID):
        pass
FURY_BUTTON_CLICK = mgr.createIID(IOnFuryButtonClick)

本文稱IOnFuryButtonClick為接口類,它可能包含幾個(gè)接口(消息處理函數(shù)),接口類代表著一類消息集合;本文稱函數(shù)on_fury_button_click為消息處理函數(shù),它代表著一個(gè)消息。如果要監(jiān)聽消息,必須監(jiān)聽接口類中的所有消息

2.2 object接口的注冊和使用

接口注冊和監(jiān)聽信息保存

在某個(gè)object中重寫函數(shù)init_interfaces,使用add_interface添加接口的IID,這個(gè)object需要實(shí)現(xiàn)接口類中的所有消息處理函數(shù)。

def init_interfaces(self):
    if super(FuryAction, self).init_interfaces():
        self.add_interface(G.IID.FURY_BUTTON_CLICK)
        return True
    return False

object在創(chuàng)建時(shí),自動將監(jiān)聽信息保存到ObjectManager中。

消息調(diào)用

使用以下代碼,則所有實(shí)現(xiàn)了該接口的object中的函數(shù)on_fury_button_click都會被調(diào)用。

G.IID.IOnFuryButtonClick.on_fury_button_click.objs_call(self.furyStateID)

2.3 觀察者模式的注冊和使用

register_observer可以將object A注冊為objectB的某一消息的觀察者,當(dāng)觸發(fā)objectB的消息時(shí),會調(diào)用A中的消息處理函數(shù)。

接口注冊和監(jiān)聽信息保存

接口注冊,重寫函數(shù)init_observer_interfaces并使用add_observer_interface添加接口IID。


def init_observer_interfaces(self):
    if super(CompUnitManagerAction, self).init_observer_interfaces():
        self.add_observer_interface(G.IID.DEAD)
        return True
    return False

監(jiān)聽信息保存,通過unitA.actionManager.register_observer(G.IID.DEAD,unit_observer,repeatTimes)保存監(jiān)聽信息到actionManager中,將unit_observer作為unitA的觀察者,觀察unit的IID消息。

消息調(diào)用

當(dāng)消息發(fā)生時(shí)使用代碼G.IID.IDeadHandle.on_dead.actions_call(unitA)即可通知觀察unitA的所有觀察者,并調(diào)用觀察者的on_dead消息處理函數(shù)。

2.4 action接口注冊和監(jiān)聽

action接口的注冊只能在action中使用。

接口注冊和監(jiān)聽信息保存

接口注冊,在action中,重寫init_action_interfaces()函數(shù)使用add_action_interface注冊接口類,action注冊接口類需要同時(shí)實(shí)現(xiàn)接口所擁有的所有消息處理函數(shù)。

def init_action_interfaces(self):
    if super(FireEffectAction, self).init_action_interfaces():
        self.add_action_interface(G.IID.ISKILL_APPLY)
        return True
    return False

監(jiān)聽信息保存(此步為自動),當(dāng)action在enter時(shí),會將action注冊到actionManager里面,同時(shí)開始監(jiān)聽接口相關(guān)的消息。

消息調(diào)用

當(dāng)消息發(fā)生,調(diào)用G.IID.ISkillApply.on_apply_skill.actions_call(unitA, self.skillID)就會調(diào)用unitA中實(shí)現(xiàn)了ISKILL_APPLY接口的action中的on_apply_skill函數(shù)。

注意,actions_call(unitA)同時(shí)觸發(fā)觀察者模式的消息回調(diào)和action的接口,首先調(diào)用觀察unitA的觀察者,然后調(diào)用unitA中action實(shí)現(xiàn)的接口。

3 此模塊所依賴的模塊

此模塊將消息處理接口信息注冊到ActionManager和ObjectManager中,只依賴這兩個(gè)模塊的實(shí)現(xiàn)。

4 代碼原理

下文介紹代碼的具體原理,只要記住消息機(jī)制分為四個(gè)步驟:接口聲明,接口注冊,監(jiān)聽信息保存以及消息觸發(fā),那么就比較容易理解。

4.1 消息聲明

聲明了接口,在三種機(jī)制中都可以使用。

在ClientEventInterface中,預(yù)先定義所有的消息處理函數(shù),并將這些處理函數(shù)分類,將同一類的消息處理函數(shù)作為一個(gè)接口類。

interfaceManager給每個(gè)接口類分配一個(gè)IID,并將接口類及消息處理函數(shù)相關(guān)信息存放在InterfaceManager中。

在InterfaceManager中根據(jù)接口類IID就能獲得這個(gè)接口類所有的消息處理函數(shù)信息。

將每個(gè)接口類的接口函數(shù)改為指向一個(gè)ObjectInterfaceFunctor對象,此對象保存iid信息,消息處理函數(shù)ID信息,封裝消息函數(shù)查找過程等,actions_callobjs_call都屬于該對象。

4.2 object接口

object的創(chuàng)建時(shí)首先進(jìn)行接口注冊,init_interface調(diào)用add_interface根據(jù)添加的接口IID,獲得接口所有的消息處理函數(shù)名,然后根據(jù)函數(shù)名找到object的對應(yīng)函數(shù),存放在object.interfaces中,interfaces={iid:{fid:func},...}

object創(chuàng)建同時(shí)要注冊到ObjectManager中,此時(shí)保存監(jiān)聽消息到ObjectManager.actionMap中。

在objs_call中,首先根據(jù)IID在ObjectManager中找到監(jiān)聽IID消息的object,然后根據(jù)funcId在object.__class__.interfaces中找到對應(yīng)的函數(shù),然后調(diào)用。

4.3 觀察者模式

使用object.add_observer_interface(iid)為object進(jìn)行接口注冊,此時(shí)將object實(shí)現(xiàn)的所有的消息處理函數(shù)信息存放在object.__class__observerInterfaces[iid]中,其中函數(shù)信息格式為{funcid:func,..}。

使用ActionManager.register_observer(iid,observer,repeatTimes)actionManager.__observers
保存監(jiān)聽iid消息的observer的oid。

當(dāng)actions_call消息觸發(fā)時(shí),actionManager去查找監(jiān)聽此消息的觀察者,根據(jù)消息的funid調(diào)用觀察者的消息處理函數(shù)。

4.4 action接口

使用action.add_action_interface(iid)為action進(jìn)行接口注冊,此時(shí)將action實(shí)現(xiàn)的所有的消息處理函數(shù)信息存放在action.__class__.actionInterfaces[iid]中。

在action enter的時(shí)候,自動調(diào)用actionManager.register_action(action),這時(shí)actionManager.__activeActionInterfaceMap保存監(jiān)聽iid消息的action。

當(dāng)actions_call消息觸發(fā)時(shí),actionManager去查找監(jiān)聽此消息的所有action,根據(jù)消息的funid調(diào)用action的消息處理函數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • 【編者按】本文作者是 BAE 系統(tǒng)公司的軟件工程師 Justin Albano。在本篇文章中,作者通過在 Java...
    OneAPM閱讀 611評論 0 2
  • 一、什么是runloop 字面意思是“消息循環(huán)、運(yùn)行循環(huán)”。它不是線程,但它和線程息息相關(guān)。一般來講,一個(gè)線程一次...
    WeiHing閱讀 8,173評論 11 111
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,762評論 0 9
  • 1、固定收益類基金:保本基金,債券型基金,貨幣基金 權(quán)益類基金:股票型基金,混合型基金、指數(shù)型基金 2、在選指數(shù)基...
    kmforever閱讀 224評論 0 2