-
Notifications
You must be signed in to change notification settings - Fork 60
/
listener.go
139 lines (112 loc) · 2.89 KB
/
listener.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package event
import (
"reflect"
"sort"
)
// Listener interface
type Listener interface {
Handle(e Event) error
}
// ListenerFunc func definition.
type ListenerFunc func(e Event) error
// Handle event. implements the Listener interface
func (fn ListenerFunc) Handle(e Event) error {
return fn(e)
}
// Subscriber event subscriber interface.
//
// you can register multi event listeners in a struct func.
type Subscriber interface {
// SubscribedEvents register event listeners
//
// - key: is event name. eg "user.created" "user.*" "user.**"
// - value: can be Listener or ListenerItem interface
SubscribedEvents() map[string]any
}
// ListenerItem storage a event listener and it's priority value.
type ListenerItem struct {
Priority int
Listener Listener
}
/*************************************************************
* Listener Queue
*************************************************************/
// ListenerQueue storage sorted Listener instance.
type ListenerQueue struct {
items []*ListenerItem
}
// Len get items length
func (lq *ListenerQueue) Len() int {
return len(lq.items)
}
// IsEmpty get items length == 0
func (lq *ListenerQueue) IsEmpty() bool {
return len(lq.items) == 0
}
// Push get items length
func (lq *ListenerQueue) Push(li *ListenerItem) *ListenerQueue {
lq.items = append(lq.items, li)
return lq
}
// Sort the queue items by ListenerItem's priority.
//
// Priority:
//
// High > Low
func (lq *ListenerQueue) Sort() *ListenerQueue {
// if lq.IsEmpty() {
// return lq
// }
ls := ByPriorityItems(lq.items)
// check items is sorted
if !sort.IsSorted(ls) {
sort.Sort(ls)
}
return lq
}
// Items get all ListenerItem
func (lq *ListenerQueue) Items() []*ListenerItem {
return lq.items
}
// Remove a listener from the queue
func (lq *ListenerQueue) Remove(listener Listener) {
if listener == nil {
return
}
// unsafe.Pointer(listener)
ptrVal := getListenCompareKey(listener)
var newItems []*ListenerItem
for _, li := range lq.items {
liPtrVal := getListenCompareKey(li.Listener)
if liPtrVal == ptrVal {
continue
}
newItems = append(newItems, li)
}
lq.items = newItems
}
// Clear all listeners
func (lq *ListenerQueue) Clear() {
lq.items = lq.items[:0]
}
// getListenCompareKey get listener compare key
func getListenCompareKey(src Listener) reflect.Value {
return reflect.ValueOf(src)
}
/*************************************************************
* Sorted PriorityItems
*************************************************************/
// ByPriorityItems type. implements the sort.Interface
type ByPriorityItems []*ListenerItem
// Len get items length
func (ls ByPriorityItems) Len() int {
return len(ls)
}
// Less implements the sort.Interface.Less.
func (ls ByPriorityItems) Less(i, j int) bool {
return ls[i].Priority > ls[j].Priority
}
// Swap implements the sort.Interface.Swap.
func (ls ByPriorityItems) Swap(i, j int) {
ls[i], ls[j] = ls[j], ls[i]
}