///|
pub(all) struct HostileMatrix {
matrix : Map[Int, RouteBitSet]
max_routes : Int
} derive(Debug)
///|
pub fn HostileMatrix::new(max_routes : Int) -> HostileMatrix {
{ matrix: Map([]), max_routes }
}
///|
pub fn HostileMatrix::set_hostile(
self : HostileMatrix,
r1 : @interlocking.RouteId,
r2 : @interlocking.RouteId,
) -> Unit {
let bs1 = match self.matrix.get(r1.id) {
Some(bs) => bs
None => {
let bs = RouteBitSet::empty()
self.matrix.set(r1.id, bs)
bs
}
}
bs1.set(r2.id)
let bs2 = match self.matrix.get(r2.id) {
Some(bs) => bs
None => {
let bs = RouteBitSet::empty()
self.matrix.set(r2.id, bs)
bs
}
}
bs2.set(r1.id)
}
///|
pub fn HostileMatrix::are_hostile(
self : HostileMatrix,
r1 : @interlocking.RouteId,
r2 : @interlocking.RouteId,
) -> Bool {
match self.matrix.get(r1.id) {
None => false
Some(bs) => bs.get(r2.id)
}
}
///|
pub fn HostileMatrix::is_conflict_with_active_mask(
self : HostileMatrix,
r_id : @interlocking.RouteId,
active_mask : RouteBitSet,
) -> Bool {
match self.matrix.get(r_id.id) {
None => false
Some(hostile_mask) => hostile_mask.intersects(active_mask)
}
}
///|
pub fn HostileMatrix::build_from_interlocking_table(
table : @interlocking.InterlockingTable,
) -> HostileMatrix {
let hm = HostileMatrix::new(256)
for _, rule in table.rules {
for h_id in rule.hostile_route_ids {
hm.set_hostile(rule.id, h_id)
}
}
hm
}
///|
pub fn HostileMatrix::build_topological_conflict_table(
table : @interlocking.InterlockingTable,
) -> HostileMatrix {
let matrix = HostileMatrix::new(256)
// This is intentionally built when the detector is constructed, outside the
// 10 ms scan loop. The scan path then uses only fixed RouteBitSet masks.
for _, rule_a in table.rules {
for _, rule_b in table.rules {
match detect_topological_conflicts(rule_a, rule_b) {
Some(_) => matrix.set_hostile(rule_a.id, rule_b.id)
None => ()
}
}
}
matrix
}