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  }