Make Handler an interface type; make dispatcher private; correctly unbox ev.

This commit is contained in:
Alex Bramley 2011-07-27 17:49:34 +01:00
parent 2c10e19f58
commit cce112465f
1 changed files with 35 additions and 22 deletions

View File

@ -8,24 +8,37 @@ import (
) )
type HandlerID uint32 type HandlerID uint32
type Handler struct {
Run func(...interface{})
ID HandlerID
}
var hidCounter uint32 = 0 var hidCounter uint32 = 0
func NewHandlerID() HandlerID { func NewHandlerID() HandlerID {
return HandlerID(atomic.AddUint32(&hidCounter, 1)) return HandlerID(atomic.AddUint32(&hidCounter, 1))
} }
func NewHandler(h func(...interface{})) *Handler { type Handler interface {
return &Handler{h, NewHandlerID()} Run(...interface{})
Id() HandlerID
}
type basicHandler struct {
fn func(...interface{})
id HandlerID
}
func (h *basicHandler) Run(ev ...interface{}) {
h.fn(ev...)
}
func (h *basicHandler) Id() HandlerID {
return h.id
}
func NewHandler(h func(...interface{})) Handler {
return &basicHandler{h, NewHandlerID()}
} }
type EventRegistry interface { type EventRegistry interface {
AddHandler(name string, h *Handler) AddHandler(name string, h Handler)
DelHandler(h *Handler) DelHandler(h Handler)
Dispatch(name string, ev ...interface{}) Dispatch(name string, ev ...interface{})
ClearEvents(name string) ClearEvents(name string)
} }
@ -34,7 +47,7 @@ type registry struct {
// Event registry as a lockable map of linked-lists // Event registry as a lockable map of linked-lists
sync.RWMutex sync.RWMutex
events map[string]*list.List events map[string]*list.List
Dispatcher func(r *registry, name string, ev ...interface{}) dispatcher func(r *registry, name string, ev ...interface{})
} }
func NewRegistry() *registry { func NewRegistry() *registry {
@ -43,7 +56,7 @@ func NewRegistry() *registry {
return r return r
} }
func (r *registry) AddHandler(name string, h *Handler) { func (r *registry) AddHandler(name string, h Handler) {
name = strings.ToLower(name) name = strings.ToLower(name)
r.Lock() r.Lock()
defer r.Unlock() defer r.Unlock()
@ -52,20 +65,20 @@ func (r *registry) AddHandler(name string, h *Handler) {
} }
for e := r.events[name].Front(); e != nil; e = e.Next() { for e := r.events[name].Front(); e != nil; e = e.Next() {
// Check we're not adding a duplicate handler to this event // Check we're not adding a duplicate handler to this event
if e.Value.(*Handler).ID == h.ID { if e.Value.(Handler).Id() == h.Id() {
return return
} }
} }
r.events[name].PushBack(h) r.events[name].PushBack(h)
} }
func (r *registry) DelHandler(h *Handler) { func (r *registry) DelHandler(h Handler) {
// This is a bit brute-force. Don't add too many handlers! // This is a bit brute-force. Don't add too many handlers!
r.Lock() r.Lock()
defer r.Unlock() defer r.Unlock()
for _, l := range r.events { for _, l := range r.events {
for e := l.Front(); e != nil; e = e.Next() { for e := l.Front(); e != nil; e = e.Next() {
if e.Value.(*Handler).ID == h.ID { if e.Value.(Handler).Id() == h.Id() {
l.Remove(e) l.Remove(e)
} }
} }
@ -73,15 +86,15 @@ func (r *registry) DelHandler(h *Handler) {
} }
func (r *registry) Dispatch(name string, ev ...interface{}) { func (r *registry) Dispatch(name string, ev ...interface{}) {
r.Dispatcher(r, name, ev) r.dispatcher(r, name, ev...)
} }
func (r *registry) Parallel() { func (r *registry) Parallel() {
r.Dispatcher = (*registry).parallelDispatch r.dispatcher = (*registry).parallelDispatch
} }
func (r *registry) Serial() { func (r *registry) Serial() {
r.Dispatcher = (*registry).serialDispatch r.dispatcher = (*registry).serialDispatch
} }
func (r *registry) parallelDispatch(name string, ev ...interface{}) { func (r *registry) parallelDispatch(name string, ev ...interface{}) {
@ -90,8 +103,8 @@ func (r *registry) parallelDispatch(name string, ev ...interface{}) {
defer r.RUnlock() defer r.RUnlock()
if l, ok := r.events[name]; ok { if l, ok := r.events[name]; ok {
for e := l.Front(); e != nil; e = e.Next() { for e := l.Front(); e != nil; e = e.Next() {
h := e.Value.(*Handler) h := e.Value.(Handler)
go h.Run(ev) go h.Run(ev...)
} }
} }
} }
@ -101,13 +114,13 @@ func (r *registry) serialDispatch(name string, ev ...interface{}) {
r.RLock() r.RLock()
defer r.RUnlock() defer r.RUnlock()
if l, ok := r.events[name]; ok { if l, ok := r.events[name]; ok {
hlist := make([]*Handler, 0, l.Len()) hlist := make([]Handler, 0, l.Len())
for e := l.Front(); e != nil; e = e.Next() { for e := l.Front(); e != nil; e = e.Next() {
hlist = append(hlist, e.Value.(*Handler)) hlist = append(hlist, e.Value.(Handler))
} }
go func() { go func() {
for _, h := range hlist { for _, h := range hlist {
h.Run(ev) h.Run(ev...)
} }
}() }()
} }