rts-sim-module/system/psd_system.go
2023-08-18 10:06:17 +08:00

208 lines
6.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.DeviceIdentityComponent, components.PsdStateComponent, components.EntityTagHandlerComponent))
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.EntityTagHandlerComponent.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.PsdCellOperatingComponent))
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.PsdCellStateComponent.Get(e)
if allClosed {
if cellState.CloseRate < 100 {
allClosed = false
}
}
if allOpened {
if cellState.CloseRate > 0 {
allOpened = false
}
}
})
//
psdState := components.PsdStateComponent.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.PsdCellOperatingComponent.Get(e); psdCellOpt.Start {
psdCellState := components.PsdCellStateComponent.Get(e)
if psdCellOpt.RemainingDistance <= 0 {
psdCellOpt.Start = false
psdCellOpt.RemainingDistance = 0
e.RemoveComponent(components.PsdCellOperatingComponent)
} 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.DeviceIdentityComponent.Get(e).Id {
psdEntry = e
}
})
//
if psdEntry == nil {
return false
}
components.PsdStateComponent.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.DeviceIdentityComponent.Get(e).Id {
psdEntry = e
}
})
//
if psdEntry == nil {
return false
}
//
var closeRate int
if closeOpt {
closeRate = 100
} else {
closeRate = 0
}
//
psdTag := components.EntityTagHandlerComponent.Get(psdEntry).Tag
psdCellQuery := ecs.NewQuery(filter.Contains(psdTag))
psdCellQuery.Each(world, func(e *ecs.Entry) {
psdCellId := components.DeviceIdentityComponent.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.DeviceIdentityComponent.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.EntityTagHandlerComponent.Get(psdEntry).Tag
psdCellQuery := ecs.NewQuery(filter.Contains(psdTag))
var psdCellEntry *ecs.Entry = nil
psdCellQuery.Each(world, func(e *ecs.Entry) {
if psdCellId == components.DeviceIdentityComponent.Get(e).Id {
psdCellEntry = e
}
})
if psdCellEntry == nil {
return false
}
//
psdCellState := components.PsdCellStateComponent.Get(psdCellEntry)
if closeRate == int(psdCellState.CloseRate) {
return true
}
// 判断是关门还是开门操作
close := closeRate > int(psdCellState.CloseRate)
//
if !psdCellEntry.HasComponent(components.PsdCellOperatingComponent) {
psdCellEntry.AddComponent(components.PsdCellOperatingComponent)
}
//
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.PsdCellOperatingComponent.Get(psdCellEntry)) = state.PsdCellOperating{
Start: true,
CloseOperate: close,
InitDistance: initDistance,
SumDistance: sumDistance,
RemainingDistance: sumDistance,
}
//
return true
}