详解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 相关文章推荐
完整显示当前日期和时间的JS代码
Sep 17 Javascript
jQuery formValidator表单验证插件开源了 含API帮助、源码、示例
Aug 14 Javascript
输入框过滤非数字的js代码
Sep 18 Javascript
再探JavaScript作用域
Sep 24 Javascript
AngularJS入门教程之与服务器(Ajax)交互操作示例【附完整demo源码下载】
Nov 02 Javascript
Bootstrap table使用方法详细介绍
Dec 09 Javascript
原生js实现对Ajax的封装(仿jquery)
Jan 22 Javascript
bootstrap daterangepicker汉化以及扩展功能
Jun 15 Javascript
angular中不同的组件间传值与通信的方法
Nov 04 Javascript
使用async-validator编写Form组件的方法
Jan 10 Javascript
axios+Vue实现上传文件显示进度功能
Apr 14 Javascript
解决layui弹框失效的问题
Sep 09 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
PHP中的use关键字及文件的加载详解
2016/11/28 PHP
thinkPHP5.0框架模块设计详解
2017/03/18 PHP
PHP面向对象程序设计之多态性的应用示例
2018/12/19 PHP
gearman中任务的优先级和返回状态实例分析
2020/02/27 PHP
解决FireFox下[使用event很麻烦]的问题
2006/11/26 Javascript
JavaScript中实现块作用域的方法
2010/04/01 Javascript
YUI的Tab切换实现代码
2010/04/11 Javascript
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
2013/12/26 Javascript
浅谈Node.js中的定时器
2015/06/18 Javascript
BootStrap3使用错误记录及解决办法
2016/12/22 Javascript
jQuery实现动态加载select下拉列表项功能示例
2018/05/31 jQuery
react-native使用leanclound消息推送的方法
2018/08/06 Javascript
React SSR样式及SEO的实践
2018/10/22 Javascript
jQuery插件实现非常实用的tab栏切换功能【案例】
2019/02/18 jQuery
Node.js API详解之 os模块用法实例分析
2020/05/06 Javascript
Django集成CAS单点登录的方法示例
2019/06/10 Python
Python获取数据库数据并保存在excel表格中的方法
2019/06/12 Python
PyCharm取消波浪线、下划线和中划线的实现
2020/03/03 Python
python opencv 检测移动物体并截图保存实例
2020/03/10 Python
Python 读取位于包中的数据文件
2020/08/07 Python
纯CSS3制作漂亮带动画效果的主机价格表
2015/04/25 HTML / CSS
英国知名衬衫品牌美国网站:Charles Tyrwhitt美国
2016/08/28 全球购物
StubHub墨西哥:购买和出售您的门票
2016/09/17 全球购物
印度低票价航空公司:GoAir
2017/10/11 全球购物
师范生实习自我鉴定
2013/11/01 职场文书
《乌塔》教学反思
2014/02/17 职场文书
品牌宣传方案
2014/03/21 职场文书
2014年宣传部个人工作总结
2014/12/06 职场文书
2015年教师教学工作总结
2015/04/28 职场文书
超搞笑婚前保证书
2015/05/08 职场文书
经营场所使用证明
2015/06/19 职场文书
《火烧云》教学反思
2016/02/23 职场文书
2019商业计划书格式、范文
2019/04/24 职场文书
css3中transform属性实现的4种功能
2021/08/07 HTML / CSS
mysql分组后合并显示一个字段的多条数据方式
2022/01/22 MySQL
根德5570型九灯四波段立体声收音机是电子管收音机的楷模 ? 再论5570
2022/04/05 无线电