rts-sim-module/sys/circuit_sys/psd.go

230 lines
6.8 KiB
Go

package circuit_sys
import (
"joylink.club/ecs"
"joylink.club/ecs/filter"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/component/component_proto"
"joylink.club/rtsssimulation/consts"
"joylink.club/rtsssimulation/entity"
"strings"
)
type PsdSys struct {
query *ecs.Query
}
func NewPsdSys() *PsdSys {
return &PsdSys{
query: ecs.NewQuery(filter.Contains(entity.PsdBaseComponentTypeArr...)),
}
}
func (p *PsdSys) Update(world ecs.World) {
p.query.Each(world, func(entry *ecs.Entry) {
psc := component.PscType.Get(entry)
//更新屏蔽门电路及PSC相关状态
asdList := component.AsdListType.Get(entry)
if entry.HasComponent(component.PsdCircuitType) { //有屏蔽门电路
psdDrive := component.PsdInterlockDriveCircuitType.Get(entry)
psdCircuit := component.PsdCircuitType.Get(entry)
p.exciteByDrive(psdCircuit, psdDrive)
if psdCircuit.GMJ != nil {
p.exciteGMJ(psdCircuit, psdDrive)
psc.InterlockGM = component.BitStateType.Get(psdCircuit.GMJ).Val
}
if psdCircuit.KMJ4 != nil {
p.exciteKMJ4(psdCircuit, psdDrive)
psc.InterlockKM4 = component.BitStateType.Get(psdCircuit.KMJ4).Val
}
if psdCircuit.KMJ8 != nil {
p.exciteKMJ8(psdCircuit, psdDrive)
psc.InterlockKM8 = component.BitStateType.Get(psdCircuit.KMJ8).Val
}
if psdCircuit.MGJ != nil {
p.exciteMGJ(psdCircuit, asdList)
}
p.exciteMPLJ(world, psdCircuit, component.UidType.Get(entry))
psc.InterlockMPL = component.BitStateType.Get(psdCircuit.MPLJ).Val
}
psdState := component.PsdStateType.Get(entry)
p.updatePsdState(psdState, asdList)
//更新站台门控箱电路及PSC相关状态
pmc := component.PlatformMkxCircuitType.Get(entry)
var pcbTd bool
var pobTd bool
var pabTd bool
for _, mkxEntry := range pmc.MkxList {
mkx := component.MkxType.Get(mkxEntry)
if mkx.PCB != nil && component.BitStateType.Get(mkx.PCB).Val {
pcbTd = true
}
if mkx.POB != nil && component.BitStateType.Get(mkx.POB).Val {
pobTd = true
}
if mkx.PAB != nil && component.BitStateType.Get(mkx.PAB).Val {
pabTd = true
}
}
if pmc.PCBJ != nil {
component.RelayDriveType.Get(pmc.PCBJ).Td = pcbTd
psc.MkxGM = component.BitStateType.Get(pmc.PCBJ).Val
}
if pmc.POBJ != nil {
component.RelayDriveType.Get(pmc.POBJ).Td = pobTd
psc.MkxKM = component.BitStateType.Get(pmc.POBJ).Val
}
if pmc.PABJ != nil {
component.RelayDriveType.Get(pmc.PABJ).Td = pabTd
}
//设置滑动门电机通断电状态
repo := entity.GetWorldData(world).Repo
psd := repo.FindPsd(component.UidType.Get(entry).Id)
if psc.MkxGM { //优先门控箱的关门
p.gm(asdList)
} else if psc.MkxKM { //其次门控箱的开门
group := psd.FindAsdGroup(8)
p.km(group.Start, group.End, asdList)
} else if !psc.InterlockMPL { //联锁操作没有被旁路
if psc.InterlockGM {
p.gm(asdList)
} else if psc.InterlockKM8 {
group := psd.FindAsdGroup(8)
p.km(group.Start, group.End, asdList)
} else if psc.InterlockKM4 {
group := psd.FindAsdGroup(4)
p.km(group.Start, group.End, asdList)
}
}
})
}
func (p *PsdSys) km(start int32, end int32, asdList *component.AsdList) {
for i := start - 1; i < end; i++ {
asd := asdList.List[i]
component.AsdMotorStateType.Get(asd).TD = true
component.AsdMotorStateType.Get(asd).KM = true
}
}
func (p *PsdSys) gm(asdList *component.AsdList) {
for _, asd := range asdList.List {
component.AsdMotorStateType.Get(asd).TD = true
component.AsdMotorStateType.Get(asd).KM = false
}
}
func (p *PsdSys) exciteByDrive(psd *component.PsdCircuit, drive *component.PsdInterlockDriveCircuit) {
if drive.GMJ {
component.RelayDriveType.Get(psd.GMJ).Td = true
component.BitStateType.Get(psd.GMJ).Val = true
}
if drive.KMJ4 {
component.RelayDriveType.Get(psd.KMJ4).Td = true
component.BitStateType.Get(psd.KMJ4).Val = true
}
if drive.KMJ8 {
component.RelayDriveType.Get(psd.KMJ8).Td = true
component.BitStateType.Get(psd.KMJ8).Val = true
}
}
func (p *PsdSys) exciteGMJ(psd *component.PsdCircuit, psdDrive *component.PsdInterlockDriveCircuit) {
gmj := component.BitStateType.Get(psd.GMJ)
kmj4 := component.BitStateType.Get(psd.KMJ4)
kmj8 := component.BitStateType.Get(psd.KMJ8)
if psdDrive.GMJ { //驱动电路接通
component.RelayDriveType.Get(psd.GMJ).Td = true
gmj.Val = true
} else if gmj.Val {
if !kmj4.Val && !kmj8.Val {
component.RelayDriveType.Get(psd.GMJ).Td = true
} else {
component.RelayDriveType.Get(psd.GMJ).Td = false
gmj.Val = false
}
}
}
func (p *PsdSys) exciteKMJ4(psd *component.PsdCircuit, psdDrive *component.PsdInterlockDriveCircuit) {
kmj4 := component.BitStateType.Get(psd.KMJ4)
gmj := component.BitStateType.Get(psd.GMJ)
kmj8 := component.BitStateType.Get(psd.KMJ8)
if psdDrive.KMJ4 {
component.RelayDriveType.Get(psd.KMJ4).Td = true
kmj4.Val = true
} else if kmj4.Val {
if !gmj.Val && !kmj8.Val {
component.RelayDriveType.Get(psd.KMJ4).Td = true
} else {
component.RelayDriveType.Get(psd.KMJ4).Td = false
kmj4.Val = false
}
}
}
func (p *PsdSys) exciteKMJ8(psd *component.PsdCircuit, psdDrive *component.PsdInterlockDriveCircuit) {
kmj8 := component.BitStateType.Get(psd.KMJ8)
gmj := component.BitStateType.Get(psd.GMJ)
kmj4 := component.BitStateType.Get(psd.KMJ4)
if psdDrive.KMJ4 {
component.RelayDriveType.Get(psd.KMJ8).Td = true
kmj8.Val = true
} else if kmj8.Val {
if !gmj.Val && !kmj4.Val {
component.RelayDriveType.Get(psd.KMJ8).Td = true
} else {
component.RelayDriveType.Get(psd.KMJ8).Td = false
kmj8.Val = false
}
}
}
func (p *PsdSys) exciteMGJ(psdCircuit *component.PsdCircuit, asdList *component.AsdList) {
for _, asdEntry := range asdList.List {
asdMotor := component.AsdMotorStateType.Get(asdEntry)
if asdMotor.KM {
component.BitStateType.Get(psdCircuit.MGJ).Val = false
return
}
}
component.BitStateType.Get(psdCircuit.MGJ).Val = true
}
func (p *PsdSys) updatePsdState(psdState *component_proto.PsdState, asdList *component.AsdList) {
for _, asdEntry := range asdList.List {
position := component.TwoPositionTransformType.Get(asdEntry)
if position.GetPos() != consts.TwoPosMin {
psdState.Close = false
return
}
}
psdState.Close = true
}
func (p *PsdSys) exciteMPLJ(world ecs.World, circuit *component.PsdCircuit, uid *component.Uid) {
data := entity.GetWorldData(world)
psd := data.Repo.FindPsd(uid.Id)
platform := psd.Platform()
station := platform.Station()
var buttonCode string
if strings.Contains(platform.Code(), "上行") {
buttonCode = "S旁路"
} else if strings.Contains(platform.Code(), "下行") {
buttonCode = "X旁路"
} else {
return
}
for _, button := range station.GetIbpSpk().Buttons() {
if button.Code() != buttonCode {
return
}
btnEntry, ok := entity.GetEntityByUid(world, button.Id())
if !ok {
return
}
component.RelayDriveType.Get(circuit.MPLJ).Td = component.BitStateType.Get(btnEntry).Val
}
}