package system import ( "fmt" "github.com/yohamta/donburi/filter" "joylink.club/ecs" sysEvent "joylink.club/rtsssimulation/system/event" ) // Signal2XH1State 电路状态:**信号机2XH-1(红-绿) 出段(场)信号机 或 **出站区间阻挡信号机 type Signal2XH1State struct { // 物理绿灯,true-亮 L bool // 物理红灯,true-亮 H bool // 点灯继电器,true-吸合,常态落下表示逻辑点灯 DDJ bool //灯丝继电器,true-吸合 DJ bool //列车信号继电器,true-吸合 LXJ bool } // Signal2XH1FilamentState 信号机2XH-1 灯丝状态 type Signal2XH1FilamentState struct { // 物理绿灯,true-灯丝正常 Lf bool // 物理红灯,true-灯丝正常 Hf bool } func NewSignal2XH1FilamentState() *Signal2XH1FilamentState { return &Signal2XH1FilamentState{Lf: true, Hf: true} } // NewSignal2XH1CdcState 出段(场)信号机 func NewSignal2XH1CdcState() *Signal2XH1State { return &Signal2XH1State{DDJ: false, LXJ: false, DJ: true, L: false, H: true} } // NewSignal2XH1CzqzState 出站区间阻挡信号机 func NewSignal2XH1CzqzState() *Signal2XH1State { return &Signal2XH1State{DDJ: true, LXJ: false, DJ: false, L: false, H: false} } var Signal2XH1StateComponent = ecs.NewComponentType[Signal2XH1State]() var Signal2XH1FilamentStateComponent = ecs.NewComponentType[Signal2XH1FilamentState]() var signal2XH1Query = ecs.NewQuery(filter.Contains(EntityIdentityComponent, Signal2XH1StateComponent)) type Signal2XH1System struct { } func NewSignal2XH1System() *Signal2XH1System { return &Signal2XH1System{} } // Update world 执行 func (me *Signal2XH1System) Update(w ecs.World) { signal2XH1Query.Each(w, func(entry *ecs.Entry) { state := Signal2XH1StateComponent.Get(entry) filament := Signal2XH1FilamentStateComponent.Get(entry) me.calculateL(state, filament) me.calculateH(state, filament) me.calculateDJ(w, entry, state, filament) }) } // Signal2XH1RelayActionEventProcessor 继电器动作事件处理 // 将继电器动作的结果同步到系统 var Signal2XH1RelayActionEventProcessor = func(w ecs.World, event sysEvent.RelayActionEvent) { //根据event来更新Signal2XH1State中对应继电器的状态 signal2XH1Query.Each(w, func(e *ecs.Entry) { signalModel := FindModelStorage(w).FindById(EntityIdentityComponent.Get(e).Id) roler, ok := signalModel.(IRelayCRole) if ok { if relayGroup, relayName, find := roler.FindCircuitRoleById(event.Id); find { if relayGroup == SIGNAL_2XH1 { state := Signal2XH1StateComponent.Get(e) switch relayName { case SIGNAL_DDJ: state.DDJ = event.Xh case SIGNAL_DJ: state.DJ = event.Xh case SIGNAL_LXJ: state.LXJ = event.Xh default: panic(fmt.Sprintf("Signal2XH1的模型[%s]中继电器功能名称[%s]无法识别", signalModel.Id(), relayName)) } } else { panic(fmt.Sprintf("Signal2XH1的模型[%s]中继电器组合类型[%s]无法识别", signalModel.Id(), relayGroup)) } } } else { panic("Signal2XH1的模型未实现接口umi.IRelayCRoler") } }) } func (me *Signal2XH1System) calculateL(state *Signal2XH1State, filament *Signal2XH1FilamentState) { isL := !state.DDJ && state.LXJ && filament.Lf state.L = isL } func (me *Signal2XH1System) calculateH(state *Signal2XH1State, filament *Signal2XH1FilamentState) { isH := !state.DDJ && !state.LXJ && filament.Hf state.H = isH } func (me *Signal2XH1System) calculateDJ(w ecs.World, e *ecs.Entry, state *Signal2XH1State, filament *Signal2XH1FilamentState) { isDJ := !state.DDJ && state.LXJ && filament.Lf || !state.DDJ && !state.LXJ && filament.Hf //通知继电器进行动作 if state.DJ != isDJ { if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(e).Id, SIGNAL_2XH1, SIGNAL_DJ, isDJ); ok { sysEvent.RelayNeedChangeEventBus.Publish(w, event) } } }