Skip to main content

traaains/sim/signal/
mod.rs

1//! Track signals.
2
3use std::fmt::Display;
4
5use bevy::ecs::component::Component;
6use strum::{EnumDiscriminants, EnumIter};
7
8use crate::sim::signal::main::MainSignal;
9
10pub mod commands;
11pub mod main;
12
13pub const TRACK_OFFSET: f32 = 2.0;
14
15/// A signal position along the track.
16/// Only valid on an interval of [0.0; 1.0], which is comparable on all of its domain
17#[derive(PartialEq)]
18pub struct SignalPos(pub f32);
19
20impl TryFrom<f32> for SignalPos {
21    type Error = &'static str;
22
23    fn try_from(value: f32) -> Result<Self, Self::Error> {
24        if (0.0..=1.0).contains(&value) {
25            Ok(SignalPos(value))
26        } else {
27            Err("signal position must be in [0.0; 1.0]")
28        }
29    }
30}
31
32impl Eq for SignalPos {}
33
34impl Ord for SignalPos {
35    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
36        self.0.partial_cmp(&other.0).unwrap()
37    }
38}
39
40impl PartialOrd for SignalPos {
41    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
42        Some(self.cmp(other))
43    }
44}
45
46/// An enum wrapping all of the different types of signals available.
47#[derive(Component, EnumDiscriminants)]
48#[strum_discriminants(derive(EnumIter))]
49pub enum Signals {
50    Main(MainSignal),
51    Stop,
52}
53
54impl Display for SignalsDiscriminants {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        match self {
57            SignalsDiscriminants::Main => write!(f, "Main"),
58            SignalsDiscriminants::Stop => write!(f, "Stop"),
59        }
60    }
61}
62
63impl TryFrom<usize> for SignalsDiscriminants {
64    type Error = &'static str;
65
66    fn try_from(value: usize) -> Result<Self, Self::Error> {
67        match value {
68            0 => Ok(SignalsDiscriminants::Main),
69            1 => Ok(SignalsDiscriminants::Stop),
70            _ => Err("Invalid parameter"),
71        }
72    }
73}