package system import ( "github.com/yohamta/donburi/filter" "joylink.club/ecs" "joylink.club/rtsssimulation/components" "joylink.club/rtsssimulation/state" ) var psdQuery = ecs.NewQuery(filter.Contains(components.ComDeviceIdentity, components.ComPsdState, components.ComEntityTagHandler)) type PsdSystem struct { psdTagMap map[state.EntityTag][]*ecs.Query } func NewPsdSystem() *PsdSystem { return &PsdSystem{ psdTagMap: make(map[state.EntityTag][]*ecs.Query), } } // world 执行 func (me *PsdSystem) Update(world ecs.World) { me.updatePsdCell(world) me.updatePsd(world) } // 车站单侧屏蔽门 func (me *PsdSystem) updatePsd(world ecs.World) { psdQuery.Each(world, func(e *ecs.Entry) { psdTag := components.ComEntityTagHandler.Get(e).Tag _, ok := me.psdTagMap[psdTag] if !ok { me.psdTagMap[psdTag] = make([]*ecs.Query, 2) //psd的所有cell查询 psdCellQuery := ecs.NewQuery(filter.Contains(psdTag)) me.psdTagMap[psdTag][0] = psdCellQuery //psd的所有cell中的操作查询 psdCellOperateQuery := ecs.NewQuery(filter.Contains(psdTag, components.ComPsdCellOperating)) me.psdTagMap[psdTag][1] = psdCellOperateQuery } var allClosed bool = true var allOpened bool = true me.psdTagMap[psdTag][0].Each(world, func(e *ecs.Entry) { cellState := components.ComPsdCellState.Get(e) if allClosed { if cellState.CloseRate < 100 { allClosed = false } } if allOpened { if cellState.CloseRate > 0 { allOpened = false } } }) // psdState := components.ComPsdState.Get(e) psdState.AllClosed = allClosed psdState.AllOpened = allOpened }) } const ( //把时间映射到距离,1000ms<=>1000mm //注意距离不是门的真实宽度,仅用于门开关相关计算 //门移动最大路程3000mm pSD_CELL_LEN = 3000 //cell门移动速度,单位mm/ms pSD_CELL_MOVE_SPEED = 1 ) // 单个门 func (me *PsdSystem) updatePsdCell(world ecs.World) { for _, psdTagQueries := range me.psdTagMap { //遍历某个车站单侧的所有单个门的操作 psdTagQueries[1].Each(world, func(e *ecs.Entry) { if psdCellOpt := components.ComPsdCellOperating.Get(e); psdCellOpt.Start { psdCellState := components.ComPsdCellState.Get(e) if psdCellOpt.RemainingDistance <= 0 { psdCellOpt.Start = false psdCellOpt.RemainingDistance = 0 e.RemoveComponent(components.ComPsdCellOperating) } else { psdCellOpt.RemainingDistance -= int64(pSD_CELL_MOVE_SPEED * world.Tick()) } // if psdCellOpt.CloseOperate { psdCellState.CloseRate = int32((float32(psdCellOpt.InitDistance+psdCellOpt.SumDistance-psdCellOpt.RemainingDistance) / float32(pSD_CELL_LEN)) * 100) } else { psdCellState.CloseRate = 100 - int32((float32(psdCellOpt.InitDistance+psdCellOpt.SumDistance-psdCellOpt.RemainingDistance)/float32(pSD_CELL_LEN))*100) } } }) } } // 车站单侧屏蔽门互锁解除操作 func FirePsdInterlockRelease(world ecs.World, psdId string, lockRelease bool) bool { var psdEntry *ecs.Entry = nil psdQuery.Each(world, func(e *ecs.Entry) { if psdId == components.ComDeviceIdentity.Get(e).Id { psdEntry = e } }) // if psdEntry == nil { return false } components.ComPsdState.Get(psdEntry).InterlockReleased = lockRelease // return true } // 车站单侧屏蔽门操作 // closeOpt true-关门操作,false-开门操作 func FirePsdMove(world ecs.World, psdId string, closeOpt bool) bool { var psdEntry *ecs.Entry = nil psdQuery.Each(world, func(e *ecs.Entry) { if psdId == components.ComDeviceIdentity.Get(e).Id { psdEntry = e } }) // if psdEntry == nil { return false } // var closeRate int if closeOpt { closeRate = 100 } else { closeRate = 0 } // psdTag := components.ComEntityTagHandler.Get(psdEntry).Tag psdCellQuery := ecs.NewQuery(filter.Contains(psdTag)) psdCellQuery.Each(world, func(e *ecs.Entry) { psdCellId := components.ComDeviceIdentity.Get(e).Id firePsdCellMove0(world, psdEntry, psdCellId, closeRate) }) // return true } // 单个门操作 // psdId 单侧屏蔽门id // psdCellId 屏蔽门cell的id // closeRate 门最终关闭的百分比,0-完全开门,100-完全关门 func FirePsdCellMove(world ecs.World, psdId string, psdCellId string, closeRate int) bool { var psdEntry *ecs.Entry = nil psdQuery.Each(world, func(e *ecs.Entry) { if psdId == components.ComDeviceIdentity.Get(e).Id { psdEntry = e } }) return firePsdCellMove0(world, psdEntry, psdCellId, closeRate) } func firePsdCellMove0(world ecs.World, psdEntry *ecs.Entry, psdCellId string, closeRate int) bool { // if psdEntry == nil { return false } // psdTag := components.ComEntityTagHandler.Get(psdEntry).Tag psdCellQuery := ecs.NewQuery(filter.Contains(psdTag)) var psdCellEntry *ecs.Entry = nil psdCellQuery.Each(world, func(e *ecs.Entry) { if psdCellId == components.ComDeviceIdentity.Get(e).Id { psdCellEntry = e } }) if psdCellEntry == nil { return false } // psdCellState := components.ComPsdCellState.Get(psdCellEntry) if closeRate == int(psdCellState.CloseRate) { return true } // 判断是关门还是开门操作 close := closeRate > int(psdCellState.CloseRate) // if !psdCellEntry.HasComponent(components.ComPsdCellOperating) { psdCellEntry.AddComponent(components.ComPsdCellOperating) } // var initDistance int64 var sumDistance int64 if close { initDistance = int64(float32(pSD_CELL_LEN) * (float32(psdCellState.CloseRate) / float32(100))) sumDistance = int64(float32(pSD_CELL_LEN) * (float32(closeRate-int(psdCellState.CloseRate)) / float32(100))) } else { initDistance = int64(float32(pSD_CELL_LEN) * (float32(100-psdCellState.CloseRate) / float32(100))) sumDistance = int64(float32(pSD_CELL_LEN) * (float32(int(psdCellState.CloseRate)-closeRate) / float32(100))) } // *(components.ComPsdCellOperating.Get(psdCellEntry)) = state.PsdCellOperating{ Start: true, CloseOperate: close, InitDistance: initDistance, SumDistance: sumDistance, RemainingDistance: sumDistance, } // return true }