Added event handler ids

This commit is contained in:
Quentin Renard
2023-09-29 11:42:33 +02:00
parent fb223224a0
commit 3ce0c68655
4 changed files with 57 additions and 33 deletions
+36 -31
View File
@@ -1,7 +1,6 @@
package astikit
import (
"sort"
"sync"
)
@@ -10,62 +9,68 @@ type EventHandler func(payload interface{}) (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[int]EventHandler
idx int
m *sync.Mutex
hs map[EventName]map[uint64]EventHandler
m *sync.Mutex
}
func NewEventManager() *EventManager {
return &EventManager{
hs: make(map[EventName]map[int]EventHandler),
hs: make(map[EventName]map[uint64]EventHandler),
m: &sync.Mutex{},
}
}
func (m *EventManager) On(n EventName, h EventHandler) {
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[int]EventHandler)
m.hs[n] = make(map[uint64]EventHandler)
}
// Increment index
m.idx++
// Increment handler count
m.handlerCount++
// Add handler
m.hs[n][m.idx] = h
m.hs[n][m.handlerCount] = h
// Return id
return m.handlerCount
}
func (m *EventManager) del(n EventName, idx int) {
func (m *EventManager) Off(id uint64) {
// Lock
m.m.Lock()
defer m.m.Unlock()
// Event name doesn't exist
if _, ok := m.hs[n]; !ok {
return
// Loop through handlers
for _, ids := range m.hs {
// Loop through ids
for v := range ids {
// Id matches
if id == v {
delete(ids, id)
}
}
}
// Delete index
delete(m.hs[n], idx)
}
func (m *EventManager) Emit(n EventName, payload interface{}) {
// Loop through handlers
for _, h := range m.handlers(n) {
if h.h(payload) {
m.del(n, h.idx)
m.Off(h.id)
}
}
}
type eventManagerHandler struct {
h EventHandler
idx int
h EventHandler
id uint64
}
func (m *EventManager) handlers(n EventName) (hs []eventManagerHandler) {
@@ -74,24 +79,24 @@ func (m *EventManager) handlers(n EventName) (hs []eventManagerHandler) {
defer m.m.Unlock()
// Index handlers
hsm := make(map[int]eventManagerHandler)
var idxs []int
hsm := make(map[uint64]eventManagerHandler)
var ids []uint64
if _, ok := m.hs[n]; ok {
for idx, h := range m.hs[n] {
hsm[idx] = eventManagerHandler{
h: h,
idx: idx,
for id, h := range m.hs[n] {
hsm[id] = eventManagerHandler{
h: h,
id: id,
}
idxs = append(idxs, idx)
ids = append(ids, id)
}
}
// Sort indexes
sort.Ints(idxs)
// Sort ids
SortUint64(ids)
// Append
for _, idx := range idxs {
hs = append(hs, hsm[idx])
for _, id := range ids {
hs = append(hs, hsm[id])
}
return
}
+4 -1
View File
@@ -19,7 +19,7 @@ func TestEvent(t *testing.T) {
ons[eventName1] = append(ons[eventName1], payload)
return true
})
m.On(eventName3, func(payload interface{}) (delete bool) {
id := m.On(eventName3, func(payload interface{}) (delete bool) {
ons[eventName3] = append(ons[eventName3], payload)
return false
})
@@ -31,6 +31,9 @@ func TestEvent(t *testing.T) {
m.Emit(eventName3, 1)
m.Emit(eventName3, 2)
m.Off(id)
m.Emit(eventName3, 3)
if e, g := map[astikit.EventName][]interface{}{
eventName1: {1},
eventName3: {1, 2},
+10
View File
@@ -11,3 +11,13 @@ type SortInt64Slice []int64
func (p SortInt64Slice) Len() int { return len(p) }
func (p SortInt64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p SortInt64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// SortUint64 sorts a slice of uint64s in increasing order.
func SortUint64(a []uint64) { sort.Sort(SortUint64Slice(a)) }
// SortUint64Slice attaches the methods of Interface to []uint64, sorting in increasing order.
type SortUint64Slice []uint64
func (p SortUint64Slice) Len() int { return len(p) }
func (p SortUint64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p SortUint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+7 -1
View File
@@ -5,10 +5,16 @@ import (
"testing"
)
func TestSortInt64(t *testing.T) {
func TestSort(t *testing.T) {
i := []int64{3, 2, 4, 1}
SortInt64(i)
if e := []int64{1, 2, 3, 4}; !reflect.DeepEqual(e, i) {
t.Errorf("expected %+v, got %+v", e, i)
}
ui := []uint64{3, 2, 4, 1}
SortUint64(ui)
if e := []uint64{1, 2, 3, 4}; !reflect.DeepEqual(e, ui) {
t.Errorf("expected %+v, got %+v", e, ui)
}
}