///|
pub(all) struct Station {
name : String
graph : StationGraph
mut next_node_id : Int
mut next_edge_id : Int
mut next_track_id : Int
mut next_turnout_id : Int
mut next_signal_id : Int
} derive(Debug)
///|
pub fn Station::new(name : String) -> Station {
{
name,
graph: StationGraph::new(),
next_node_id: 1,
next_edge_id: 1,
next_track_id: 1,
next_turnout_id: 1,
next_signal_id: 1,
}
}
///|
pub fn Station::create_node(
self : Station,
name : String,
node_type : NodeType,
) -> NodeId {
let id = NodeId::new(self.next_node_id)
self.next_node_id = self.next_node_id + 1
let node = TopologyNode::new(id, name, node_type)
self.graph.add_node(node)
id
}
///|
pub fn Station::create_track(
self : Station,
name : String,
length : Double,
speed : Double,
start_node : NodeId,
end_node : NodeId,
direction : TrackDirection,
) -> TrackId {
let track_id = TrackId::new(self.next_track_id)
self.next_track_id = self.next_track_id + 1
let track = TrackSegment::new(
track_id, name, length, speed, start_node, end_node, direction,
)
self.graph.add_track(track)
let edge_id1 = EdgeId::new(self.next_edge_id)
self.next_edge_id = self.next_edge_id + 1
let edge1 = TopologyEdge::new(
edge_id1, start_node, end_node, track_id, length, direction,
)
self.graph.add_edge(edge1)
if direction == BiDirectional {
let edge_id2 = EdgeId::new(self.next_edge_id)
self.next_edge_id = self.next_edge_id + 1
let edge2 = TopologyEdge::new(
edge_id2, end_node, start_node, track_id, length, direction,
)
self.graph.add_edge(edge2)
}
track_id
}
///|
pub fn Station::create_turnout(
self : Station,
name : String,
base_node : NodeId,
normal_next_node : NodeId,
reverse_next_node : NodeId,
) -> TurnoutId {
let t_id = TurnoutId::new(self.next_turnout_id)
self.next_turnout_id = self.next_turnout_id + 1
let turnout = Turnout::new(
t_id, name, base_node, normal_next_node, reverse_next_node,
)
self.graph.add_turnout(turnout)
for node_id in [base_node, normal_next_node, reverse_next_node] {
match self.graph.get_node(node_id) {
Some(node) => node.associated_turnout = Some(t_id)
None => ()
}
}
t_id
}
///|
pub fn Station::create_signal(
self : Station,
name : String,
signal_type : SignalType,
bound_node : NodeId,
direction : TrackDirection,
) -> SignalId {
let s_id = SignalId::new(self.next_signal_id)
self.next_signal_id = self.next_signal_id + 1
let signal = Signal::new(s_id, name, signal_type, bound_node, direction)
self.graph.add_signal(signal)
match self.graph.get_node(bound_node) {
Some(node) => node.associated_signal = Some(s_id)
None => ()
}
s_id
}
///|
pub fn Station::set_turnout_position(
self : Station,
t_id : TurnoutId,
pos : TurnoutPosition,
) -> Result[Unit, String] {
match self.graph.get_turnout(t_id) {
None => Err("Turnout not found: " + t_id.id.to_string())
Some(t) =>
if t.is_locked {
Err("Cannot throw turnout " + t.name + ": it is locked by route!")
} else if t.is_in_fault {
Err("Cannot throw turnout " + t.name + ": turnout in fault state!")
} else {
t.position = pos
t.target_position = pos
Ok(())
}
}
}
///|
pub fn Station::lock_turnout(
self : Station,
t_id : TurnoutId,
) -> Result[Unit, String] {
match self.graph.get_turnout(t_id) {
None => Err("Turnout not found: " + t_id.id.to_string())
Some(t) => {
t.is_locked = true
Ok(())
}
}
}
///|
pub fn Station::unlock_turnout(
self : Station,
t_id : TurnoutId,
) -> Result[Unit, String] {
match self.graph.get_turnout(t_id) {
None => Err("Turnout not found: " + t_id.id.to_string())
Some(t) => {
t.is_locked = false
Ok(())
}
}
}
///|
pub fn Station::set_track_state(
self : Station,
tr_id : TrackId,
state : TrackState,
train_id : String,
) -> Result[Unit, String] {
match self.graph.get_track(tr_id) {
None => Err("Track segment not found: " + tr_id.id.to_string())
Some(track) => {
track.state = state
track.occupying_train_id = train_id
Ok(())
}
}
}
///|
pub fn Station::set_signal_aspect(
self : Station,
s_id : SignalId,
aspect : SignalAspect,
) -> Result[Unit, String] {
match self.graph.get_signal(s_id) {
None => Err("Signal not found: " + s_id.id.to_string())
Some(sig) => {
sig.current_aspect = aspect
sig.requested_aspect = aspect
Ok(())
}
}
}
///|
pub fn Station::lock_signal(
self : Station,
s_id : SignalId,
) -> Result[Unit, String] {
match self.graph.get_signal(s_id) {
None => Err("Signal not found: " + s_id.id.to_string())
Some(sig) => {
sig.is_locked = true
Ok(())
}
}
}
///|
pub fn Station::unlock_signal(
self : Station,
s_id : SignalId,
) -> Result[Unit, String] {
match self.graph.get_signal(s_id) {
None => Err("Signal not found: " + s_id.id.to_string())
Some(sig) => {
sig.is_locked = false
Ok(())
}
}
}