rts-sim-module/creator/init_simulation.go
2023-08-29 16:22:39 +08:00

157 lines
6.5 KiB
Go

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
}