diff --git a/client/connection.go b/client/connection.go index 8c032e7..eb7ff29 100644 --- a/client/connection.go +++ b/client/connection.go @@ -23,8 +23,10 @@ type Conn struct { Me *Nick Network string - // Event handler mapping + // Event handler registry and dispatcher Registry event.EventRegistry + Dispatcher event.EventDispatcher + // Map of channels we're on chans map[string]*Channel // 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 // that you can add event handlers to it. See AddHandler() for details. func New(nick, user, name string) *Conn { + reg := event.NewRegistry() conn := &Conn{ - Registry: event.NewRegistry(), + Registry: reg, + Dispatcher: reg, in: make(chan *Line, 32), out: make(chan string, 32), Err: make(chan os.Error, 4), @@ -89,7 +93,7 @@ func New(nick, user, name string) *Conn { TSFormat: "15:04:05", } conn.initialise() - conn.setupEvents() + conn.SetupHandlers() conn.Me = conn.NewNick(nick, user, name, "") return conn } @@ -209,7 +213,7 @@ func (conn *Conn) runLoop() { for { select { case line := <-conn.in: - conn.dispatchEvent(line) + conn.Dispatcher.Dispatch(line.Cmd, conn, line) case <-conn.cLoop: // strobe on control channel, bail out return @@ -262,7 +266,7 @@ func (conn *Conn) shutdown() { conn.sock.Close() conn.cSend <- true conn.cLoop <- true - conn.dispatchEvent(&Line{Cmd: "DISCONNECTED"}) + conn.Dispatcher.Dispatch("disconnected") // reinit datastructures ready for next connection // do this here rather than after runLoop()'s for due to race conn.initialise() diff --git a/client/handlers.go b/client/handlers.go index 19af1fd..4e4ef02 100644 --- a/client/handlers.go +++ b/client/handlers.go @@ -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 func (conn *Conn) h_PING(line *Line) { 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 func (conn *Conn) h_001(line *Line) { // we're connected! - conn.dispatchEvent(&Line{Cmd: "CONNECTED"}) + conn.Dispatcher.Dispatch("connected") // and we're being given our hostname (from the server's perspective) t := line.Args[len(line.Args)-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 -func (conn *Conn) setupEvents() { +func (conn *Conn) SetupHandlers() { conn.AddHandler("CTCP", (*Conn).h_CTCP) conn.AddHandler("JOIN", (*Conn).h_JOIN) conn.AddHandler("KICK", (*Conn).h_KICK) diff --git a/event/registry.go b/event/registry.go index c5e4d58..ed6c228 100644 --- a/event/registry.go +++ b/event/registry.go @@ -36,6 +36,10 @@ func NewHandler(h func(...interface{})) Handler { return &basicHandler{h, NewHandlerID()} } +type EventDispatcher interface { + Dispatch(name string, ev...interface{}) +} + type EventRegistry interface { AddHandler(name string, h Handler) DelHandler(h Handler)