Add an overridable Dispatcher to Conn, and use that to dispatch events.

This commit is contained in:
Alex Bramley 2011-07-27 21:35:45 +01:00
parent 900afb5c48
commit 8e6de2f3c7
3 changed files with 15 additions and 12 deletions

View File

@ -23,8 +23,10 @@ type Conn struct {
Me *Nick Me *Nick
Network string Network string
// Event handler mapping // Event handler registry and dispatcher
Registry event.EventRegistry Registry event.EventRegistry
Dispatcher event.EventDispatcher
// Map of channels we're on // Map of channels we're on
chans map[string]*Channel chans map[string]*Channel
// Map of nicks we know about // Map of nicks we know about
@ -72,8 +74,10 @@ type Conn struct {
// Creates a new IRC connection object, but doesn't connect to anything so // Creates a new IRC connection object, but doesn't connect to anything so
// that you can add event handlers to it. See AddHandler() for details. // that you can add event handlers to it. See AddHandler() for details.
func New(nick, user, name string) *Conn { func New(nick, user, name string) *Conn {
reg := event.NewRegistry()
conn := &Conn{ conn := &Conn{
Registry: event.NewRegistry(), Registry: reg,
Dispatcher: reg,
in: make(chan *Line, 32), in: make(chan *Line, 32),
out: make(chan string, 32), out: make(chan string, 32),
Err: make(chan os.Error, 4), Err: make(chan os.Error, 4),
@ -89,7 +93,7 @@ func New(nick, user, name string) *Conn {
TSFormat: "15:04:05", TSFormat: "15:04:05",
} }
conn.initialise() conn.initialise()
conn.setupEvents() conn.SetupHandlers()
conn.Me = conn.NewNick(nick, user, name, "") conn.Me = conn.NewNick(nick, user, name, "")
return conn return conn
} }
@ -209,7 +213,7 @@ func (conn *Conn) runLoop() {
for { for {
select { select {
case line := <-conn.in: case line := <-conn.in:
conn.dispatchEvent(line) conn.Dispatcher.Dispatch(line.Cmd, conn, line)
case <-conn.cLoop: case <-conn.cLoop:
// strobe on control channel, bail out // strobe on control channel, bail out
return return
@ -262,7 +266,7 @@ func (conn *Conn) shutdown() {
conn.sock.Close() conn.sock.Close()
conn.cSend <- true conn.cSend <- true
conn.cLoop <- true conn.cLoop <- true
conn.dispatchEvent(&Line{Cmd: "DISCONNECTED"}) conn.Dispatcher.Dispatch("disconnected")
// reinit datastructures ready for next connection // reinit datastructures ready for next connection
// do this here rather than after runLoop()'s for due to race // do this here rather than after runLoop()'s for due to race
conn.initialise() conn.initialise()

View File

@ -28,11 +28,6 @@ func (conn *Conn) AddHandler(name string, f func(*Conn, *Line)) {
})) }))
} }
// loops through all event handlers for line.Cmd, running each in a goroutine
func (conn *Conn) dispatchEvent(line *Line) {
conn.Registry.Dispatch(line.Cmd, conn, line)
}
// Basic ping/pong handler // Basic ping/pong handler
func (conn *Conn) h_PING(line *Line) { func (conn *Conn) h_PING(line *Line) {
conn.Raw("PONG :" + line.Args[0]) conn.Raw("PONG :" + line.Args[0])
@ -41,7 +36,7 @@ func (conn *Conn) h_PING(line *Line) {
// Handler to trigger a "CONNECTED" event on receipt of numeric 001 // Handler to trigger a "CONNECTED" event on receipt of numeric 001
func (conn *Conn) h_001(line *Line) { func (conn *Conn) h_001(line *Line) {
// we're connected! // we're connected!
conn.dispatchEvent(&Line{Cmd: "CONNECTED"}) conn.Dispatcher.Dispatch("connected")
// and we're being given our hostname (from the server's perspective) // and we're being given our hostname (from the server's perspective)
t := line.Args[len(line.Args)-1] t := line.Args[len(line.Args)-1]
if idx := strings.LastIndex(t, " "); idx != -1 { if idx := strings.LastIndex(t, " "); idx != -1 {
@ -288,7 +283,7 @@ func (conn *Conn) h_671(line *Line) {
} }
// sets up the internal event handlers to do useful things with lines // sets up the internal event handlers to do useful things with lines
func (conn *Conn) setupEvents() { func (conn *Conn) SetupHandlers() {
conn.AddHandler("CTCP", (*Conn).h_CTCP) conn.AddHandler("CTCP", (*Conn).h_CTCP)
conn.AddHandler("JOIN", (*Conn).h_JOIN) conn.AddHandler("JOIN", (*Conn).h_JOIN)
conn.AddHandler("KICK", (*Conn).h_KICK) conn.AddHandler("KICK", (*Conn).h_KICK)

View File

@ -36,6 +36,10 @@ func NewHandler(h func(...interface{})) Handler {
return &basicHandler{h, NewHandlerID()} return &basicHandler{h, NewHandlerID()}
} }
type EventDispatcher interface {
Dispatch(name string, ev...interface{})
}
type EventRegistry interface { type EventRegistry interface {
AddHandler(name string, h Handler) AddHandler(name string, h Handler)
DelHandler(h Handler) DelHandler(h Handler)