mirror of
https://github.com/asticode/go-astikit.git
synced 2025-12-24 11:50:53 +08:00
103 lines
1.7 KiB
Go
103 lines
1.7 KiB
Go
package astikit
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
type EventHandler func(payload any) (delete bool)
|
|
|
|
type EventName string
|
|
|
|
type EventManager struct {
|
|
handlerCount uint64
|
|
// We use a map[int]... so that deletion is as smooth as possible
|
|
hs map[EventName]map[uint64]EventHandler
|
|
m *sync.Mutex
|
|
}
|
|
|
|
func NewEventManager() *EventManager {
|
|
return &EventManager{
|
|
hs: make(map[EventName]map[uint64]EventHandler),
|
|
m: &sync.Mutex{},
|
|
}
|
|
}
|
|
|
|
func (m *EventManager) On(n EventName, h EventHandler) uint64 {
|
|
// Lock
|
|
m.m.Lock()
|
|
defer m.m.Unlock()
|
|
|
|
// Make sure event name exists
|
|
if _, ok := m.hs[n]; !ok {
|
|
m.hs[n] = make(map[uint64]EventHandler)
|
|
}
|
|
|
|
// Increment handler count
|
|
m.handlerCount++
|
|
|
|
// Add handler
|
|
m.hs[n][m.handlerCount] = h
|
|
|
|
// Return id
|
|
return m.handlerCount
|
|
}
|
|
|
|
func (m *EventManager) Off(id uint64) {
|
|
// Lock
|
|
m.m.Lock()
|
|
defer m.m.Unlock()
|
|
|
|
// Loop through handlers
|
|
for _, ids := range m.hs {
|
|
// Loop through ids
|
|
for v := range ids {
|
|
// Id matches
|
|
if id == v {
|
|
delete(ids, id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *EventManager) Emit(n EventName, payload any) {
|
|
// Loop through handlers
|
|
for _, h := range m.handlers(n) {
|
|
if h.h(payload) {
|
|
m.Off(h.id)
|
|
}
|
|
}
|
|
}
|
|
|
|
type eventManagerHandler struct {
|
|
h EventHandler
|
|
id uint64
|
|
}
|
|
|
|
func (m *EventManager) handlers(n EventName) (hs []eventManagerHandler) {
|
|
// Lock
|
|
m.m.Lock()
|
|
defer m.m.Unlock()
|
|
|
|
// Index handlers
|
|
hsm := make(map[uint64]eventManagerHandler)
|
|
var ids []uint64
|
|
if _, ok := m.hs[n]; ok {
|
|
for id, h := range m.hs[n] {
|
|
hsm[id] = eventManagerHandler{
|
|
h: h,
|
|
id: id,
|
|
}
|
|
ids = append(ids, id)
|
|
}
|
|
}
|
|
|
|
// Sort ids
|
|
SortUint64(ids)
|
|
|
|
// Append
|
|
for _, id := range ids {
|
|
hs = append(hs, hsm[id])
|
|
}
|
|
return
|
|
}
|