Merge pull request #24 from darkliquid/callback-tweaks

Looks good to me. The id generating code may need some tweaking but should work fine as is :)
This commit is contained in:
Thomas Jager 2014-02-12 08:17:43 +01:00
commit bbbdd715fa
3 changed files with 132 additions and 14 deletions

View File

@ -4,30 +4,63 @@ import (
"strconv"
"strings"
"time"
"crypto/sha1"
"fmt"
"reflect"
"math/rand"
)
func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) {
func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) string {
eventcode = strings.ToUpper(eventcode)
if _, ok := irc.events[eventcode]; ok {
irc.events[eventcode] = append(irc.events[eventcode], callback)
} else {
irc.events[eventcode] = make([]func(*Event), 1)
irc.events[eventcode][0] = callback
if _, ok := irc.events[eventcode]; !ok {
irc.events[eventcode] = make(map[string]func(*Event))
}
h := sha1.New()
rawId := []byte(fmt.Sprintf("%v%d", reflect.ValueOf(callback).Pointer(), rand.Int63()))
h.Write(rawId)
id := fmt.Sprintf("%x", h.Sum(nil))
irc.events[eventcode][id] = callback
return id
}
func (irc *Connection) ReplaceCallback(eventcode string, i int, callback func(*Event)) {
func (irc *Connection) RemoveCallback(eventcode string, i string) bool {
eventcode = strings.ToUpper(eventcode)
if event, ok := irc.events[eventcode]; ok{
if _, ok := event[i]; ok {
delete(irc.events[eventcode], i)
return true
}
irc.Log.Printf("Event found, but no callback found at id %s\n", i)
return false
}
irc.Log.Println("Event not found")
return false
}
func (irc *Connection) ClearCallback(eventcode string) bool {
eventcode = strings.ToUpper(eventcode)
if _, ok := irc.events[eventcode]; ok{
irc.events[eventcode] = make(map[string]func(*Event))
return true
}
irc.Log.Println("Event not found")
return false
}
func (irc *Connection) ReplaceCallback(eventcode string, i string, callback func(*Event)) {
eventcode = strings.ToUpper(eventcode)
if event, ok := irc.events[eventcode]; ok {
if i < len(event) {
if _, ok := event[i]; ok {
event[i] = callback
return
}
irc.Log.Printf("Event found, but no callback found at index %d. Use AddCallback\n", i)
return
irc.Log.Printf("Event found, but no callback found at id %s\n", i)
}
irc.Log.Printf("Event not found. Use AddCallBack\n")
}
@ -71,14 +104,23 @@ func (irc *Connection) RunCallbacks(event *Event) {
for _, callback := range callbacks {
go callback(event)
}
} else if irc.VerboseCallbackHandler {
irc.Log.Printf("%v (0) >> %#v\n", event.Code, event)
}
if callbacks, ok := irc.events["*"]; ok {
if irc.VerboseCallbackHandler {
irc.Log.Printf("Wildcard %v (%v) >> %#v\n", event.Code, len(callbacks), event)
}
for _, callback := range callbacks {
go callback(event)
}
}
}
func (irc *Connection) setupCallbacks() {
irc.events = make(map[string][]func(*Event))
irc.events = make(map[string]map[string]func(*Event))
//Handle ping events
irc.AddCallback("PING", func(e *Event) { irc.SendRaw("PONG :" + e.Message()) })

View File

@ -33,7 +33,7 @@ type Connection struct {
user string
registered bool
server string
events map[string][]func(*Event)
events map[string]map[string]func(*Event)
lastMessage time.Time

View File

@ -44,3 +44,79 @@ func TestConnectionSSL(t *testing.T) {
irccon.Loop()
}
func TestRemoveCallback(t *testing.T) {
irccon := IRC("go-eventirc", "go-eventirc")
irccon.VerboseCallbackHandler = true
done := make(chan int, 10)
irccon.AddCallback("TEST", func(e *Event) { done <- 1 })
id := irccon.AddCallback("TEST", func(e *Event) { done <- 2 })
irccon.AddCallback("TEST", func(e *Event) { done <- 3 })
// Should remove callback at index 1
irccon.RemoveCallback("TEST", id)
irccon.RunCallbacks(&Event{
Code: "TEST",
})
var results []int
results = append(results, <-done)
results = append(results, <-done)
if len(results) != 2 || !(results[0] == 1 && results[1] == 3) {
t.Error("Callback 2 not removed")
}
}
func TestWildcardCallback(t *testing.T) {
irccon := IRC("go-eventirc", "go-eventirc")
irccon.VerboseCallbackHandler = true
done := make(chan int, 10)
irccon.AddCallback("TEST", func(e *Event) { done <- 1 })
irccon.AddCallback("*", func(e *Event) { done <- 2 })
irccon.RunCallbacks(&Event{
Code: "TEST",
})
var results []int
results = append(results, <-done)
results = append(results, <-done)
if len(results) != 2 || !(results[0] == 1 && results[1] == 2) {
t.Error("Wildcard callback not called")
}
}
func TestClearCallback(t *testing.T) {
irccon := IRC("go-eventirc", "go-eventirc")
irccon.VerboseCallbackHandler = true
done := make(chan int, 10)
irccon.AddCallback("TEST", func(e *Event) { done <- 0 })
irccon.AddCallback("TEST", func(e *Event) { done <- 1 })
irccon.ClearCallback("TEST")
irccon.AddCallback("TEST", func(e *Event) { done <- 2 })
irccon.AddCallback("TEST", func(e *Event) { done <- 3 })
irccon.RunCallbacks(&Event{
Code: "TEST",
})
var results []int
results = append(results, <-done)
results = append(results, <-done)
if len(results) != 2 || !(results[0] == 2 && results[1] == 3) {
t.Error("Callbacks not cleared")
}
}