详解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 ToolTip提示效果
Jul 20 Javascript
判断js对象是否拥有某一个属性的js代码
Aug 16 Javascript
jQuery的显示和隐藏方法与css隐藏的样式对比
Oct 18 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
Feb 04 Javascript
js获取本机操作系统类型的两种方法
Dec 19 Javascript
vue-dialog的弹出层组件
May 25 Javascript
老生常谈angularjs中的$state.go
Apr 24 Javascript
angular ng-click防止重复提交实例
Jun 16 Javascript
JS实现的计数排序与基数排序算法示例
Dec 04 Javascript
js实现手机web图片左右滑动效果
Dec 29 Javascript
js全屏事件fullscreenchange 实现全屏、退出全屏操作
Sep 17 Javascript
微信小程序自定义yPicker组件实现省市区三级联动功能
Oct 29 Javascript
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
海贼王:最美的悬赏令!
2020/03/02 日漫
php 文件缓存函数
2011/10/08 PHP
迅速确定php多维数组的深度的方法
2014/01/07 PHP
php实现改变图片直接打开为下载的方法
2015/04/14 PHP
PHP常用的小程序代码段
2015/11/14 PHP
WordPress导航菜单的滚动和淡入淡出效果的实现要点
2015/12/14 PHP
Zend Framework教程之视图组件Zend_View用法详解
2016/03/05 PHP
关于php支持的协议与封装协议总结(推荐)
2017/11/17 PHP
PHP使用ActiveMQ实例
2018/02/05 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
一个可以随意添加多个序列的tag函数
2009/07/21 Javascript
禁止JQuery中的load方法装载IE缓存中文件的方法
2009/09/11 Javascript
JavaScript浏览器选项卡效果
2010/08/25 Javascript
使用iframe window的scroll方法控制iframe页面滚动
2014/03/05 Javascript
Angular 输入框实现自定义验证功能
2017/02/19 Javascript
vue项目国际化vue-i18n的安装使用教程
2018/03/14 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
[01:25]DOTA2自定义游戏灵园鬼域等你踏足
2015/10/30 DOTA
python轻松查到删除自己的微信好友
2016/01/10 Python
python获取指定字符串中重复模式最高的字符串方法
2018/06/29 Python
python正则表达式匹配[]中间为任意字符的实例
2018/12/25 Python
python线程优先级队列知识点总结
2021/02/28 Python
Agoda西班牙:全球特价酒店预订
2017/06/03 全球购物
瑞士图书网站:Weltbild.ch
2019/09/17 全球购物
中职生自我鉴定范文
2013/10/03 职场文书
致接力运动员广播稿
2014/02/17 职场文书
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
小学生爱国演讲稿
2014/04/25 职场文书
普通党员个人剖析材料
2014/10/08 职场文书
迁户口计划生育证明
2014/10/19 职场文书
民主评议党员个人总结
2015/02/13 职场文书
入党自传范文2015
2015/06/26 职场文书
劳动模范获奖感言
2015/07/31 职场文书
小学2016年第十八届推普周活动总结
2016/04/05 职场文书
python 用递归实现通用爬虫解析器
2021/04/16 Python
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记