详解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获取IP和PcName(IE)在vs中可用
Aug 02 Javascript
JS获取select的value和text值的简单实例
Feb 26 Javascript
JavaScript使用ActiveXObject访问Access和SQL Server数据库
Apr 02 Javascript
充分发挥Node.js程序性能的一些方法介绍
Jun 23 Javascript
JavaScript中的Promise使用详解
Jun 24 Javascript
jquery实现点击查看更多内容控制段落文字展开折叠效果
Aug 06 Javascript
Javascript编程中几种继承方式比较分析
Nov 28 Javascript
AngularJS 整理一些优化的小技巧
Aug 18 Javascript
移动端Ionic App 资讯上下循环滚动的实现代码(跑马灯效果)
Aug 29 Javascript
jQuery简单判断值是否存在于数组中的方法示例
Apr 17 jQuery
js实现头像上传并且可预览提交
Dec 25 Javascript
node脚手架搭建服务器实现token验证的方法
Jan 20 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
论建造顺序的重要性
2020/03/04 星际争霸
Zend的AutoLoad机制介绍
2012/09/27 PHP
php mssql扩展SQL查询中文字段名解决方法
2012/10/15 PHP
php实现最简单的MVC框架实例教程
2014/09/08 PHP
PHP进阶学习之命名空间基本用法分析
2019/06/18 PHP
这些年、我收集的JQuery代码小结
2012/08/01 Javascript
javascript ajax的5种状态介绍
2014/08/18 Javascript
jQuery tagsinput在h5邮件客户端中应用详解
2016/09/26 Javascript
Javascript实现汉字和拼音互转的终极方案
2016/10/19 Javascript
纯js代码生成可搜索选择下拉列表的实例
2018/01/11 Javascript
使用Angular CLI进行单元测试和E2E测试的方法
2018/03/24 Javascript
NodeJS模块与ES6模块系统语法及注意点详解
2019/01/04 NodeJs
详解js常用分割取字符串的方法
2019/05/15 Javascript
javascript实现的字符串转换成数组操作示例
2019/06/13 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
vue实现商城秒杀倒计时功能
2019/12/12 Javascript
JavaScript实现刮刮乐效果
2020/11/01 Javascript
[01:08:32]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第二场 1月18日
2021/03/11 DOTA
[06:57]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD 选手采访
2021/03/11 DOTA
基于 Django 的手机管理系统实现过程详解
2019/08/16 Python
python读取ini配置的类封装代码实例
2020/01/08 Python
在Keras中利用np.random.shuffle()打乱数据集实例
2020/06/15 Python
Python APScheduler执行使用方法详解
2020/12/10 Python
tensorflow与numpy的版本兼容性问题的解决
2021/01/08 Python
澳大利亚的奢侈品牌:Oroton
2016/08/26 全球购物
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
西雅图的买手店:Totokaelo
2019/10/19 全球购物
网络体系结构及协议的定义
2014/03/13 面试题
离职感谢信
2015/01/21 职场文书
贪污检举信范文
2015/03/02 职场文书
个人求职意向书
2015/05/11 职场文书
葬礼主持词
2015/07/02 职场文书
党员干部学习心得体会
2016/01/23 职场文书
关于党风廉政建设宣传教育月的活动总结!
2019/08/08 职场文书
Mysql关于数据库是否应该使用外键约束详解说明
2021/10/24 MySQL
Redis中缓存穿透/击穿/雪崩问题和解决方法
2021/12/04 Redis