use crate::*;
#[cfg(feature = "bevy")]
use bevy::prelude::{Bundle, Component};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "bevy", derive(Bundle))]
pub struct Lane<T: RefTrait> {
pub anchors: Edge<T>,
#[serde(default, skip_serializing_if = "is_default")]
pub forward: Motion,
#[serde(default, skip_serializing_if = "is_default")]
pub reverse: ReverseLane,
#[serde(default, skip_serializing_if = "is_default")]
pub mutex: Affiliation<T>,
pub graphs: AssociatedGraphs<T>,
#[serde(skip)]
pub marker: LaneMarker,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct LaneMarker;
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct Motion {
#[serde(default, skip_serializing_if = "OrientationConstraint::is_none")]
pub orientation_constraint: OrientationConstraint,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub speed_limit: Option<f32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dock: Option<Dock>,
}
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct RecallMotion {
pub relative_yaw: Option<Angle>,
pub absolute_yaw: Option<Angle>,
pub speed_limit: Option<f32>,
pub dock: Option<Dock>,
pub dock_name: Option<String>,
pub dock_duration: Option<f32>,
}
impl Recall for RecallMotion {
type Source = Motion;
fn remember(&mut self, source: &Motion) {
match source.orientation_constraint {
OrientationConstraint::RelativeYaw(v) => {
self.relative_yaw = Some(v);
}
OrientationConstraint::AbsoluteYaw(v) => {
self.absolute_yaw = Some(v);
}
_ => {
}
}
if let Some(s) = source.speed_limit {
self.speed_limit = Some(s);
}
if let Some(dock) = &source.dock {
self.dock = Some(dock.clone());
self.dock_name = Some(dock.name.clone());
if let Some(duration) = dock.duration {
self.dock_duration = Some(duration);
}
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
pub enum OrientationConstraint {
None,
Forwards,
Backwards,
RelativeYaw(Angle),
AbsoluteYaw(Angle),
}
impl OrientationConstraint {
pub fn is_none(&self) -> bool {
matches!(self, Self::None)
}
pub fn relative_yaw(&self) -> Option<Angle> {
match self {
Self::RelativeYaw(yaw) => Some(*yaw),
_ => None,
}
}
pub fn absolute_yaw(&self) -> Option<Angle> {
match self {
Self::AbsoluteYaw(yaw) => Some(*yaw),
_ => None,
}
}
pub fn label(&self) -> &str {
match self {
Self::None => "None",
Self::Forwards => "Forwards",
Self::Backwards => "Backwards",
Self::RelativeYaw(_) => "Relative Yaw",
Self::AbsoluteYaw(_) => "Absolute Yaw",
}
}
}
impl Default for OrientationConstraint {
fn default() -> Self {
Self::None
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub enum ReverseLane {
Same,
Disable,
Different(Motion),
}
impl ReverseLane {
pub fn label(&self) -> &str {
match self {
Self::Same => "Same",
Self::Disable => "Disabled",
Self::Different(_) => "Different",
}
}
pub fn different_motion(&self) -> Option<&Motion> {
match self {
Self::Different(motion) => Some(motion),
_ => None,
}
}
}
impl Default for ReverseLane {
fn default() -> Self {
ReverseLane::Same
}
}
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct RecallReverseLane {
pub motion: Option<Motion>,
pub previous: RecallMotion,
}
impl Recall for RecallReverseLane {
type Source = ReverseLane;
fn remember(&mut self, from_reverse: &ReverseLane) {
match from_reverse {
ReverseLane::Different(from_motion) => {
self.motion = Some(from_motion.clone());
self.previous.remember(from_motion);
}
_ => {
}
}
}
}
impl<T: RefTrait> Lane<T> {
pub fn convert<U: RefTrait>(&self, id_map: &HashMap<T, U>) -> Result<Lane<U>, T> {
Ok(Lane {
anchors: self.anchors.convert(id_map)?,
forward: self.forward.clone(),
reverse: self.reverse.clone(),
mutex: self.mutex.convert(id_map)?,
graphs: self.graphs.convert(id_map)?,
marker: Default::default(),
})
}
}
impl<T: RefTrait> From<Edge<T>> for Lane<T> {
fn from(edge: Edge<T>) -> Self {
Lane {
anchors: edge,
forward: Default::default(),
reverse: Default::default(),
mutex: Default::default(),
graphs: Default::default(),
marker: Default::default(),
}
}
}