gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/myx/eventx/dispatcher.go (about) 1 package eventx 2 3 import ( 4 "math" 5 ) 6 7 func newDispatcher(event string) *Dispatcher { 8 dispatcher := &Dispatcher{} 9 dispatcher.eventName = event 10 dispatcher.listenerList = []*Event{} 11 dispatcher.bufList = []*Event{} 12 return dispatcher 13 } 14 15 type Dispatcher struct { 16 // 属主 17 eventName string 18 /// 事件的侦听列表 19 listenerList []*Event 20 /// 引入buf,避免创建太多的数组对象 21 bufList []*Event 22 23 lastEventOn *Event 24 // 25 idCount int 26 } 27 28 func (dispatcher *Dispatcher) Dispose() { 29 if dispatcher == nil { 30 return 31 } 32 dispatcher.OffAll() 33 dispatcher.lastEventOn = nil 34 dispatcher.bufList = nil 35 dispatcher.listenerList = nil 36 } 37 38 func (dispatcher *Dispatcher) OnKey(handlerKey string, priority int, params ...interface{}) (event *Event) { 39 handler := keyToHandler[handlerKey] 40 return dispatcher.createListener(handler, priority, false, params...) 41 } 42 43 // On 添加类型为[type],处理方法为[handler]的监听器,优先级[priority]的数值越大,越早触发 44 func (dispatcher *Dispatcher) On(handler Handler, priority int, params ...interface{}) (event *Event) { 45 return dispatcher.createListener(handler, priority, false, params...) 46 } 47 48 func (dispatcher *Dispatcher) Once(handler Handler, priority int, params ...interface{}) (event *Event) { 49 return dispatcher.createListener(handler, priority, true, params...) 50 } 51 52 func (dispatcher *Dispatcher) createListener(handler Handler, priority int, once bool, params ...interface{}) (event *Event) { 53 if handler == nil { 54 panic("#GetDispatcher.On() error: handler is nil") 55 } 56 57 var list = dispatcher.listenerList 58 var item = &Event{} 59 item.dispatcher = dispatcher 60 dispatcher.idCount++ 61 item.id = dispatcher.idCount 62 dispatcher.lastEventOn = item 63 item.priority = priority 64 item.handler = handler 65 item.OnParams = params 66 item.isOnce = once 67 68 var index = 0 69 for i := len(list) - 1; i >= 0; i-- { 70 if priority > list[i].priority { 71 index = i + 1 72 break 73 } 74 } 75 76 index = int(math.Max(float64(0), float64(index))) 77 list = append(list, nil) 78 copy(list[index+1:], list[index:]) 79 list[index] = item 80 dispatcher.listenerList = list 81 82 return item 83 } 84 85 func (dispatcher *Dispatcher) Off(event *Event) { 86 var list = dispatcher.listenerList 87 if list == nil { 88 return 89 } 90 if len(list) == 0 { 91 return 92 } 93 94 var index = -1 95 var remove *Event 96 for i, e := range list { 97 if e.id == event.id { 98 index = i 99 remove = event 100 break 101 } 102 } 103 if index == -1 { 104 return 105 } 106 107 remove.isRemoved = true 108 remove.Reset() 109 dispatcher.listenerList = append(list[:index], list[index+1:]...) 110 } 111 112 func (dispatcher *Dispatcher) OffAll() { 113 if dispatcher == nil { 114 return 115 } 116 dispatcher.listenerList = []*Event{} 117 } 118 119 // Dispatch / 派发消息,实现了冒泡 120 func (dispatcher *Dispatcher) Dispatch(params ...interface{}) (err error) { 121 return dispatcher.dispatchBubble(params) 122 } 123 124 /// 事件冒泡 125 func (dispatcher *Dispatcher) dispatchBubble(params []interface{}) error { 126 var list = dispatcher.listenerList 127 if list != nil { 128 var buf = dispatcher.bufList 129 for { 130 if len(list) <= 0 { 131 break 132 } 133 var item = list[len(list)-1] 134 list = list[:len(list)-1] 135 // 如果事件已经标记删除,不触发事件处理,继续下一个 136 if item.isRemoved == true { 137 continue 138 } 139 140 item.DispatchParams = params 141 // 触发事件的处理函数 142 err := item.handler(item) 143 if err != nil { 144 return err 145 } 146 147 // 只执行一次 148 if item.isOnce { 149 dispatcher.Off(item) 150 } 151 // 避免内存泄漏 152 item.DispatchParams = nil 153 // 如果事件没有标记删除,添加到缓存中 154 if item.isRemoved == false { 155 buf = append(buf, nil) 156 copy(buf[1:], buf[0:]) 157 buf[0] = item 158 } 159 } 160 // 设置事件kind指向缓存列表 161 dispatcher.listenerList = buf 162 // 旧的,已经遍历完成的当前列表,放入缓存中 163 dispatcher.bufList = list 164 } 165 166 return nil 167 }