package circuit_sys import ( "joylink.club/rtsssimulation/repository/model/proto" "strings" "joylink.club/ecs" "joylink.club/ecs/filter" "joylink.club/rtsssimulation/component" "joylink.club/rtsssimulation/entity" ) 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) { worldData := entity.GetWorldData(world) p.query.Each(world, func(entry *ecs.Entry) { psc := component.PscType.Get(entry) //更新屏蔽门电路及PSC相关状态 asdList := component.AsdListType.Get(entry) psdState := component.PsdStateType.Get(entry) if entry.HasComponent(component.PsdCircuitType) { //有屏蔽门电路 psdCircuit := component.PsdCircuitType.Get(entry) //屏蔽门驱动 if psdCircuit.GMJ != nil { p.exciteGMJ(worldData, psdCircuit) psc.InterlockGM = component.BitStateType.Get(psdCircuit.GMJ).Val } for group, kmj := range psdCircuit.KMJMap { p.exciteKMJ(worldData, psdCircuit, kmj) psc.InterlockKmGroup[group] = component.BitStateType.Get(kmj).Val } if psdCircuit.MGJ != nil { p.exciteMGJ(psdCircuit, asdList) psdState.Close = component.BitStateType.Get(psdCircuit.MGJ).Val } if psdCircuit.MPLJ != nil { p.exciteMPLJ(world, psdCircuit, component.UidType.Get(entry)) psc.InterlockMPL = component.BitStateType.Get(psdCircuit.MPLJ).Val } //间隙探测 if psdCircuit.QDTCJ != nil && psdCircuit.TZTCJ != nil { p.exciteQDTCJ(worldData, psdCircuit) p.exciteTZTCJ(worldData, psdCircuit) psc.QDTC = component.BitStateType.Get(psdCircuit.QDTCJ).Val psc.TZTC = component.BitStateType.Get(psdCircuit.TZTCJ).Val } } else { psdState.Close = p.isAllAsdMotorClosed(asdList) } //更新站台门控箱电路及PSC相关状态 if entry.HasComponent(component.PlatformMkxCircuitType) { 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.MkxKM { //优先门控箱的开门 p.allKm(asdList) } else if psc.MkxGM { //其次门控箱的关门 p.gm(asdList) } else if !psc.InterlockMPL { //联锁操作没有被旁路 if psc.InterlockGM { p.gm(asdList) } else { for group, km := range psc.InterlockKmGroup { if km { var asdGroup *proto.AsdGroup if group == 0 { asdGroup = psd.FindFirstAsdGroup() } else { asdGroup = psd.FindAsdGroup(group) } p.km(asdGroup.Start, asdGroup.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) allKm(asdList *component.AsdList) { for _, asd := range asdList.List { 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) exciteGMJ(data *component.WorldData, circuit *component.PsdCircuit) { bit, err := data.QueryQdBit(component.UidType.Get(circuit.GMJ).Id) if err != nil { return } if bit { //驱动 component.RelayDriveType.Get(circuit.GMJ).Td = true } else if component.BitStateType.Get(circuit.GMJ).Val { //判断自保持 for _, entry := range circuit.KMJMap { if component.BitStateType.Get(entry).Val { //无法自保持 component.RelayDriveType.Get(circuit.GMJ).Td = false return } } //自保持 component.RelayDriveType.Get(circuit.GMJ).Td = true } } func (p *PsdSys) exciteKMJ(data *component.WorldData, circuit *component.PsdCircuit, kmj *ecs.Entry) { bit, err := data.QueryQdBit(component.UidType.Get(kmj).Id) if err != nil { return } if bit { //驱动 component.RelayDriveType.Get(kmj).Td = true } else if component.BitStateType.Get(kmj).Val { //判断自保持 if component.BitStateType.Get(circuit.GMJ).Val { component.RelayDriveType.Get(kmj).Td = false return } for _, entry := range circuit.KMJMap { if entry != kmj && component.BitStateType.Get(entry).Val { component.RelayDriveType.Get(kmj).Td = false return } } //自保持 component.RelayDriveType.Get(kmj).Td = true } } func (p *PsdSys) exciteMGJ(psdCircuit *component.PsdCircuit, asdList *component.AsdList) { component.BitStateType.Get(psdCircuit.MGJ).Val = p.isAllAsdMotorClosed(asdList) } // 是否所有滑动门电机都是关闭状态(继电器表示) func (p *PsdSys) isAllAsdMotorClosed(asdList *component.AsdList) bool { for _, asdEntry := range asdList.List { asdMotor := component.AsdMotorStateType.Get(asdEntry) if !asdMotor.MG { return false } } return 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.SpksButtons() { 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 } } func (p *PsdSys) exciteQDTCJ(data *component.WorldData, circuit *component.PsdCircuit) { bit, err := data.QueryQdBit(component.UidType.Get(circuit.QDTCJ).Id) if err != nil { return } qdtcj := component.BitStateType.Get(circuit.QDTCJ) tztcj := component.BitStateType.Get(circuit.TZTCJ) if bit { //驱动 component.RelayDriveType.Get(circuit.QDTCJ).Td = true } else if qdtcj.Val { //自保持 component.RelayDriveType.Get(circuit.QDTCJ).Td = !tztcj.Val } } func (p *PsdSys) exciteTZTCJ(data *component.WorldData, circuit *component.PsdCircuit) { bit, err := data.QueryQdBit(component.UidType.Get(circuit.TZTCJ).Id) if err != nil { return } tztcj := component.BitStateType.Get(circuit.TZTCJ) qdtcj := component.BitStateType.Get(circuit.QDTCJ) if bit { //驱动 component.RelayDriveType.Get(circuit.TZTCJ).Td = true } else if tztcj.Val { //自保持 component.RelayDriveType.Get(circuit.TZTCJ).Td = !qdtcj.Val } }