aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfaiface <faiface@ksp.sk>2017-08-18 19:32:34 +0200
committerfaiface <faiface@ksp.sk>2017-08-18 19:32:34 +0200
commitc900b5f71877660fffad5bc276aeda4c9a345ad1 (patch)
treeee1d4416270e8efd9f9756124098d4028037013f
parent7208aae9ed2707d6c2c7de6c8e4fffe19bd639a7 (diff)
downloadgui-c900b5f71877660fffad5bc276aeda4c9a345ad1.zip
add event dispatch
-rw-r--r--event/dispatch.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/event/dispatch.go b/event/dispatch.go
new file mode 100644
index 0000000..e84da18
--- /dev/null
+++ b/event/dispatch.go
@@ -0,0 +1,70 @@
+package event
+
+import (
+ "strings"
+ "sync"
+)
+
+const Sep = "/"
+
+type Dispatch struct {
+ mu sync.Mutex
+ handlers []func(event string)
+ trie map[string]*Dispatch
+}
+
+func (d *Dispatch) Event(pattern string, handler func(event string)) {
+ if pattern == "" {
+ d.event(nil, handler)
+ return
+ }
+ d.event(strings.Split(pattern, Sep), handler)
+}
+
+func (d *Dispatch) Happen(event string) {
+ if event == "" {
+ d.happen(nil)
+ return
+ }
+ d.happen(strings.Split(event, Sep))
+}
+
+func (d *Dispatch) event(pattern []string, handler func(event string)) {
+ 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) {
+ d.mu.Lock()
+ handlers := d.handlers
+ d.mu.Unlock()
+
+ for _, handler := range handlers {
+ handler(strings.Join(event, Sep))
+ }
+
+ if len(event) == 0 {
+ return
+ }
+
+ d.mu.Lock()
+ next := d.trie[event[0]]
+ d.mu.Unlock()
+
+ if next != nil {
+ next.happen(event[1:])
+ }
+}