重构
This commit is contained in:
parent
c1dd45bdf5
commit
0124956a51
@ -1,15 +0,0 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
)
|
||||
|
||||
// 按钮状态组件
|
||||
var ButtonStateComponent = ecs.NewComponentType[cstate.ButtonState]()
|
||||
|
||||
// 按钮操作组件
|
||||
var ButtonPressOperatingComponent = ecs.NewComponentType[cstate.ButtonPressOperating]()
|
||||
|
||||
// 按钮确认组件
|
||||
var ButtonConfirmOperatingComponent = ecs.NewComponentType[cstate.ButtonConfirmOperating]()
|
@ -1,60 +0,0 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
)
|
||||
|
||||
// 系统时钟组件
|
||||
var SystemTimerComponent = ecs.NewComponentType[cstate.SystemTimer]()
|
||||
|
||||
// 模型仓库引用组件,单例
|
||||
var ModelStorageRefComponent = ecs.NewComponentType[cstate.ModelStorageRef]()
|
||||
|
||||
// 身份组件
|
||||
var DeviceIdentityComponent = ecs.NewComponentType[cstate.DeviceIdentity]()
|
||||
|
||||
// 存储屏蔽门标签组件
|
||||
var PsdTagHandlerComponent = ecs.NewComponentType[cstate.EntityTagHandler]()
|
||||
|
||||
// 存储继电器标签组件
|
||||
var RelayTagHandlerComponent = ecs.NewComponentType[cstate.EntityTagHandler]()
|
||||
|
||||
// 可移动设备组件
|
||||
var MovableDeviceStateComponent = ecs.NewComponentType[cstate.MovableDeviceState]()
|
||||
|
||||
// 比率设备组件
|
||||
var PercentageDeviceStateComponent = ecs.NewComponentType[cstate.PercentageDeviceState]()
|
||||
|
||||
// 道岔继电器状态组件
|
||||
var SwitchRelayStateComponent = ecs.NewComponentType[cstate.SwitchRelayState]()
|
||||
|
||||
// 物理区段状态组件
|
||||
var PhysicalSectionStateComponent = ecs.NewComponentType[cstate.PhysicalSectionState]()
|
||||
|
||||
// 信号机状态组件
|
||||
var SignalStateComponent = ecs.NewComponentType[cstate.SignalState]()
|
||||
|
||||
// 站台单侧屏蔽门状态组件
|
||||
var PsdStateComponent = ecs.NewComponentType[cstate.PsdState]()
|
||||
|
||||
// 应答器状态组件
|
||||
var BaliseStateComponent = ecs.NewComponentType[cstate.BaliseState]()
|
||||
|
||||
// 列车状态组件
|
||||
var TrainStateComponent = ecs.NewComponentType[cstate.TrainState]()
|
||||
|
||||
// 两档按钮/旋钮状态组件
|
||||
var TowPositionButtonStateComponent = ecs.NewComponentType[cstate.TowPositionButtonState]()
|
||||
|
||||
// 继电器状态组件
|
||||
var RelayStateComponent = ecs.NewComponentType[cstate.RelayState]()
|
||||
|
||||
// 紧急停车按钮状态组件
|
||||
var EmpStateComponent = ecs.NewComponentType[cstate.EmpState]()
|
||||
|
||||
// 生成标签组件
|
||||
// 用于标记实体便于查找
|
||||
func NewComponentTag() *ecs.ComponentType[struct{}] {
|
||||
return ecs.NewComponentType[struct{}]()
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,54 +0,0 @@
|
||||
package cstate
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/yohamta/donburi/component"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 此文件中为与设备无关的仿真系统自身的状态定义
|
||||
|
||||
// 系统时钟,单例
|
||||
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)
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
// 实体标签
|
||||
type EntityTag = component.IComponentType
|
||||
|
||||
type EntityTagHandler struct {
|
||||
Tag EntityTag
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
// 模型仓库引用
|
||||
// 用于world内使用,查询模型
|
||||
type ModelStorageRef struct {
|
||||
ModelManager umi.IModelManager
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
package creator
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 仿真world配置
|
||||
type WorldConfig struct {
|
||||
//模型管理器,接收模型仓库管理器实例的指针
|
||||
ModelManager umi.IModelManager
|
||||
//world 系统
|
||||
Systems []ecs.ISystem
|
||||
//world tick
|
||||
Tick int
|
||||
//world 起始时间
|
||||
InitTime time.Time
|
||||
}
|
||||
|
||||
// 初始化仿真world
|
||||
func InitializeWorld(config *WorldConfig) ecs.World {
|
||||
world := ecs.NewWorld(config.Tick)
|
||||
// 初始化系统
|
||||
for _, sys := range config.Systems {
|
||||
world.AddSystem(sys)
|
||||
}
|
||||
// 初始化实体
|
||||
initEntites(config, world)
|
||||
//
|
||||
return world
|
||||
}
|
||||
|
||||
// 初始化实体
|
||||
func initEntites(config *WorldConfig, world ecs.World) {
|
||||
modelStorageRefEntry := CreateModelStorageRefEntity(world)
|
||||
components.ModelStorageRefComponent.Set(modelStorageRefEntry, &cstate.ModelStorageRef{ModelManager: config.ModelManager})
|
||||
//world time
|
||||
worldTime := CreateWorldTimeEntity(world)
|
||||
components.SystemTimerComponent.Set(worldTime, cstate.NewSystemTimer(&config.InitTime))
|
||||
//
|
||||
foreachModels(config.ModelManager, umi.Switch, func(md umi.IDeviceModel) {
|
||||
entry := CreateSwitchEntity(world)
|
||||
components.DeviceIdentityComponent.Set(entry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.SwitchRelayStateComponent.Set(entry, &cstate.SwitchRelayState{DcJ: false, FcJ: false, DbJ: true, FbJ: false})
|
||||
components.PercentageDeviceStateComponent.Set(entry, &cstate.PercentageDeviceState{Rate: system.SwitchNormalVaule, Target: system.SwitchNormalVaule})
|
||||
components.MovableDeviceStateComponent.Set(entry, &cstate.MovableDeviceState{ToH: false, Speed: 0, Position: system.SwitchNormalVaule})
|
||||
})
|
||||
//
|
||||
foreachModels(config.ModelManager, umi.Signal, func(md umi.IDeviceModel) {
|
||||
entry := CreateSignalEntity(world)
|
||||
components.DeviceIdentityComponent.Set(entry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.SignalStateComponent.Set(entry, &cstate.SignalState{Display: cstate.SignalAspect_No})
|
||||
})
|
||||
//
|
||||
foreachModels(config.ModelManager, umi.Psd, func(md umi.IDeviceModel) {
|
||||
psdEntry := CreatePsdEntity(world)
|
||||
components.DeviceIdentityComponent.Set(psdEntry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.PsdStateComponent.Set(psdEntry, &cstate.PsdState{AllClosed: true, AllOpened: false, InterlockReleased: false})
|
||||
//
|
||||
psd := md.(umi.IPsdModel)
|
||||
for _, psdCell := range psd.AllDeviceCells() {
|
||||
cellEntry := CreatePsdCellEntity(world, psdEntry)
|
||||
components.DeviceIdentityComponent.Set(cellEntry, &cstate.DeviceIdentity{Id: psdCell.GetId()})
|
||||
components.PercentageDeviceStateComponent.Set(cellEntry, &cstate.PercentageDeviceState{Rate: system.PsdCellWholeCloseValue, Target: system.PsdCellWholeCloseValue})
|
||||
components.MovableDeviceStateComponent.Set(cellEntry, &cstate.MovableDeviceState{ToH: true, Speed: 0, Position: system.PsdCellWholeCloseValue})
|
||||
}
|
||||
})
|
||||
//
|
||||
foreachModels(config.ModelManager, umi.TowPosButton, func(md umi.IDeviceModel) {
|
||||
entry := CreateTowPosButtonEntity(world)
|
||||
components.DeviceIdentityComponent.Set(entry, &cstate.DeviceIdentity{Id: md.GetId()})
|
||||
components.TowPositionButtonStateComponent.Set(entry, &cstate.TowPositionButtonState{Pos1: false, Pos2: true})
|
||||
})
|
||||
}
|
||||
func foreachModels(modelManager umi.IModelManager, deviceType umi.DeviceType, eachFunc func(deviceModel umi.IDeviceModel)) {
|
||||
for _, model := range modelManager.FindByType(deviceType) {
|
||||
eachFunc(model)
|
||||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 创建模型仓库引用实体
|
||||
func CreateModelStorageRefEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.ModelStorageRefComponent)
|
||||
}
|
||||
|
||||
// 创建world time 实体
|
||||
func CreateWorldTimeEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.SystemTimerComponent)
|
||||
}
|
||||
|
||||
// 创建道岔实体
|
||||
func CreateSwitchEntity(w ecs.World) *ecs.Entry {
|
||||
e := w.Create(components.DeviceIdentityComponent, components.SwitchRelayStateComponent, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent, components.RelayTagHandlerComponent)
|
||||
components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: components.NewComponentTag()})
|
||||
return e
|
||||
}
|
||||
|
||||
// 创建信号机实体
|
||||
func CreateSignalEntity(w ecs.World) *ecs.Entry {
|
||||
e := w.Create(components.DeviceIdentityComponent, components.SignalStateComponent, components.RelayTagHandlerComponent)
|
||||
components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: components.NewComponentTag()})
|
||||
return e
|
||||
}
|
||||
|
||||
// 创建物理区段实体
|
||||
func CreatePhysicalSectionEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.PhysicalSectionStateComponent)
|
||||
}
|
||||
|
||||
// 创建站台单侧屏蔽门实体
|
||||
func CreatePsdEntity(w ecs.World) *ecs.Entry {
|
||||
e := w.Create(components.DeviceIdentityComponent, components.PsdStateComponent, components.PsdTagHandlerComponent, components.RelayTagHandlerComponent)
|
||||
components.PsdTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: components.NewComponentTag()})
|
||||
components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: components.NewComponentTag()})
|
||||
return e
|
||||
}
|
||||
|
||||
// 创建屏蔽门cell实体
|
||||
func CreatePsdCellEntity(w ecs.World, psdEntry *ecs.Entry) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent, components.PsdTagHandlerComponent.Get(psdEntry).Tag)
|
||||
}
|
||||
|
||||
// 创建应答器实体
|
||||
func CreateBaliseEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.BaliseStateComponent)
|
||||
}
|
||||
|
||||
// 创建列车实体
|
||||
func CreateTrainEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.TrainStateComponent)
|
||||
}
|
||||
|
||||
// 创建两档位按钮实体
|
||||
func CreateTowPosButtonEntity(w ecs.World) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.TowPositionButtonStateComponent)
|
||||
}
|
||||
|
||||
// 创建继电器实体
|
||||
// deviceEntry: 被继电器控制的设备
|
||||
func CreateRelayEntity(w ecs.World, deviceEntry *ecs.Entry) *ecs.Entry {
|
||||
return w.Create(components.DeviceIdentityComponent, components.RelayStateComponent, components.RelayTagHandlerComponent.Get(deviceEntry).Tag)
|
||||
}
|
||||
|
||||
// 创建紧急停车按钮实体
|
||||
func CreateEmpEntity(w ecs.World) *ecs.Entry {
|
||||
e := w.Create(components.DeviceIdentityComponent, components.EmpStateComponent, components.RelayTagHandlerComponent)
|
||||
components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: components.NewComponentTag()})
|
||||
return e
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/creator"
|
||||
"joylink.club/rtsssimulation/examples/test1/tmodel"
|
||||
"joylink.club/rtsssimulation/examples/test1/tstorages"
|
||||
"joylink.club/rtsssimulation/operate"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
// 具体共享模型仓库key
|
||||
var StorageKeyXaV1 = tstorages.StorageKey{LineId: "xa-1", Version: "0.1"}
|
||||
|
||||
func main() {
|
||||
initShareModels()
|
||||
// 通过共享仓库生成具体仿真world的模型仓库
|
||||
woldModelStorage := tstorages.ShareStoragesMapper.CreateWorldStorageWithShare(StorageKeyXaV1, initLinkModels())
|
||||
//
|
||||
config := &creator.WorldConfig{
|
||||
ModelManager: woldModelStorage,
|
||||
Tick: 300,
|
||||
InitTime: time.Now(),
|
||||
Systems: []ecs.ISystem{
|
||||
system.NewMovableDeviceSystem(),
|
||||
system.NewPercentageDeviceSystem(),
|
||||
system.NewSwitchSystem(),
|
||||
system.NewPsdSystem(),
|
||||
system.NewTimerSystem(),
|
||||
system.NewDebugSystem()},
|
||||
}
|
||||
world := creator.InitializeWorld(config)
|
||||
//
|
||||
world.StartUp()
|
||||
//
|
||||
time.Sleep(2 * time.Second)
|
||||
//
|
||||
//testPsdOpt(world)
|
||||
//testPsdCellOpt(world)
|
||||
testSwitchTurn(world)
|
||||
//
|
||||
time.Sleep(120 * time.Second)
|
||||
}
|
||||
|
||||
// 构建具体仿真link模型
|
||||
func initLinkModels() *tstorages.ModelStorage {
|
||||
mds := tstorages.NewModelStorage()
|
||||
//
|
||||
link1 := tmodel.NewLinkModel("link1")
|
||||
link2 := tmodel.NewLinkModel("link2")
|
||||
mds.AddModel(link1)
|
||||
mds.AddModel(link2)
|
||||
return mds
|
||||
}
|
||||
|
||||
// 构建模型
|
||||
func initShareModels() {
|
||||
mds := tstorages.NewModelStorage()
|
||||
//
|
||||
signal1 := tmodel.NewSignalModel("signal1")
|
||||
signal2 := tmodel.NewSignalModel("signal2")
|
||||
mds.AddModel(signal1)
|
||||
mds.AddModel(signal2)
|
||||
//
|
||||
switch1 := tmodel.NewSwitchModel("switch1")
|
||||
switch1.TurnTime = 3000
|
||||
switch2 := tmodel.NewSwitchModel("switch2")
|
||||
switch2.TurnTime = 2500
|
||||
mds.AddModel(switch1)
|
||||
mds.AddModel(switch2)
|
||||
//
|
||||
psd1 := tmodel.NewPsdModel("psd1")
|
||||
psd1.MoveTime = 5000
|
||||
psd1Cell1 := tmodel.NewPsdCellModel("psd1Cell1", psd1)
|
||||
psd1Cell2 := tmodel.NewPsdCellModel("psd1Cell2", psd1)
|
||||
psd2 := tmodel.NewPsdModel("psd2")
|
||||
psd2.MoveTime = 6000
|
||||
psd2Cell1 := tmodel.NewPsdCellModel("psd2Cell1", psd2)
|
||||
psd2Cell2 := tmodel.NewPsdCellModel("psd2Cell2", psd2)
|
||||
mds.AddModel(psd1)
|
||||
mds.AddModel(psd1Cell1)
|
||||
mds.AddModel(psd1Cell2)
|
||||
mds.AddModel(psd2)
|
||||
mds.AddModel(psd2Cell1)
|
||||
mds.AddModel(psd2Cell2)
|
||||
//
|
||||
button1 := tmodel.NewTowPosButtonModel("button1")
|
||||
mds.AddModel(button1)
|
||||
//
|
||||
tstorages.ShareStoragesMapper.AddShareModelStorage(StorageKeyXaV1, mds)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
func testPsdOpt(w ecs.World) {
|
||||
operate.FirePsdOperation(w, "psd1", true)
|
||||
time.Sleep(5 * time.Second)
|
||||
operate.FirePsdOperation(w, "psd1", false)
|
||||
}
|
||||
func testPsdCellOpt(w ecs.World) {
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell1", 0)
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell2", 0)
|
||||
time.Sleep(10 * time.Second)
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell1", 100-20)
|
||||
operate.FirePsdCellOperation(w, "psd1", "psd1Cell2", 100)
|
||||
//
|
||||
time.Sleep(10 * time.Second)
|
||||
operate.FirePsdCellOperation(w, "psd2", "psd2Cell1", 0)
|
||||
operate.FirePsdCellOperation(w, "psd2", "psd2Cell2", 0)
|
||||
time.Sleep(10 * time.Second)
|
||||
operate.FirePsdCellOperation(w, "psd2", "psd2Cell1", 100-20)
|
||||
operate.FirePsdCellOperation(w, "psd2", "psd2Cell2", 100)
|
||||
}
|
||||
func testSwitchTurn(w ecs.World) {
|
||||
operate.FireSwitchFcj(w, "switch1")
|
||||
time.Sleep(3 * time.Second)
|
||||
operate.FireSwitchDcj(w, "switch1")
|
||||
|
||||
}
|
||||
func testSignalOpt(w ecs.World) {
|
||||
operate.SetSignalDisplay(w, "siganl1", cstate.SignalAspect_B)
|
||||
}
|
||||
func testButtonOpt(world ecs.World) {
|
||||
operate.FireTowPositionButtonMoving(world, "button1")
|
||||
time.Sleep(3 * time.Second)
|
||||
operate.FireTowPositionButtonArrivedPos1(world, "button1")
|
||||
time.Sleep(3 * time.Second)
|
||||
operate.FireTowPositionButtonArrivedPos2(world, "button1")
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package tmodel
|
||||
|
||||
import (
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
@ -10,10 +9,6 @@ type SignalModel struct {
|
||||
DeviceModel
|
||||
//信号机所在轨道
|
||||
LinkOffset *LinkOffsetRef
|
||||
//信号机类型,出厂已确定,即几个色灯、排列顺序
|
||||
Type cstate.SignalAspect
|
||||
//默认显示信号
|
||||
DefaultDisplay cstate.SignalAspect
|
||||
}
|
||||
|
||||
func NewSignalModel(id string) *SignalModel {
|
||||
|
@ -1,28 +0,0 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
// 应答器查询
|
||||
var baliseQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.BaliseStateComponent))
|
||||
|
||||
//
|
||||
|
||||
// 发送消息到应答器
|
||||
// 当要清空应答器中报文时,则message=nil
|
||||
func SendMessageToTransponder(world ecs.World, transponderId string, message *cstate.BaliseContent) bool {
|
||||
transponderEntry := system.QueryEntityById(world, baliseQuery, transponderId)
|
||||
//
|
||||
if transponderEntry == nil {
|
||||
return false
|
||||
}
|
||||
//
|
||||
components.BaliseStateComponent.Get(transponderEntry).Content = message
|
||||
//
|
||||
return true
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
// 紧急停车按钮查询
|
||||
var empQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.EmpStateComponent))
|
||||
|
||||
func findEmpEntry(world ecs.World, empId string) (*ecs.Entry, error) {
|
||||
empEntry := system.QueryEntityById(world, empQuery, empId)
|
||||
if empEntry == nil {
|
||||
return nil, fmt.Errorf("紧急停车按钮[%s]实体不存在", empId)
|
||||
} else {
|
||||
return empEntry, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 激活紧急停车按钮
|
||||
func FireEmpPressed(world ecs.World, empId string) error {
|
||||
entry, err := findEmpEntry(world, empId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
components.EmpStateComponent.Get(entry).Pressed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// 复位紧急停车按钮
|
||||
func FireEmpReset(world ecs.World, empId string) error {
|
||||
entry, err := findEmpEntry(world, empId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
components.EmpStateComponent.Get(entry).Pressed = false
|
||||
return nil
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
// 触发比率设备变动到目标比率
|
||||
// lhDistance: 从L到H的总耗时,单位ms
|
||||
// targetRateValue: 变动的最终目标比率值,[0,100000]
|
||||
func FirePercentageDevice(world ecs.World, deviceEntry *ecs.Entry, lhDistance int64, targetRateValue int64) error {
|
||||
if targetRateValue < system.PercentageRateValueMin || targetRateValue > system.PercentageRateValueMax {
|
||||
return fmt.Errorf("targetRateValue须在[%d,%d]范围内", system.PercentageRateValueMin, system.PercentageRateValueMax)
|
||||
}
|
||||
//
|
||||
id := components.DeviceIdentityComponent.Get(deviceEntry).Id
|
||||
if !deviceEntry.HasComponent(components.PercentageDeviceStateComponent) {
|
||||
return fmt.Errorf("比率设备[%s]实体中没有百分比组件", id)
|
||||
}
|
||||
if !deviceEntry.HasComponent(components.MovableDeviceStateComponent) {
|
||||
return fmt.Errorf("比率设备[%s]实体中没有按速度移动组件", id)
|
||||
}
|
||||
//
|
||||
speed := int32(float64(world.Tick()) * (float64(system.PercentageRateValueMax) / float64(lhDistance)))
|
||||
//
|
||||
percent := components.PercentageDeviceStateComponent.Get(deviceEntry)
|
||||
movable := components.MovableDeviceStateComponent.Get(deviceEntry)
|
||||
//
|
||||
percent.Target = targetRateValue
|
||||
movable.Speed = speed
|
||||
movable.ToH = targetRateValue > percent.Rate
|
||||
//
|
||||
return nil
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
const (
|
||||
//屏蔽门完全关闭,百分比
|
||||
PsdCellWholeCloseRate int8 = system.PercentageRateMax
|
||||
//屏蔽门完全打开,百分比
|
||||
PsdCellWholeOpenRate int8 = system.PercentageRateMin
|
||||
)
|
||||
|
||||
// 车站单侧屏蔽门互锁解除操作
|
||||
func FirePsdInterlockRelease(world ecs.World, psdId string, lockRelease bool) error {
|
||||
psdEntry, err := findPsdEntry(world, psdId)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
components.PsdStateComponent.Get(psdEntry).InterlockReleased = lockRelease
|
||||
//
|
||||
return nil
|
||||
}
|
||||
|
||||
// 屏蔽门全开
|
||||
func FirePsdWholeOpen(world ecs.World, psdId string) error {
|
||||
return FirePsdOperation(world, psdId, false)
|
||||
}
|
||||
|
||||
// 屏蔽门全关
|
||||
func FirePsdWholeClose(world ecs.World, psdId string) error {
|
||||
return FirePsdOperation(world, psdId, true)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 车站单侧屏蔽门操作
|
||||
// closeOpt true-关门操作,false-开门操作
|
||||
func FirePsdOperation(world ecs.World, psdId string, closeOpt bool) error {
|
||||
psdEntry, err := findPsdEntry(world, psdId)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
//屏蔽门标签
|
||||
psdTag := components.PsdTagHandlerComponent.Get(psdEntry).Tag
|
||||
psdCellQuery := ecs.NewQuery(filter.Contains(psdTag))
|
||||
var errPercent error = nil
|
||||
psdCellQuery.Each(world, func(psdCellEntry *ecs.Entry) {
|
||||
if errPercent == nil {
|
||||
if closeOpt {
|
||||
errPercent = FirePercentageDevice(world, psdCellEntry, findPsdWholeMoveTime(world, psdId), system.GetRateValue(PsdCellWholeCloseRate))
|
||||
} else {
|
||||
errPercent = FirePercentageDevice(world, psdCellEntry, findPsdWholeMoveTime(world, psdId), system.GetRateValue(PsdCellWholeOpenRate))
|
||||
}
|
||||
}
|
||||
})
|
||||
//
|
||||
return errPercent
|
||||
}
|
||||
|
||||
// 车站单侧屏蔽门单元cell操作
|
||||
// closeRate cell最终关上的百分比,100-完全关上,0-完全未关即完全打开,(0,100)内即半关闭
|
||||
func FirePsdCellOperation(world ecs.World, psdId string, psdCellId string, closeRate int8) error {
|
||||
if closeRate < 0 || closeRate > 100 {
|
||||
return fmt.Errorf("屏蔽门单元操作closeRate(%d)不在[0,100]内", closeRate)
|
||||
}
|
||||
//
|
||||
psdEntry, err := findPsdEntry(world, psdId)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
//屏蔽门标签
|
||||
psdTag := components.PsdTagHandlerComponent.Get(psdEntry).Tag
|
||||
psdCellQuery := ecs.NewQuery(filter.Contains(psdTag))
|
||||
psdCellEntry := system.QueryEntityById(world, psdCellQuery, psdCellId)
|
||||
if psdCellEntry == nil {
|
||||
return fmt.Errorf("屏蔽门[%s]的单元门[%s]的实体不存在", psdId, psdCellId)
|
||||
}
|
||||
//
|
||||
return FirePercentageDevice(world, psdCellEntry, findPsdWholeMoveTime(world, psdId), system.GetRateValue(closeRate))
|
||||
}
|
||||
|
||||
// 获取屏蔽门实体
|
||||
func findPsdEntry(world ecs.World, psdId string) (*ecs.Entry, error) {
|
||||
psdEntry := system.QueryEntityById(world, system.PsdQuery, psdId)
|
||||
if psdEntry == nil {
|
||||
return nil, fmt.Errorf("屏蔽门[%s]实体不存在", psdId)
|
||||
} else {
|
||||
return psdEntry, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 获取屏蔽门从完全开到完全关所需时间,单位ms
|
||||
func findPsdWholeMoveTime(world ecs.World, psdId string) int64 {
|
||||
psd := system.WorldModelStorage(world).FindById(psdId)
|
||||
psdUmi := psd.(umi.IPsdModel)
|
||||
return psdUmi.MovingTime()
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
// 信号机显示状态查询
|
||||
var signalQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.SignalStateComponent))
|
||||
|
||||
// 设置某个信号机的显示
|
||||
// 返回值:true-设置成功,false-设置失败
|
||||
func SetSignalDisplay(w ecs.World, signalId string, display cstate.SignalAspect) error {
|
||||
signalEntry, err := findSignalEntry(w, signalId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//
|
||||
signalState := components.SignalStateComponent.Get(signalEntry)
|
||||
signalState.Display = display
|
||||
//
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取信号机实体
|
||||
func findSignalEntry(w ecs.World, signalId string) (*ecs.Entry, error) {
|
||||
var signalEntry *ecs.Entry = system.QueryEntityById(w, signalQuery, signalId)
|
||||
if signalEntry != nil {
|
||||
return signalEntry, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("信号机[%s]的实体不存在", signalId)
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
const (
|
||||
//道岔定位
|
||||
SwitchNormalRate int8 = system.PercentageRateMin
|
||||
//道岔反位
|
||||
SwitchReverseRate int8 = system.PercentageRateMax
|
||||
)
|
||||
|
||||
// 道岔定操
|
||||
func FireSwitchDcj(w ecs.World, switchId string) error {
|
||||
return fireSwitchTurn(w, switchId, true)
|
||||
}
|
||||
|
||||
// 道岔反操
|
||||
func FireSwitchFcj(w ecs.World, switchId string) error {
|
||||
return fireSwitchTurn(w, switchId, false)
|
||||
}
|
||||
func fireSwitchTurn(w ecs.World, switchId string, turnNormal bool) error {
|
||||
var switchEntry *ecs.Entry = system.QueryEntityById(w, system.SwitchQuery, switchId)
|
||||
if switchEntry == nil {
|
||||
return fmt.Errorf("道岔[%s]的实体不存在", switchId)
|
||||
}
|
||||
relay := components.SwitchRelayStateComponent.Get(switchEntry)
|
||||
relay.DcJ = turnNormal
|
||||
relay.FcJ = !turnNormal
|
||||
//
|
||||
return nil
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package operate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/system"
|
||||
)
|
||||
|
||||
var towPosButtonsQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.TowPositionButtonStateComponent))
|
||||
|
||||
// 档位变换过程中指令
|
||||
// 该指令执行后,按钮处于未知状态
|
||||
func FireTowPositionButtonMoving(w ecs.World, buttonId string) error {
|
||||
entry := system.QueryEntityById(w, towPosButtonsQuery, buttonId)
|
||||
if nil == entry {
|
||||
return fmt.Errorf("两档位按钮[%s]实体不存在", buttonId)
|
||||
}
|
||||
//
|
||||
state := components.TowPositionButtonStateComponent.Get(entry)
|
||||
state.Pos1 = false
|
||||
state.Pos2 = false
|
||||
//
|
||||
return nil
|
||||
}
|
||||
|
||||
// 档位变换到达pos1指令
|
||||
// 执行该指令后,按钮处于pos1稳定态
|
||||
func FireTowPositionButtonArrivedPos1(w ecs.World, buttonId string) error {
|
||||
return fireTowPositionButtonArrivedPos(w, buttonId, true)
|
||||
}
|
||||
|
||||
// 档位变换到达pos2指令
|
||||
// 执行该指令后,按钮处于pos2稳定态
|
||||
func FireTowPositionButtonArrivedPos2(w ecs.World, buttonId string) error {
|
||||
return fireTowPositionButtonArrivedPos(w, buttonId, false)
|
||||
}
|
||||
func fireTowPositionButtonArrivedPos(w ecs.World, buttonId string, arrivedPos1 bool) error {
|
||||
entry := system.QueryEntityById(w, towPosButtonsQuery, buttonId)
|
||||
if nil == entry {
|
||||
return fmt.Errorf("两档位按钮[%s]实体不存在", buttonId)
|
||||
}
|
||||
//
|
||||
state := components.TowPositionButtonStateComponent.Get(entry)
|
||||
if arrivedPos1 {
|
||||
state.Pos1 = true
|
||||
state.Pos2 = false
|
||||
} else {
|
||||
state.Pos1 = false
|
||||
state.Pos2 = true
|
||||
}
|
||||
//
|
||||
return nil
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
)
|
||||
|
||||
// 按钮系统
|
||||
type ButtonSystem struct {
|
||||
}
|
||||
|
||||
// 按钮组件
|
||||
var btnIdCom, btnStaCom, btnPreOperCom, btnConOperCom = components.DeviceIdentityComponent,
|
||||
components.ButtonStateComponent, components.ButtonPressOperatingComponent, components.ButtonConfirmOperatingComponent
|
||||
|
||||
// 查询
|
||||
var btnIdQuery = ecs.NewQuery(filter.Contains(btnIdCom))
|
||||
var btnUpdateQuery = ecs.NewQuery(filter.Contains(btnStaCom, btnPreOperCom, btnConOperCom))
|
||||
|
||||
func NewButtonSystem() *ButtonSystem {
|
||||
return &ButtonSystem{}
|
||||
}
|
||||
|
||||
// 按钮操作
|
||||
func PressDownAndUpButton(w ecs.World, btnId string, down bool) bool {
|
||||
buttonEntry := queryButton(w, btnId)
|
||||
if buttonEntry == nil {
|
||||
return false
|
||||
}
|
||||
t, b := getButtonBaseInfo(btnId)
|
||||
if !buttonEntry.HasComponent(btnPreOperCom) { // 操作组件
|
||||
buttonEntry.AddComponent(btnPreOperCom)
|
||||
}
|
||||
preOper := btnPreOperCom.Get(buttonEntry)
|
||||
preOper.Start, preOper.Down, preOper.NeedConfirm, preOper.OperateTime = true, down, b, t
|
||||
return true
|
||||
}
|
||||
|
||||
// 确认操作
|
||||
func ConfirmButton(w ecs.World, btnId string, confirm bool) bool {
|
||||
buttonEntry := queryButton(w, btnId)
|
||||
if buttonEntry == nil {
|
||||
return false
|
||||
}
|
||||
if !buttonEntry.HasComponent(btnConOperCom) { // 确认组件
|
||||
buttonEntry.AddComponent(btnConOperCom)
|
||||
}
|
||||
conOper := btnConOperCom.Get(buttonEntry)
|
||||
conOper.Confirm, conOper.Cancel = confirm, !confirm
|
||||
return true
|
||||
}
|
||||
|
||||
// 更新按钮状态
|
||||
func (bs *ButtonSystem) Update(w ecs.World) {
|
||||
btnUpdateQuery.Each(w, func(e *ecs.Entry) {
|
||||
if e.HasComponent(btnPreOperCom) {
|
||||
btnPreOper := btnPreOperCom.Get(e)
|
||||
if btnPreOper.Start { // 按钮开始操作
|
||||
if btnPreOper.OperateTime <= 0 { // 按钮操作时间大于0
|
||||
btnPreOper.Start, btnPreOper.OperateTime = false, 0
|
||||
} else {
|
||||
btnPreOper.OperateTime -= int64(w.Tick())
|
||||
if btnPreOper.NeedConfirm {
|
||||
conOper := btnConOperCom.Get(e)
|
||||
if e.HasComponent(btnConOperCom) && (conOper.Cancel || conOper.Confirm) {
|
||||
if conOper.Confirm {
|
||||
btnSta := btnStaCom.Get(e)
|
||||
btnSta.PressDown = btnPreOper.Down
|
||||
}
|
||||
btnPreOper.Start, btnPreOper.OperateTime = false, 0
|
||||
conOper.Cancel, conOper.Confirm = false, false
|
||||
e.RemoveComponent(btnPreOperCom)
|
||||
e.RemoveComponent(btnConOperCom)
|
||||
}
|
||||
} else {
|
||||
btnSta := btnStaCom.Get(e)
|
||||
btnSta.PressDown = btnPreOper.Down
|
||||
btnPreOper.Start, btnPreOper.OperateTime = false, 0
|
||||
e.RemoveComponent(btnPreOperCom)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
e.RemoveComponent(btnPreOperCom)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查找按钮
|
||||
func queryButton(w ecs.World, btnId string) *ecs.Entry {
|
||||
var buttonEntry *ecs.Entry = nil
|
||||
btnIdQuery.Each(w, func(e *ecs.Entry) {
|
||||
if id := btnIdCom.Get(e).Id; id == btnId {
|
||||
buttonEntry = e
|
||||
}
|
||||
})
|
||||
return buttonEntry
|
||||
}
|
||||
|
||||
// 获取按钮设置信息
|
||||
func getButtonBaseInfo(btnId string) (int64, bool) {
|
||||
return 15, false
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
)
|
||||
|
||||
// 调试时显示一些信息
|
||||
type DebugSystem struct {
|
||||
}
|
||||
|
||||
func NewDebugSystem() *DebugSystem {
|
||||
return &DebugSystem{}
|
||||
}
|
||||
|
||||
// world 执行
|
||||
func (me *DebugSystem) Update(w ecs.World) {
|
||||
//debugMovableDevice(w)
|
||||
//debugPsd(w)
|
||||
debugSwitch(w)
|
||||
//debugSignal(w)
|
||||
//debugTowPosButton(w)
|
||||
}
|
||||
|
||||
// 可按速度移动组件
|
||||
func debugMovableDevice(w ecs.World) {
|
||||
query := ecs.NewQuery(filter.Contains(components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent))
|
||||
query.Each(w, func(e *ecs.Entry) {
|
||||
id := components.DeviceIdentityComponent.Get(e).Id
|
||||
if "psd1Cell1" == id {
|
||||
percent := components.PercentageDeviceStateComponent.Get(e)
|
||||
movable := components.MovableDeviceStateComponent.Get(e)
|
||||
fmt.Printf("==>>屏蔽门cell [%s],curRateValue = %d ,targetRateValue = %d , speed = %d position = %d\n", id, percent.Rate, percent.Target, movable.Speed, movable.Position)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 两档位按钮旋钮
|
||||
func debugTowPosButton(w ecs.World) {
|
||||
towPosButtonsQuery := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.TowPositionButtonStateComponent))
|
||||
towPosButtonsQuery.Each(w, func(e *ecs.Entry) {
|
||||
id := components.DeviceIdentityComponent.Get(e).Id
|
||||
state := components.TowPositionButtonStateComponent.Get(e)
|
||||
switch {
|
||||
case state.Pos1 && !state.Pos2:
|
||||
{
|
||||
fmt.Printf("两档位按钮[%s],处于 一 档稳态\n", id)
|
||||
}
|
||||
case !state.Pos1 && state.Pos2:
|
||||
{
|
||||
fmt.Printf("两档位按钮[%s],处于 二 档稳态\n", id)
|
||||
}
|
||||
case !state.Pos1 && !state.Pos2:
|
||||
{
|
||||
fmt.Printf("两档位按钮[%s],处于未知或变换过程中 ......\n", id)
|
||||
}
|
||||
default:
|
||||
{
|
||||
fmt.Printf("两档位按钮[%s],异常同时处于 一二 档 !!\n", id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 屏蔽门状态
|
||||
func debugPsd(w ecs.World) {
|
||||
psdQuery := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.PsdStateComponent, components.PsdTagHandlerComponent))
|
||||
psdQuery.Each(w, func(e *ecs.Entry) {
|
||||
psdId := components.DeviceIdentityComponent.Get(e).Id
|
||||
psdState := components.PsdStateComponent.Get(e)
|
||||
psdTag := components.PsdTagHandlerComponent.Get(e).Tag
|
||||
fmt.Printf("屏蔽门[%s] ,全关=%t ,全开=%t ,互锁解除=%t > ", psdId, psdState.AllClosed, psdState.AllOpened, psdState.InterlockReleased)
|
||||
//
|
||||
psdCellQuery := ecs.NewQuery(filter.Contains(psdTag))
|
||||
psdCellQuery.Each(w, func(e *ecs.Entry) {
|
||||
psdCellId := components.DeviceIdentityComponent.Get(e).Id
|
||||
psdCellPercent := components.PercentageDeviceStateComponent.Get(e)
|
||||
psdCellMovable := components.MovableDeviceStateComponent.Get(e)
|
||||
//
|
||||
fmt.Printf("|| cell[%s] ,closeRate=%d ", psdCellId, GetRate(psdCellPercent.Rate))
|
||||
if psdCellMovable.Speed > 0 {
|
||||
if psdCellMovable.ToH {
|
||||
fmt.Printf("== 关门操作中,移动速率=%d", psdCellMovable.Speed)
|
||||
} else {
|
||||
fmt.Printf("== 开门操作中,移动速率=%d", psdCellMovable.Speed)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
//
|
||||
fmt.Println()
|
||||
})
|
||||
}
|
||||
|
||||
// 显示信号机状态
|
||||
func debugSignal(w ecs.World) {
|
||||
siganlQuery := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.SignalStateComponent))
|
||||
siganlQuery.Each(w, func(e *ecs.Entry) {
|
||||
id := components.DeviceIdentityComponent.Get(e).Id
|
||||
state := components.SignalStateComponent.Get(e)
|
||||
fmt.Printf("==>>信号机[%s],显示=%d\n", id, state.Display)
|
||||
})
|
||||
}
|
||||
|
||||
// 显示道岔状态
|
||||
func debugSwitch(w ecs.World) {
|
||||
switchesQuery := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.SwitchRelayStateComponent))
|
||||
switchesQuery.Each(w, func(e *ecs.Entry) {
|
||||
percent := components.PercentageDeviceStateComponent.Get(e)
|
||||
movable := components.MovableDeviceStateComponent.Get(e)
|
||||
id := components.DeviceIdentityComponent.Get(e).Id
|
||||
curRate := GetRate(percent.Rate)
|
||||
j := components.SwitchRelayStateComponent.Get(e)
|
||||
fmt.Printf("道岔 [%s],当前位置百分比 [%d] ,Dcj = %t, Fcj = %t, Dbj = %t ,Fbj = %t ,", id, curRate, j.DcJ, j.FcJ, j.DbJ, j.FbJ)
|
||||
if movable.Speed > 0 {
|
||||
fmt.Printf(" ==> 正在转动,移动速率[%d]", movable.Speed)
|
||||
}
|
||||
fmt.Println()
|
||||
})
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
)
|
||||
|
||||
// 按速度移动的设备系统
|
||||
// 只负责按速度移动位置,由该组件的观察者负责解释位置
|
||||
type MovableDeviceSystem struct {
|
||||
query *ecs.Query
|
||||
}
|
||||
|
||||
func NewMovableDeviceSystem() *MovableDeviceSystem {
|
||||
return &MovableDeviceSystem{query: ecs.NewQuery(filter.Contains(components.MovableDeviceStateComponent))}
|
||||
}
|
||||
|
||||
// world 执行
|
||||
func (me *MovableDeviceSystem) Update(world ecs.World) {
|
||||
me.query.Each(world, func(e *ecs.Entry) {
|
||||
md := components.MovableDeviceStateComponent.Get(e)
|
||||
if md.Speed > 0 {
|
||||
if md.ToH {
|
||||
md.Position += int64(md.Speed)
|
||||
} else {
|
||||
md.Position -= int64(md.Speed)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
)
|
||||
|
||||
type PercentageDeviceSystem struct {
|
||||
query *ecs.Query
|
||||
}
|
||||
|
||||
func NewPercentageDeviceSystem() *PercentageDeviceSystem {
|
||||
return &PercentageDeviceSystem{query: ecs.NewQuery(filter.Contains(components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent))}
|
||||
}
|
||||
|
||||
const (
|
||||
PercentageRateValueMax int64 = 100000
|
||||
PercentageRateValueMin int64 = 0
|
||||
)
|
||||
const (
|
||||
PercentageRateMax int8 = 100
|
||||
PercentageRateMin int8 = 0
|
||||
)
|
||||
|
||||
// world 执行
|
||||
func (me *PercentageDeviceSystem) Update(world ecs.World) {
|
||||
me.query.Each(world, func(e *ecs.Entry) {
|
||||
movable := components.MovableDeviceStateComponent.Get(e)
|
||||
if movable.Speed > 0 {
|
||||
percentage := components.PercentageDeviceStateComponent.Get(e)
|
||||
if movable.ToH {
|
||||
if movable.Position >= percentage.Target {
|
||||
movable.Speed = 0
|
||||
movable.Position = percentage.Target
|
||||
}
|
||||
} else {
|
||||
if movable.Position <= percentage.Target {
|
||||
movable.Speed = 0
|
||||
movable.Position = percentage.Target
|
||||
}
|
||||
}
|
||||
//
|
||||
percentage.Rate = movable.Position
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 映射百分比到大数值
|
||||
func GetRateValue(rate int8) int64 {
|
||||
return int64(float64(float32(rate)/float32(100)) * float64(PercentageRateValueMax))
|
||||
}
|
||||
|
||||
// 大数值映射到百分比
|
||||
func GetRate(rateValue int64) int8 {
|
||||
return int8((float64(rateValue) / float64(PercentageRateValueMax)) * float64(100))
|
||||
}
|
||||
|
||||
// 比率值变动速率计算
|
||||
func CalculateRateSpeed(tick int32, lhDistance int64) int32 {
|
||||
return int32(float64(tick) * (float64(PercentageRateValueMax) / float64(lhDistance)))
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/components/cstate"
|
||||
)
|
||||
|
||||
var PsdQuery = ecs.NewQuery(filter.Contains(components.PsdStateComponent, components.PsdTagHandlerComponent))
|
||||
|
||||
const (
|
||||
//屏蔽门完全关闭
|
||||
PsdCellWholeCloseValue = PercentageRateValueMax
|
||||
//屏蔽门完全打开
|
||||
PsdCellWholeOpenValue = PercentageRateValueMin
|
||||
)
|
||||
|
||||
type PsdSystem struct {
|
||||
cellsQuery map[cstate.EntityTag]*ecs.Query
|
||||
}
|
||||
|
||||
func NewPsdSystem() *PsdSystem {
|
||||
return &PsdSystem{cellsQuery: make(map[cstate.EntityTag]*ecs.Query)}
|
||||
}
|
||||
|
||||
// world 执行
|
||||
func (me *PsdSystem) Update(world ecs.World) {
|
||||
PsdQuery.Each(world, func(psdEntry *ecs.Entry) {
|
||||
psdTag := components.PsdTagHandlerComponent.Get(psdEntry).Tag
|
||||
psdCellQuery, ok := me.cellsQuery[psdTag]
|
||||
if !ok {
|
||||
psdCellQuery = ecs.NewQuery(filter.Contains(psdTag, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent))
|
||||
me.cellsQuery[psdTag] = psdCellQuery
|
||||
}
|
||||
//
|
||||
var allCellClosed, allCellOpened bool = true, true
|
||||
psdCellQuery.Each(world, func(psdCellEntry *ecs.Entry) {
|
||||
psdCellRate := components.PercentageDeviceStateComponent.Get(psdCellEntry).Rate
|
||||
if allCellClosed {
|
||||
allCellClosed = psdCellRate == PsdCellWholeCloseValue
|
||||
}
|
||||
if allCellOpened {
|
||||
allCellOpened = psdCellRate == PsdCellWholeOpenValue
|
||||
}
|
||||
})
|
||||
//
|
||||
psdState := components.PsdStateComponent.Get(psdEntry)
|
||||
psdState.AllClosed = allCellClosed
|
||||
psdState.AllOpened = allCellOpened
|
||||
})
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
var SwitchQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.SwitchRelayStateComponent, components.PercentageDeviceStateComponent))
|
||||
|
||||
const (
|
||||
//道岔定位
|
||||
SwitchNormalVaule int64 = PercentageRateValueMin
|
||||
//道岔反位
|
||||
SwitchReverseValue int64 = PercentageRateValueMax
|
||||
)
|
||||
|
||||
// 道岔系统操作
|
||||
type SwitchSystem struct {
|
||||
}
|
||||
|
||||
func NewSwitchSystem() *SwitchSystem {
|
||||
return &SwitchSystem{}
|
||||
}
|
||||
|
||||
// world 执行
|
||||
func (me *SwitchSystem) Update(w ecs.World) {
|
||||
//根据定操反操继电器来设置道岔转动参数
|
||||
SwitchQuery.Each(w, func(e *ecs.Entry) {
|
||||
relay := components.SwitchRelayStateComponent.Get(e)
|
||||
if relay.DcJ || relay.FcJ {
|
||||
movable := components.MovableDeviceStateComponent.Get(e)
|
||||
percent := components.PercentageDeviceStateComponent.Get(e)
|
||||
switchId := components.DeviceIdentityComponent.Get(e).Id
|
||||
if relay.DcJ {
|
||||
movable.ToH = false
|
||||
percent.Target = SwitchNormalVaule
|
||||
}
|
||||
if relay.FcJ {
|
||||
movable.ToH = true
|
||||
percent.Target = SwitchReverseValue
|
||||
}
|
||||
movable.Speed = CalculateRateSpeed(int32(w.Tick()), getSwitchTurnTime(w, switchId))
|
||||
}
|
||||
})
|
||||
//观察道岔百分比组件来更新道岔逻辑继电器状态
|
||||
SwitchQuery.Each(w, func(e *ecs.Entry) {
|
||||
switchPercent := components.PercentageDeviceStateComponent.Get(e)
|
||||
switchRelay := components.SwitchRelayStateComponent.Get(e)
|
||||
if switchPercent.Rate == switchPercent.Target {
|
||||
switchRelay.DcJ = false
|
||||
switchRelay.FcJ = false
|
||||
switchRelay.DbJ = switchPercent.Rate <= SwitchNormalVaule
|
||||
switchRelay.FbJ = switchPercent.Rate >= SwitchReverseValue
|
||||
} else {
|
||||
switchRelay.DbJ = false
|
||||
switchRelay.FbJ = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取道岔转动耗时ms
|
||||
func getSwitchTurnTime(world ecs.World, switchId string) int64 {
|
||||
dcModel := WorldModelStorage(world).FindById(switchId)
|
||||
var dc umi.ISwitchModel = dcModel.(umi.ISwitchModel)
|
||||
return dc.TurningTime()
|
||||
}
|
@ -3,14 +3,22 @@ package system
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yohamta/donburi/component"
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
"joylink.club/rtsssimulation/umi"
|
||||
)
|
||||
|
||||
// 实体身份定义
|
||||
type EntityIdentity struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
// 实体身份组件
|
||||
var EntityIdentityComponent = ecs.NewComponentType[EntityIdentity]()
|
||||
|
||||
func FindEntityById(world ecs.World, id string) *ecs.Entry {
|
||||
query := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent))
|
||||
query := ecs.NewQuery(filter.Contains(EntityIdentityComponent))
|
||||
return QueryEntityById(world, query, id)
|
||||
}
|
||||
func QueryEntityById(world ecs.World, q *ecs.Query, id string) *ecs.Entry {
|
||||
@ -18,7 +26,7 @@ func QueryEntityById(world ecs.World, q *ecs.Query, id string) *ecs.Entry {
|
||||
func() {
|
||||
defer simpleRecover()
|
||||
q.Each(world, func(e *ecs.Entry) {
|
||||
if id == components.DeviceIdentityComponent.Get(e).Id {
|
||||
if id == EntityIdentityComponent.Get(e).Id {
|
||||
entry = e
|
||||
panic(fmt.Sprintf("找到实体[%s],结束查找", id))
|
||||
}
|
||||
@ -33,33 +41,19 @@ func simpleRecover() {
|
||||
recover()
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// 模型仓库查询
|
||||
var worldModelStorageQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.ModelStorageRefComponent))
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
func WorldModelStorage(world ecs.World) umi.IModelManager {
|
||||
e, ok := worldModelStorageQuery.First(world)
|
||||
if ok {
|
||||
return components.ModelStorageRefComponent.Get(e).ModelManager
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
// 实体标签
|
||||
type EntityTag = component.IComponentType
|
||||
|
||||
type EntityTagHandler struct {
|
||||
Tag EntityTag
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////
|
||||
// 继电器系统
|
||||
type relaySystem struct {
|
||||
// key-设备id
|
||||
relayQuery map[string]*ecs.Query
|
||||
}
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
// 获取设备的相关继电器的查询
|
||||
func (me *relaySystem) getDeviceRelayQuery(deviceEntry *ecs.Entry) *ecs.Query {
|
||||
id := components.DeviceIdentityComponent.Get(deviceEntry).Id
|
||||
query, ok := me.relayQuery[id]
|
||||
if !ok {
|
||||
query = ecs.NewQuery(filter.Contains(components.RelayTagHandlerComponent.Get(deviceEntry).Tag))
|
||||
me.relayQuery[id] = query
|
||||
}
|
||||
return query
|
||||
// 模型仓库引用
|
||||
// 用于world内使用,查询模型
|
||||
type ModelStorageRef struct {
|
||||
ModelManager umi.IModelManager
|
||||
}
|
||||
|
@ -5,10 +5,11 @@ import (
|
||||
|
||||
"github.com/yohamta/donburi/filter"
|
||||
"joylink.club/ecs"
|
||||
"joylink.club/rtsssimulation/components"
|
||||
)
|
||||
|
||||
var timerQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.SystemTimerComponent))
|
||||
var SystemTimerComponent = ecs.NewComponentType[SystemTimer]()
|
||||
|
||||
var timerQuery *ecs.Query = ecs.NewQuery(filter.Contains(SystemTimerComponent))
|
||||
|
||||
// 系统时钟操作
|
||||
type TimerSystem struct {
|
||||
@ -21,7 +22,7 @@ func NewTimerSystem() *TimerSystem {
|
||||
// world 执行
|
||||
func (me *TimerSystem) Update(w ecs.World) {
|
||||
if e, ok := timerQuery.First(w); ok {
|
||||
timer := components.SystemTimerComponent.Get(e)
|
||||
timer := SystemTimerComponent.Get(e)
|
||||
timer.Tick(w.Tick())
|
||||
}
|
||||
}
|
||||
@ -29,7 +30,7 @@ func (me *TimerSystem) Update(w ecs.World) {
|
||||
// 重置world时间
|
||||
func ResetWorldTimer(w ecs.World, time time.Time) {
|
||||
if e, ok := timerQuery.First(w); ok {
|
||||
timer := components.SystemTimerComponent.Get(e)
|
||||
timer := SystemTimerComponent.Get(e)
|
||||
timer.ResetTime(time)
|
||||
}
|
||||
}
|
||||
@ -37,9 +38,38 @@ func ResetWorldTimer(w ecs.World, time time.Time) {
|
||||
// 获取world当前时间
|
||||
func GetWorldNow(w ecs.World) *time.Time {
|
||||
if e, ok := timerQuery.First(w); ok {
|
||||
timer := components.SystemTimerComponent.Get(e)
|
||||
timer := SystemTimerComponent.Get(e)
|
||||
now := timer.Now()
|
||||
return &now
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// 系统时钟,单例
|
||||
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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user