rts-sim-module/system/signal_3xh2_system.go
2023-09-21 16:23:03 +08:00

142 lines
4.7 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"
sysEvent "joylink.club/rtsssimulation/system/event"
"joylink.club/rtsssimulation/umi"
)
// Signal3XH2State 电路状态信号机3XH-2(红-绿-黄) 道岔防护信号机(三显示不封灯、无单黄显示、带引导)
// 引导信号:红黄
type Signal3XH2State struct {
// 物理黄灯true-亮
U bool
// 物理绿灯true-亮
L bool
// 物理红灯true-亮
H bool
// 点灯继电器true-吸合,常态落下表示逻辑点灯
DDJ bool
//2DJ灯丝继电器true-吸合
EDJ bool
//灯丝继电器true-吸合
DJ bool
//列车信号继电器true-吸合
LXJ bool
//引导信号继电器true-吸合
YXJ bool
}
// Signal3XH2FilamentState 信号机3XH-2 灯丝状态
type Signal3XH2FilamentState struct {
// 物理黄灯true-灯丝正常
Uf bool
// 物理绿灯true-灯丝正常
Lf bool
// 物理红灯true-灯丝正常
Hf bool
}
// Signal3XH2StateComponent 信号机3XH-2状态组件
var Signal3XH2StateComponent = ecs.NewComponentType[Signal3XH2State]()
var Signal3XH2FilamentStateComponent = ecs.NewComponentType[Signal3XH2FilamentState]()
var signal3XH2Query = ecs.NewQuery(filter.Contains(EntityIdentityComponent, Signal3XH2StateComponent))
func NewSignal3XH2State() *Signal3XH2State {
return &Signal3XH2State{DDJ: true, EDJ: false, DJ: false, LXJ: false, YXJ: false, U: false, L: false, H: false}
}
func NewSignal3XH2FilamentState() *Signal3XH2FilamentState {
return &Signal3XH2FilamentState{Uf: true, Lf: true, Hf: true}
}
type Signal3XH2System struct {
}
func NewSignal3XH2System() *Signal3XH2System {
return &Signal3XH2System{}
}
// Update world 执行
func (me *Signal3XH2System) Update(w ecs.World) {
signal3XH2Query.Each(w, func(e *ecs.Entry) {
state := Signal3XH2StateComponent.Get(e)
filament := Signal3XH2FilamentStateComponent.Get(e)
me.calculateU(w, state, filament)
me.calculateL(w, state, filament)
me.calculateH(w, state, filament)
me.calculateDJ(w, e, state, filament)
me.calculate2DJ(w, e, state, filament)
})
}
// Signal3XH2RelayActionEventProcessor 继电器动作事件处理
var Signal3XH2RelayActionEventProcessor = func(w ecs.World, event sysEvent.RelayActionEvent) {
//根据event来更新Signal3XH1State中对应继电器的状态
signal3XH2Query.Each(w, func(e *ecs.Entry) {
signalModel := FindModelStorage(w).FindById(EntityIdentityComponent.Get(e).Id)
roler, ok := signalModel.(umi.IRelayCRole)
if ok {
if relayGroup, relayName, find := roler.FindCircuitRoleById(event.Id); find {
if relayGroup == SIGNAL_3XH2 {
state := Signal3XH2StateComponent.Get(e)
switch relayName {
case SIGNAL_DDJ:
state.DDJ = event.Xh
case SIGNAL_DJ:
state.DJ = event.Xh
case SIGNAL_2DJ:
state.EDJ = event.Xh
case SIGNAL_LXJ:
state.LXJ = event.Xh
case SIGNAL_YXJ:
state.YXJ = event.Xh
default:
panic(fmt.Sprintf("Signal3XH2的模型[%s]中继电器功能名称[%s]无法识别", signalModel.Id(), relayName))
}
} else {
panic(fmt.Sprintf("Signal3XH2的模型[%s]中继电器组合类型[%s]无法识别", signalModel.Id(), relayGroup))
}
}
} else {
panic("Signal3XH2的模型未实现接口umi.IRelayCRoler")
}
})
}
func (me *Signal3XH2System) calculateU(w ecs.World, state *Signal3XH2State, filament *Signal3XH2FilamentState) {
isU := filament.Uf && !state.DDJ && !state.LXJ && state.DJ && state.YXJ
state.U = isU
}
func (me *Signal3XH2System) calculateL(w ecs.World, state *Signal3XH2State, filament *Signal3XH2FilamentState) {
isL := filament.Lf && !state.DDJ && state.LXJ
state.L = isL
}
func (me *Signal3XH2System) calculateH(w ecs.World, state *Signal3XH2State, filament *Signal3XH2FilamentState) {
isH := filament.Hf && !state.DDJ && !state.LXJ
state.H = isH
}
func (me *Signal3XH2System) calculateDJ(w ecs.World, e *ecs.Entry, state *Signal3XH2State, filament *Signal3XH2FilamentState) {
isDJ := filament.Lf && !state.DDJ && state.LXJ || filament.Hf && !state.DDJ && !state.LXJ
//通知继电器进行动作
if isDJ != state.DJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(e).Id, SIGNAL_3XH2, SIGNAL_DJ, isDJ); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}
func (me *Signal3XH2System) calculate2DJ(w ecs.World, e *ecs.Entry, state *Signal3XH2State, filament *Signal3XH2FilamentState) {
is2DJ := filament.Uf && !state.DDJ && !state.LXJ && state.DJ && state.YXJ
//通知继电器进行动作
if is2DJ != state.EDJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(e).Id, SIGNAL_3XH2, SIGNAL_2DJ, is2DJ); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}