详解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 相关文章推荐
offsetParent 算法分析
Apr 05 Javascript
JS 按钮点击触发(兼容IE、火狐)
Aug 07 Javascript
开发中可能会用到的jQuery小技巧
Mar 07 Javascript
js获取ajax返回值代码
Apr 30 Javascript
javascript中call apply 的应用场景
Apr 16 Javascript
javascript获取wx.config内部字段解决微信分享
Mar 09 Javascript
使用BootStrap和Metroui设计的metro风格微网站或手机app界面
Oct 21 Javascript
JS实现滑动门效果的方法详解
Dec 19 Javascript
angularjs数组判断是否含有某个元素的实例
Feb 27 Javascript
JS实现的A*寻路算法详解
Dec 14 Javascript
微信小程序HTTP接口请求封装的实现
Feb 21 Javascript
vscode配置vue下的es6规范自动格式化详解
Mar 20 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
解析Linux下Varnish缓存的配置优化
2013/06/20 PHP
PHP实现的浏览器检查类
2016/04/11 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
laravel实现上传图片,并且制作缩略图,按照日期存放的代码
2019/10/16 PHP
goto语法在PHP中的使用教程
2020/09/17 PHP
使用jQuery同时控制四张图片的伸缩实现代码
2013/04/19 Javascript
js仿3366小游戏选字游戏
2016/04/14 Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
2016/09/12 Javascript
详解Angular2中Input和Output用法及示例
2017/05/21 Javascript
Vue页面骨架屏注入方法
2018/05/13 Javascript
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】
2018/08/29 Javascript
AJAX在JQuery中的应用详解
2019/01/30 jQuery
node中IO以及定时器优先级详解
2019/05/10 Javascript
python操作MongoDB基础知识
2013/11/01 Python
python使用matplotlib绘制柱状图教程
2017/02/08 Python
Python+Pandas 获取数据库并加入DataFrame的实例
2018/07/25 Python
python标记语句块使用方法总结
2019/08/05 Python
Python使用matplotlib 模块scatter方法画散点图示例
2019/09/27 Python
python二元表达式用法
2019/12/04 Python
基于django 的orm中非主键自增的实现方式
2020/05/18 Python
django filter过滤器实现显示某个类型指定字段不同值方式
2020/07/16 Python
python音频处理的示例详解
2020/12/23 Python
利用css3画个同心圆示例代码
2017/07/03 HTML / CSS
CSS3+JavaScript实现炫酷呼吸效果的示例代码
2020/06/15 HTML / CSS
英国简约舒适女装品牌:Great Plains
2018/07/27 全球购物
高级护理实习生自荐信
2013/09/28 职场文书
教育学专业毕业生的自我鉴定
2013/11/26 职场文书
《日月潭》教学反思
2014/02/28 职场文书
大学生求职信
2014/06/17 职场文书
优秀大专毕业生求职信
2014/08/04 职场文书
全国法院系统开展党的群众路线教育实践活动综述(全文)
2014/10/25 职场文书
餐饮店长岗位职责
2015/04/14 职场文书
JS新手入门数组处理的实用方法汇总
2021/04/07 Javascript
详解分布式系统中如何用python实现Paxos
2021/05/18 Python
MYSQL中文乱码问题的解决方案
2022/06/14 MySQL