仿真系统

This commit is contained in:
xzb 2023-08-15 16:50:24 +08:00
parent 58f9d22a94
commit 0f1e3258e4
7 changed files with 221 additions and 3 deletions

View File

@ -5,11 +5,16 @@ import (
"joylink.club/rtsssimulation/state"
)
// 系统时钟组件
var ComSystemTimer = ecs.NewComponentType[state.SystemTimer]()
// 身份组件
var ComDeviceIdentity = ecs.NewComponentType[state.DeviceIdentity]()
// 道岔状态组件
var ComSwitchState = ecs.NewComponentType[state.SwitchState]()
// 道岔正常转动组件
var ComSwitchTurnOperating = ecs.NewComponentType[state.SwitchTurnOperating]()
// 物理区段状态组件

View File

@ -0,0 +1,38 @@
package main
import (
"fmt"
"time"
"joylink.club/ecs"
"joylink.club/rtsssimulation/components"
"joylink.club/rtsssimulation/memory"
"joylink.club/rtsssimulation/state"
"joylink.club/rtsssimulation/system"
)
func main() {
world := ecs.NewWorld(300)
worlTime := time.Now()
//外界与world交互的门面
face := memory.InitializeWorld(world, worlTime)
//当组件为显示set值时world会初始化组件的零值
switch1Entry := world.Create(components.ComDeviceIdentity, components.ComSwitchState, components.ComSwitchTurnOperating)
components.ComDeviceIdentity.Set(switch1Entry, &state.DeviceIdentity{Id: "switch1"})
components.ComSwitchState.Set(switch1Entry, &state.SwitchState{Normal: true, Reverse: false})
world.AddSystem(system.NewSwitchSystem())
//
world.StartUp()
time.Sleep(2 * time.Second)
//
reslult, _ := face.Call(func(w ecs.World) any {
fmt.Println("==>>3触发转动道岔 ...")
return system.FireSwitchTurn(w, "switch1", false, 3000)
})
fmt.Println("==>>3触发转动道岔 。。。", reslult)
//
fmt.Println("==>>world 当前时间:", face.WorldTime().GoString())
time.Sleep(4 * time.Second)
world.Close()
}

View File

@ -0,0 +1,23 @@
package memory
import (
"time"
"joylink.club/ecs"
"joylink.club/rtsssimulation/components"
"joylink.club/rtsssimulation/state"
"joylink.club/rtsssimulation/system"
)
// 初始化world添加一些内置的组件和系统
func InitializeWorld(w ecs.World, worldTime time.Time) *system.FaceSystem {
//初始化world时钟
timeEntry := w.Create(components.ComSystemTimer)
components.ComSystemTimer.Set(timeEntry, state.NewSystemTimer(&worldTime))
w.AddSystem(system.NewTimerSystem())
//初始化world与外界交互的门面
faceSystem := system.NewFaceSystem(w)
w.AddSystem(faceSystem)
//
return faceSystem
}

View File

@ -0,0 +1,32 @@
package state
import "time"
// 此文件中为与设备无关的仿真系统自身的状态定义
// 系统时钟,单例
type SystemTimer struct {
timer *time.Time
}
// 以指定时间构建
func NewSystemTimer(time *time.Time) *SystemTimer {
return &SystemTimer{
timer: time,
}
}
// 重置时间
func (me *SystemTimer) ResetTime(time time.Time) {
*me.timer = time
}
// 获取当前时间的副本
func (me *SystemTimer) Now() time.Time {
return *me.timer
}
// tick系统时钟,单位ms
func (me *SystemTimer) Tick(tick int) {
*me.timer = me.timer.Add(time.Duration(tick) * time.Millisecond)
}

View File

@ -0,0 +1,71 @@
package system
import (
"sync"
"time"
"joylink.club/ecs"
)
// 外界与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
}
// 获取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
}
}

View File

@ -1,6 +1,8 @@
package system
import (
"fmt"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/components"
@ -24,7 +26,7 @@ func NewSwitchSystem() *SwitchSystem {
// switchId: 道岔id
// turnNormal: true-道岔转动到定位false-道岔转动到反位
// turnTime: 道岔转动耗时ms
func FireSwitchTurn(w ecs.World, switchId string, turnNormal bool, turnTime int64) bool {
func FireSwitchTurn(w ecs.World, switchId string, turnNormal bool, turnTime int) bool {
fireQuery := ecs.NewQuery(filter.Contains(components.ComDeviceIdentity, components.ComSwitchTurnOperating))
//
var turnOperating *state.SwitchTurnOperating
@ -39,7 +41,7 @@ func FireSwitchTurn(w ecs.World, switchId string, turnNormal bool, turnTime int6
}
//
turnOperating.TurnNormal = turnNormal
turnOperating.TurningTime = turnTime
turnOperating.TurningTime = int64(turnTime)
turnOperating.StartTurn = true
return true
}
@ -50,7 +52,8 @@ func (me *SwitchSystem) Update(w ecs.World) {
me.turningQuery.Each(w, func(e *ecs.Entry) {
if turnOperting := components.ComSwitchTurnOperating.Get(e); turnOperting.StartTurn {
if turnOperting.TurningTime > 0 { //正在转动
//todo
turnOperting.TurningTime -= int64(w.Tick())
fmt.Println("==>>正在转动道岔 ...")
} else { //转动完成
turnOperting.StartTurn = false
state := components.ComSwitchState.Get(e)
@ -61,6 +64,7 @@ func (me *SwitchSystem) Update(w ecs.World) {
state.Normal = false
state.Reverse = true
}
fmt.Println("==>>完成转动道岔")
}
}
})

View File

@ -0,0 +1,45 @@
package system
import (
"time"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/components"
)
var timerQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.ComSystemTimer))
// 系统时钟操作
type TimerSystem struct {
}
func NewTimerSystem() *TimerSystem {
return &TimerSystem{}
}
// world 执行
func (me *TimerSystem) Update(w ecs.World) {
if e, ok := timerQuery.First(w); ok {
timer := components.ComSystemTimer.Get(e)
timer.Tick(w.Tick())
}
}
// 重置world时间
func ResetWorldTimer(w ecs.World, time time.Time) {
if e, ok := timerQuery.First(w); ok {
timer := components.ComSystemTimer.Get(e)
timer.ResetTime(time)
}
}
// 获取world当前时间
func GetWorldNow(w ecs.World) *time.Time {
if e, ok := timerQuery.First(w); ok {
timer := components.ComSystemTimer.Get(e)
now := timer.Now()
return &now
}
return nil
}