github.com/metaworking/channeld@v0.7.3/pkg/channeld/event.go (about) 1 package channeld 2 3 import ( 4 "sync" 5 6 "github.com/metaworking/channeld/pkg/channeldpb" 7 "github.com/metaworking/channeld/pkg/common" 8 ) 9 10 var Event_GlobalChannelPossessed = &Event[*Channel]{} 11 var Event_GlobalChannelUnpossessed = &Event[struct{}]{} 12 var Event_ChannelCreated = &Event[*Channel]{} 13 var Event_ChannelRemoving = &Event[*Channel]{} 14 var Event_ChannelRemoved = &Event[common.ChannelId]{} 15 16 type AuthEventData struct { 17 AuthResult channeldpb.AuthResultMessage_AuthResult 18 Connection ConnectionInChannel 19 PlayerIdentifierToken string 20 } 21 22 var Event_AuthComplete = &Event[AuthEventData]{} 23 24 var Event_FsmDisallowed = &Event[*Connection]{} 25 26 type EventData interface { 27 } 28 29 type eventHandler[T EventData] struct { 30 owner interface{} 31 handlerFunc func(data T) 32 triggerOnce bool 33 } 34 35 type Event[T EventData] struct { 36 handlersLock sync.RWMutex 37 handlers []*eventHandler[T] 38 } 39 40 func (e *Event[T]) Listen(handlerFunc func(data T)) { 41 e.ListenFor(nil, handlerFunc) 42 } 43 44 func (e *Event[T]) ListenOnce(handlerFunc func(data T)) { 45 e.handlersLock.Lock() 46 defer e.handlersLock.Unlock() 47 if e.handlers == nil { 48 e.handlers = make([]*eventHandler[T], 0) 49 } 50 e.handlers = append(e.handlers, &eventHandler[T]{nil, handlerFunc, true}) 51 } 52 53 func (e *Event[T]) ListenFor(owner interface{}, handlerFunc func(data T)) { 54 e.handlersLock.Lock() 55 defer e.handlersLock.Unlock() 56 if e.handlers == nil { 57 e.handlers = make([]*eventHandler[T], 0) 58 } 59 e.handlers = append(e.handlers, &eventHandler[T]{owner, handlerFunc, false}) 60 } 61 62 func (e *Event[T]) UnlistenFor(owner interface{}) { 63 e.handlersLock.Lock() 64 defer e.handlersLock.Unlock() 65 for i, handler := range e.handlers { 66 if handler.owner == owner { 67 e.handlers = append(e.handlers[:i], e.handlers[i+1:]...) 68 } 69 } 70 } 71 72 func (e *Event[T]) Wait() chan T { 73 ch := make(chan T) 74 e.ListenOnce(func(data T) { 75 ch <- data 76 }) 77 return ch 78 } 79 80 func (e *Event[T]) Broadcast(data T) { 81 e.handlersLock.RLock() 82 defer e.handlersLock.RUnlock() 83 for i, handler := range e.handlers { 84 handler.handlerFunc(data) 85 if handler.triggerOnce { 86 e.handlers = append(e.handlers[:i], e.handlers[i+1:]...) 87 } 88 } 89 }