irc-go/eventmgr/events.go
2016-01-18 17:21:27 +10:00

100 lines
2.7 KiB
Go

// written by Daniel Oaks <daniel@danieloaks.net>
// released under the ISC license
package eventmgr
import "sort"
// HandlerFn defines a function we can call as a handler.
type HandlerFn func(string, InfoMap)
// InfoMap defines a map we pass through event dispatches.
type InfoMap map[string]interface{}
// NewInfoMap returns a new, empty InfoMap.
func NewInfoMap() InfoMap {
var info InfoMap
info = make(InfoMap)
return info
}
// EventHandler holds the priority and handler function of an event.
type EventHandler struct {
Handler HandlerFn
Priority int
}
// Handlers holds a list of EventHandlers, including keeping them sorted.
type Handlers struct {
Handlers []EventHandler
}
// Attach attaches a handler to our internal list and returns a new Handlers.
//
// This isn't optimised as much as we probably could. I think most event
// handlers will attach everything at startup, so it's not a massive issue,
// though it is something to look at.
func (handlers Handlers) Attach(eventhandler EventHandler) Handlers {
if handlers.Handlers == nil {
handlers.Handlers = make([]EventHandler, 0)
}
handlers.Handlers = append(handlers.Handlers, eventhandler)
sort.Sort(handlers)
return handlers
}
// Dispatch dispatches an event to all of our handlers.
func (handlers Handlers) Dispatch(event string, info map[string]interface{}) {
for _, eventhandler := range handlers.Handlers {
eventhandler.Handler(event, info)
}
}
// Len returns the length of the HandlerList
func (handlers Handlers) Len() int {
return len(handlers.Handlers)
}
// Less returns whether i is less than j.
func (handlers Handlers) Less(i, j int) bool {
return handlers.Handlers[i].Priority < handlers.Handlers[j].Priority
}
// Swap swaps i and j.
func (handlers Handlers) Swap(i, j int) {
handlers.Handlers[i], handlers.Handlers[j] = handlers.Handlers[j], handlers.Handlers[i]
}
// EventManager lets you attach to and dispatch events.
type EventManager struct {
Events map[string]Handlers
}
// Attach lets you attach a handler to the given event.
func (manager *EventManager) Attach(event string, handler HandlerFn, priority int) {
var fullhandler EventHandler
fullhandler.Handler = handler
fullhandler.Priority = priority
if manager.Events == nil {
manager.Events = make(map[string]Handlers)
}
_, exists := manager.Events[event]
if !exists {
var handlers Handlers
manager.Events[event] = handlers
}
manager.Events[event] = manager.Events[event].Attach(fullhandler)
}
// Dispatch dispatches the given event/info to all the matching event handlers.
func (manager *EventManager) Dispatch(event string, info map[string]interface{}) {
events, exists := manager.Events[event]
if exists {
events.Dispatch(event, info)
}
}