Make enabling/disabling state-tracking easier. Improve constructors.

This commit is contained in:
Alex Bramley 2011-11-07 13:34:13 +00:00
parent 6e87169e2c
commit aa75e0e0c6
4 changed files with 78 additions and 33 deletions

View File

@ -66,20 +66,31 @@ 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.
// Dependency injection is a bitch :-/ func SimpleClient(nick string, args ...string) *Conn {
func New(nick, user, name string, st bool, r := event.NewRegistry()
r event.EventRegistry, l logging.Logger) *Conn { l := logging.NewFromFlags()
if r == nil { ident := "goirc"
r = event.NewRegistry() name := "Powered by GoIRC"
if len(args) > 0 && args[0] != "" {
ident = args[0]
} }
if l == nil { if len(args) > 1 && args[1] != "" {
l = logging.NewFromFlags() name = args[1]
}
return Client(nick, ident, name, r, l)
}
func Client(nick, ident, name string,
r event.EventRegistry, l logging.Logger) *Conn {
if r == nil || l == nil {
return nil
} }
conn := &Conn{ conn := &Conn{
ER: r, ER: r,
ED: r, ED: r,
l: l, l: l,
st: st, st: false,
in: make(chan *Line, 32), in: make(chan *Line, 32),
out: make(chan string, 32), out: make(chan string, 32),
cSend: make(chan bool), cSend: make(chan bool),
@ -92,20 +103,35 @@ func New(nick, user, name string, st bool,
lastsent: 0, lastsent: 0,
} }
conn.addIntHandlers() conn.addIntHandlers()
if st {
conn.ST = state.NewTracker(nick, l)
conn.Me = conn.ST.Me()
conn.addSTHandlers()
} else {
conn.Me = state.NewNick(nick, l) conn.Me = state.NewNick(nick, l)
} conn.Me.Ident = ident
conn.Me.Ident = user
conn.Me.Name = name conn.Me.Name = name
conn.initialise() conn.initialise()
return conn return conn
} }
func (conn *Conn) EnableStateTracking() {
if !conn.st {
n := conn.Me
conn.ST = state.NewTracker(n.Nick, conn.l)
conn.Me = conn.ST.Me()
conn.Me.Ident = n.Ident
conn.Me.Name = n.Name
conn.addSTHandlers()
conn.st = true
}
}
func (conn *Conn) DisableStateTracking() {
if conn.st {
conn.st = false
conn.delSTHandlers()
conn.ST.Wipe()
conn.ST = nil
}
}
// Per-connection state initialisation. // Per-connection state initialisation.
func (conn *Conn) initialise() { func (conn *Conn) initialise() {
conn.io = nil conn.io = nil

View File

@ -1,6 +1,7 @@
package client package client
import ( import (
"github.com/fluffle/goirc/event"
"github.com/fluffle/goirc/logging" "github.com/fluffle/goirc/logging"
"github.com/fluffle/goirc/state" "github.com/fluffle/goirc/state"
"gomock.googlecode.com/hg/gomock" "gomock.googlecode.com/hg/gomock"
@ -20,9 +21,10 @@ type testState struct {
func setUp(t *testing.T) (*Conn, *testState) { func setUp(t *testing.T) (*Conn, *testState) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
st := state.NewMockStateTracker(ctrl) st := state.NewMockStateTracker(ctrl)
r := event.NewRegistry()
l := logging.NewMockLogger(ctrl) l := logging.NewMockLogger(ctrl)
nc := MockNetConn(t) nc := MockNetConn(t)
c := New("test", "test", "Testing IRC", false, nil, l) c := Client("test", "test", "Testing IRC", r, l)
// We don't want to have to specify s.log.EXPECT().Debug() for all the // We don't want to have to specify s.log.EXPECT().Debug() for all the
// random crap that gets logged. This mocks it all out nicely. // random crap that gets logged. This mocks it all out nicely.

View File

@ -19,8 +19,10 @@ type IRCHandler func(*Conn, *Line)
// "PRIVMSG", "JOIN", etc. but all the numeric replies are left as ascii // "PRIVMSG", "JOIN", etc. but all the numeric replies are left as ascii
// strings of digits like "332" (mainly because I really didn't feel like // strings of digits like "332" (mainly because I really didn't feel like
// putting massive constant tables in). // putting massive constant tables in).
func (conn *Conn) AddHandler(name string, f IRCHandler) { func (conn *Conn) AddHandler(name string, f IRCHandler) event.Handler {
conn.ER.AddHandler(name, NewHandler(f)) h := NewHandler(f)
conn.ER.AddHandler(h, name)
return h
} }
// Wrap f in an anonymous unboxing function // Wrap f in an anonymous unboxing function

View File

@ -4,24 +4,39 @@ package client
// to manage tracking state for an IRC connection // to manage tracking state for an IRC connection
import ( import (
"github.com/fluffle/goirc/event"
"strings" "strings"
) )
func (conn *Conn) addSTHandlers() { var stHandlers map[string]event.Handler
conn.AddHandler("JOIN", (*Conn).h_JOIN)
conn.AddHandler("KICK", (*Conn).h_KICK)
conn.AddHandler("MODE", (*Conn).h_MODE)
conn.AddHandler("NICK", (*Conn).h_STNICK)
conn.AddHandler("PART", (*Conn).h_PART)
conn.AddHandler("QUIT", (*Conn).h_QUIT)
conn.AddHandler("TOPIC", (*Conn).h_TOPIC)
conn.AddHandler("311", (*Conn).h_311) func init() {
conn.AddHandler("324", (*Conn).h_324) stHandlers = make(map[string]event.Handler)
conn.AddHandler("332", (*Conn).h_332) stHandlers["JOIN"] = NewHandler((*Conn).h_JOIN)
conn.AddHandler("352", (*Conn).h_352) stHandlers["KICK"] = NewHandler((*Conn).h_KICK)
conn.AddHandler("353", (*Conn).h_353) stHandlers["MODE"] = NewHandler((*Conn).h_MODE)
conn.AddHandler("671", (*Conn).h_671) stHandlers["NICK"] = NewHandler((*Conn).h_STNICK)
stHandlers["PART"] = NewHandler((*Conn).h_PART)
stHandlers["QUIT"] = NewHandler((*Conn).h_QUIT)
stHandlers["TOPIC"] = NewHandler((*Conn).h_TOPIC)
stHandlers["311"] = NewHandler((*Conn).h_311)
stHandlers["324"] = NewHandler((*Conn).h_324)
stHandlers["332"] = NewHandler((*Conn).h_332)
stHandlers["352"] = NewHandler((*Conn).h_352)
stHandlers["353"] = NewHandler((*Conn).h_353)
stHandlers["671"] = NewHandler((*Conn).h_671)
}
func (conn *Conn) addSTHandlers() {
for n, h := range stHandlers {
conn.ER.AddHandler(h, n)
}
}
func (conn *Conn) delSTHandlers() {
for n, h := range stHandlers {
conn.ER.DelHandler(h, n)
}
} }
// Handle NICK messages that need to update the state tracker // Handle NICK messages that need to update the state tracker