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" "strconv"
"strings" "strings"
"time" "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) eventcode = strings.ToUpper(eventcode)
if _, ok := irc.events[eventcode]; ok { if _, ok := irc.events[eventcode]; !ok {
irc.events[eventcode] = append(irc.events[eventcode], callback) irc.events[eventcode] = make(map[string]func(*Event))
} else {
irc.events[eventcode] = make([]func(*Event), 1)
irc.events[eventcode][0] = callback
} }
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) eventcode = strings.ToUpper(eventcode)
if event, ok := irc.events[eventcode]; ok{ if event, ok := irc.events[eventcode]; ok{
if i < len(event) { 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 _, ok := event[i]; ok {
event[i] = callback event[i] = callback
return return
} }
irc.Log.Printf("Event found, but no callback found at index %d. Use AddCallback\n", i) irc.Log.Printf("Event found, but no callback found at id %s\n", i)
return
} }
irc.Log.Printf("Event not found. Use AddCallBack\n") irc.Log.Printf("Event not found. Use AddCallBack\n")
} }
@ -71,14 +104,23 @@ func (irc *Connection) RunCallbacks(event *Event) {
for _, callback := range callbacks { for _, callback := range callbacks {
go callback(event) go callback(event)
} }
} else if irc.VerboseCallbackHandler { } else if irc.VerboseCallbackHandler {
irc.Log.Printf("%v (0) >> %#v\n", event.Code, event) 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() { func (irc *Connection) setupCallbacks() {
irc.events = make(map[string][]func(*Event)) irc.events = make(map[string]map[string]func(*Event))
//Handle ping events //Handle ping events
irc.AddCallback("PING", func(e *Event) { irc.SendRaw("PONG :" + e.Message()) }) irc.AddCallback("PING", func(e *Event) { irc.SendRaw("PONG :" + e.Message()) })

View File

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

View File

@ -44,3 +44,79 @@ func TestConnectionSSL(t *testing.T) {
irccon.Loop() 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")
}
}