ecs事件多world支持

This commit is contained in:
xzb 2023-08-31 17:49:25 +08:00
parent 806b92aa61
commit 0d2b516362

View File

@ -1,7 +1,9 @@
package ecs
import (
"fmt"
"reflect"
"sync"
"github.com/yohamta/donburi"
"github.com/yohamta/donburi/features/events"
@ -14,7 +16,8 @@ type (
// 事件类型定义
EventType[T any] struct {
et *events.EventType[T]
subscriberMap map[uintptr]events.Subscriber[T]
subscriberMap map[string]events.Subscriber[T]
subscriberMapLock sync.Mutex //
}
// 事件订阅者定义
Subscriber[T any] func(w World, event T)
@ -31,7 +34,8 @@ func init() {
func NewEventType[T any]() *EventType[T] {
return &EventType[T]{
et: events.NewEventType[T](),
subscriberMap: make(map[uintptr]events.Subscriber[T]),
subscriberMap: make(map[string]events.Subscriber[T]),
subscriberMapLock: sync.Mutex{},
}
}
@ -78,19 +82,25 @@ func (me *EventType[T]) Publish(wd World, event *T) {
// 订阅该类型的事件
func (me *EventType[T]) subscribe(wd World, subscriber Subscriber[T]) {
wdSubscriberPointer := reflect.ValueOf(subscriber).Pointer()
me.subscriberMap[wdSubscriberPointer] = func(w donburi.World, event T) {
me.subscriberMapLock.Lock()
defer me.subscriberMapLock.Unlock()
//
subscriberKey := subscriberKey[T](wd, subscriber)
me.subscriberMap[subscriberKey] = func(w donburi.World, event T) {
subscriber(wd, event)
}
me.et.Subscribe(wd.(*world).world, me.subscriberMap[wdSubscriberPointer])
me.et.Subscribe(wd.(*world).world, me.subscriberMap[subscriberKey])
}
// 取消订阅该类型的事件
func (me *EventType[T]) unsubscribe(wd World, subscriber Subscriber[T]) {
wdSubscriberPointer := reflect.ValueOf(subscriber).Pointer()
if sub, ok := me.subscriberMap[wdSubscriberPointer]; ok {
me.subscriberMapLock.Lock()
defer me.subscriberMapLock.Unlock()
//
subscriberKey := subscriberKey[T](wd, subscriber)
if sub, ok := me.subscriberMap[subscriberKey]; ok {
me.et.Unsubscribe(wd.(*world).world, sub)
delete(me.subscriberMap, wdSubscriberPointer)
delete(me.subscriberMap, subscriberKey)
}
}
@ -98,3 +108,9 @@ func (me *EventType[T]) unsubscribe(wd World, subscriber Subscriber[T]) {
func (me *EventType[T]) publish(wd World, event *T) {
me.et.Publish(wd.(*world).world, *event)
}
func subscriberKey[T any](wd World, subscriber Subscriber[T]) string {
wdSubscriberPointer := reflect.ValueOf(subscriber).Pointer()
subscriberKey := fmt.Sprintf("%d-%d", wd.GoroutineId(), wdSubscriberPointer)
return subscriberKey
}