diff --git a/irc_callback.go b/irc_callback.go index 0e4c87b..fd74fa2 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -4,46 +4,51 @@ import ( "strconv" "strings" "time" + "crypto/sha1" + "fmt" + "reflect" + "math/rand" ) -func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) (idx int) { +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) - idx = len(irc.events[eventcode]) - 1 - } else { - irc.events[eventcode] = make([]func(*Event), 1) - irc.events[eventcode][0] = callback - idx = 0 + if _, ok := irc.events[eventcode]; !ok { + irc.events[eventcode] = make(map[string]func(*Event)) } - return + 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) RemoveCallback(eventcode string, i int) { +func (irc *Connection) RemoveCallback(eventcode string, i string) bool { eventcode = strings.ToUpper(eventcode) - if event, ok := irc.events[eventcode]; ok { - if i < len(event) { - irc.events[eventcode] = append(event[:i], event[i+1:]...) - return + 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 index %d.\n", i) - return + irc.Log.Printf("Event found, but no callback found at id %s\n", i) + return false } - irc.Log.Printf("Event not found\n") + + irc.Log.Println("Event not found") + return false } -func (irc *Connection) ReplaceCallback(eventcode string, i int, callback func(*Event)) { +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") } @@ -102,7 +107,7 @@ func (irc *Connection) RunCallbacks(event *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) }) diff --git a/irc_struct.go b/irc_struct.go index f3c1883..964928e 100644 --- a/irc_struct.go +++ b/irc_struct.go @@ -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 diff --git a/irc_test.go b/irc_test.go index c91f8ab..9938c3d 100644 --- a/irc_test.go +++ b/irc_test.go @@ -44,3 +44,53 @@ 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") + } +}