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.
This commit is contained in:
Alex Bramley 2011-11-07 13:13:46 +00:00
parent 4853024928
commit 6e87169e2c
2 changed files with 37 additions and 21 deletions

View File

@ -42,8 +42,8 @@ type EventDispatcher interface {
} }
type EventRegistry interface { type EventRegistry interface {
AddHandler(name string, h Handler) AddHandler(h Handler, names ...string)
DelHandler(h Handler) DelHandler(h Handler, names ...string)
Dispatch(name string, ev ...interface{}) Dispatch(name string, ev ...interface{})
ClearEvents(name string) ClearEvents(name string)
} }
@ -61,10 +61,14 @@ func NewRegistry() EventRegistry {
return r return r
} }
func (r *registry) AddHandler(name string, h Handler) { func (r *registry) AddHandler(h Handler, names ...string) {
name = strings.ToLower(name) if len(names) == 0 {
return
}
r.Lock() r.Lock()
defer r.Unlock() defer r.Unlock()
for _, name := range names {
name = strings.ToLower(name)
if _, ok := r.events[name]; !ok { if _, ok := r.events[name]; !ok {
r.events[name] = list.New() r.events[name] = list.New()
} }
@ -75,16 +79,28 @@ func (r *registry) AddHandler(name string, h Handler) {
} }
} }
r.events[name].PushBack(h) r.events[name].PushBack(h)
}
} }
func (r *registry) DelHandler(h Handler) { func _del(l *list.List, id HandlerID) {
// This is a bit brute-force. Don't add too many handlers! 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() r.Lock()
defer r.Unlock() defer r.Unlock()
if len(names) == 0 {
for _, l := range r.events { for _, l := range r.events {
for e := l.Front(); e != nil; e = e.Next() { _del(l, h.Id())
if e.Value.(Handler).Id() == h.Id() { }
l.Remove(e) } else {
for _, name := range names {
if l, ok := r.events[name]; ok {
_del(l, h.Id())
} }
} }
} }

View File

@ -14,7 +14,7 @@ func TestSimpleDispatch(t *testing.T) {
h := NewHandler(func(ev ...interface{}) { h := NewHandler(func(ev ...interface{}) {
out <- ev[0].(bool) out <- ev[0].(bool)
}) })
r.AddHandler("send", h) r.AddHandler(h, "send")
r.Dispatch("send", true) r.Dispatch("send", true)
if val := <-out; !val { if val := <-out; !val {
@ -42,7 +42,7 @@ func TestParallelDispatch(t *testing.T) {
// create some handlers and send an event to them // create some handlers and send an event to them
for _, t := range []int{5, 11, 2, 15, 8} { for _, t := range []int{5, 11, 2, 15, 8} {
r.AddHandler("send", factory(t)) r.AddHandler(factory(t), "send")
} }
r.Dispatch("send") r.Dispatch("send")
@ -80,7 +80,7 @@ func TestSerialDispatch(t *testing.T) {
// create some handlers and send an event to them // create some handlers and send an event to them
for _, t := range []int{5, 11, 2, 15, 8} { for _, t := range []int{5, 11, 2, 15, 8} {
r.AddHandler("send", factory(t)) r.AddHandler(factory(t), "send")
} }
r.Dispatch("send") r.Dispatch("send")