rts-sim-module/system/face_system.go
2023-08-22 15:04:46 +08:00

99 lines
2.0 KiB
Go

package system
import (
"fmt"
"sync"
"time"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/components"
"joylink.club/rtsssimulation/util"
)
// 外界与world交互请求定义
type FaceRequest func(w ecs.World) any
type faceOutcome struct {
outcome any
ok bool
}
// 外界与world的交互
type FaceSystem struct {
req chan FaceRequest
rsp chan *faceOutcome
world ecs.World
//保证与world的交互串行
locker *sync.Mutex
}
func NewFaceSystem(w ecs.World) *FaceSystem {
return &FaceSystem{req: make(chan FaceRequest), rsp: make(chan *faceOutcome), locker: &sync.Mutex{}, world: w}
}
// world 执行
func (me *FaceSystem) Update(world ecs.World) {
select {
case reqFunc := <-me.req:
{
response := reqFunc(world)
if nil != response {
me.rsp <- &faceOutcome{outcome: response, ok: true}
} else {
me.rsp <- &faceOutcome{outcome: nil, ok: false}
}
}
default:
}
}
// 外界调用此方法与world交互
func (me *FaceSystem) Call(request FaceRequest) (any, bool) {
if !me.world.Running() {
return nil, false
}
//
me.locker.Lock()
defer me.locker.Unlock()
//
me.req <- request
//
result := <-me.rsp
return result.outcome, result.ok
}
// 根据id获取实体
func (me *FaceSystem) FindEntity(id string) *ecs.Entry {
return findEntityById(me.world, id)
}
// 获取world当前时间
func (me *FaceSystem) WorldTime() *time.Time {
now, ok := me.Call(func(w ecs.World) any {
return GetWorldNow(w)
})
if ok {
return now.(*time.Time)
} else {
return nil
}
}
func findEntityById(world ecs.World, id string) *ecs.Entry {
query := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent))
return queryEntityById(world, query, id)
}
func queryEntityById(world ecs.World, q *ecs.Query, id string) *ecs.Entry {
var entry *ecs.Entry = nil
func() {
defer util.Recover()
q.Each(world, func(e *ecs.Entry) {
if id == components.DeviceIdentityComponent.Get(e).Id {
entry = e
panic(fmt.Sprintf("找到实体[%s],结束查找", id))
}
})
}()
//
return entry
}