详解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奇异的arguments分析
Oct 20 Javascript
10分钟学会写Jquery插件实例教程
Sep 06 Javascript
简述AngularJS的控制器的使用
Jun 16 Javascript
javascript数据结构之双链表插入排序实例详解
Nov 25 Javascript
微信小程序 获取相册照片实例详解
Nov 16 Javascript
AngularJS中$http的交互问题
Mar 29 Javascript
Webpack实现按需打包Lodash的几种方法详解
May 08 Javascript
JavaScript实现的浏览器下载文件的方法
Aug 09 Javascript
Vue shopCart 组件开发详解
Jan 26 Javascript
vue.js实现的经典计算器/科学计算器功能示例
Jul 11 Javascript
微信小程序点击view动态添加样式过程解析
Jan 21 Javascript
Javascript中Microtask和Macrotask鲜为人知的知识点
Apr 02 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
php汉字转拼音的示例
2014/02/27 PHP
wordpress自定义标签云与随机获取标签的方法详解
2019/03/22 PHP
defer属性导致引用JQuery的页面报“浏览器无法打开网站xxx,操作被中止”错误的解决方法
2010/04/27 Javascript
仿微博字符限制效果实现代码
2012/04/20 Javascript
js获取IFRAME当前的URL的方法
2013/11/13 Javascript
js实现仿百度瀑布流的方法
2015/02/05 Javascript
AspNet中使用JQuery上传插件Uploadify详解
2015/05/20 Javascript
ECMAScript中函数function类型
2015/06/03 Javascript
初识angular框架后的所思所想
2016/02/19 Javascript
12 款 JS 代码测试必备工具(翻译)
2016/12/13 Javascript
Bootstrap的modal拖动效果
2016/12/25 Javascript
Jquery获取radio选中的值
2017/05/05 jQuery
微信浏览器禁止页面下拉查看网址实例详解
2017/06/28 Javascript
webpack 1.x升级过程中的踩坑总结大全
2017/08/09 Javascript
Node.js学习之TCP/IP数据通讯(实例讲解)
2017/10/11 Javascript
vue-cli 如何打包上线的方法示例
2018/05/08 Javascript
使用p5.js临摹动态图形
2019/10/23 Javascript
javascript中导出与导入实现模块化管理教程
2020/12/03 Javascript
Python中类的定义、继承及使用对象实例详解
2015/04/30 Python
python中字符串类型json操作的注意事项
2017/05/02 Python
Python Opencv任意形状目标检测并绘制框图
2019/07/23 Python
弄懂这56个Python使用技巧(轻松掌握Python高效开发)
2019/09/18 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
浅谈sklearn中predict与predict_proba区别
2020/06/28 Python
Python自动巡检H3C交换机实现过程解析
2020/08/14 Python
伦敦高级内衣品牌:Agent Provocateur(大内密探)
2016/08/23 全球购物
美国在线家装零售商:Build.com
2016/09/02 全球购物
波兰在线体育用品商店:Hop-Sport.pl
2019/07/23 全球购物
外贸专业求职信
2014/03/09 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
张家口市高新区党工委群众路线教育实践活动整改方案
2014/10/25 职场文书
房屋产权共有协议书范本
2014/11/03 职场文书
自主招生推荐信怎么写
2015/03/26 职场文书
装饰技术负责人岗位职责
2015/04/13 职场文书
防震减灾主题班会
2015/08/14 职场文书
Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换
2022/04/24 Python