package fcast import ( "encoding/json" "log" "reflect" "sync" ) type EventHandler func(message Message) type CodeRegistry struct { handler EventHandler constructor func() Message } type EventManager struct { codes map[OpCode]CodeRegistry mu sync.RWMutex } func (em *EventManager) SetHandler(message Message, handler EventHandler) { em.mu.Lock() defer em.mu.Unlock() if em.codes == nil { em.codes = make(map[OpCode]CodeRegistry) } em.codes[message.getOpCode()] = CodeRegistry{ handler: handler, constructor: func() Message { return reflect.New(reflect.TypeOf(message)).Interface().(Message) }, } } func (em *EventManager) dispatchMessage(raw *RawMessage) error { if _, exists := em.codes[raw.Header.OpCode]; !exists { log.Printf("[INFO] fcast: Got a message without a listener - OpCode=%d, Size=%d, Body=%s\n", raw.Header.OpCode, raw.Header.Size, string(raw.Body)) return nil } constructor := em.codes[raw.Header.OpCode].constructor handler := em.codes[raw.Header.OpCode].handler msg := constructor() if len(raw.Body) > 0 { if err := json.Unmarshal(raw.Body, msg); err != nil { return err } } handler(msg) return nil }