Callbacks -> Handlers
This commit is contained in:
parent
c9243b15b3
commit
69a6d77ac8
@ -9,67 +9,67 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// registerHandlers sets up built-in callbacks/helpers, based on client
|
||||
// registerBuiltin sets up built-in handlers, based on client
|
||||
// configuration.
|
||||
func (c *Client) registerHandlers() {
|
||||
func (c *Client) registerBuiltin() {
|
||||
c.debug.Print("registering built-in handlers")
|
||||
c.Callbacks.mu.Lock()
|
||||
c.Handlers.mu.Lock()
|
||||
|
||||
// Built-in things that should always be supported.
|
||||
c.Callbacks.register(true, RPL_WELCOME, CallbackFunc(func(c *Client, e Event) {
|
||||
c.Handlers.register(true, RPL_WELCOME, HandlerFunc(func(c *Client, e Event) {
|
||||
go handleConnect(c, e)
|
||||
}))
|
||||
c.Callbacks.register(true, PING, CallbackFunc(handlePING))
|
||||
c.Handlers.register(true, PING, HandlerFunc(handlePING))
|
||||
|
||||
if !c.Config.disableTracking {
|
||||
// Joins/parts/anything that may add/remove/rename users.
|
||||
c.Callbacks.register(true, JOIN, CallbackFunc(handleJOIN))
|
||||
c.Callbacks.register(true, PART, CallbackFunc(handlePART))
|
||||
c.Callbacks.register(true, KICK, CallbackFunc(handleKICK))
|
||||
c.Callbacks.register(true, QUIT, CallbackFunc(handleQUIT))
|
||||
c.Callbacks.register(true, NICK, CallbackFunc(handleNICK))
|
||||
c.Callbacks.register(true, RPL_NAMREPLY, CallbackFunc(handleNAMES))
|
||||
c.Handlers.register(true, JOIN, HandlerFunc(handleJOIN))
|
||||
c.Handlers.register(true, PART, HandlerFunc(handlePART))
|
||||
c.Handlers.register(true, KICK, HandlerFunc(handleKICK))
|
||||
c.Handlers.register(true, QUIT, HandlerFunc(handleQUIT))
|
||||
c.Handlers.register(true, NICK, HandlerFunc(handleNICK))
|
||||
c.Handlers.register(true, RPL_NAMREPLY, HandlerFunc(handleNAMES))
|
||||
|
||||
// Modes.
|
||||
c.Callbacks.register(true, MODE, CallbackFunc(handleMODE))
|
||||
c.Callbacks.register(true, RPL_CHANNELMODEIS, CallbackFunc(handleMODE))
|
||||
c.Handlers.register(true, MODE, HandlerFunc(handleMODE))
|
||||
c.Handlers.register(true, RPL_CHANNELMODEIS, HandlerFunc(handleMODE))
|
||||
|
||||
// WHO/WHOX responses.
|
||||
c.Callbacks.register(true, RPL_WHOREPLY, CallbackFunc(handleWHO))
|
||||
c.Callbacks.register(true, RPL_WHOSPCRPL, CallbackFunc(handleWHO))
|
||||
c.Handlers.register(true, RPL_WHOREPLY, HandlerFunc(handleWHO))
|
||||
c.Handlers.register(true, RPL_WHOSPCRPL, HandlerFunc(handleWHO))
|
||||
|
||||
// Other misc. useful stuff.
|
||||
c.Callbacks.register(true, TOPIC, CallbackFunc(handleTOPIC))
|
||||
c.Callbacks.register(true, RPL_TOPIC, CallbackFunc(handleTOPIC))
|
||||
c.Callbacks.register(true, RPL_MYINFO, CallbackFunc(handleMYINFO))
|
||||
c.Callbacks.register(true, RPL_ISUPPORT, CallbackFunc(handleISUPPORT))
|
||||
c.Callbacks.register(true, RPL_MOTDSTART, CallbackFunc(handleMOTD))
|
||||
c.Callbacks.register(true, RPL_MOTD, CallbackFunc(handleMOTD))
|
||||
c.Handlers.register(true, TOPIC, HandlerFunc(handleTOPIC))
|
||||
c.Handlers.register(true, RPL_TOPIC, HandlerFunc(handleTOPIC))
|
||||
c.Handlers.register(true, RPL_MYINFO, HandlerFunc(handleMYINFO))
|
||||
c.Handlers.register(true, RPL_ISUPPORT, HandlerFunc(handleISUPPORT))
|
||||
c.Handlers.register(true, RPL_MOTDSTART, HandlerFunc(handleMOTD))
|
||||
c.Handlers.register(true, RPL_MOTD, HandlerFunc(handleMOTD))
|
||||
|
||||
// Keep users lastactive times up to date.
|
||||
c.Callbacks.register(true, PRIVMSG, CallbackFunc(updateLastActive))
|
||||
c.Callbacks.register(true, NOTICE, CallbackFunc(updateLastActive))
|
||||
c.Callbacks.register(true, TOPIC, CallbackFunc(updateLastActive))
|
||||
c.Callbacks.register(true, KICK, CallbackFunc(updateLastActive))
|
||||
c.Handlers.register(true, PRIVMSG, HandlerFunc(updateLastActive))
|
||||
c.Handlers.register(true, NOTICE, HandlerFunc(updateLastActive))
|
||||
c.Handlers.register(true, TOPIC, HandlerFunc(updateLastActive))
|
||||
c.Handlers.register(true, KICK, HandlerFunc(updateLastActive))
|
||||
|
||||
// CAP IRCv3-specific tracking and functionality.
|
||||
if !c.Config.disableCapTracking {
|
||||
c.Callbacks.register(true, CAP, CallbackFunc(handleCAP))
|
||||
c.Callbacks.register(true, CAP_CHGHOST, CallbackFunc(handleCHGHOST))
|
||||
c.Callbacks.register(true, CAP_AWAY, CallbackFunc(handleAWAY))
|
||||
c.Callbacks.register(true, CAP_ACCOUNT, CallbackFunc(handleACCOUNT))
|
||||
c.Callbacks.register(true, ALLEVENTS, CallbackFunc(handleTags))
|
||||
c.Handlers.register(true, CAP, HandlerFunc(handleCAP))
|
||||
c.Handlers.register(true, CAP_CHGHOST, HandlerFunc(handleCHGHOST))
|
||||
c.Handlers.register(true, CAP_AWAY, HandlerFunc(handleAWAY))
|
||||
c.Handlers.register(true, CAP_ACCOUNT, HandlerFunc(handleACCOUNT))
|
||||
c.Handlers.register(true, ALLEVENTS, HandlerFunc(handleTags))
|
||||
}
|
||||
}
|
||||
|
||||
// Nickname collisions.
|
||||
if !c.Config.disableNickCollision {
|
||||
c.Callbacks.register(true, ERR_NICKNAMEINUSE, CallbackFunc(nickCollisionHandler))
|
||||
c.Callbacks.register(true, ERR_NICKCOLLISION, CallbackFunc(nickCollisionHandler))
|
||||
c.Callbacks.register(true, ERR_UNAVAILRESOURCE, CallbackFunc(nickCollisionHandler))
|
||||
c.Handlers.register(true, ERR_NICKNAMEINUSE, HandlerFunc(nickCollisionHandler))
|
||||
c.Handlers.register(true, ERR_NICKCOLLISION, HandlerFunc(nickCollisionHandler))
|
||||
c.Handlers.register(true, ERR_UNAVAILRESOURCE, HandlerFunc(nickCollisionHandler))
|
||||
}
|
||||
|
||||
c.Callbacks.mu.Unlock()
|
||||
c.Handlers.mu.Unlock()
|
||||
}
|
||||
|
||||
// handleConnect is a helper function which lets the client know that enough
|
||||
@ -286,7 +286,7 @@ func handleMYINFO(c *Client, e Event) {
|
||||
// For example, things like max channel name length, or nickname length.
|
||||
func handleISUPPORT(c *Client, e Event) {
|
||||
// Must be a ISUPPORT-based message. 005 is also used for server bounce
|
||||
// related things, so this callback may be triggered during other
|
||||
// related things, so this handler may be triggered during other
|
||||
// situations.
|
||||
|
||||
// Also known as RPL_PROTOCTL.
|
165
caller.go
165
caller.go
@ -13,8 +13,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// RunCallbacks manually runs callbacks for a given event.
|
||||
func (c *Client) RunCallbacks(event *Event) {
|
||||
// RunHandlers manually runs handlers for a given event.
|
||||
func (c *Client) RunHandlers(event *Event) {
|
||||
if event == nil {
|
||||
return
|
||||
}
|
||||
@ -22,11 +22,11 @@ func (c *Client) RunCallbacks(event *Event) {
|
||||
// Log the event.
|
||||
c.debug.Print("< " + StripRaw(event.String()))
|
||||
|
||||
// Regular wildcard callbacks.
|
||||
c.Callbacks.exec(ALLEVENTS, c, event.Copy())
|
||||
// Regular wildcard handlers.
|
||||
c.Handlers.exec(ALLEVENTS, c, event.Copy())
|
||||
|
||||
// Then regular callbacks.
|
||||
c.Callbacks.exec(event.Command, c, event.Copy())
|
||||
// Then regular handlers.
|
||||
c.Handlers.exec(event.Command, c, event.Copy())
|
||||
|
||||
// Check if it's a CTCP.
|
||||
if ctcp := decodeCTCP(event.Copy()); ctcp != nil {
|
||||
@ -35,52 +35,52 @@ func (c *Client) RunCallbacks(event *Event) {
|
||||
}
|
||||
}
|
||||
|
||||
// Callback is lower level implementation of a callback. See
|
||||
// Handler is lower level implementation of a handler. See
|
||||
// Caller.AddHandler()
|
||||
type Callback interface {
|
||||
type Handler interface {
|
||||
Execute(*Client, Event)
|
||||
}
|
||||
|
||||
// CallbackFunc is a type that represents the function necessary to
|
||||
// implement Callback.
|
||||
type CallbackFunc func(c *Client, e Event)
|
||||
// HandlerFunc is a type that represents the function necessary to
|
||||
// implement Handler.
|
||||
type HandlerFunc func(c *Client, e Event)
|
||||
|
||||
// Execute calls the CallbackFunc with the sender and irc message.
|
||||
func (f CallbackFunc) Execute(c *Client, e Event) {
|
||||
// Execute calls the HandlerFunc with the sender and irc message.
|
||||
func (f HandlerFunc) Execute(c *Client, e Event) {
|
||||
f(c, e)
|
||||
}
|
||||
|
||||
// Caller manages internal and external (user facing) callbacks.
|
||||
//
|
||||
// external/internal keys are of structure:
|
||||
// map[COMMAND][CUID]Callback
|
||||
//
|
||||
// Also of note: "COMMAND" should always be uppercase for normalization.
|
||||
// Caller manages internal and external (user facing) handlers.
|
||||
type Caller struct {
|
||||
// mu is the mutex that should be used when accessing callbacks.
|
||||
// mu is the mutex that should be used when accessing handlers.
|
||||
mu sync.RWMutex
|
||||
// wg is the waitgroup which is used to execute all callbacks concurrently.
|
||||
// wg is the waitgroup which is used to execute all handlers concurrently.
|
||||
wg sync.WaitGroup
|
||||
// external is a map of user facing callbacks.
|
||||
external map[string]map[string]Callback
|
||||
// internal is a map of internally used callbacks for the client.
|
||||
internal map[string]map[string]Callback
|
||||
|
||||
// external/internal keys are of structure:
|
||||
// map[COMMAND][CUID]Handler
|
||||
// Also of note: "COMMAND" should always be uppercase for normalization.
|
||||
|
||||
// external is a map of user facing handlers.
|
||||
external map[string]map[string]Handler
|
||||
// internal is a map of internally used handlers for the client.
|
||||
internal map[string]map[string]Handler
|
||||
// debug is the clients logger used for debugging.
|
||||
debug *log.Logger
|
||||
}
|
||||
|
||||
// newCaller creates and initializes a new callback handler.
|
||||
// newCaller creates and initializes a new handler.
|
||||
func newCaller(debugger *log.Logger) *Caller {
|
||||
c := &Caller{
|
||||
external: map[string]map[string]Callback{},
|
||||
internal: map[string]map[string]Callback{},
|
||||
external: map[string]map[string]Handler{},
|
||||
internal: map[string]map[string]Handler{},
|
||||
debug: debugger,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// Len returns the total amount of user-entered registered callbacks.
|
||||
// Len returns the total amount of user-entered registered handlers.
|
||||
func (c *Caller) Len() int {
|
||||
var total int
|
||||
|
||||
@ -94,7 +94,7 @@ func (c *Caller) Len() int {
|
||||
}
|
||||
|
||||
// Count is much like Caller.Len(), however it counts the number of
|
||||
// registered callbacks for a given command.
|
||||
// registered handlers for a given command.
|
||||
func (c *Caller) Count(cmd string) int {
|
||||
var total int
|
||||
|
||||
@ -125,7 +125,7 @@ func (c *Caller) String() string {
|
||||
|
||||
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
// cuid generates a unique UID string for each callback for ease of removal.
|
||||
// cuid generates a unique UID string for each handler for ease of removal.
|
||||
func (c *Caller) cuid(cmd string, n int) (cuid, uid string) {
|
||||
b := make([]byte, n)
|
||||
|
||||
@ -137,7 +137,7 @@ func (c *Caller) cuid(cmd string, n int) (cuid, uid string) {
|
||||
}
|
||||
|
||||
// cuidToID allows easy mapping between a generated cuid and the caller
|
||||
// external/internal callback maps.
|
||||
// external/internal handler maps.
|
||||
func (c *Caller) cuidToID(input string) (cmd, uid string) {
|
||||
// Ignore the errors because the strings will default to empty anyway.
|
||||
_, _ = fmt.Sscanf(input, "%s:%s", &cmd, &uid)
|
||||
@ -145,29 +145,28 @@ func (c *Caller) cuidToID(input string) (cmd, uid string) {
|
||||
}
|
||||
|
||||
type execStack struct {
|
||||
Callback Callback
|
||||
Handler
|
||||
cuid string
|
||||
}
|
||||
|
||||
// exec executes all callbacks pertaining to specified event. Internal first,
|
||||
// exec executes all handlers pertaining to specified event. Internal first,
|
||||
// then external.
|
||||
//
|
||||
// Please note that there is no specific order/priority for which the
|
||||
// callback types themselves or the callbacks are executed.
|
||||
// handler types themselves or the handlers are executed.
|
||||
func (c *Caller) exec(command string, client *Client, event *Event) {
|
||||
// Build a stack of callbacks which can be executed concurrently.
|
||||
// Build a stack of handlers which can be executed concurrently.
|
||||
var stack []execStack
|
||||
// var execstack []Callback
|
||||
|
||||
c.mu.RLock()
|
||||
// Get internal callbacks first.
|
||||
// Get internal handlers first.
|
||||
if _, ok := c.internal[command]; ok {
|
||||
for cuid := range c.internal[command] {
|
||||
stack = append(stack, execStack{c.internal[command][cuid], cuid})
|
||||
}
|
||||
}
|
||||
|
||||
// Aaand then external callbacks.
|
||||
// Aaand then external handlers.
|
||||
if _, ok := c.external[command]; ok {
|
||||
for cuid := range c.external[command] {
|
||||
stack = append(stack, execStack{c.external[command][cuid], cuid})
|
||||
@ -175,49 +174,49 @@ func (c *Caller) exec(command string, client *Client, event *Event) {
|
||||
}
|
||||
c.mu.RUnlock()
|
||||
|
||||
// Run all callbacks concurrently across the same event. This should
|
||||
// Run all handlers concurrently across the same event. This should
|
||||
// still help prevent mis-ordered events, while speeding up the
|
||||
// execution speed.
|
||||
c.wg.Add(len(stack))
|
||||
for i := 0; i < len(stack); i++ {
|
||||
go func(index int) {
|
||||
c.debug.Printf("executing callback %s for event %s", stack[index].cuid, command)
|
||||
c.debug.Printf("executing handler %s for event %s", stack[index].cuid, command)
|
||||
start := time.Now()
|
||||
|
||||
stack[index].Callback.Execute(client, *event)
|
||||
stack[index].Execute(client, *event)
|
||||
|
||||
c.debug.Printf("execution of %s took %s", stack[index].cuid, time.Since(start))
|
||||
c.wg.Done()
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Wait for all of the callbacks to complete. Not doing this may cause
|
||||
// new events from becoming ahead of older callbacks.
|
||||
// Wait for all of the handlers to complete. Not doing this may cause
|
||||
// new events from becoming ahead of older handlers.
|
||||
c.wg.Wait()
|
||||
}
|
||||
|
||||
// ClearAll clears all external callbacks currently setup within the client.
|
||||
// This ignores internal callbacks.
|
||||
// ClearAll clears all external handlers currently setup within the client.
|
||||
// This ignores internal handlers.
|
||||
func (c *Caller) ClearAll() {
|
||||
c.mu.Lock()
|
||||
c.external = map[string]map[string]Callback{}
|
||||
c.external = map[string]map[string]Handler{}
|
||||
c.mu.Unlock()
|
||||
|
||||
c.debug.Print("cleared all external callbacks")
|
||||
c.debug.Print("cleared all external handlers")
|
||||
}
|
||||
|
||||
// clearInternal clears all internal callbacks currently setup within the
|
||||
// clearInternal clears all internal handlers currently setup within the
|
||||
// client.
|
||||
func (c *Caller) clearInternal() {
|
||||
c.mu.Lock()
|
||||
c.internal = map[string]map[string]Callback{}
|
||||
c.internal = map[string]map[string]Handler{}
|
||||
c.mu.Unlock()
|
||||
|
||||
c.debug.Print("cleared all internal callbacks")
|
||||
c.debug.Print("cleared all internal handlers")
|
||||
}
|
||||
|
||||
// Clear clears all of the callbacks for the given event.
|
||||
// This ignores internal callbacks.
|
||||
// Clear clears all of the handlers for the given event.
|
||||
// This ignores internal handlers.
|
||||
func (c *Caller) Clear(cmd string) {
|
||||
cmd = strings.ToUpper(cmd)
|
||||
|
||||
@ -227,12 +226,12 @@ func (c *Caller) Clear(cmd string) {
|
||||
}
|
||||
c.mu.Unlock()
|
||||
|
||||
c.debug.Printf("cleared external callbacks for %q", cmd)
|
||||
c.debug.Printf("cleared external handlers for %q", cmd)
|
||||
}
|
||||
|
||||
// Remove removes the callback with cuid from the callback stack. success
|
||||
// Remove removes the handler with cuid from the handler stack. success
|
||||
// indicates that it existed, and has been removed. If not success, it
|
||||
// wasn't a registered callback.
|
||||
// wasn't a registered handler.
|
||||
func (c *Caller) Remove(cuid string) (success bool) {
|
||||
c.mu.Lock()
|
||||
success = c.remove(cuid)
|
||||
@ -249,19 +248,19 @@ func (c *Caller) remove(cuid string) (success bool) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if the irc command/event has any callbacks on it.
|
||||
// Check if the irc command/event has any handlers on it.
|
||||
if _, ok := c.external[cmd]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check to see if it's actually a registered callback.
|
||||
// Check to see if it's actually a registered handler.
|
||||
if _, ok := c.external[cmd][cuid]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
delete(c.external[cmd], uid)
|
||||
|
||||
c.debug.Printf("removed callback %q", cuid)
|
||||
c.debug.Printf("removed handler %q", cuid)
|
||||
|
||||
// Assume success.
|
||||
return true
|
||||
@ -269,60 +268,60 @@ func (c *Caller) remove(cuid string) (success bool) {
|
||||
|
||||
// sregister is much like Caller.register(), except that it safely locks
|
||||
// the Caller mutex.
|
||||
func (c *Caller) sregister(internal bool, cmd string, callback Callback) (cuid string) {
|
||||
func (c *Caller) sregister(internal bool, cmd string, handler Handler) (cuid string) {
|
||||
c.mu.Lock()
|
||||
cuid = c.register(internal, cmd, callback)
|
||||
cuid = c.register(internal, cmd, handler)
|
||||
c.mu.Unlock()
|
||||
|
||||
return cuid
|
||||
}
|
||||
|
||||
// register will register a callback in the internal tracker. Unsafe (you
|
||||
// register will register a handler in the internal tracker. Unsafe (you
|
||||
// must lock c.mu yourself!)
|
||||
func (c *Caller) register(internal bool, cmd string, callback Callback) (cuid string) {
|
||||
func (c *Caller) register(internal bool, cmd string, handler Handler) (cuid string) {
|
||||
var uid string
|
||||
|
||||
cmd = strings.ToUpper(cmd)
|
||||
|
||||
if internal {
|
||||
if _, ok := c.internal[cmd]; !ok {
|
||||
c.internal[cmd] = map[string]Callback{}
|
||||
c.internal[cmd] = map[string]Handler{}
|
||||
}
|
||||
|
||||
cuid, uid = c.cuid(cmd, 20)
|
||||
c.internal[cmd][uid] = callback
|
||||
c.internal[cmd][uid] = handler
|
||||
} else {
|
||||
if _, ok := c.external[cmd]; !ok {
|
||||
c.external[cmd] = map[string]Callback{}
|
||||
c.external[cmd] = map[string]Handler{}
|
||||
}
|
||||
|
||||
cuid, uid = c.cuid(cmd, 20)
|
||||
c.external[cmd][uid] = callback
|
||||
c.external[cmd][uid] = handler
|
||||
}
|
||||
|
||||
c.debug.Printf("registering callback for %q with cuid %q (internal: %t)", cmd, cuid, internal)
|
||||
c.debug.Printf("registering handler for %q with cuid %q (internal: %t)", cmd, cuid, internal)
|
||||
|
||||
return cuid
|
||||
}
|
||||
|
||||
// AddHandler registers a callback (matching the Callback interface) for the
|
||||
// given event. cuid is the callback uid which can be used to remove the
|
||||
// callback with Caller.Remove().
|
||||
func (c *Caller) AddHandler(cmd string, callback Callback) (cuid string) {
|
||||
return c.sregister(false, cmd, callback)
|
||||
// AddHandler registers a handler (matching the handler interface) for the
|
||||
// given event. cuid is the handler uid which can be used to remove the
|
||||
// handler with Caller.Remove().
|
||||
func (c *Caller) AddHandler(cmd string, handler Handler) (cuid string) {
|
||||
return c.sregister(false, cmd, handler)
|
||||
}
|
||||
|
||||
// Add registers the callback function for the given event. cuid is the
|
||||
// callback uid which can be used to remove the callback with Caller.Remove().
|
||||
func (c *Caller) Add(cmd string, callback func(c *Client, e Event)) (cuid string) {
|
||||
return c.sregister(false, cmd, CallbackFunc(callback))
|
||||
// Add registers the handler function for the given event. cuid is the
|
||||
// handler uid which can be used to remove the handler with Caller.Remove().
|
||||
func (c *Caller) Add(cmd string, handler func(c *Client, e Event)) (cuid string) {
|
||||
return c.sregister(false, cmd, HandlerFunc(handler))
|
||||
}
|
||||
|
||||
// AddBg registers the callback function for the given event and executes it
|
||||
// in a go-routine. cuid is the callback uid which can be used to remove the
|
||||
// callback with Caller.Remove().
|
||||
func (c *Caller) AddBg(cmd string, callback func(c *Client, e Event)) (cuid string) {
|
||||
return c.sregister(false, cmd, CallbackFunc(func(c *Client, e Event) {
|
||||
go callback(c, e)
|
||||
// AddBg registers the handler function for the given event and executes it
|
||||
// in a go-routine. cuid is the handler uid which can be used to remove the
|
||||
// handler with Caller.Remove().
|
||||
func (c *Caller) AddBg(cmd string, handler func(c *Client, e Event)) (cuid string) {
|
||||
return c.sregister(false, cmd, HandlerFunc(func(c *Client, e Event) {
|
||||
go handler(c, e)
|
||||
}))
|
||||
}
|
||||
|
38
client.go
38
client.go
@ -31,8 +31,8 @@ type Client struct {
|
||||
// initTime represents the creation time of the client.
|
||||
initTime time.Time
|
||||
|
||||
// Callbacks is a handler which manages internal and external callbacks.
|
||||
Callbacks *Caller
|
||||
// Handlers is a handler which manages internal and external handlers.
|
||||
Handlers *Caller
|
||||
// CTCP is a handler which manages internal and external CTCP handlers.
|
||||
CTCP *CTCP
|
||||
|
||||
@ -155,13 +155,13 @@ func New(config Config) *Client {
|
||||
c.debug.Print("initializing debugging")
|
||||
|
||||
// Setup the caller.
|
||||
c.Callbacks = newCaller(c.debug)
|
||||
c.Handlers = newCaller(c.debug)
|
||||
|
||||
// Give ourselves a new state.
|
||||
c.state = newState()
|
||||
|
||||
// Register builtin handlers.
|
||||
c.registerHandlers()
|
||||
c.registerBuiltin()
|
||||
|
||||
// Register default CTCP responses.
|
||||
c.CTCP.addDefaultHandlers()
|
||||
@ -170,25 +170,25 @@ func New(config Config) *Client {
|
||||
}
|
||||
|
||||
// DisableTracking disables all channel and user-level tracking, and clears
|
||||
// all internal callbacks. Useful for highly embedded scripts with single
|
||||
// all internal handlers. Useful for highly embedded scripts with single
|
||||
// purposes. This cannot be un-done.
|
||||
func (c *Client) DisableTracking() {
|
||||
c.debug.Print("disabling tracking")
|
||||
c.Config.disableTracking = true
|
||||
c.Callbacks.clearInternal()
|
||||
c.Handlers.clearInternal()
|
||||
c.state.mu.Lock()
|
||||
c.state.channels = nil
|
||||
c.state.mu.Unlock()
|
||||
c.registerHandlers()
|
||||
c.registerBuiltin()
|
||||
}
|
||||
|
||||
// DisableCapTracking disables all network/server capability tracking, and
|
||||
// clears all internal callbacks. This includes determining what feature the
|
||||
// clears all internal handlers. This includes determining what feature the
|
||||
// IRC server supports, what the "NETWORK=" variables are, and other useful
|
||||
// stuff. DisableTracking() cannot be called if you want to also track
|
||||
// capabilities.
|
||||
func (c *Client) DisableCapTracking() {
|
||||
// No need to mess with internal callbacks. That should already be
|
||||
// No need to mess with internal handlers. That should already be
|
||||
// handled by the clear in Client.DisableTracking().
|
||||
if c.Config.disableCapTracking {
|
||||
return
|
||||
@ -196,8 +196,8 @@ func (c *Client) DisableCapTracking() {
|
||||
|
||||
c.debug.Print("disabling CAP tracking")
|
||||
c.Config.disableCapTracking = true
|
||||
c.Callbacks.clearInternal()
|
||||
c.registerHandlers()
|
||||
c.Handlers.clearInternal()
|
||||
c.registerBuiltin()
|
||||
}
|
||||
|
||||
// DisableNickCollision disables the clients auto-response to nickname
|
||||
@ -207,11 +207,11 @@ func (c *Client) DisableCapTracking() {
|
||||
func (c *Client) DisableNickCollision() {
|
||||
c.debug.Print("disabling nick collision prevention")
|
||||
c.Config.disableNickCollision = true
|
||||
c.Callbacks.clearInternal()
|
||||
c.Handlers.clearInternal()
|
||||
c.state.mu.Lock()
|
||||
c.state.channels = nil
|
||||
c.state.mu.Unlock()
|
||||
c.registerHandlers()
|
||||
c.registerBuiltin()
|
||||
}
|
||||
|
||||
// cleanup is used to close out all threads used by the client, like read and
|
||||
@ -264,10 +264,10 @@ func (c *Client) QuitWithMessage(message string) {
|
||||
}
|
||||
|
||||
// Stop exits the clients main loop and any other goroutines created by
|
||||
// the client itself. This does not include callbacks, as they will run for
|
||||
// the client itself. This does not include handlers, as they will run for
|
||||
// any incoming events prior to when Stop() or Quit() was called, until the
|
||||
// event queue is empty and execution has completed for those callbacks. This
|
||||
// means that you are responsible to ensure that your callbacks due not
|
||||
// event queue is empty and execution has completed for those handlers. This
|
||||
// means that you are responsible to ensure that your handlers due not
|
||||
// execute forever. Use Client.Quit() first if you want to disconnect the
|
||||
// client from the server/connection gracefully.
|
||||
func (c *Client) Stop() {
|
||||
@ -467,7 +467,7 @@ func (c *Client) execLoop(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case event := <-c.Events:
|
||||
c.RunCallbacks(event)
|
||||
c.RunHandlers(event)
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
@ -494,8 +494,8 @@ func (c *Client) Lifetime() time.Duration {
|
||||
return time.Since(c.initTime)
|
||||
}
|
||||
|
||||
// Send sends an event to the server. Use Client.RunCallback() if you are
|
||||
// simply looking to trigger callbacks with an event.
|
||||
// Send sends an event to the server. Use Client.RunHandlers() if you are
|
||||
// simply looking to trigger handlers with an event.
|
||||
func (c *Client) Send(event *Event) error {
|
||||
if !c.Config.AllowFlood {
|
||||
<-time.After(c.state.rate(event.Len()))
|
||||
|
@ -47,18 +47,18 @@ func Example_simple() {
|
||||
Name: "Example bot",
|
||||
})
|
||||
|
||||
client.Callbacks.Add(girc.CONNECTED, func(c *girc.Client, e girc.Event) {
|
||||
client.Handlers.Add(girc.CONNECTED, func(c *girc.Client, e girc.Event) {
|
||||
c.Join("#dev")
|
||||
})
|
||||
|
||||
client.Callbacks.Add(girc.PRIVMSG, func(c *girc.Client, e girc.Event) {
|
||||
client.Handlers.Add(girc.PRIVMSG, func(c *girc.Client, e girc.Event) {
|
||||
if strings.Contains(e.Trailing, "hello") {
|
||||
c.Message(e.Params[0], "hello world!")
|
||||
}
|
||||
})
|
||||
|
||||
// Log useful IRC events.
|
||||
client.Callbacks.Add(girc.ALLEVENTS, func(c *girc.Client, e girc.Event) {
|
||||
client.Handlers.Add(girc.ALLEVENTS, func(c *girc.Client, e girc.Event) {
|
||||
// girc.Event.Pretty() returns true for events which are useful and
|
||||
// that can be prettified. Use Event.String() to get the raw string
|
||||
// for all events.
|
||||
@ -87,11 +87,11 @@ func Example_commands() {
|
||||
Name: "Example bot",
|
||||
})
|
||||
|
||||
client.Callbacks.Add(girc.CONNECTED, func(c *girc.Client, e girc.Event) {
|
||||
client.Handlers.Add(girc.CONNECTED, func(c *girc.Client, e girc.Event) {
|
||||
c.Join("#channel", "#other-channel")
|
||||
})
|
||||
|
||||
client.Callbacks.Add(girc.PRIVMSG, func(c *girc.Client, e girc.Event) {
|
||||
client.Handlers.Add(girc.PRIVMSG, func(c *girc.Client, e girc.Event) {
|
||||
if strings.HasPrefix(e.Trailing, "!hello") {
|
||||
c.Message(e.Params[0], "hello world!")
|
||||
return
|
||||
@ -110,7 +110,7 @@ func Example_commands() {
|
||||
})
|
||||
|
||||
// Log ALL events.
|
||||
client.Callbacks.Add(girc.ALLEVENTS, func(c *girc.Client, e girc.Event) {
|
||||
client.Handlers.Add(girc.ALLEVENTS, func(c *girc.Client, e girc.Event) {
|
||||
// The use of girc.StripRaw() is to get rid of any potential
|
||||
// non-printable characters.
|
||||
fmt.Println(girc.StripRaw(e.String()))
|
||||
|
2
ctcp.go
2
ctcp.go
@ -111,7 +111,7 @@ func encodeCTCPRaw(cmd, text string) (out string) {
|
||||
// CTCP handles the storage and execution of CTCP handlers against incoming
|
||||
// CTCP events.
|
||||
type CTCP struct {
|
||||
// mu is the mutex that should be used when accessing callbacks.
|
||||
// mu is the mutex that should be used when accessing any ctcp handlers.
|
||||
mu sync.RWMutex
|
||||
// handlers is a map of CTCP message -> functions.
|
||||
handlers map[string]CTCPHandler
|
||||
|
Loading…
Reference in New Issue
Block a user