• 售前

  • 售后

热门帖子
入门百科

详解CocosCreator消息分发机制

[复制链接]
上是中国十七地 显示全部楼层 发表于 2021-10-26 12:38:25 |阅读模式 打印 上一主题 下一主题
概述

本篇开始先容游戏业务架构相关的内容。在游戏业务层,全部必要隔离的体系和模块间通讯都可以通过消息分发解耦。比方网络返回通知、数据更新同步到界面等。
消息分发基于观察者模式计划。必要处理消息的地方向消息中央注册监听回调,派发消息时,调用消息中央的派发接口遍历该消息的监听队列,调用对应的回调方法。
详细方案

先定义监听回调类型
  1. /**
  2. * 消息监听回调方法
  3. */
  4. export type NotifyListener = (src: any, data: any) => void;
复制代码
通过key-value方式生存监听队列
  1. private static msg2listDict: Dictionary< string, Array<NotifyListenerInfo> > = new Dictionary< string, Array<NotifyListenerInfo> >();
复制代码
接口定义
  1. /**
  2. * 添加多次监听者,需要手动移除
  3. * @param msg
  4. * @param listener
  5. * @param target
  6. */
  7. public static addListener(msg: string, listener: NotifyListener, target?: any): void {}
  8. /**
  9. * 添加单次监听者,事件触发后即移除
  10. * @param msg
  11. * @param listener
  12. * @param target
  13. */
  14. public static addOnceListener(msg: string, listener: NotifyListener, target?: any): void {}
  15. /**
  16. * 移除指定消息指定的监听者
  17. * @param msg
  18. * @param listener
  19. */
  20. public static removeMsgListener(msg: string, listener: NotifyListener): void {}
  21. /**
  22. * 移除指定消息所有监听者
  23. * @param msg
  24. */
  25. public static removeMsgAllListeners(msg: string): void {}
  26. /**
  27. * 移除指定目标对指定消息的监听
  28. * @param msg
  29. * @param target
  30. */
  31. public static removeTargetMsgListen(msg: string, target: any): void {}
  32. /**
  33. * 移除指定目标所有消息监听
  34. * @param target
  35. */
  36. public static removeTargetAllMsgListen(target: any): void {}
  37. /**
  38. * 派发消息
  39. * @param msg
  40. * @param src
  41. * @param data
  42. */
  43. public static notify(msg: string, src: any, data: any): void {}
复制代码
在添加移除实现中,必要留意某消息可能正在派发。
对于一个消息新添加的监听者,应该在当前队列消息派发完后再派发,因此,添加一个待添加队列
  1. private static listener2add: Array<NotifyListenerInfo> = [];
复制代码
在添加监听者时做以下判断
  1. // 该消息正在派发,放入待添加队列
  2. if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) {
  3.     NotifyCenter.listener2add.push(info);
  4.     return;
  5. }
复制代码
同样在移除监听者时,可能正在派发消息,避免对队列的修改导致for循环异常,添加一个待移除队列,派发消息时,如果该监听者在移除队列则不派发。在消息派发完后再将其移出队列
  1. private static listener2remove: Array<NotifyListenerInfo> = [];
复制代码
在移除监听者时做以下判断
  1. // 该消息正在派发,放入待移除队列
  2. if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) {
  3.     NotifyCenter.listener2remove.push(list[i]);
  4. } else {
  5.     list.splice(i, 1);
  6. }
复制代码
派发消息时遍历指定消息下的队列
  1. // 队列不存在,不需要处理
  2. let list = NotifyCenter.msg2listDict.get(msg);
  3. if (!list) {
  4.     return;
  5. }
  6. // 标记消息正在派发,多个消息可能同时在派发,同一消息可能标记多次
  7. NotifyCenter.notifyMsgs.push(msg);
  8. // 处理消息派发
  9. for (let i = 0, n = list.length; i < n; i++) {
  10.     NotifyCenter._dispatch(list[i], src, data, false);
  11. }
复制代码
派发消息时先判断是否在移除队列
  1. // 在移除队列,不派发
  2. if (NotifyCenter.listener2remove.indexOf(info) >= 0) {
  3.     return;
  4. }
复制代码
当前队列派发完后检查待添加队列
  1. // 处理待添加队列派发
  2. for (let i = 0, n = msg2add.length; i < n; i++) {
  3.     if (listener2add[i].msg == msg) {
  4.         NotifyCenter._dispatch(listener2add[i], src, data, true);
  5.     }
  6. }
复制代码
引入消息分发中央,隔离的体系、模块间通过消息监听和派发通讯,避免互相引用耦合。
以上就是详解CocosCreator消息分发机制的详细内容,更多关于CocosCreator消息分发的资料请关注草根技术分享别的相关文章!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作