github.com/dfklegend/cell2/utils@v0.0.0-20240402033734-a0a9f3d9335d/event/light/lighteventcenter.go (about) 1 package light 2 3 import ( 4 "log" 5 6 "github.com/dfklegend/cell2/utils/common" 7 "github.com/dfklegend/cell2/utils/logger" 8 ) 9 10 /* 11 * 非线程安全 12 * Sub/Unsubscribe, 如果是对象,请传入对象实例 13 * SubscribeWithReceiver 14 * (TODO: 如果反射可以分析出func是对象的method,并获取receiver,可以简化接口) 15 */ 16 17 type CBFunc func(args ...interface{}) 18 19 type EventCenter struct { 20 idService *common.SerialIdService64 21 events map[string]*ListenerList 22 23 running bool 24 } 25 26 func NewEventCenter() *EventCenter { 27 return &EventCenter{ 28 idService: common.NewSerialIdService64(), 29 events: make(map[string]*ListenerList), 30 running: true, 31 } 32 } 33 34 func (c *EventCenter) allocId() uint64 { 35 return c.idService.AllocId() 36 } 37 38 func (c *EventCenter) Clear() { 39 c.running = false 40 c.events = make(map[string]*ListenerList) 41 } 42 43 func (c *EventCenter) getListener(eventName string, createIfMiss bool) *ListenerList { 44 v, ok := c.events[eventName] 45 if !ok { 46 if !createIfMiss { 47 return nil 48 } 49 v = NewListenerList() 50 51 if c.running { 52 c.events[eventName] = v 53 } 54 } 55 return v 56 } 57 58 func (c *EventCenter) subscribeCheck(checkCB bool, eventName string, cb CBFunc, args ...interface{}) uint64 { 59 if !c.running { 60 return 0 61 } 62 list := c.getListener(eventName, true) 63 64 if checkCB { 65 id := list.FindId(cb) 66 if id != 0 { 67 // already subscribe 68 logger.L.Warnf("already register %v with this CB", eventName) 69 return 0 70 } 71 } 72 73 l := NewEventListener(c.allocId()) 74 l.Args = args 75 l.CB = cb 76 list.Add(l) 77 78 return l.Id 79 } 80 81 func (c *EventCenter) SubscribeNoCheck(eventName string, cb CBFunc, args ...interface{}) uint64 { 82 return c.subscribeCheck(false, eventName, cb, args...) 83 } 84 85 func (c *EventCenter) Subscribe(eventName string, cb CBFunc, args ...interface{}) uint64 { 86 return c.subscribeCheck(true, eventName, cb, args...) 87 } 88 89 // SubscribeWithReceiver receiver必须是指针对象 90 func (c *EventCenter) SubscribeWithReceiver(eventName string, receiver any, cb CBFunc, args ...interface{}) uint64 { 91 if !c.running { 92 return 0 93 } 94 list := c.getListener(eventName, true) 95 96 id := list.FindIdWithReceiver(receiver, cb) 97 if id != 0 { 98 // already subscribe 99 log.Printf("already register %v with this receiver and CB", eventName) 100 return 0 101 } 102 103 l := NewEventListener(c.allocId()) 104 l.Args = args 105 l.CB = cb 106 107 l.Receiver = receiver 108 list.Add(l) 109 110 return l.Id 111 } 112 113 func (c *EventCenter) UnsubscribeById(eventName string, id uint64) { 114 list := c.getListener(eventName, false) 115 if list == nil { 116 return 117 } 118 list.Del(id) 119 } 120 121 func (c *EventCenter) Unsubscribe(eventName string, cb CBFunc) { 122 list := c.getListener(eventName, false) 123 if list == nil { 124 return 125 } 126 id := list.FindId(cb) 127 if id == 0 { 128 return 129 } 130 list.Del(id) 131 } 132 133 func (c *EventCenter) UnsubscribeWithReceiver(eventName string, receiver any, cb CBFunc) { 134 list := c.getListener(eventName, false) 135 if list == nil { 136 return 137 } 138 id := list.FindIdWithReceiver(receiver, cb) 139 if id == 0 { 140 return 141 } 142 list.Del(id) 143 } 144 145 func (c *EventCenter) Publish(eventName string, args ...interface{}) { 146 c.dispatch(eventName, args...) 147 } 148 149 func (c *EventCenter) dispatch(eventName string, args ...interface{}) { 150 ll := c.getListener(eventName, false) 151 if ll == nil { 152 return 153 } 154 listeners := ll.Listeners 155 156 for _, v := range listeners { 157 if len(v.Args) > 0 { 158 finalArgs := append(v.Args, args...) 159 v.CB(finalArgs...) 160 } else { 161 v.CB(args...) 162 } 163 164 } 165 } 166 167 // GetSubscribeNum 订阅事件的个数 168 func (c *EventCenter) GetSubscribeNum(eventName string) int { 169 ll := c.getListener(eventName, false) 170 if ll == nil { 171 return 0 172 } 173 return ll.GetSize() 174 } 175 176 func (c *EventCenter) HasSubscribers(eventName string) bool { 177 return c.GetSubscribeNum(eventName) > 0 178 } 179 180 func (c *EventCenter) DumpInfo(eventName string) { 181 ll := c.getListener(eventName, false) 182 if ll == nil { 183 return 184 } 185 186 logger.L.Infof("%v size:%v", eventName, ll.GetSize()) 187 }