详解CocosCreator消息分发机制
更新时间:2021年4月16日 00:02 点击:2488
概述
本篇开始介绍游戏业务架构相关的内容。在游戏业务层,所有需要隔离的系统和模块间通信都可以通过消息分发解耦。例如网络返回通知、数据更新同步到界面等。
消息分发基于观察者模式设计。需要处理消息的地方向消息中心注册监听回调,派发消息时,调用消息中心的派发接口遍历该消息的监听队列,调用对应的回调方法。
具体方案
先定义监听回调类型
/** * 消息监听回调方法 */ export type NotifyListener = (src: any, data: any) => void;
通过key-value方式保存监听队列
private static msg2listDict: Dictionary< string, Array<NotifyListenerInfo> > = new Dictionary< string, Array<NotifyListenerInfo> >();
接口定义
/** * 添加多次监听者,需要手动移除 * @param msg * @param listener * @param target */ public static addListener(msg: string, listener: NotifyListener, target?: any): void {} /** * 添加单次监听者,事件触发后即移除 * @param msg * @param listener * @param target */ public static addOnceListener(msg: string, listener: NotifyListener, target?: any): void {} /** * 移除指定消息指定的监听者 * @param msg * @param listener */ public static removeMsgListener(msg: string, listener: NotifyListener): void {} /** * 移除指定消息所有监听者 * @param msg */ public static removeMsgAllListeners(msg: string): void {} /** * 移除指定目标对指定消息的监听 * @param msg * @param target */ public static removeTargetMsgListen(msg: string, target: any): void {} /** * 移除指定目标所有消息监听 * @param target */ public static removeTargetAllMsgListen(target: any): void {} /** * 派发消息 * @param msg * @param src * @param data */ public static notify(msg: string, src: any, data: any): void {}
在添加移除实现中,需要注意某消息可能正在派发。
对于一个消息新添加的监听者,应该在当前队列消息派发完后再派发,因此,添加一个待添加队列
private static listener2add: Array<NotifyListenerInfo> = [];
在添加监听者时做以下判断
// 该消息正在派发,放入待添加队列 if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) { NotifyCenter.listener2add.push(info); return; }
同样在移除监听者时,可能正在派发消息,避免对队列的修改导致for循环异常,添加一个待移除队列,派发消息时,如果该监听者在移除队列则不派发。在消息派发完后再将其移出队列
private static listener2remove: Array<NotifyListenerInfo> = [];
在移除监听者时做以下判断
// 该消息正在派发,放入待移除队列 if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) { NotifyCenter.listener2remove.push(list[i]); } else { list.splice(i, 1); }
派发消息时遍历指定消息下的队列
// 队列不存在,不需要处理 let list = NotifyCenter.msg2listDict.get(msg); if (!list) { return; } // 标记消息正在派发,多个消息可能同时在派发,同一消息可能标记多次 NotifyCenter.notifyMsgs.push(msg); // 处理消息派发 for (let i = 0, n = list.length; i < n; i++) { NotifyCenter._dispatch(list[i], src, data, false); }
派发消息时先判断是否在移除队列
// 在移除队列,不派发 if (NotifyCenter.listener2remove.indexOf(info) >= 0) { return; }
当前队列派发完后检查待添加队列
// 处理待添加队列派发 for (let i = 0, n = msg2add.length; i < n; i++) { if (listener2add[i].msg == msg) { NotifyCenter._dispatch(listener2add[i], src, data, true); } }
引入消息分发中心,隔离的系统、模块间通过消息监听和派发通信,避免互相引用耦合。
以上就是详解CocosCreator消息分发机制的详细内容,更多关于CocosCreator消息分发的资料请关注猪先飞其它相关文章!
相关文章
- 这篇文章主要介绍了游戏开发中如何使用CocosCreator进行音效处理,并对音效组件进行封装,方便以后使用,同学们看完之后,一定要亲手实验一下...2021-04-15
CocosCreator ScrollView优化系列之分帧加载
这篇文章主要介绍了CocosCreator ScrollView的优化,从分帧加载进行了讲解,对性能优化感兴趣的同学,一定要看一下...2021-04-15- 这篇文章主要介绍了如何在CocosCreator里画个炫酷的雷达图,对Graphics感兴趣的同学,一定要看看,并且把代码实践一下...2021-04-16
- 这篇文章主要介绍了CocosCreator入门教程之用TS制作第一个游戏,对TypeScript感兴趣的同学,一定要看一下...2021-04-16
- 这篇文章主要介绍了CocosCreator MVC架构,同学们在制作游戏过程中,尽量使用一些架构,会避免很多问题...2021-04-16
- 这篇文章主要介绍了CocosCreator中几种计时器的使用方法,推荐使用schedule,功能多些,销毁时还能自动移除...2021-04-16
- 这篇文章主要介绍了详解CocosCreator消息分发机制,详细介绍了各模块的设计,同学们一定要自己看下...2021-04-16
- 这篇文章主要介绍了怎样在CocosCreator中使用物理引擎关节,对物理引擎感兴趣的同学,着重要看一下...2021-04-16
- 这篇文章主要介绍了CocosCreator制作射击游戏,各个方面都讲的比较详细,希望同学们自己动手试一下...2021-04-16
- 这篇文章主要介绍了详解CocosCreator项目结构机制,只有了解这些机制后,才能更好的进行项目开发,避免潜在错误,并且快速的除错...2021-04-15
- 这篇文章主要介绍了怎样使用CocosCreator的游戏手柄,每一个步骤都挺详细,资源可以随便找一些,希望同学们看完,一定要试一下...2021-04-15
CocosCreator怎样使用cc.follow进行镜头跟随
这篇文章主要介绍了CocosCreator怎样使用cc.follow进行镜头跟随,想要学习follow的同学,一定要看一下...2021-04-16- 这篇文章主要介绍了CocosCreator的网络通信,内容不多,涉及到的细节,读者可以根据实际情况,自己去延申...2021-04-16
- 这篇文章主要介绍了Cocos Creator 模块化脚本,想加深学习CocosCreator脚本的同学,一定要看一下...2021-04-16