Added more documentation, commands are a list now, not a set :)

This commit is contained in:
Chris Rhodes 2013-02-17 00:09:16 -08:00
parent 89c23a7787
commit e8eba53828
3 changed files with 36 additions and 32 deletions

View File

@ -32,6 +32,7 @@ func main() {
func(conn *irc.Conn, line *irc.Line) { quit <- true }) func(conn *irc.Conn, line *irc.Line) { quit <- true })
// Set up some simple commands, !bark and !roll. // Set up some simple commands, !bark and !roll.
// The !roll command will also get the "!help roll" command also.
c.SimpleCommandFunc("bark", func(conn *irc.Conn, line *irc.Line) { conn.Privmsg(line.Target(), "Woof Woof") }) c.SimpleCommandFunc("bark", func(conn *irc.Conn, line *irc.Line) { conn.Privmsg(line.Target(), "Woof Woof") })
c.SimpleCommandHelpFunc("roll", `Rolls a d6, "roll <n>" to roll n dice at once.`, func(conn *irc.Conn, line *irc.Line) { c.SimpleCommandHelpFunc("roll", `Rolls a d6, "roll <n>" to roll n dice at once.`, func(conn *irc.Conn, line *irc.Line) {
count := 1 count := 1
@ -50,6 +51,9 @@ func main() {
}) })
// Set up some commands that are triggered by a regex in a message. // Set up some commands that are triggered by a regex in a message.
// It is important to see that UrlRegex could actually respond to some
// of the Url's that YouTubeRegex listens to, because of this we put the
// YouTube command at a higher priority, this way it will take precedence.
c.CommandFunc(irc.YouTubeRegex, irc.YouTubeFunc, 10) c.CommandFunc(irc.YouTubeRegex, irc.YouTubeFunc, 10)
c.CommandFunc(irc.UrlRegex, irc.UrlFunc, 0) c.CommandFunc(irc.UrlRegex, irc.UrlFunc, 0)

View File

@ -22,7 +22,7 @@ type Conn struct {
// Handlers and Commands // Handlers and Commands
handlers *hSet handlers *hSet
commands *commandSet commands *commandList
// State tracker for nicks and channels // State tracker for nicks and channels
ST state.StateTracker ST state.StateTracker
@ -82,7 +82,7 @@ func Client(nick string, args ...string) *Conn {
cLoop: make(chan bool), cLoop: make(chan bool),
cPing: make(chan bool), cPing: make(chan bool),
handlers: handlerSet(), handlers: handlerSet(),
commands: newCommandSet(), commands: newCommandList(),
stRemovers: make([]Remover, 0, len(stHandlers)), stRemovers: make([]Remover, 0, len(stHandlers)),
PingFreq: 3 * time.Minute, PingFreq: 3 * time.Minute,
NewNick: func(s string) string { return s + "_" }, NewNick: func(s string) string { return s + "_" },

View File

@ -14,6 +14,12 @@ type Handler interface {
Handle(*Conn, *Line) Handle(*Conn, *Line)
} }
type HandlerFunc func(*Conn, *Line)
func (hf HandlerFunc) Handle(conn *Conn, line *Line) {
hf(conn, line)
}
// And when they've been added to the client they are removable. // And when they've been added to the client they are removable.
type Remover interface { type Remover interface {
Remove() Remove()
@ -25,12 +31,6 @@ func (r RemoverFunc) Remove() {
r() r()
} }
type HandlerFunc func(*Conn, *Line)
func (hf HandlerFunc) Handle(conn *Conn, line *Line) {
hf(conn, line)
}
type hList struct { type hList struct {
start, end *hNode start, end *hNode
} }
@ -124,7 +124,7 @@ func (hs *hSet) dispatch(conn *Conn, line *Line) {
type command struct { type command struct {
handler Handler handler Handler
set *commandSet set *commandList
regex string regex string
priority int priority int
} }
@ -137,42 +137,42 @@ func (c *command) Remove() {
c.set.remove(c) c.set.remove(c)
} }
type commandSet struct { type commandList struct {
set []*command set []*command
sync.RWMutex sync.RWMutex
} }
func newCommandSet() *commandSet { func newCommandList() *commandList {
return &commandSet{} return &commandList{}
} }
func (cs *commandSet) add(regex string, handler Handler, priority int) Remover { func (cl *commandList) add(regex string, handler Handler, priority int) Remover {
cs.Lock() cl.Lock()
defer cs.Unlock() defer cl.Unlock()
c := &command{ c := &command{
handler: handler, handler: handler,
set: cs, set: cl,
regex: regex, regex: regex,
priority: priority, priority: priority,
} }
// Check for exact regex matches. This will filter out any repeated SimpleCommands. // Check for exact regex matches. This will filter out any repeated SimpleCommands.
for _, c := range cs.set { for _, c := range cl.set {
if c.regex == regex { if c.regex == regex {
logging.Error("Command prefix '%s' already registered.", regex) logging.Error("Command prefix '%s' already registered.", regex)
return nil return nil
} }
} }
cs.set = append(cs.set, c) cl.set = append(cl.set, c)
return c return c
} }
func (cs *commandSet) remove(c *command) { func (cl *commandList) remove(c *command) {
cs.Lock() cl.Lock()
defer cs.Unlock() defer cl.Unlock()
for index, value := range cs.set { for index, value := range cl.set {
if value == c { if value == c {
copy(cs.set[index:], cs.set[index+1:]) copy(cl.set[index:], cl.set[index+1:])
cs.set = cs.set[:len(cs.set)-1] cl.set = cl.set[:len(cl.set)-1]
c.set = nil c.set = nil
return return
} }
@ -180,11 +180,11 @@ func (cs *commandSet) remove(c *command) {
} }
// Matches the command with the highest priority. // Matches the command with the highest priority.
func (cs *commandSet) match(txt string) (handler Handler) { func (cl *commandList) match(txt string) (handler Handler) {
cs.RLock() cl.RLock()
defer cs.RUnlock() defer cl.RUnlock()
maxPriority := math.MinInt32 maxPriority := math.MinInt32
for _, c := range cs.set { for _, c := range cl.set {
if c.priority > maxPriority { if c.priority > maxPriority {
if regex, error := regexp.Compile(c.regex); error == nil { if regex, error := regexp.Compile(c.regex); error == nil {
if regex.MatchString(txt) { if regex.MatchString(txt) {
@ -203,12 +203,12 @@ func (cs *commandSet) match(txt string) (handler Handler) {
// "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) Handle(name string, h Handler) Remover { func (conn *Conn) Handle(name string, handler Handler) Remover {
return conn.handlers.add(name, h) return conn.handlers.add(name, handler)
} }
func (conn *Conn) HandleFunc(name string, hf HandlerFunc) Remover { func (conn *Conn) HandleFunc(name string, handlerFunc HandlerFunc) Remover {
return conn.Handle(name, hf) return conn.Handle(name, handlerFunc)
} }
func (conn *Conn) Command(regex string, handler Handler, priority int) Remover { func (conn *Conn) Command(regex string, handler Handler, priority int) Remover {