Further comment tidy and code reorg.

This commit is contained in:
Alex Bramley 2013-03-10 13:16:14 +00:00
parent d6cb0bb026
commit 5f2665dde8
3 changed files with 20 additions and 8 deletions

View File

@ -17,6 +17,7 @@ type testState struct {
c *Conn c *Conn
} }
// NOTE: including a second argument at all prevents calling c.postConnect()
func setUp(t *testing.T, start ...bool) (*Conn, *testState) { func setUp(t *testing.T, start ...bool) (*Conn, *testState) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
st := state.NewMockTracker(ctrl) st := state.NewMockTracker(ctrl)
@ -56,7 +57,7 @@ func TestEOF(t *testing.T) {
// Set up a handler to detect whether disconnected handlers are called // Set up a handler to detect whether disconnected handlers are called
dcon := false dcon := false
c.HandleFunc("disconnected", func(conn *Conn, line *Line) { c.HandleFunc(DISCONNECTED, func(conn *Conn, line *Line) {
dcon = true dcon = true
}) })

View File

@ -6,7 +6,7 @@ import (
"sync" "sync"
) )
// An IRC handler looks like this: // An IRC Handler looks like this:
type Handler interface { type Handler interface {
Handle(*Conn, *Line) Handle(*Conn, *Line)
} }
@ -16,16 +16,28 @@ type Remover interface {
Remove() Remove()
} }
// A HandlerFunc implements Handler.
type HandlerFunc func(*Conn, *Line) type HandlerFunc func(*Conn, *Line)
func (hf HandlerFunc) Handle(conn *Conn, line *Line) { func (hf HandlerFunc) Handle(conn *Conn, line *Line) {
hf(conn, line) hf(conn, line)
} }
// Handlers are organised using a map of linked-lists, with each map
// key representing an IRC verb or numeric, and the linked list values
// being handlers that are executed in parallel when a Line from the
// server with that verb or numeric arrives.
type hSet struct {
set map[string]*hList
sync.RWMutex
}
type hList struct { type hList struct {
start, end *hNode start, end *hNode
} }
// Storing the forward and backward links in the node allows O(1) removal.
// This probably isn't strictly necessary but I think it's kinda nice.
type hNode struct { type hNode struct {
next, prev *hNode next, prev *hNode
set *hSet set *hSet
@ -33,23 +45,22 @@ type hNode struct {
handler Handler handler Handler
} }
// A hNode implements both Handler...
func (hn *hNode) Handle(conn *Conn, line *Line) { func (hn *hNode) Handle(conn *Conn, line *Line) {
hn.handler.Handle(conn, line) hn.handler.Handle(conn, line)
} }
// ... and Remover.
func (hn *hNode) Remove() { func (hn *hNode) Remove() {
hn.set.remove(hn) hn.set.remove(hn)
} }
type hSet struct {
set map[string]*hList
sync.RWMutex
}
func handlerSet() *hSet { func handlerSet() *hSet {
return &hSet{set: make(map[string]*hList)} return &hSet{set: make(map[string]*hList)}
} }
// When a new Handler is added for an event, it is wrapped in a hNode and
// returned as a Remover so the caller can remove it at a later time.
func (hs *hSet) add(ev string, h Handler) Remover { func (hs *hSet) add(ev string, h Handler) Remover {
hs.Lock() hs.Lock()
defer hs.Unlock() defer hs.Unlock()

View File

@ -12,7 +12,7 @@ func TestHandlerSet(t *testing.T) {
} }
callcount := 0 callcount := 0
f := func(c *Conn, l *Line) { f := func(_ *Conn, _ *Line) {
callcount++ callcount++
} }