EventManager.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /** @format */
  2. import {Log} from '../utils/LogUtils'
  3. import {Delegate} from './Delegate'
  4. export class EventManager {
  5. // 同一type包含多个caller多个func
  6. private mListenerMap = new Map<string, Map<any, Delegate[]>>()
  7. public has(type: string, caller: any, listener: Function): boolean {
  8. return this.find(type, caller, listener) !== null
  9. }
  10. public trigger(type: string, ...argArray: any[]): boolean {
  11. if (!type) {
  12. Log.error('Listener type is null!')
  13. return false
  14. }
  15. const delegateList: Delegate[] = []
  16. const callerList: any[] = []
  17. const listenerMap = this.mListenerMap.get(type)
  18. if (listenerMap) {
  19. listenerMap.forEach((listenerList, caller) => {
  20. for (const delegate of listenerList) {
  21. let insertIndex = delegateList.findIndex(obj => obj.priority < delegate.priority)
  22. if (insertIndex === -1) {
  23. insertIndex = delegateList.length
  24. }
  25. delegateList.splice(insertIndex, 0, delegate)
  26. callerList.splice(insertIndex, 0, caller)
  27. }
  28. for (let index = listenerList.length - 1; index >= 0; index -= 1) {
  29. if (listenerList[index].isOnce) {
  30. listenerList.splice(index, 1)
  31. }
  32. }
  33. if (listenerList.length <= 0 || !cc.isValid(caller)) {
  34. listenerMap.delete(caller)
  35. }
  36. })
  37. if (listenerMap.size <= 0) {
  38. this.mListenerMap.delete(type)
  39. }
  40. }
  41. const {length} = delegateList
  42. for (let index = 0; index < length; index++) {
  43. const delegate: Delegate = delegateList[index]
  44. if (delegate.argArray.length > 0 && delegate.argArray[0].length == 0) {
  45. delegate.listener.call(callerList[index], ...argArray)
  46. } else {
  47. delegate.listener.call(callerList[index], ...delegate.argArray, ...argArray)
  48. }
  49. }
  50. return length > 0
  51. }
  52. public add(type: string, caller: any, listener: Function, ...argArray: any[]): void {
  53. this.addListener(type, caller, listener, false, 0, ...argArray)
  54. }
  55. public addOnce(type: string, caller: any, listener: Function, ...argArray: any[]): void {
  56. this.addListener(type, caller, listener, true, 0, ...argArray)
  57. }
  58. public addTop(type: string, caller: any, listener: Function, ...argArray: any[]): void {
  59. this.addListener(type, caller, listener, false, 1, ...argArray)
  60. }
  61. public remove(type: string, caller: any, listener: Function, onceOnly?: boolean): void {
  62. this.removeBy((listenerType, listenerCaller, delegate) => {
  63. if (type && type !== listenerType) {
  64. return false
  65. }
  66. if (caller && caller !== listenerCaller) {
  67. return false
  68. }
  69. if (listener && listener !== delegate.listener) {
  70. return false
  71. }
  72. if (onceOnly && !delegate.isOnce) {
  73. return false
  74. }
  75. return true
  76. })
  77. }
  78. public removeAll(caller: any): void {
  79. this.mListenerMap.forEach((listenerMap, type) => {
  80. listenerMap.delete(caller)
  81. if (listenerMap.size <= 0) {
  82. this.mListenerMap.delete(type)
  83. }
  84. })
  85. }
  86. /**
  87. * 游戏重启时调用,防止重复注册监听
  88. */
  89. public reset() {
  90. this.mListenerMap.forEach((listenerMap, type) => {
  91. this.mListenerMap.delete(type)
  92. })
  93. }
  94. private addListener(
  95. type: string,
  96. caller: any,
  97. listener: Function,
  98. isOnce: boolean,
  99. priority: number,
  100. ...argArray: any[]
  101. ): void {
  102. let delegate = this.find(type, caller, listener)
  103. if (delegate) {
  104. delegate.isOnce = isOnce
  105. delegate.priority = priority
  106. Log.error('Listener is already exist!', type)
  107. } else {
  108. delegate = new Delegate(listener, argArray, isOnce, priority)
  109. this.mListenerMap.get(type).get(caller).push(delegate)
  110. }
  111. }
  112. private removeBy(predicate: (type: string, caller: any, delegate: Delegate) => boolean): void {
  113. if (!predicate) {
  114. return
  115. }
  116. for (const [type, listenerMap] of Array.from(this.mListenerMap.entries())) {
  117. for (const [caller, listenerList] of Array.from(listenerMap.entries())) {
  118. for (let index = listenerList.length - 1; index >= 0; --index) {
  119. const delegate = listenerList[index]
  120. if (predicate(type, caller, delegate)) {
  121. listenerList.splice(index, 1)
  122. }
  123. }
  124. if (listenerList.length <= 0) {
  125. listenerMap.delete(caller)
  126. }
  127. }
  128. if (listenerMap.size <= 0) {
  129. this.mListenerMap.delete(type)
  130. }
  131. }
  132. }
  133. private find(type: string, caller: any, listener: Function): Delegate {
  134. if (!type) {
  135. Log.error('Listener type is null!')
  136. return undefined
  137. }
  138. if (!caller) {
  139. Log.error('Caller type is null!')
  140. return undefined
  141. }
  142. if (!listener) {
  143. Log.error('Listener is null!')
  144. return undefined
  145. }
  146. let listenerMap: Map<any, Delegate[]>
  147. if (this.mListenerMap.has(type)) {
  148. listenerMap = this.mListenerMap.get(type)
  149. } else {
  150. listenerMap = new Map<any, Delegate[]>()
  151. this.mListenerMap.set(type, listenerMap)
  152. }
  153. let listenerList: Delegate[]
  154. if (listenerMap.has(caller)) {
  155. listenerList = listenerMap.get(caller)
  156. } else {
  157. listenerList = []
  158. listenerMap.set(caller, listenerList)
  159. }
  160. for (const delegate of listenerList) {
  161. if (delegate.mListener === listener) {
  162. return delegate
  163. }
  164. }
  165. return undefined
  166. }
  167. }