208 lines
6.1 KiB
Go
208 lines
6.1 KiB
Go
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
|
||
}
|