详解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,caller,callee,call,apply示例及理解
Dec 24 Javascript
基于jquery的一个OutlookBar类,动态创建导航条
Nov 19 Javascript
在jQuery ajax中按钮button和submit的区别分析
Oct 07 Javascript
深入理解JS中的变量及作用域、undefined与null
Mar 04 Javascript
完美兼容多浏览器的js判断图片路径代码汇总
Apr 17 Javascript
js实现精美的图片跟随鼠标效果实例
May 16 Javascript
JavaScript Length 属性的总结
Nov 02 Javascript
Perl Substr()函数及函数的应用
Dec 16 Javascript
axios基本入门用法教程
Mar 25 Javascript
详解如何解决vue开发请求数据跨域的问题(基于浏览器的配置解决)
Nov 12 Javascript
理解JavaScript中的Proxy 与 Reflection API
Sep 21 Javascript
JS使用setInterval计时器实现挑战10秒
Nov 08 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
令PHP初学者头疼十四条问题大总结
2008/11/12 PHP
php笔记之:有规律大文件的读取与写入的分析
2013/04/26 PHP
php 地区分类排序算法
2013/07/01 PHP
PHP中多维数组的foreach遍历示例
2014/06/13 PHP
php使用正则表达式获取图片url的方法
2015/01/16 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
jQuery 动画弹出窗体支持多种展现方式
2010/04/29 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
2012/10/11 Javascript
js格式化时间小结
2014/11/03 Javascript
JavaScript中的类数组对象介绍
2014/12/30 Javascript
javascript常用正则表达式汇总
2015/07/31 Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
2016/02/29 Javascript
jquery+ajax+text文本框实现智能提示完整实例
2016/07/09 Javascript
详解Vue中使用v-for语句抛出错误的解决方案
2017/05/04 Javascript
jquery replace方法去空格
2017/05/08 jQuery
JavaScript实现表单注册、表单验证、运算符功能
2018/10/15 Javascript
Mint UI实现A-Z字母排序的城市选择列表
2018/12/28 Javascript
小程序使用wxs解决wxml保留2位小数问题
2019/12/13 Javascript
通过实例了解Render Props回调地狱解决方案
2020/11/04 Javascript
python3批量删除豆瓣分组下的好友的实现代码
2016/06/07 Python
Python中使用platform模块获取系统信息的用法教程
2016/07/08 Python
Python动刷新抢12306火车票的代码(附源码)
2018/01/24 Python
Python实现的拟合二元一次函数功能示例【基于scipy模块】
2018/05/15 Python
python 基本数据类型占用内存空间大小的实例
2018/06/12 Python
让代码变得更易维护的7个Python库
2018/10/09 Python
对python中的高效迭代器函数详解
2018/10/18 Python
python操作小程序云数据库实现简单的增删改查功能
2019/06/06 Python
PyQt5笔记之弹出窗口大全
2019/06/20 Python
python base64库给用户名或密码加密的流程
2020/01/02 Python
python实现二分查找算法
2020/09/18 Python
详解HTML5新增标签
2017/11/27 HTML / CSS
Hotels.com爱尔兰:全球酒店预订
2017/02/24 全球购物
安踏官方商城:anta.cn
2019/12/16 全球购物
介绍Ibatis的核心类
2013/11/18 面试题
岗位明星事迹材料
2014/05/18 职场文书
工程部经理岗位职责
2015/02/02 职场文书