仿真系统
This commit is contained in:
parent
58f9d22a94
commit
0f1e3258e4
@ -5,11 +5,16 @@ import (
|
|||||||
"joylink.club/rtsssimulation/state"
|
"joylink.club/rtsssimulation/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 系统时钟组件
|
||||||
|
var ComSystemTimer = ecs.NewComponentType[state.SystemTimer]()
|
||||||
|
|
||||||
// 身份组件
|
// 身份组件
|
||||||
var ComDeviceIdentity = ecs.NewComponentType[state.DeviceIdentity]()
|
var ComDeviceIdentity = ecs.NewComponentType[state.DeviceIdentity]()
|
||||||
|
|
||||||
// 道岔状态组件
|
// 道岔状态组件
|
||||||
var ComSwitchState = ecs.NewComponentType[state.SwitchState]()
|
var ComSwitchState = ecs.NewComponentType[state.SwitchState]()
|
||||||
|
|
||||||
|
// 道岔正常转动组件
|
||||||
var ComSwitchTurnOperating = ecs.NewComponentType[state.SwitchTurnOperating]()
|
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
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/yohamta/donburi/filter"
|
"github.com/yohamta/donburi/filter"
|
||||||
"joylink.club/ecs"
|
"joylink.club/ecs"
|
||||||
"joylink.club/rtsssimulation/components"
|
"joylink.club/rtsssimulation/components"
|
||||||
@ -24,7 +26,7 @@ func NewSwitchSystem() *SwitchSystem {
|
|||||||
// switchId: 道岔id
|
// switchId: 道岔id
|
||||||
// turnNormal: true-道岔转动到定位,false-道岔转动到反位
|
// turnNormal: true-道岔转动到定位,false-道岔转动到反位
|
||||||
// turnTime: 道岔转动耗时ms
|
// 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))
|
fireQuery := ecs.NewQuery(filter.Contains(components.ComDeviceIdentity, components.ComSwitchTurnOperating))
|
||||||
//
|
//
|
||||||
var turnOperating *state.SwitchTurnOperating
|
var turnOperating *state.SwitchTurnOperating
|
||||||
@ -39,7 +41,7 @@ func FireSwitchTurn(w ecs.World, switchId string, turnNormal bool, turnTime int6
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
turnOperating.TurnNormal = turnNormal
|
turnOperating.TurnNormal = turnNormal
|
||||||
turnOperating.TurningTime = turnTime
|
turnOperating.TurningTime = int64(turnTime)
|
||||||
turnOperating.StartTurn = true
|
turnOperating.StartTurn = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -50,7 +52,8 @@ func (me *SwitchSystem) Update(w ecs.World) {
|
|||||||
me.turningQuery.Each(w, func(e *ecs.Entry) {
|
me.turningQuery.Each(w, func(e *ecs.Entry) {
|
||||||
if turnOperting := components.ComSwitchTurnOperating.Get(e); turnOperting.StartTurn {
|
if turnOperting := components.ComSwitchTurnOperating.Get(e); turnOperting.StartTurn {
|
||||||
if turnOperting.TurningTime > 0 { //正在转动
|
if turnOperting.TurningTime > 0 { //正在转动
|
||||||
//todo
|
turnOperting.TurningTime -= int64(w.Tick())
|
||||||
|
fmt.Println("==>>正在转动道岔 ...")
|
||||||
} else { //转动完成
|
} else { //转动完成
|
||||||
turnOperting.StartTurn = false
|
turnOperting.StartTurn = false
|
||||||
state := components.ComSwitchState.Get(e)
|
state := components.ComSwitchState.Get(e)
|
||||||
@ -61,6 +64,7 @@ func (me *SwitchSystem) Update(w ecs.World) {
|
|||||||
state.Normal = false
|
state.Normal = false
|
||||||
state.Reverse = true
|
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