详解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中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
Nov 03 Javascript
jquery 操作DOM案例代码分享
Apr 05 Javascript
高性能JavaScript循环语句和条件语句
Jan 20 Javascript
jQuery使用zTree插件实现树形菜单和异步加载
Feb 25 Javascript
如何判断Javascript对象是否存在的简单实例
May 18 Javascript
购物车前端开发(jQuery和bootstrap3)
Aug 27 Javascript
JavaScript实现获取远程的html到当前页面中
Mar 26 Javascript
webpack-dev-server自动更新页面方法
Feb 22 Javascript
vue+vuex+axios实现登录、注册页权限拦截
Mar 09 Javascript
JS构造一个html文本内容成文件流形式发送到后台
Jul 31 Javascript
如何在基于vue-cli的项目自定义打包环境
Nov 10 Javascript
微信JS-SDK updateAppMessageShareData安卓不能自定义分享详解
Mar 29 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
php 无限极分类
2008/03/27 PHP
PHP5 操作MySQL数据库基础代码
2009/09/29 PHP
php+xml实现在线英文词典查询的方法
2015/01/23 PHP
php 数据结构之链表队列
2017/10/17 PHP
windows 2008r2+php5.6.28环境搭建详细过程
2019/06/18 PHP
php进行md5加密简单实例方法
2019/09/19 PHP
文本加密解密
2006/06/23 Javascript
关于js中for in的缺陷浅析
2013/12/02 Javascript
深入理解javascript的执行顺序
2014/04/04 Javascript
javascript数组遍历for与for in区别详解
2014/12/04 Javascript
JavaScript判断变量是否为空的自定义函数分享
2015/01/31 Javascript
vue.js学习之递归组件
2016/12/13 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
2017/10/15 Javascript
vue 自定义全局方法,在组件里面的使用介绍
2018/02/28 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
2019/03/05 Javascript
小程序登录之支付宝授权的实现示例
2019/12/13 Javascript
php使用递归与迭代实现快速排序示例
2014/01/23 Python
python使用wmi模块获取windows下硬盘信息的方法
2015/05/15 Python
Python中用altzone()方法处理时区的教程
2015/05/22 Python
图文详解WinPE下安装Python
2016/05/17 Python
Python微信操控itchat的方法
2019/05/31 Python
Python 转换文本编码实现解析
2019/08/27 Python
python中open函数的基本用法示例
2019/09/07 Python
Django框架中间件定义与使用方法案例分析
2019/11/28 Python
解决Jupyter Notebook开始菜单栏Anaconda下消失的问题
2020/04/13 Python
Python学习之路之pycharm的第一个项目搭建过程
2020/06/18 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
HTML5获取当前地理位置并在百度地图上展示的实例
2020/07/10 HTML / CSS
英国剑桥包官网:The Cambridge Satchel Company
2016/08/01 全球购物
夫妻分居协议书范文
2014/11/26 职场文书
反邪教警示教育活动总结
2015/05/09 职场文书
2016年春节问候语
2015/11/11 职场文书
Vue项目中如何封装axios(统一管理http请求)
2021/05/02 Vue.js
python爬取豆瓣电影TOP250数据
2021/05/23 Python