详解CocosCreator消息分发机制

 更新时间:2021年04月15日 15:33:01   作者:houjia159  
这篇文章主要介绍了详解CocosCreator消息分发机制,详细介绍了各模块的设计,同学们一定要自己看下

概述

本篇开始介绍游戏业务架构相关的内容。在游戏业务层,所有需要隔离的系统和模块间通信都可以通过消息分发解耦。例如网络返回通知、数据更新同步到界面等。

消息分发基于观察者模式设计。需要处理消息的地方向消息中心注册监听回调,派发消息时,调用消息中心的派发接口遍历该消息的监听队列,调用对应的回调方法。

具体方案

先定义监听回调类型

/**
 * 消息监听回调方法
 */
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消息分发的资料请关注脚本之家其它相关文章!

相关文章

  • 悄悄用脚本检查你访问过哪些网站的代码

    悄悄用脚本检查你访问过哪些网站的代码

    YouPorn是YouTube的成人自拍版,Alexa排名61。如果你登陆YouPorn主页,它会悄悄用脚本检查你访问过哪些色情网站。
    2010-12-12
  • JavaScript将数组转换为链表的方法

    JavaScript将数组转换为链表的方法

    这篇文章主要介绍了JavaScript将数组转换为链表的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • js+springMVC 提交数组数据到后台的实例

    js+springMVC 提交数组数据到后台的实例

    今天小编就为大家分享一篇js+springMVC 提交数组数据到后台的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 让ie6也支持websocket采用flash封装实现

    让ie6也支持websocket采用flash封装实现

    ie9都不支持websocket,何况ie6,往往这些不可思议的事情却意想不到的发生了;websocket能开发那么酷的功能,怎么能让ie拦住我们的脚步,用falsh封装吧,感兴趣的你可不要错过了哈
    2013-02-02
  • 7个令人惊讶的JavaScript特性详解

    7个令人惊讶的JavaScript特性详解

    在学习ES6的过程中我碰到了几个特性,它们让我惊讶,其中大部分是关于 ES6 的特性但也有一部分是 ES3 特性,这些特性我以前从未用过,而现在我将开始使用它们,感兴趣的小伙伴可以跟着小编一起来学习
    2023-05-05
  • form+iframe解决跨域上传文件的方法

    form+iframe解决跨域上传文件的方法

    下面小编就为大家带来一篇form+iframe解决跨域上传文件的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • 前端判断页面是在PC端还是移动端打开四种方法

    前端判断页面是在PC端还是移动端打开四种方法

    本文介绍几种在前端开发中用于判断用户设备类型(PC端或移动端)的方法,包括使用navigator.userAgent、媒体查询、第三方库detect.js和Vue框架插件vue-device-detect,这些方法有助于在开发中处理设备适配和页面权限问题,需要的朋友可以参考下
    2024-10-10
  • JavaScript中的继承之类继承

    JavaScript中的继承之类继承

    在JS中继承是一个非常复杂的话题,比其他任何面向对象语言中的继承都复杂得多。接下来通过本文给大家介绍JavaScript中的继承之类继承,感兴趣的朋友一起看看吧
    2016-05-05
  • OpenLayers实现点要素图层的聚合显示的方法

    OpenLayers实现点要素图层的聚合显示的方法

    在很多情况下,点要素图层中的要素数量可能会成百上千,如果一个点要素图层中的点数量很多,我们就会采取图层聚合的方式对其进行处理,本文就来介绍一下,感兴趣的可以了解一下
    2021-09-09

最新评论