消息管理器是用来在各个实体对象和功能模块之间进行数据通信的.一个好的消息管理器可以最大限度的实现解藕操作,使得模块具有"热插拔"特性,这是我们所希望达到效果.但是在实现的过程中有几点细节实现需要仔细斟酌,比如消息管理与分发的方式,如何实现一个通用的支持动态更新的消息管理器.下面是我学习根据自身经验实现的一个消息管理器,希望能够抛砖引玉,共同提高 :)
基本思路:
1. 面向接口编程: 实现一个IMsgListener抽象接口类,所有需要消息处理的类都需要从该接口类继承.
2. 以列表的方式对单一消息的所有监听器进行管理维护: 这样做的目的是可以动态的改变监听者的意图.
3. 采用有针对性的分发方式:在2的基础上进行消息分发,而不是老式的对所有监听器发送.
4. 细化消息处理返回值: 这样做可以减少不必要的消息发送,提高效率的同时更符合实际需要.
主要代码如下:
1. 监听者接口类:
1/**//**
2@ Enum: 处理消息的结果
3@ Mark:
4*/
5enum enMsgHandleResult
6{
7 EMHR_UNKNOWN, // 不识别
8 EMHR_IGNORE, // 忽略不处理
9 EMHR_CONTINUE, // 处理并继续
10 EMHR_TERMINATE, // 私有消息,处理后不允许继续分发继续处理
11};
12
13/**//**
14@ Class: 消息处理器接口
15@ Mark:
16*/
17class IMsgListener
18{
19public:
20 virtual ~IMsgListener( void ) {};
21public:
22 /**//**
23 @ Function: 消息接收
24 @ Mark:
25 */
26virtual enMsgHandleResult HandleMessage( size_t msgid, const CVarList& varlist ) = 0;
27
28 /**//**
29 @ Function: 获取监听器名字
30 @ Mark:
31 */
32 virtual const char* GetName( void ) = 0;
33
34 /**//**
35 @ Function: 获取监听器ID
36 @ Mark:
37 */
38 virtual CHashItem GetID( void ) = 0;
39};
2. 消息管理器类
1class CMsgManager
2{
3public:
4 CMsgManager( void );
5 ~CMsgManager( void ) ;
6
7public:
8 /**//**
9 @ Function: 注册消息监听器对指定消息的监听
10 @ Mark:
11 */
12 virtual bool RegisterListener( int msgid, IMsgListener* listener );
13
14 /**//**
15 @ Function: 注销消息监听器对指定消息的监听
16 @ Mark:
17 */
18 virtual bool RemoveListener( int msgid, IMsgListener* listener );
19
20 /**//**
21 @ Function: 注销消息监听器对所有消息的监听
22 @ Mark:
23 */
24 virtual bool RemoveListener( IMsgListener* listener );
25
26 /**//**
27 @ Function: 1对1发送消息
28 @ Mark:
29 */
30 virtual void SendMessage( size_t objectid, const CVarList& varlist );
31
32 /**//**
33 @ Function: 广播发送消息
34 @ Mark:
35 */
36 virtual void BroadcastMessage( const CVarList& varlist );
37
38 /**//**
39 @ Function: 获取有效消息数量
40 @ Mark:
41 */
42 virtual size_t GetMsgCount( void );
43
44 /**//**
45 @ Function: 获取指定消息的监听者数量
46 @ Mark:
47 */
48 virtual size_t GetMsgListenerCount( int msgid );
49
50protected:
51
52 typedef std::list MsgListenersList, *MsgListenersListPtr;
53 typedef std::map< int, MsgListenersList > MsgMap;
54
55 MsgMap m_MsgMap;
56};
注: CVarlist是一个参数列表
CHashItem为一个size_t的哈希值,代表监听器对象
在具体的使用中,将自己和自己关注的消息进行注册即可.