rts-sim-module/system/signal_3xh3_system.go
2023-09-18 17:34:06 +08:00

129 lines
4.3 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"
)
// Signal3XH3State 电路状态信号机3XH-3(红-绿-黄) 道岔防护信号机(三显示封绿灯、有单黄显示、带引导)
// 引导信号:红黄
type Signal3XH3State struct {
// 物理黄灯true-亮
U bool
// 物理红灯true-亮
H bool
// 点灯继电器true-吸合,常态落下表示逻辑点灯
DDJ bool
//2DJ灯丝继电器true-吸合
EDJ bool
//灯丝继电器true-吸合
DJ bool
//列车信号继电器true-吸合
LXJ bool
//引导信号继电器true-吸合
YXJ bool
}
// Signal3XH3FilamentState 信号机3XH-3 灯丝状态
type Signal3XH3FilamentState struct {
// 物理黄灯true-灯丝正常
Uf bool
// 物理红灯true-灯丝正常
Hf bool
}
func NewSignal3XH3State() *Signal3XH3State {
return &Signal3XH3State{U: false, H: false, DDJ: true, EDJ: false, DJ: false, LXJ: false, YXJ: false}
}
func NewSignal3XH3FilamentState() *Signal3XH3FilamentState {
return &Signal3XH3FilamentState{Uf: true, Hf: true}
}
var Signal3XH3StateComponent = ecs.NewComponentType[Signal3XH3State]()
var Signal3XH3FilamentStateComponent = ecs.NewComponentType[Signal3XH3FilamentState]()
var signal3XH3Query = ecs.NewQuery(filter.Contains(EntityIdentityComponent, Signal3XH3StateComponent))
type Signal3XH3System struct {
}
func NewSignal3XH3System() *Signal3XH3System {
return &Signal3XH3System{}
}
// Update world 执行
func (me *Signal3XH3System) Update(w ecs.World) {
signal3XH3Query.Each(w, func(e *ecs.Entry) {
state := Signal3XH3StateComponent.Get(e)
filament := Signal3XH3FilamentStateComponent.Get(e)
//
me.calculateU(w, state, filament)
me.calculateH(w, state, filament)
me.calculateDJ(w, e, state, filament)
me.calculate2DJ(w, e, state, filament)
})
}
// Signal3XH3RelayActionEventProcessor 继电器动作事件处理
var Signal3XH3RelayActionEventProcessor = func(w ecs.World, event sysEvent.RelayActionEvent) {
//根据event来更新Signal3XH3State中对应继电器的状态
signal3XH3Query.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_3XH3 {
state := Signal3XH3StateComponent.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("Signal3XH3的模型[%s]中继电器功能名称[%s]无法识别", signalModel.GetId(), relayName))
}
} else {
panic(fmt.Sprintf("Signal3XH3的模型[%s]中继电器组合类型[%s]无法识别", signalModel.GetId(), relayGroup))
}
}
} else {
panic("Signal3XH3的模型未实现接口umi.IRelayCRoler")
}
})
}
func (me *Signal3XH3System) calculateU(w ecs.World, state *Signal3XH3State, filament *Signal3XH3FilamentState) {
isU := filament.Uf && (!state.DDJ && !state.LXJ && state.DJ && state.YXJ || !state.DDJ && state.LXJ)
state.U = isU
}
func (me *Signal3XH3System) calculateH(w ecs.World, state *Signal3XH3State, filament *Signal3XH3FilamentState) {
isH := filament.Hf && !state.DDJ && !state.LXJ
state.H = isH
}
func (me *Signal3XH3System) calculateDJ(w ecs.World, e *ecs.Entry, state *Signal3XH3State, filament *Signal3XH3FilamentState) {
isDJ := filament.Uf && !state.DDJ && state.LXJ || filament.Hf && !state.DDJ && !state.LXJ
if isDJ != state.DJ {
if event, ok := createRelayNeedChangeEvent(w, EntityIdentityComponent.Get(e).Id, SIGNAL_3XH3, SIGNAL_DJ, isDJ); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}
func (me *Signal3XH3System) calculate2DJ(w ecs.World, e *ecs.Entry, state *Signal3XH3State, filament *Signal3XH3FilamentState) {
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_3XH3, SIGNAL_2DJ, is2DJ); ok {
sysEvent.RelayNeedChangeEventBus.Publish(w, event)
}
}
}