Small performance improvement. Added tests.
This commit is contained in:
parent
6fa99712ef
commit
88335b6f54
3 changed files with 50 additions and 6 deletions
12
discord.go
12
discord.go
|
@ -151,10 +151,10 @@ func (s *Session) AddHandler(handler interface{}) {
|
||||||
|
|
||||||
handlers := s.Handlers[eventType]
|
handlers := s.Handlers[eventType]
|
||||||
if handlers == nil {
|
if handlers == nil {
|
||||||
handlers = []interface{}{}
|
handlers = []reflect.Value{}
|
||||||
}
|
}
|
||||||
|
|
||||||
handlers = append(handlers, handler)
|
handlers = append(handlers, reflect.ValueOf(handler))
|
||||||
s.Handlers[eventType] = handlers
|
s.Handlers[eventType] = handlers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,15 +162,17 @@ func (s *Session) handle(event interface{}) {
|
||||||
s.RLock()
|
s.RLock()
|
||||||
defer s.RUnlock()
|
defer s.RUnlock()
|
||||||
|
|
||||||
|
handlerParameters := []reflect.Value{reflect.ValueOf(s), reflect.ValueOf(event)}
|
||||||
|
|
||||||
if handlers, ok := s.Handlers[reflect.TypeOf(event)]; ok {
|
if handlers, ok := s.Handlers[reflect.TypeOf(event)]; ok {
|
||||||
for _, handler := range handlers {
|
for _, handler := range handlers {
|
||||||
reflect.ValueOf(handler).Call([]reflect.Value{reflect.ValueOf(s), reflect.ValueOf(event)})
|
handler.Call(handlerParameters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if handlers, ok := s.Handlers[nil]; ok {
|
if handlers, ok := s.Handlers[nil]; ok {
|
||||||
for _, handler := range handlers {
|
for _, handler := range handlers {
|
||||||
reflect.ValueOf(handler).Call([]reflect.Value{reflect.ValueOf(s), reflect.ValueOf(event)})
|
handler.Call(handlerParameters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +180,7 @@ func (s *Session) handle(event interface{}) {
|
||||||
// initialize adds all internal handlers and state tracking handlers.
|
// initialize adds all internal handlers and state tracking handlers.
|
||||||
func (s *Session) initialize() {
|
func (s *Session) initialize() {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
s.Handlers = map[interface{}][]interface{}{}
|
s.Handlers = map[interface{}][]reflect.Value{}
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
|
|
||||||
s.AddHandler(s.onEvent)
|
s.AddHandler(s.onEvent)
|
||||||
|
|
|
@ -224,3 +224,39 @@ func TestOpenClose(t *testing.T) {
|
||||||
t.Fatalf("TestClose, d.Close failed: %+v", err)
|
t.Fatalf("TestClose, d.Close failed: %+v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandlers(t *testing.T) {
|
||||||
|
testHandlerCalled := false
|
||||||
|
testHandler := func(s *Session, t *testing.T) {
|
||||||
|
testHandlerCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaceHandlerCalled := false
|
||||||
|
interfaceHandler := func(s *Session, i interface{}) {
|
||||||
|
interfaceHandlerCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
bogusHandlerCalled := false
|
||||||
|
bogusHandler := func(s *Session, se *Session) {
|
||||||
|
bogusHandlerCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
d := Session{}
|
||||||
|
d.AddHandler(testHandler)
|
||||||
|
d.AddHandler(interfaceHandler)
|
||||||
|
d.AddHandler(bogusHandler)
|
||||||
|
|
||||||
|
d.handle(t)
|
||||||
|
|
||||||
|
if !testHandlerCalled {
|
||||||
|
t.Fatalf("testHandler was not called.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !interfaceHandlerCalled {
|
||||||
|
t.Fatalf("interfaceHandler was not called.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if bogusHandlerCalled {
|
||||||
|
t.Fatalf("bogusHandler was called.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ package discordgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -29,7 +30,12 @@ type Session struct {
|
||||||
Token string // Authentication token for this session
|
Token string // Authentication token for this session
|
||||||
Debug bool // Debug for printing JSON request/responses
|
Debug bool // Debug for printing JSON request/responses
|
||||||
|
|
||||||
Handlers map[interface{}][]interface{}
|
// This is a mapping of event structs to a reflected value
|
||||||
|
// for event handlers.
|
||||||
|
// We store the reflected value instead of the function
|
||||||
|
// reference as it is more performant, instead of re-reflecting
|
||||||
|
// the function each event.
|
||||||
|
Handlers map[interface{}][]reflect.Value
|
||||||
|
|
||||||
// Exposed but should not be modified by User.
|
// Exposed but should not be modified by User.
|
||||||
SessionID string // from websocket READY packet
|
SessionID string // from websocket READY packet
|
||||||
|
|
Loading…
Reference in a new issue