///|
pub(all) struct RouteId {
id : Int
} derive(Eq, Debug, Compare)
///|
pub fn RouteId::new(id : Int) -> RouteId {
{ id, }
}
///|
pub(all) enum RouteState {
RouteInactive
RouteRequested
SwitchesThrowing
RouteLocked
ApproachLocked
TrainInRoute
SectionalUnlocking
RouteCancelling
RouteFault
} derive(Eq, Debug)
///|
pub fn RouteState::to_string(self : RouteState) -> String {
match self {
RouteInactive => "INACTIVE"
RouteRequested => "REQUESTED"
SwitchesThrowing => "THROWING_SWITCHES"
RouteLocked => "LOCKED"
ApproachLocked => "APPROACH_LOCKED"
TrainInRoute => "TRAIN_IN_ROUTE"
SectionalUnlocking => "UNLOCKING"
RouteCancelling => "CANCELLING"
RouteFault => "FAULT"
}
}
///|
pub(all) enum RouteType {
ReceivingRoute // 进站列车进路
DepartureRoute // 出站列车进路
PassingRoute // 通过列车进路
ShuntingRoute // 调车进路
} derive(Eq, Debug)
///|
pub fn RouteType::to_string(self : RouteType) -> String {
match self {
ReceivingRoute => "RECEIVING"
DepartureRoute => "DEPARTURE"
PassingRoute => "PASSING"
ShuntingRoute => "SHUNTING"
}
}
///|
pub(all) struct SwitchRequirement {
turnout_id : @topology.TurnoutId
required_position : @topology.TurnoutPosition
} derive(Debug)
///|
pub fn SwitchRequirement::new(
turnout_id : @topology.TurnoutId,
required_position : @topology.TurnoutPosition,
) -> SwitchRequirement {
{ turnout_id, required_position }
}
///|
pub(all) struct FlankProtection {
turnout_id : @topology.TurnoutId
required_position : @topology.TurnoutPosition
description : String
} derive(Debug)
///|
pub fn FlankProtection::new(
turnout_id : @topology.TurnoutId,
required_position : @topology.TurnoutPosition,
description : String,
) -> FlankProtection {
{ turnout_id, required_position, description }
}
///|
pub(all) enum ReleaseStage {
StageNotStarted
StageApproachOccupied // 接近区段占用
StageEntrySectionOccupied // 进路入口区段占用
StageMiddleSectionOccupied // 进路中间区段占用
StageExitSectionOccupied // 进路出口区段占用
StageFullyReleased // 完全解锁
} derive(Eq, Debug)
///|
pub(all) struct InterlockingRule {
id : RouteId
name : String
route_type : RouteType
entry_signal : @topology.SignalId
exit_signal : @topology.SignalId
switches : Array[SwitchRequirement]
flank_switches : Array[FlankProtection]
track_sections : Array[@topology.TrackId]
hostile_route_ids : Array[RouteId]
target_aspect : @topology.SignalAspect
approach_section : @topology.TrackId?
} derive(Debug)
///|
pub fn InterlockingRule::new(
id : RouteId,
name : String,
route_type : RouteType,
entry_signal : @topology.SignalId,
exit_signal : @topology.SignalId,
switches : Array[SwitchRequirement],
flank_switches : Array[FlankProtection],
track_sections : Array[@topology.TrackId],
hostile_route_ids : Array[RouteId],
target_aspect : @topology.SignalAspect,
approach_section : @topology.TrackId?,
) -> InterlockingRule {
{
id,
name,
route_type,
entry_signal,
exit_signal,
switches,
flank_switches,
track_sections,
hostile_route_ids,
target_aspect,
approach_section,
}
}
///|
pub(all) struct ActiveRouteState {
mut rule : InterlockingRule
mut state : RouteState
mut release_stage : ReleaseStage
unlocked_sections : FixedArray[Bool]
occupied_sections : FixedArray[Bool]
mut highest_observed_section_index : Int
mut occupancy_order_violation : Bool
mut observed_train_id : String
mut entry_time_ms : Int64
} derive(Debug)
///|
pub fn ActiveRouteState::new(rule : InterlockingRule) -> ActiveRouteState {
{
rule,
state: RouteInactive,
release_stage: StageNotStarted,
unlocked_sections: FixedArray::make(256, false),
occupied_sections: FixedArray::make(256, false),
highest_observed_section_index: -1,
occupancy_order_violation: false,
observed_train_id: "",
entry_time_ms: 0,
}
}
///|
fn ActiveRouteState::reset_for_rule(
self : ActiveRouteState,
rule : InterlockingRule,
) -> Unit {
self.rule = rule
self.state = RouteInactive
self.release_stage = StageNotStarted
self.highest_observed_section_index = -1
self.occupancy_order_violation = false
self.observed_train_id = ""
self.entry_time_ms = 0
let mut index = 0
while index < 256 {
self.unlocked_sections[index] = false
self.occupied_sections[index] = false
index = index + 1
}
}