///|
pub fn render_station_dashboard(engine : @simulator.SimulationEngine) -> String {
let sb = StringBuilder::new()
let station = engine.station
let table = engine.table
sb.write_string(
"================================================================================\n",
)
sb.write_string(
ansi_bold(" MOONBIT COMPUTER INTERLOCKING (CI) SAFETY ENGINE SIMULATOR\n"),
)
sb.write_string(" Station Topology: " + station.name + "\n")
sb.write_string(
"================================================================================\n\n",
)
// Station track status
sb.write_string(ansi_bold("[ TRACK CIRCUITS STATUS ]\n"))
for id, track in station.graph.tracks {
let state_str = match track.state {
Clear => ansi_white("[ CLEAR ]")
Occupied => ansi_red("[ OCCUPIED by " + track.occupying_train_id + " ]")
Locked => ansi_magenta("[ ROUTE LOCKED ]")
Fault => ansi_yellow("[ FAULT ]")
}
sb.write_string(
" Track #" +
id.to_string() +
" (" +
track.name +
"): " +
state_str +
"\n",
)
}
// Turnout status
sb.write_string("\n" + ansi_bold("[ TURNOUT SWITCHES STATUS ]\n"))
for id, turnout in station.graph.turnouts {
let pos_str = match turnout.position {
Normal => ansi_green("NORMAL (定位)")
Reverse => ansi_yellow("REVERSE (反位)")
Moving => ansi_blue("MOVING (转换中)")
UnknownPosition => ansi_red("FAULT")
}
let lock_str = if turnout.is_locked {
ansi_magenta(" [ LOCKED ]")
} else {
ansi_white(" [ UNLOCKED ]")
}
sb.write_string(
" Turnout #" +
id.to_string() +
" (" +
turnout.name +
"): " +
pos_str +
lock_str +
"\n",
)
}
// Signal lights status
sb.write_string("\n" + ansi_bold("[ SIGNALS LIGHT ASPECT ]\n"))
for id, signal in station.graph.signals {
let aspect_str = match signal.current_aspect {
Red => ansi_red("● RED (停车)")
Yellow => ansi_yellow("● YELLOW (注意)")
Green => ansi_green("● GREEN (允许)")
DoubleYellow => ansi_yellow("●● DOUBLE YELLOW (侧线通号)")
YellowGreen => ansi_yellow("● GREEN/YELLOW (预告接近)")
Blue => ansi_blue("● BLUE (调车禁止)")
White => ansi_white("● WHITE (调车允许)")
FlashingYellow => ansi_yellow("◐ FLASH YELLOW")
Dark => "○ DARK"
}
sb.write_string(
" Signal #" +
id.to_string() +
" (" +
signal.name +
"): " +
aspect_str +
"\n",
)
}
// Active routes summary
sb.write_string("\n" + ansi_bold("[ ACTIVE INTERLOCKING ROUTES ]\n"))
if table.active_slot_count() == 0 {
sb.write_string(" (No active routes locked)\n")
} else {
for r_id_int, active_state in table.active_routes {
if table.is_route_reserved(@interlocking.RouteId::new(r_id_int)) {
let r_str = active_state.rule.name
let state_str = active_state.state.to_string()
sb.write_string(
" Route #" +
r_id_int.to_string() +
" [" +
r_str +
"]: State=" +
ansi_cyan(state_str) +
"\n",
)
}
}
}
sb.write_string(
"\n--------------------------------------------------------------------------------\n",
)
sb.to_string()
}