rts-sim-module/system/psd_system.go

208 lines
5.9 KiB
Go
Raw Normal View History

2023-08-16 17:17:20 +08:00
package system
2023-08-16 18:13:18 +08:00
import (
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/components"
"joylink.club/rtsssimulation/state"
)
2023-08-16 17:17:20 +08:00
2023-08-17 14:25:18 +08:00
var psdQuery = ecs.NewQuery(filter.Contains(components.ComDeviceIdentity, components.ComPsdState, components.ComEntityTagHandler))
2023-08-16 17:17:20 +08:00
type PsdSystem struct {
2023-08-17 14:25:18 +08:00
psdTagMap map[state.EntityTag][]*ecs.Query
2023-08-16 17:17:20 +08:00
}
func NewPsdSystem() *PsdSystem {
2023-08-16 18:13:18 +08:00
return &PsdSystem{
2023-08-17 14:25:18 +08:00
psdTagMap: make(map[state.EntityTag][]*ecs.Query),
2023-08-16 18:13:18 +08:00
}
2023-08-16 17:17:20 +08:00
}
// world 执行
func (me *PsdSystem) Update(world ecs.World) {
2023-08-16 18:13:18 +08:00
me.updatePsdCell(world)
2023-08-17 14:25:18 +08:00
me.updatePsd(world)
2023-08-16 18:13:18 +08:00
}
// 车站单侧屏蔽门
func (me *PsdSystem) updatePsd(world ecs.World) {
2023-08-17 14:25:18 +08:00
psdQuery.Each(world, func(e *ecs.Entry) {
2023-08-16 18:13:18 +08:00
psdTag := components.ComEntityTagHandler.Get(e).Tag
2023-08-17 14:25:18 +08:00
_, ok := me.psdTagMap[psdTag]
2023-08-16 18:13:18 +08:00
if !ok {
2023-08-17 14:25:18 +08:00
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
2023-08-16 18:13:18 +08:00
}
var allClosed bool = true
var allOpened bool = true
2023-08-17 14:25:18 +08:00
me.psdTagMap[psdTag][0].Each(world, func(e *ecs.Entry) {
2023-08-16 18:13:18 +08:00
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
})
}
2023-08-17 14:25:18 +08:00
const (
2023-08-17 17:39:57 +08:00
//把时间映射到距离1000ms<=>1000mm
//注意距离不是门的真实宽度,仅用于门开关相关计算
2023-08-17 14:25:18 +08:00
//门移动最大路程3000mm
pSD_CELL_LEN = 3000
//cell门移动速度单位mm/ms
pSD_CELL_MOVE_SPEED = 1
)
2023-08-16 18:13:18 +08:00
// 单个门
func (me *PsdSystem) updatePsdCell(world ecs.World) {
2023-08-17 14:25:18 +08:00
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)
}
}
2023-08-16 18:13:18 +08:00
})
}
2023-08-16 17:17:20 +08:00
}
2023-08-17 14:25:18 +08:00
// 车站单侧屏蔽门互锁解除操作
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
}