use crate::world::World;
use super::{DispatchManifest, ElevatorGroup};
pub const EPSILON: f64 = 1e-9;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SweepDirection {
Up,
Down,
}
impl SweepDirection {
pub const fn reversed(self) -> Self {
match self {
Self::Up => Self::Down,
Self::Down => Self::Up,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SweepMode {
Strict,
Lenient,
}
pub fn strict_demand_ahead(
dir: SweepDirection,
car_pos: f64,
group: &ElevatorGroup,
manifest: &DispatchManifest,
world: &World,
) -> bool {
group.stop_entities().iter().any(|&s| {
if !manifest.has_demand(s) {
return false;
}
let Some(p) = world.stop_position(s) else {
return false;
};
match dir {
SweepDirection::Up => p > car_pos + EPSILON,
SweepDirection::Down => p < car_pos - EPSILON,
}
})
}
pub fn rank(
mode: SweepMode,
direction: SweepDirection,
car_position: f64,
stop_position: f64,
) -> Option<f64> {
let accept = match (mode, direction) {
(SweepMode::Strict, SweepDirection::Up) => stop_position > car_position + EPSILON,
(SweepMode::Strict, SweepDirection::Down) => stop_position < car_position - EPSILON,
(SweepMode::Lenient, SweepDirection::Up) => stop_position > car_position - EPSILON,
(SweepMode::Lenient, SweepDirection::Down) => stop_position < car_position + EPSILON,
};
if accept {
Some((car_position - stop_position).abs())
} else {
None
}
}