rts-sim-module/system/psd_system.go
2023-08-18 16:15:19 +08:00

140 lines
4.0 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 (
"fmt"
"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))
const (
//屏蔽门完全关闭
PsdCellWholeCloseRate = 100
//屏蔽门完全打开
PsdCellWholeOpenRate = 0
)
type PsdSystem struct {
cellsQuery map[state.EntityTag]*ecs.Query
}
func NewPsdSystem() *PsdSystem {
return &PsdSystem{cellsQuery: make(map[state.EntityTag]*ecs.Query)}
}
// world 执行
func (me *PsdSystem) Update(world ecs.World) {
psdQuery.Each(world, func(psdEntry *ecs.Entry) {
psdTag := components.EntityTagHandlerComponent.Get(psdEntry).Tag
psdCellQuery, ok := me.cellsQuery[psdTag]
if !ok {
me.cellsQuery[psdTag] = ecs.NewQuery(filter.Contains(psdTag, components.PercentageDeviceComponent))
psdCellQuery = me.cellsQuery[psdTag]
}
//
var allCellClosed, allCellOpened bool = true, true
psdCellQuery.Each(world, func(psdCellEntry *ecs.Entry) {
psdCellRate := components.PercentageDeviceComponent.Get(psdCellEntry).Rate
if allCellClosed {
allCellClosed = psdCellRate == PsdCellWholeCloseRate
}
if allCellOpened {
allCellOpened = psdCellRate == PsdCellWholeOpenRate
}
})
//
psdState := components.PsdStateComponent.Get(psdEntry)
psdState.AllClosed = allCellClosed
psdState.AllOpened = allCellOpened
})
}
// 车站单侧屏蔽门互锁解除操作
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 FirePsdOperation(world ecs.World, psdId string, closeOpt bool) error {
psdEntry, err := findPsdEntry(world, psdId)
if nil != err {
return err
}
//屏蔽门标签
psdTag := components.EntityTagHandlerComponent.Get(psdEntry).Tag
psdCellQuery := ecs.NewQuery(filter.Contains(psdTag))
psdCellQuery.Each(world, func(psdCellEntry *ecs.Entry) {
if closeOpt {
FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(psdId), PsdCellWholeCloseRate)
} else {
FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(psdId), PsdCellWholeOpenRate)
}
})
//
return nil
}
// 车站单侧屏蔽门单元cell操作
// closeRate cell最终关上的百分比100-完全关上0-完全未关即完全打开,(0,100)内即半关闭
func FirePsdCellOperation(world ecs.World, psdId string, psdCellId string, closeRate int32) error {
if closeRate < 0 || closeRate > 100 {
return fmt.Errorf("屏蔽门单元操作closeRate(%d)不在[0,100]内", closeRate)
}
//
psdEntry, err := findPsdEntry(world, psdId)
if nil != err {
return err
}
//屏蔽门标签
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 fmt.Errorf("屏蔽门[%s]的单元门[%s]的实体不存在", psdId, psdCellId)
}
//
return FirePercentageDeviceOperation(world, psdCellEntry, findPsdWholeMoveTime(psdId), closeRate)
}
// 获取屏蔽门实体
func findPsdEntry(world ecs.World, psdId string) (*ecs.Entry, error) {
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 nil, fmt.Errorf("屏蔽门[%s]实体不存在", psdId)
} else {
return psdEntry, nil
}
}
// 获取屏蔽门从完全开到完全关所需时间单位ms
func findPsdWholeMoveTime(psdId string) int64 {
return 4000
}