仿真系统
This commit is contained in:
parent
58f9d22a94
commit
0f1e3258e4
@ -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]()
|
||||
|
||||
// 物理区段状态组件
|
38
simulation/examples/main.go
Normal file
38
simulation/examples/main.go
Normal 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()
|
||||
}
|
23
simulation/memory/init_world.go
Normal file
23
simulation/memory/init_world.go
Normal 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
|
||||
}
|
32
simulation/state/system_state.go
Normal file
32
simulation/state/system_state.go
Normal 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)
|
||||
}
|
71
simulation/system/face_system.go
Normal file
71
simulation/system/face_system.go
Normal 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
|
||||
}
|
||||
}
|
@ -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("==>>完成转动道岔")
|
||||
}
|
||||
}
|
||||
})
|
45
simulation/system/timer_system.go
Normal file
45
simulation/system/timer_system.go
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user