ecs测试--id组件
This commit is contained in:
parent
f803324cf4
commit
a6dc0c0023
@ -53,3 +53,8 @@ type LinkLocation struct {
|
|||||||
LinkId string
|
LinkId string
|
||||||
LinkOffset int64
|
LinkOffset int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//id组件数据定义
|
||||||
|
type IdData struct {
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
@ -35,10 +35,10 @@ import (
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
func main() {
|
func main() {
|
||||||
//
|
// 构建固定模型
|
||||||
|
initMemoryModel()
|
||||||
|
// 创建一个仿真实例
|
||||||
simWorld := ecs.NewWorld(300)
|
simWorld := ecs.NewWorld(300)
|
||||||
//
|
|
||||||
initMemoryModel(simWorld)
|
|
||||||
//道岔
|
//道岔
|
||||||
initSwitchState(simWorld)
|
initSwitchState(simWorld)
|
||||||
//轨道
|
//轨道
|
||||||
@ -63,21 +63,18 @@ func main() {
|
|||||||
|
|
||||||
// 根据道岔id来搬动道岔
|
// 根据道岔id来搬动道岔
|
||||||
func operateSwitch(world ecs.World, dcId string) {
|
func operateSwitch(world ecs.World, dcId string) {
|
||||||
query := ecs.NewQuery(filter.Contains(simulation.ComSwitchState, simulation.ComSwitchOperating))
|
query := ecs.NewQuery(filter.Contains(simulation.ComId, simulation.ComSwitchState, simulation.ComSwitchOperating))
|
||||||
query.Each(world, func(e *ecs.Entry) {
|
query.Each(world, func(e *ecs.Entry) {
|
||||||
dcState := simulation.ComSwitchState.Get(e)
|
idData := simulation.ComId.Get(e)
|
||||||
if dcState.Id == dcId {
|
if idData.Id == dcId {
|
||||||
simulation.ComSwitchOperating.SetValue(e, state.SwitchOperating{EnableStart: true, StartTime: time.Now()})
|
simulation.ComSwitchOperating.SetValue(e, state.SwitchOperating{EnableStart: true, StartTime: time.Now()})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化memory
|
// 初始化memory
|
||||||
func initMemoryModel(world ecs.World) {
|
func initMemoryModel() {
|
||||||
memoryEntry := world.Create(simulation.ComSimMemory)
|
simMemory := simulation.ModelsMemory
|
||||||
//simulation.ComSimMemory.SetValue(memoryEntry, *simulation.NewSimMemory())
|
|
||||||
simMemory := simulation.NewSimMemory()
|
|
||||||
simulation.ComSimMemory.Set(memoryEntry, simMemory)
|
|
||||||
createSkeletonModelsRelation(simMemory)
|
createSkeletonModelsRelation(simMemory)
|
||||||
createKilometerSignModelsRelation(simMemory)
|
createKilometerSignModelsRelation(simMemory)
|
||||||
createPhsicalSectionModelsRelation(simMemory)
|
createPhsicalSectionModelsRelation(simMemory)
|
||||||
@ -85,17 +82,18 @@ func initMemoryModel(world ecs.World) {
|
|||||||
|
|
||||||
// 初始化道岔状态
|
// 初始化道岔状态
|
||||||
func initSwitchState(world ecs.World) {
|
func initSwitchState(world ecs.World) {
|
||||||
simMemory := simulation.GetMemoryModel(world)
|
simMemory := simulation.ModelsMemory
|
||||||
for _, switchModel := range simMemory.Switchs {
|
for _, switchModel := range simMemory.Switchs {
|
||||||
dc1 := &state.SwitchState{Id: switchModel.GetId(), Normal: true, Reverse: false}
|
dc1 := &state.SwitchState{Normal: true, Reverse: false}
|
||||||
dc1Entry := world.Create(simulation.ComSwitchState, simulation.ComSwitchOperating)
|
dc1Entry := world.Create(simulation.ComId, simulation.ComSwitchState, simulation.ComSwitchOperating)
|
||||||
simulation.ComSwitchState.Set(dc1Entry, dc1)
|
simulation.ComSwitchState.Set(dc1Entry, dc1)
|
||||||
|
simulation.ComId.Set(dc1Entry, &iwayside.IdData{Id: switchModel.GetId()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化轨道状态
|
// 初始化轨道状态
|
||||||
func initLinkState(world ecs.World) {
|
func initLinkState(world ecs.World) {
|
||||||
simMemory := simulation.GetMemoryModel(world)
|
simMemory := simulation.ModelsMemory
|
||||||
for _, linkModel := range simMemory.Links {
|
for _, linkModel := range simMemory.Links {
|
||||||
linkState := &state.LinkState{Id: linkModel.GetId(), Occupied: false}
|
linkState := &state.LinkState{Id: linkModel.GetId(), Occupied: false}
|
||||||
linkEntry := world.Create(simulation.ComLinkState)
|
linkEntry := world.Create(simulation.ComLinkState)
|
||||||
@ -105,19 +103,21 @@ func initLinkState(world ecs.World) {
|
|||||||
|
|
||||||
// 初始化物理区段状态
|
// 初始化物理区段状态
|
||||||
func initPhsicalSectionState(world ecs.World) {
|
func initPhsicalSectionState(world ecs.World) {
|
||||||
simMemory := simulation.GetMemoryModel(world)
|
simMemory := simulation.ModelsMemory
|
||||||
for _, phSecModel := range simMemory.PhysicalSections {
|
for _, phSecModel := range simMemory.PhysicalSections {
|
||||||
sectionState := &state.PhysicalSectionState{Id: phSecModel.GetId(), Occupied: false}
|
sectionState := &state.PhysicalSectionState{Occupied: false}
|
||||||
sectionEntry := world.Create(simulation.ComPhsicalSectionState)
|
sectionEntry := world.Create(simulation.ComId, simulation.ComPhsicalSectionState)
|
||||||
simulation.ComPhsicalSectionState.Set(sectionEntry, sectionState)
|
simulation.ComPhsicalSectionState.Set(sectionEntry, sectionState)
|
||||||
|
simulation.ComId.Set(sectionEntry, &iwayside.IdData{Id: phSecModel.GetId()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加列车并初始化
|
// 添加列车并初始化
|
||||||
func initTrainState(world ecs.World, trainId string, linkLocation iwayside.LinkLocation, up bool) {
|
func initTrainState(world ecs.World, trainId string, linkLocation iwayside.LinkLocation, up bool) {
|
||||||
train := &state.TrainState{Id: trainId, LinkId: linkLocation.LinkId, LinkOffset: linkLocation.LinkOffset, Up: up}
|
train := &state.TrainState{LinkId: linkLocation.LinkId, LinkOffset: linkLocation.LinkOffset, Up: up}
|
||||||
trainEntry := world.Create(simulation.ComTrainState)
|
trainEntry := world.Create(simulation.ComId, simulation.ComTrainState)
|
||||||
simulation.ComTrainState.Set(trainEntry, train)
|
simulation.ComTrainState.Set(trainEntry, train)
|
||||||
|
simulation.ComId.Set(trainEntry, &iwayside.IdData{Id: trainId})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 固定关系:构建骨架模型关系,即长link与道岔的连接关系
|
// 固定关系:构建骨架模型关系,即长link与道岔的连接关系
|
||||||
|
@ -2,9 +2,13 @@ package simulation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"joylink.club/ecs"
|
"joylink.club/ecs"
|
||||||
|
"joylink.club/ecs/examples/rtss-cg/iwayside"
|
||||||
"joylink.club/ecs/examples/rtss-cg/state"
|
"joylink.club/ecs/examples/rtss-cg/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// id组件
|
||||||
|
var ComId = ecs.NewComponentType[iwayside.IdData]()
|
||||||
|
|
||||||
// 道岔状态组件
|
// 道岔状态组件
|
||||||
var ComSwitchState = ecs.NewComponentType[state.SwitchState]()
|
var ComSwitchState = ecs.NewComponentType[state.SwitchState]()
|
||||||
var ComSwitchOperating = ecs.NewComponentType[state.SwitchOperating]()
|
var ComSwitchOperating = ecs.NewComponentType[state.SwitchOperating]()
|
||||||
@ -17,6 +21,3 @@ var ComPhsicalSectionState = ecs.NewComponentType[state.PhysicalSectionState]()
|
|||||||
|
|
||||||
// 列车状态组件
|
// 列车状态组件
|
||||||
var ComTrainState = ecs.NewComponentType[state.TrainState]()
|
var ComTrainState = ecs.NewComponentType[state.TrainState]()
|
||||||
|
|
||||||
// 仿真模型组件
|
|
||||||
var ComSimMemory = ecs.NewComponentType[SimMemory]()
|
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
package simulation
|
package simulation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/yohamta/donburi/component"
|
|
||||||
"github.com/yohamta/donburi/filter"
|
|
||||||
"joylink.club/ecs"
|
|
||||||
"joylink.club/ecs/examples/rtss-cg/iwayside"
|
"joylink.club/ecs/examples/rtss-cg/iwayside"
|
||||||
"joylink.club/ecs/examples/rtss-cg/mwayside"
|
"joylink.club/ecs/examples/rtss-cg/mwayside"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 模型数据全局一份,多个仿真实例共用
|
||||||
|
var ModelsMemory *SimMemory
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ModelsMemory = newSimMemory()
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
|
||||||
type SimMemory struct {
|
type SimMemory struct {
|
||||||
Links map[string]iwayside.ILinkModel
|
Links map[string]iwayside.ILinkModel
|
||||||
Switchs map[string]iwayside.ISwitchModel
|
Switchs map[string]iwayside.ISwitchModel
|
||||||
@ -15,7 +21,7 @@ type SimMemory struct {
|
|||||||
PhysicalSections map[string]iwayside.IPhysicalSectionModel
|
PhysicalSections map[string]iwayside.IPhysicalSectionModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSimMemory() *SimMemory {
|
func newSimMemory() *SimMemory {
|
||||||
return &SimMemory{
|
return &SimMemory{
|
||||||
Links: make(map[string]iwayside.ILinkModel),
|
Links: make(map[string]iwayside.ILinkModel),
|
||||||
Switchs: make(map[string]iwayside.ISwitchModel),
|
Switchs: make(map[string]iwayside.ISwitchModel),
|
||||||
@ -24,13 +30,6 @@ func NewSimMemory() *SimMemory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMemoryModel(world ecs.World) *SimMemory {
|
|
||||||
if memoryEntry, ok := ecs.NewQuery(filter.Exact([]component.IComponentType{ComSimMemory})).First(world); ok {
|
|
||||||
return ComSimMemory.Get(memoryEntry)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将列车轨道位置偏移转换为公里标,道岔处用投影近似
|
// 将列车轨道位置偏移转换为公里标,道岔处用投影近似
|
||||||
func (me *SimMemory) LinkOffsetToKilometerSign(linkId string, linkOffset int64) int64 {
|
func (me *SimMemory) LinkOffsetToKilometerSign(linkId string, linkOffset int64) int64 {
|
||||||
link := me.Links[linkId].(*mwayside.LinkModel)
|
link := me.Links[linkId].(*mwayside.LinkModel)
|
||||||
|
@ -2,8 +2,6 @@ package state
|
|||||||
|
|
||||||
//物理区段状态
|
//物理区段状态
|
||||||
type PhysicalSectionState struct {
|
type PhysicalSectionState struct {
|
||||||
//区段id
|
|
||||||
Id string
|
|
||||||
//是否有车占用
|
//是否有车占用
|
||||||
Occupied bool
|
Occupied bool
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import "time"
|
|||||||
|
|
||||||
//道岔状态
|
//道岔状态
|
||||||
type SwitchState struct {
|
type SwitchState struct {
|
||||||
Id string
|
|
||||||
Normal bool
|
Normal bool
|
||||||
Reverse bool
|
Reverse bool
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ package state
|
|||||||
|
|
||||||
//列车状态
|
//列车状态
|
||||||
type TrainState struct {
|
type TrainState struct {
|
||||||
//列车id
|
|
||||||
Id string
|
|
||||||
//列车所在linkid
|
//列车所在linkid
|
||||||
LinkId string
|
LinkId string
|
||||||
//列车在link上的偏移量(A端为起点)
|
//列车在link上的偏移量(A端为起点)
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"joylink.club/ecs/examples/rtss-cg/iwayside"
|
"joylink.club/ecs/examples/rtss-cg/iwayside"
|
||||||
"joylink.club/ecs/examples/rtss-cg/mwayside"
|
"joylink.club/ecs/examples/rtss-cg/mwayside"
|
||||||
"joylink.club/ecs/examples/rtss-cg/simulation"
|
"joylink.club/ecs/examples/rtss-cg/simulation"
|
||||||
"joylink.club/ecs/examples/rtss-cg/state"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 物理区段状态检测
|
// 物理区段状态检测
|
||||||
@ -22,12 +21,12 @@ type SectionSystem struct {
|
|||||||
|
|
||||||
func NewSectionSystem() *SectionSystem {
|
func NewSectionSystem() *SectionSystem {
|
||||||
return &SectionSystem{
|
return &SectionSystem{
|
||||||
trainQuery: ecs.NewQuery(filter.Contains(simulation.ComTrainState)),
|
trainQuery: ecs.NewQuery(filter.Contains(simulation.ComId, simulation.ComTrainState)),
|
||||||
sectionQuery: ecs.NewQuery(filter.Contains(simulation.ComPhsicalSectionState)),
|
sectionQuery: ecs.NewQuery(filter.Contains(simulation.ComId, simulation.ComPhsicalSectionState)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (me *SectionSystem) Update(w ecs.World) {
|
func (me *SectionSystem) Update(w ecs.World) {
|
||||||
memory := simulation.GetMemoryModel(w)
|
memory := simulation.ModelsMemory
|
||||||
//收集轨道占用点
|
//收集轨道占用点
|
||||||
var standPoints []*standingPoint
|
var standPoints []*standingPoint
|
||||||
me.trainQuery.Each(w, func(e *ecs.Entry) {
|
me.trainQuery.Each(w, func(e *ecs.Entry) {
|
||||||
@ -36,23 +35,25 @@ func (me *SectionSystem) Update(w ecs.World) {
|
|||||||
})
|
})
|
||||||
//物理区段状态
|
//物理区段状态
|
||||||
me.sectionQuery.Each(w, func(e *ecs.Entry) {
|
me.sectionQuery.Each(w, func(e *ecs.Entry) {
|
||||||
|
sectionId := simulation.ComId.Get(e).Id
|
||||||
sectionState := simulation.ComPhsicalSectionState.Get(e)
|
sectionState := simulation.ComPhsicalSectionState.Get(e)
|
||||||
sectionState.Occupied = checkOccupy(memory, standPoints, sectionState)
|
sectionState.Occupied = checkOccupy(memory, standPoints, sectionId)
|
||||||
})
|
})
|
||||||
//
|
//
|
||||||
sb := &strings.Builder{}
|
sb := &strings.Builder{}
|
||||||
me.sectionQuery.Each(w, func(e *ecs.Entry) {
|
me.sectionQuery.Each(w, func(e *ecs.Entry) {
|
||||||
|
sectionId := simulation.ComId.Get(e).Id
|
||||||
sectionState := simulation.ComPhsicalSectionState.Get(e)
|
sectionState := simulation.ComPhsicalSectionState.Get(e)
|
||||||
sb.WriteString(fmt.Sprintf("区段[%s]占用[%t] ||", sectionState.Id, sectionState.Occupied))
|
sb.WriteString(fmt.Sprintf("区段[%s]占用[%t] ||", sectionId, sectionState.Occupied))
|
||||||
})
|
})
|
||||||
fmt.Println("==>>", sb.String())
|
fmt.Println("==>>", sb.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断物理区段是否有列车占用
|
// 判断物理区段是否有列车占用
|
||||||
func checkOccupy(memory *simulation.SimMemory, standPoints []*standingPoint, sectionState *state.PhysicalSectionState) bool {
|
func checkOccupy(memory *simulation.SimMemory, standPoints []*standingPoint, sectionId string) bool {
|
||||||
occupied := false
|
occupied := false
|
||||||
//
|
//
|
||||||
sectionModel := memory.PhysicalSections[sectionState.Id].(*mwayside.PhysicalSectionModel)
|
sectionModel := memory.PhysicalSections[sectionId].(*mwayside.PhysicalSectionModel)
|
||||||
for _, standPoint := range standPoints {
|
for _, standPoint := range standPoints {
|
||||||
if occupied = containsPoint(sectionModel, standPoint); occupied {
|
if occupied = containsPoint(sectionModel, standPoint); occupied {
|
||||||
break
|
break
|
||||||
|
@ -16,8 +16,9 @@ type SwitchSystem struct {
|
|||||||
|
|
||||||
func (me *SwitchSystem) Update(w ecs.World) {
|
func (me *SwitchSystem) Update(w ecs.World) {
|
||||||
me.ComQuery.Each(w, func(e *ecs.Entry) {
|
me.ComQuery.Each(w, func(e *ecs.Entry) {
|
||||||
|
switchId := simulation.ComId.Get(e).Id
|
||||||
state := simulation.ComSwitchState.Get(e)
|
state := simulation.ComSwitchState.Get(e)
|
||||||
fmt.Printf("==>>当前状态:道岔id=%s 定位=%t 反位=%t ", state.Id, state.Normal, state.Reverse)
|
fmt.Printf("==>>当前状态:道岔id=%s 定位=%t 反位=%t ", switchId, state.Normal, state.Reverse)
|
||||||
opt := simulation.ComSwitchOperating.Get(e)
|
opt := simulation.ComSwitchOperating.Get(e)
|
||||||
if nil != opt && opt.EnableStart {
|
if nil != opt && opt.EnableStart {
|
||||||
if time.Duration(time.Now().Second()-opt.StartTime.Second()) <= 4 {
|
if time.Duration(time.Now().Second()-opt.StartTime.Second()) <= 4 {
|
||||||
@ -35,7 +36,7 @@ func (me *SwitchSystem) Update(w ecs.World) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
func NewSwitchSystem() *SwitchSystem {
|
func NewSwitchSystem() *SwitchSystem {
|
||||||
return &SwitchSystem{ComQuery: ecs.NewQuery(filter.Contains(simulation.ComSwitchOperating))}
|
return &SwitchSystem{ComQuery: ecs.NewQuery(filter.Contains(simulation.ComId, simulation.ComSwitchOperating))}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断点是否在该物理区段内
|
// 判断点是否在该物理区段内
|
||||||
|
@ -19,8 +19,9 @@ type TrainSystem struct {
|
|||||||
// 模拟列车运行,更新列车位置
|
// 模拟列车运行,更新列车位置
|
||||||
func (me *TrainSystem) Update(w ecs.World) {
|
func (me *TrainSystem) Update(w ecs.World) {
|
||||||
me.ComTrainQuery.Each(w, func(e *ecs.Entry) {
|
me.ComTrainQuery.Each(w, func(e *ecs.Entry) {
|
||||||
|
trainId := simulation.ComId.Get(e)
|
||||||
train := simulation.ComTrainState.Get(e)
|
train := simulation.ComTrainState.Get(e)
|
||||||
fmt.Println("==>>列车 id = ", train.Id, " linkId = ", train.LinkId, " offset = ", train.LinkOffset, " up = ", train.Up)
|
fmt.Println("==>>列车 id = ", trainId.Id, " linkId = ", train.LinkId, " offset = ", train.LinkOffset, " up = ", train.Up)
|
||||||
curLink := findTrainLinkModel(w, train.LinkId)
|
curLink := findTrainLinkModel(w, train.LinkId)
|
||||||
var offset int64 = train.LinkOffset + func() int64 {
|
var offset int64 = train.LinkOffset + func() int64 {
|
||||||
//列车一个循环移动1m
|
//列车一个循环移动1m
|
||||||
@ -42,7 +43,7 @@ func (me *TrainSystem) Update(w ecs.World) {
|
|||||||
train.LinkOffset = nextLink.Len
|
train.LinkOffset = nextLink.Len
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("==>>列车 id = ", train.Id, " , 路到尽头")
|
fmt.Println("==>>列车 id = ", trainId.Id, " , 路到尽头")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,24 +146,25 @@ func findNextLink(w ecs.World, ts *TrainSystem, curLink *mwayside.LinkModel, up
|
|||||||
func findSwitchModel(w ecs.World, ts *TrainSystem, switchId string) (*state.SwitchState, *mwayside.SwitchModel) {
|
func findSwitchModel(w ecs.World, ts *TrainSystem, switchId string) (*state.SwitchState, *mwayside.SwitchModel) {
|
||||||
var dcState *state.SwitchState = nil
|
var dcState *state.SwitchState = nil
|
||||||
ts.ComSwitchQuery.Each(w, func(e *ecs.Entry) {
|
ts.ComSwitchQuery.Each(w, func(e *ecs.Entry) {
|
||||||
|
idData := simulation.ComId.Get(e)
|
||||||
switchState := simulation.ComSwitchState.Get(e)
|
switchState := simulation.ComSwitchState.Get(e)
|
||||||
if switchState.Id == switchId {
|
if idData.Id == switchId {
|
||||||
dcState = switchState
|
dcState = switchState
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if nil == dcState {
|
if nil == dcState {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return dcState, simulation.GetMemoryModel(w).Switchs[dcState.Id].(*mwayside.SwitchModel)
|
return dcState, simulation.ModelsMemory.Switchs[switchId].(*mwayside.SwitchModel)
|
||||||
}
|
}
|
||||||
func NewTrainSystem() *TrainSystem {
|
func NewTrainSystem() *TrainSystem {
|
||||||
return &TrainSystem{
|
return &TrainSystem{
|
||||||
ComTrainQuery: ecs.NewQuery(filter.Contains(simulation.ComTrainState)),
|
ComTrainQuery: ecs.NewQuery(filter.Contains(simulation.ComId, simulation.ComTrainState)),
|
||||||
ComSwitchQuery: ecs.NewQuery(filter.Contains(simulation.ComSwitchState)),
|
ComSwitchQuery: ecs.NewQuery(filter.Contains(simulation.ComId, simulation.ComSwitchState)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取列车当前所在轨道
|
// 获取列车当前所在轨道
|
||||||
func findTrainLinkModel(w ecs.World, linkId string) *mwayside.LinkModel {
|
func findTrainLinkModel(w ecs.World, linkId string) *mwayside.LinkModel {
|
||||||
return simulation.GetMemoryModel(w).Links[linkId].(*mwayside.LinkModel)
|
return simulation.ModelsMemory.Links[linkId].(*mwayside.LinkModel)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user