From 6e87169e2c2f4dbd544089b5aab4d02a1bd20803 Mon Sep 17 00:00:00 2001 From: Alex Bramley Date: Mon, 7 Nov 2011 13:13:46 +0000 Subject: [PATCH] Make API for adding/deleting handlers more coherent. Previously, it was possible to add the same handler (as returned by NewHandler) to multiple different event lists, but DelHandler only removed a handler from *all* event lists it was present in. This may not be wanted behaviour, and reduces control over the event lists. Instead, allow both Add and DelHandler to take a variadic list of events to add or delete handlers from. --- event/registry.go | 52 +++++++++++++++++++++++++++--------------- event/registry_test.go | 6 ++--- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/event/registry.go b/event/registry.go index 740dc8d..379aed3 100644 --- a/event/registry.go +++ b/event/registry.go @@ -42,8 +42,8 @@ type EventDispatcher interface { } type EventRegistry interface { - AddHandler(name string, h Handler) - DelHandler(h Handler) + AddHandler(h Handler, names ...string) + DelHandler(h Handler, names ...string) Dispatch(name string, ev ...interface{}) ClearEvents(name string) } @@ -61,30 +61,46 @@ func NewRegistry() EventRegistry { return r } -func (r *registry) AddHandler(name string, h Handler) { - name = strings.ToLower(name) +func (r *registry) AddHandler(h Handler, names ...string) { + if len(names) == 0 { + return + } r.Lock() defer r.Unlock() - if _, ok := r.events[name]; !ok { - r.events[name] = list.New() - } - for e := r.events[name].Front(); e != nil; e = e.Next() { - // Check we're not adding a duplicate handler to this event - if e.Value.(Handler).Id() == h.Id() { - return + for _, name := range names { + name = strings.ToLower(name) + if _, ok := r.events[name]; !ok { + r.events[name] = list.New() } + for e := r.events[name].Front(); e != nil; e = e.Next() { + // Check we're not adding a duplicate handler to this event + if e.Value.(Handler).Id() == h.Id() { + return + } + } + r.events[name].PushBack(h) } - r.events[name].PushBack(h) } -func (r *registry) DelHandler(h Handler) { - // This is a bit brute-force. Don't add too many handlers! +func _del(l *list.List, id HandlerID) { + for e := l.Front(); e != nil; e = e.Next() { + if e.Value.(Handler).Id() == id { + l.Remove(e) + } + } +} + +func (r *registry) DelHandler(h Handler, names ...string) { r.Lock() defer r.Unlock() - for _, l := range r.events { - for e := l.Front(); e != nil; e = e.Next() { - if e.Value.(Handler).Id() == h.Id() { - l.Remove(e) + if len(names) == 0 { + for _, l := range r.events { + _del(l, h.Id()) + } + } else { + for _, name := range names { + if l, ok := r.events[name]; ok { + _del(l, h.Id()) } } } diff --git a/event/registry_test.go b/event/registry_test.go index 135f81c..4d194e9 100644 --- a/event/registry_test.go +++ b/event/registry_test.go @@ -14,7 +14,7 @@ func TestSimpleDispatch(t *testing.T) { h := NewHandler(func(ev ...interface{}) { out <- ev[0].(bool) }) - r.AddHandler("send", h) + r.AddHandler(h, "send") r.Dispatch("send", true) if val := <-out; !val { @@ -42,7 +42,7 @@ func TestParallelDispatch(t *testing.T) { // create some handlers and send an event to them for _, t := range []int{5, 11, 2, 15, 8} { - r.AddHandler("send", factory(t)) + r.AddHandler(factory(t), "send") } r.Dispatch("send") @@ -80,7 +80,7 @@ func TestSerialDispatch(t *testing.T) { // create some handlers and send an event to them for _, t := range []int{5, 11, 2, 15, 8} { - r.AddHandler("send", factory(t)) + r.AddHandler(factory(t), "send") } r.Dispatch("send")