jl-ecs/events.go

90 lines
1.9 KiB
Go
Raw Permalink Normal View History

2023-08-04 11:02:08 +08:00
package ecs
2023-08-31 16:19:41 +08:00
import (
2023-08-31 17:49:25 +08:00
"fmt"
2023-08-31 16:19:41 +08:00
"reflect"
2023-08-31 17:49:25 +08:00
"sync"
2023-08-31 16:19:41 +08:00
"github.com/yohamta/donburi"
"github.com/yohamta/donburi/features/events"
)
// 事件订阅发布功能,底层使用donburi事件订阅发布
// 注意:事件订阅处理中应避免再次发布事件
2023-08-31 16:19:41 +08:00
// 事件相关定义
2023-08-04 11:02:08 +08:00
type (
2023-08-31 16:19:41 +08:00
// 事件类型定义
2023-08-04 11:02:08 +08:00
EventType[T any] struct {
et *events.EventType[T]
mu sync.Mutex // 锁
subMap map[string]events.Subscriber[T]
2023-08-04 11:02:08 +08:00
}
2023-08-31 16:19:41 +08:00
// 事件订阅者定义
Subscriber[T any] func(w World, event T)
2023-08-04 11:02:08 +08:00
)
2023-08-31 16:19:41 +08:00
2023-09-01 09:21:22 +08:00
// 开启底层事件处理调试
func EventsDebugEnable() {
events.Debug = true
2023-08-31 16:19:41 +08:00
}
// 创建事件类型的实例
2023-08-31 17:21:46 +08:00
func NewEventType[T any]() *EventType[T] {
2023-08-31 16:19:41 +08:00
return &EventType[T]{
et: events.NewEventType[T](),
mu: sync.Mutex{},
subMap: make(map[string]events.Subscriber[T], 0),
2023-08-31 16:19:41 +08:00
}
}
// 迭代处理所有事件
func processAllEvents(w World) {
events.ProcessAllEvents(w)
2023-08-31 16:19:41 +08:00
}
// 执行事件
func (me *EventType[T]) ProcessEvents(wd World) {
me.mu.Lock()
defer me.mu.Unlock()
me.et.ProcessEvents(wd)
2023-08-31 16:19:41 +08:00
}
// 发布该类型的事件
func (me *EventType[T]) Publish(wd World, event *T) {
me.mu.Lock()
defer me.mu.Unlock()
me.et.Publish(wd, *event)
}
2023-08-31 16:19:41 +08:00
// 订阅该类型的事件
2023-09-15 11:17:31 +08:00
func (me *EventType[T]) Subscribe(wd World, subscriber Subscriber[T]) {
me.mu.Lock()
defer me.mu.Unlock()
sp := buildKey(wd, subscriber)
if _, ok := me.subMap[sp]; ok { // 已经订阅过
return
}
sub := func(w donburi.World, event T) {
subscriber(wd, event)
2023-08-31 16:19:41 +08:00
}
me.subMap[sp] = sub
me.et.Subscribe(wd, sub)
2023-08-31 16:19:41 +08:00
}
// 取消订阅该类型的事件
2023-09-15 11:17:31 +08:00
func (me *EventType[T]) Unsubscribe(wd World, subscriber Subscriber[T]) {
me.mu.Lock()
defer me.mu.Unlock()
sp := buildKey(wd, subscriber)
if sub, ok := me.subMap[sp]; ok { // 存在, 取消订阅
me.et.Unsubscribe(wd, sub)
2023-08-31 16:19:41 +08:00
}
}
// 生成订阅键
func buildKey[T any](wd World, subscriber Subscriber[T]) string {
sp := fmt.Sprintf("%v_%v", wd.Id(), reflect.ValueOf(subscriber).Pointer())
return sp
2023-08-31 17:49:25 +08:00
}