mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-10 04:08:13 +08:00
147 lines
2.7 KiB
Go
147 lines
2.7 KiB
Go
package event
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
type EventId string
|
|
|
|
type Event struct {
|
|
Id EventId
|
|
Cancelled bool
|
|
Data interface{}
|
|
Outdated bool
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
type HandlerFunc func(event *Event)
|
|
|
|
type Handler struct {
|
|
EventId EventId
|
|
Name string
|
|
Handler HandlerFunc
|
|
SkipOutdated bool
|
|
}
|
|
|
|
type Manager struct {
|
|
handlers map[EventId]map[string]*Handler
|
|
prevEvent map[EventId]*Event
|
|
queue chan func()
|
|
stopSig chan int
|
|
queueSize int
|
|
workerSize int
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
func NewManger(queueSize int, workerSize int) *Manager {
|
|
manager := &Manager{
|
|
handlers: make(map[EventId]map[string]*Handler),
|
|
prevEvent: make(map[EventId]*Event),
|
|
queue: make(chan func(), queueSize),
|
|
stopSig: make(chan int, workerSize),
|
|
queueSize: queueSize,
|
|
workerSize: workerSize,
|
|
}
|
|
for i := 0; i < workerSize; i++ {
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-manager.stopSig:
|
|
return
|
|
case f := <-manager.queue:
|
|
f()
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
return manager
|
|
}
|
|
|
|
func (h *Manager) NewChildManager() *Manager {
|
|
return &Manager{
|
|
handlers: make(map[EventId]map[string]*Handler),
|
|
prevEvent: make(map[EventId]*Event),
|
|
queue: h.queue,
|
|
stopSig: h.stopSig,
|
|
queueSize: h.queueSize,
|
|
workerSize: h.workerSize,
|
|
}
|
|
}
|
|
|
|
func (h *Manager) Stop() {
|
|
for i := 0; i < h.workerSize; i++ {
|
|
h.stopSig <- 0
|
|
}
|
|
}
|
|
|
|
func (h *Manager) Register(handler *Handler) {
|
|
h.lock.Lock()
|
|
defer h.lock.Unlock()
|
|
m, ok := h.handlers[handler.EventId]
|
|
if !ok {
|
|
m = make(map[string]*Handler)
|
|
h.handlers[handler.EventId] = m
|
|
}
|
|
m[handler.Name] = handler
|
|
}
|
|
|
|
func (h *Manager) RegisterA(id EventId, name string, handler HandlerFunc) {
|
|
h.Register(&Handler{
|
|
EventId: id,
|
|
Name: name,
|
|
Handler: handler,
|
|
SkipOutdated: true,
|
|
})
|
|
}
|
|
|
|
func (h *Manager) UnregisterAll() {
|
|
h.lock.Lock()
|
|
defer h.lock.Unlock()
|
|
h.handlers = make(map[EventId]map[string]*Handler)
|
|
}
|
|
|
|
func (h *Manager) Unregister(name string) {
|
|
h.lock.Lock()
|
|
defer h.lock.Unlock()
|
|
for _, m := range h.handlers {
|
|
if _, ok := m[name]; ok {
|
|
delete(m, name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (h *Manager) Call(event *Event) {
|
|
h.lock.Lock()
|
|
|
|
handlers, ok := h.handlers[event.Id]
|
|
if e := h.prevEvent[event.Id]; e != nil {
|
|
e.lock.Lock()
|
|
e.Outdated = true
|
|
e.lock.Unlock()
|
|
}
|
|
h.prevEvent[event.Id] = event
|
|
h.lock.Unlock()
|
|
if !ok {
|
|
return
|
|
}
|
|
for _, eh := range handlers {
|
|
eventHandler := eh
|
|
h.queue <- func() {
|
|
event.lock.Lock()
|
|
if eventHandler.SkipOutdated && event.Outdated {
|
|
event.lock.Unlock()
|
|
return
|
|
}
|
|
eventHandler.Handler(event)
|
|
event.lock.Unlock()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (h *Manager) CallA(id EventId, data interface{}) {
|
|
h.Call(&Event{
|
|
Id: id,
|
|
Data: data,
|
|
})
|
|
}
|