详解CocosCreator消息分发机制


Posted in Javascript onApril 16, 2021

概述

本篇开始介绍游戏业务架构相关的内容。在游戏业务层,所有需要隔离的系统和模块间通信都可以通过消息分发解耦。例如网络返回通知、数据更新同步到界面等。

消息分发基于观察者模式设计。需要处理消息的地方向消息中心注册监听回调,派发消息时,调用消息中心的派发接口遍历该消息的监听队列,调用对应的回调方法。

具体方案

先定义监听回调类型

/**
 * 消息监听回调方法
 */
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消息分发的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
JavaScript脚本性能优化注意事项
Nov 18 Javascript
jQuery 遍历-nextUntil()方法以及prevUntil()方法的使用介绍
Apr 26 Javascript
javascript中SetInterval与setTimeout的定时器用法
Aug 24 Javascript
jquery判断复选框是否被选中的方法
Oct 16 Javascript
fastclick插件导致日期(input[type=&quot;date&quot;])控件无法被触发该如何解决
Nov 09 Javascript
浅谈原生JS实现jQuery的animate()动画示例
Mar 08 Javascript
vue.js父组件使用外部对象的方法示例
Apr 25 Javascript
基于JavaScript中标识符的命名规则介绍
Jan 06 Javascript
JavaScript This指向问题详解
Nov 25 Javascript
vue实现标签云效果的示例
Nov 09 Javascript
jQuery实现tab栏切换效果
Dec 22 jQuery
Vue操作Storage本地化存储
Apr 29 Vue.js
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
php cURL和Rolling cURL并发方式比较
2013/10/30 PHP
PHP查询快递信息的方法
2015/03/07 PHP
如何解决PHP无法实现多线程的问题
2015/09/25 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
2016/08/23 PHP
javascript获取url上某个参数的方法
2013/11/08 Javascript
技术男用来对妹子表白的百度首页
2014/07/23 Javascript
用JavaScript实现用一个DIV来包装文本元素节点
2014/09/09 Javascript
JQuery选择器绑定事件及修改内容的方法
2015/01/23 Javascript
JS实现控制表格内指定单元格内容对齐的方法
2015/03/30 Javascript
jQuery定义插件的方法
2015/12/18 Javascript
深入浅析NodeJs并发异步的回调处理
2015/12/21 NodeJs
你有必要知道的25个JavaScript面试题
2015/12/29 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
vue.js 左侧二级菜单显示与隐藏切换的实例代码
2017/05/23 Javascript
vue+jquery+lodash实现滑动时顶部悬浮固定效果
2018/04/28 jQuery
微信小程序文章详情功能完整实例
2020/06/03 Javascript
Python实现的凯撒密码算法示例
2018/04/12 Python
TensorFlow利用saver保存和提取参数的实例
2018/07/26 Python
pyqt远程批量执行Linux命令程序的方法
2019/02/14 Python
利用python和百度地图API实现数据地图标注的方法
2019/05/13 Python
基于keras 模型、结构、权重保存的实现
2020/01/24 Python
django rest framework serializers序列化实例
2020/05/13 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
通用C#笔试题附答案
2016/11/26 面试题
什么时候需要进行强制类型转换
2016/09/03 面试题
家长给孩子的表扬信
2014/01/17 职场文书
创先争优制度
2014/01/21 职场文书
公司应聘自荐书
2014/06/14 职场文书
英语课前三分钟演讲稿
2014/08/19 职场文书
竞选班长演讲稿500字
2014/08/22 职场文书
单方离婚协议书范本(2014版)
2014/09/30 职场文书
悬崖上的金鱼姬观后感
2015/06/15 职场文书
开发一个封装iframe的vue组件
2021/03/29 Vue.js
元素水平垂直居中的方式
2021/03/31 HTML / CSS
CSS3实现的3D隧道效果
2021/04/27 HTML / CSS
vue实现水波涟漪效果的点击反馈指令
2021/05/31 Vue.js