详解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 新浪背投广告实现代码
Jul 07 Javascript
深入了解Node.js中的一些特性
Sep 25 Javascript
JavaScript实现下拉列表框数据增加、删除、上下排序的方法
Aug 11 Javascript
jquery.validate使用详解
Jun 02 Javascript
探索Vue.js component内容实现
Nov 03 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
Oct 27 Javascript
关于TypeScript模块导入的那些事
Jun 12 Javascript
JavaScript使用闭包模仿块级作用域操作示例
Jan 21 Javascript
详解Vue中的scoped及穿透方法
Apr 18 Javascript
JS正则表达式封装与使用操作示例
May 15 Javascript
JavaScript实现HSL拾色器
May 21 Javascript
在vue中实现嵌套页面(iframe)
Jul 30 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
在PHP中使用Sockets 从Usenet中获取文件
2008/01/10 PHP
javascript当onmousedown、onmouseup、onclick同时应用于同一个标签节点Element
2010/01/05 Javascript
JavaScript在XHTML中的用法详解
2013/04/11 Javascript
用jquery中插件dialog实现弹框效果实例代码
2013/11/15 Javascript
如何正确使用javascript 来进行我们的程序开发
2014/06/23 Javascript
jQuery中scrollLeft()方法用法实例
2015/01/16 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
2015/09/30 Javascript
JavaScript通过代码调用Flash显示的方法
2016/02/02 Javascript
Nodejs全局安装和本地安装的不同之处
2016/07/04 NodeJs
html+js+highcharts绘制圆饼图表的简单实例
2016/08/04 Javascript
Angularjs的Controller间通信机制实例分析
2016/11/07 Javascript
javascript事件的传播基础实例讲解(35)
2017/02/14 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
2017/03/15 Javascript
webpack构建的详细流程探底
2018/01/08 Javascript
vue初始化动画加载的实例
2018/09/01 Javascript
浅谈React Native 传参的几种方式(小结)
2019/05/21 Javascript
解决layui laydate 时间控件一闪而过的问题
2019/09/28 Javascript
node.js开发辅助工具nodemon安装与配置详解
2020/02/06 Javascript
解决vue侦听器watch,调用this时出现undefined的问题
2020/10/30 Javascript
基于Python实现的扫雷游戏实例代码
2014/08/01 Python
python中使用psutil查看内存占用的情况
2018/06/11 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
Python 使用类写装饰器的小技巧
2018/09/30 Python
对python3 Serial 串口助手的接收读取数据方法详解
2019/06/12 Python
pandas使用之宽表变窄表的实现
2020/04/12 Python
实例讲解CSS3中的border-radius属性
2015/08/18 HTML / CSS
html5 postMessage解决跨域、跨窗口消息传递方案
2016/12/20 HTML / CSS
Fashion Eyewear美国:英国线上设计师眼镜和太阳镜的零售商
2016/08/15 全球购物
幼儿园教师自我鉴定
2014/03/20 职场文书
个人承诺书
2014/03/26 职场文书
机械工程学院大学生求职信
2014/05/25 职场文书
运动会口号16字
2014/06/07 职场文书
争先创优活动总结
2014/08/27 职场文书
2014国庆黄金周超市促销活动方案
2014/09/21 职场文书
实习介绍信模板
2015/01/30 职场文书
2019年入党思想汇报
2019/03/25 职场文书