详解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 相关文章推荐
jQuery使用手册之 事件处理
Mar 24 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
Feb 28 Javascript
javascript的解析执行顺序在各个浏览器中的不同
Mar 17 Javascript
JavaScript判断浏览器类型的方法
Feb 10 Javascript
js实现单击图片放大图片的方法
Feb 17 Javascript
jquery简单实现网页层的展开与收缩效果
Aug 07 Javascript
js实现n秒倒计时后才可以点击的效果
Dec 20 Javascript
浅谈JS对html标签的属性的干预以及对CSS样式表属性的干预
Jun 25 Javascript
在vue中获取dom元素内容的方法
Jul 10 Javascript
vue根据进入的路由进行原路返回的方法
Sep 26 Javascript
使用jquery实现轮播图效果
Jan 02 jQuery
Vue全家桶入门基础教程
May 14 Vue.js
CocosCreator入门教程之网络通信
Apr 16 #Javascript
JavaScript嵌入百度地图API的最详细方法
用javascript制作qq注册动态页面
利用javaScript处理常用事件详解
Apr 14 #Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 #Javascript
游戏开发中如何使用CocosCreator进行音效处理
详解CocosCreator项目结构机制
You might like
PHP无敌近乎加密方式!
2010/07/17 PHP
php中限制ip段访问、禁止ip提交表单的代码分享
2014/08/22 PHP
javascript英文日期(有时间)选择器
2007/05/02 Javascript
解决IE6的PNG透明JS插件使用介绍
2013/04/17 Javascript
解析prototype,JQuery中跳出each循环的方法
2013/12/12 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
2014/02/08 Javascript
学习JavaScript设计模式(多态)
2015/11/25 Javascript
再谈Javascript中的异步以及如何异步
2016/08/19 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
2017/03/04 Javascript
详解vue-router 2.0 常用基础知识点之router-link
2017/05/10 Javascript
深入探究angular2 UI组件之primeNG用法
2017/07/26 Javascript
React Native 自定义下拉刷新上拉加载的列表的示例
2018/03/01 Javascript
基于Vue实现关键词实时搜索高亮显示关键词
2018/07/21 Javascript
详解vue项目打包步骤
2019/03/29 Javascript
一文快速详解前端框架 Vue 最强大的功能
2019/05/21 Javascript
纯JS实现五子棋游戏
2020/05/28 Javascript
Python2.x与Python3.x的区别
2016/01/14 Python
Python松散正则表达式用法分析
2016/04/29 Python
django1.11.1 models 数据库同步方法
2018/05/30 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
2019/01/15 Python
python UDP(udp)协议发送和接收的实例
2019/07/22 Python
python可视化实现KNN算法
2019/10/16 Python
tensorflow 获取所有variable或tensor的name示例
2020/01/04 Python
Python matplotlib可视化实例解析
2020/06/01 Python
基于Python绘制个人足迹地图
2020/06/01 Python
Python selenium键盘鼠标事件实现过程详解
2020/07/28 Python
python爬虫筛选工作实例讲解
2020/11/23 Python
经典c++面试题三
2015/07/08 面试题
新学期红领巾广播稿
2014/01/14 职场文书
致标枪运动员广播稿
2014/02/06 职场文书
简单租房协议书
2014/10/21 职场文书
朝花夕拾读书笔记
2015/06/29 职场文书
高三数学教学反思
2016/02/18 职场文书
职工趣味运动会开幕词
2016/03/04 职场文书
2019年公司卫生管理制度样本
2019/08/21 职场文书
MySQL系列之七 MySQL存储引擎
2021/07/02 MySQL