EventManager.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import { Component } from "cc";
  2. /***
  3. * 事件管理器
  4. * 事件可一对一也可一对多
  5. */
  6. export class EventManager {
  7. //事件
  8. private _events = new Map<string, { id: string, func: Function, target: any }[]>();
  9. //事件ID缓存
  10. private _targets = new Set<string>();
  11. //只触发一次事件
  12. private _onceEvents = new Map<string, { id: string, func: Function, target: any }[]>();
  13. //只触发一次事件ID缓存
  14. private _onceTargets = new Set<string>();
  15. constructor() {
  16. this._events.clear();
  17. this._targets.clear();
  18. this._onceEvents.clear();
  19. this._onceTargets.clear();
  20. }
  21. /**
  22. * 添加事件
  23. * @param name 事件名
  24. * @param callback 回调函数
  25. * @param target 回调目标
  26. * @param uuid 事件唯一ID,如果在组件调用不需要该值
  27. */
  28. addEvent(name: string, callback: (...val: any[]) => void, target: any, uuid: string = null) {
  29. if (!name || !callback || !target) {
  30. console.error("添加事件失败name,callback或者target为空.");
  31. return false;
  32. }
  33. if (!this._events.has(name)) {
  34. this._events.set(name, []);
  35. }
  36. if (!uuid) {
  37. uuid = target.node.uuid;
  38. }
  39. this._events.get(name).push({ id: uuid, func: callback.bind(target), target: target });
  40. if (!this._targets.has(uuid)) {
  41. this._targets.add(uuid);
  42. }
  43. return true;
  44. }
  45. /**
  46. * 只触发一次事件
  47. * @param name 事件名
  48. * @param callback 回调函数
  49. * @param target 回调目标
  50. * @param uuid 事件唯一ID,如果在组件调用不需要该值
  51. */
  52. onceEvent(name: string, callback: (...val: any[]) => void, target: any, uuid: string = null) {
  53. if (!name || !callback || !target) {
  54. console.error("添加事件失败name,callback或者target为空.");
  55. return false;
  56. }
  57. if (!this._onceEvents.has(name)) {
  58. this._onceEvents.set(name, []);
  59. }
  60. if (!uuid) {
  61. uuid = target.node.uuid;
  62. }
  63. this._onceEvents.get(name).push({ id: uuid, func: callback.bind(target), target: target });
  64. if (!this._onceTargets.has(uuid)) {
  65. this._onceTargets.add(uuid);
  66. }
  67. return true;
  68. }
  69. /**
  70. * 发射事件
  71. * @param name 事件名
  72. * @param val 传递的数据
  73. */
  74. fireEvent(name: string, ...val: any[]) {
  75. let event = this._events.get(name);
  76. if (event) {
  77. for (let i = event.length - 1; i >= 0; --i) {
  78. if (event[i].target instanceof Component) {
  79. if (event[i].target.isValid) {
  80. event[i].func(...val);
  81. } else {
  82. event.splice(i, 1);
  83. }
  84. } else {
  85. event[i].func(...val);
  86. }
  87. }
  88. }
  89. let onceEvent = this._onceEvents.get(name);
  90. if (onceEvent) {
  91. for (let i = onceEvent.length - 1; i >= 0; --i) {
  92. if (onceEvent[i].target instanceof Component) {
  93. if (onceEvent[i].target.isValid) {
  94. onceEvent[i].func(...val);
  95. }
  96. } else {
  97. onceEvent[i].func(...val);
  98. }
  99. }
  100. this._onceEvents.delete(name);
  101. }
  102. }
  103. /**
  104. * 移除组件所有事件
  105. * @param target 目标组件或事件的唯一标识
  106. */
  107. removeEvent(target: Component | string) {
  108. let uuid = (typeof target === "string") ? target : target?.node?.uuid;
  109. if (this._targets.has(uuid)) {
  110. this._targets.delete(uuid);
  111. this._events.forEach((events, name) => {
  112. for (let i = events.length - 1; i >= 0; --i) {
  113. if (events[i].id === uuid) {
  114. events.splice(i, 1);
  115. }
  116. }
  117. if (events.length === 0) {
  118. this._events.delete(name);
  119. }
  120. });
  121. }
  122. if (this._onceTargets.has(uuid)) {
  123. this._onceTargets.delete(uuid);
  124. this._onceEvents.forEach((events, name) => {
  125. for (let i = events.length - 1; i >= 0; --i) {
  126. if (events[i].id === uuid) {
  127. events.splice(i, 1);
  128. }
  129. }
  130. if (events.length === 0) {
  131. this._onceEvents.delete(name);
  132. }
  133. });
  134. }
  135. }
  136. removeAll() {
  137. this._events.clear();
  138. this._targets.clear();
  139. this._onceEvents.clear();
  140. this._onceTargets.clear();
  141. }
  142. }
  143. export let EventMgr = new EventManager;
  144. /**
  145. * 如果在组件上添加事件则所有的target为this
  146. * addEvent("Level_Up",callback,this)
  147. * 移除组件所有的事件,如果组件为UIMgr管理则会自动调用
  148. * removeEvent(this)
  149. *
  150. * 如果在非组件上监听事件
  151. * addEvent("Level_Up",callback,this,only_uuid)
  152. * 移除事件
  153. * removeEvent(only_uuid)
  154. */