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
|
package event
import (
"bytes"
"fmt"
"strings"
"sync"
)
const Sep = "/"
func Sprint(a ...interface{}) string {
var buf bytes.Buffer
for i := range a {
if i > 0 {
buf.WriteString(Sep)
}
fmt.Fprint(&buf, a[i])
}
return buf.String()
}
func Sscan(event string, a ...interface{}) {
for i, part := range strings.Split(event, Sep) {
fmt.Sscan(part, a[i])
}
}
type Dispatch struct {
mu sync.Mutex
handlers []func(event string) bool
trie map[string]*Dispatch
}
func (d *Dispatch) Event(pattern string, handler func(event string) bool) {
if pattern == "" {
d.event(nil, handler)
return
}
d.event(strings.Split(pattern, Sep), handler)
}
func (d *Dispatch) Happen(event string) bool {
if event == "" {
return d.happen(nil)
}
return d.happen(strings.Split(event, Sep))
}
func (d *Dispatch) event(pattern []string, handler func(event string) bool) {
d.mu.Lock()
defer d.mu.Unlock()
if len(pattern) == 0 {
d.handlers = append(d.handlers, handler)
return
}
if d.trie == nil {
d.trie = make(map[string]*Dispatch)
}
if d.trie[pattern[0]] == nil {
d.trie[pattern[0]] = &Dispatch{}
}
d.trie[pattern[0]].event(pattern[1:], handler)
}
func (d *Dispatch) happen(event []string) bool {
d.mu.Lock()
handlers := d.handlers
d.mu.Unlock()
for _, handler := range handlers {
if handler(strings.Join(event, Sep)) {
return true
}
}
if len(event) == 0 {
return false
}
d.mu.Lock()
next := d.trie[event[0]]
d.mu.Unlock()
if next != nil {
return next.happen(event[1:])
}
return false
}
|