use crate::types::{
basic::{Double, OSString},
entities::axles::Axles,
entities::vehicle::{Performance, Properties},
entities::{ScenarioObject, Vehicle},
enums::VehicleCategory,
geometry::{BoundingBox, Center, Dimensions},
};
pub struct VehicleBuilder<'parent> {
parent: &'parent mut crate::builder::scenario::ScenarioBuilder<
crate::builder::scenario::HasEntities,
>,
name: String,
vehicle_data: PartialVehicleData,
}
pub struct DetachedVehicleBuilder {
name: String,
vehicle_data: PartialVehicleData,
}
#[derive(Debug, Default)]
struct PartialVehicleData {
name: Option<String>,
vehicle_category: Option<VehicleCategory>,
properties: Option<Properties>,
bounding_box: Option<BoundingBox>,
performance: Option<Performance>,
axles: Option<Axles>,
}
impl<'parent> VehicleBuilder<'parent> {
pub fn new(
parent: &'parent mut crate::builder::scenario::ScenarioBuilder<
crate::builder::scenario::HasEntities,
>,
name: &str,
) -> Self {
Self {
parent,
name: name.to_string(),
vehicle_data: PartialVehicleData::default(),
}
}
pub fn car(mut self) -> Self {
self.vehicle_data.vehicle_category = Some(VehicleCategory::Car);
self.vehicle_data.name = Some("PassengerCar".to_string());
self.vehicle_data.bounding_box = Some(BoundingBox {
center: Center {
x: Double::literal(1.4),
y: Double::literal(0.0),
z: Double::literal(0.9),
},
dimensions: Dimensions {
width: Double::literal(1.8),
length: Double::literal(4.5),
height: Double::literal(1.4),
},
});
self.vehicle_data.performance = Some(Performance::default());
self.vehicle_data.axles = Some(Axles::car());
self
}
pub fn truck(mut self) -> Self {
self.vehicle_data.vehicle_category = Some(VehicleCategory::Truck);
self.vehicle_data.name = Some("Truck".to_string());
self.vehicle_data.bounding_box = Some(BoundingBox {
center: Center {
x: Double::literal(4.0),
y: Double::literal(0.0),
z: Double::literal(1.5),
},
dimensions: Dimensions {
width: Double::literal(2.5),
length: Double::literal(8.0),
height: Double::literal(3.0),
},
});
self.vehicle_data.performance = Some(Performance {
max_speed: Double::literal(120.0),
max_acceleration: Double::literal(3.0),
max_deceleration: Double::literal(8.0),
});
self.vehicle_data.axles = Some(Axles::truck());
self
}
pub fn with_dimensions(mut self, length: f64, width: f64, height: f64) -> Self {
let existing_bbox = self.vehicle_data.bounding_box.unwrap_or_default();
self.vehicle_data.bounding_box = Some(BoundingBox {
center: existing_bbox.center,
dimensions: Dimensions {
width: Double::literal(width),
length: Double::literal(length),
height: Double::literal(height),
},
});
self
}
pub fn with_performance(
mut self,
max_speed: f64,
max_acceleration: f64,
max_deceleration: f64,
) -> Self {
self.vehicle_data.performance = Some(Performance {
max_speed: Double::literal(max_speed),
max_acceleration: Double::literal(max_acceleration),
max_deceleration: Double::literal(max_deceleration),
});
self
}
pub fn finish(
self,
) -> &'parent mut crate::builder::scenario::ScenarioBuilder<crate::builder::scenario::HasEntities>
{
let vehicle = Vehicle {
name: OSString::literal(
self.vehicle_data
.name
.unwrap_or_else(|| "DefaultVehicle".to_string()),
),
vehicle_category: self
.vehicle_data
.vehicle_category
.unwrap_or(VehicleCategory::Car),
bounding_box: self.vehicle_data.bounding_box.unwrap_or_default(),
performance: self.vehicle_data.performance.unwrap_or_default(),
axles: self.vehicle_data.axles.unwrap_or_else(|| Axles::car()),
properties: self.vehicle_data.properties,
};
let scenario_object = ScenarioObject::new_vehicle(self.name.clone(), vehicle);
if let Some(ref mut entities) = self.parent.data.entities {
entities.add_object(scenario_object);
}
self.parent
}
pub fn detached(self) -> DetachedVehicleBuilder {
DetachedVehicleBuilder {
name: self.name,
vehicle_data: self.vehicle_data,
}
}
}
impl DetachedVehicleBuilder {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
vehicle_data: PartialVehicleData::default(),
}
}
pub fn car(mut self) -> Self {
self.vehicle_data.vehicle_category = Some(VehicleCategory::Car);
self.vehicle_data.name = Some("PassengerCar".to_string());
self.vehicle_data.bounding_box = Some(BoundingBox {
center: Center {
x: Double::literal(1.4),
y: Double::literal(0.0),
z: Double::literal(0.9),
},
dimensions: Dimensions {
width: Double::literal(1.8),
length: Double::literal(4.5),
height: Double::literal(1.4),
},
});
self.vehicle_data.performance = Some(Performance::default());
self.vehicle_data.axles = Some(Axles::car());
self
}
pub fn truck(mut self) -> Self {
self.vehicle_data.vehicle_category = Some(VehicleCategory::Truck);
self.vehicle_data.name = Some("Truck".to_string());
self.vehicle_data.bounding_box = Some(BoundingBox {
center: Center {
x: Double::literal(4.0),
y: Double::literal(0.0),
z: Double::literal(1.5),
},
dimensions: Dimensions {
width: Double::literal(2.5),
length: Double::literal(8.0),
height: Double::literal(3.0),
},
});
self.vehicle_data.performance = Some(Performance {
max_speed: Double::literal(120.0),
max_acceleration: Double::literal(3.0),
max_deceleration: Double::literal(8.0),
});
self.vehicle_data.axles = Some(Axles::truck());
self
}
pub fn with_dimensions(mut self, length: f64, width: f64, height: f64) -> Self {
let existing_bbox = self.vehicle_data.bounding_box.unwrap_or_default();
self.vehicle_data.bounding_box = Some(BoundingBox {
center: existing_bbox.center,
dimensions: Dimensions {
width: Double::literal(width),
length: Double::literal(length),
height: Double::literal(height),
},
});
self
}
pub fn with_performance(
mut self,
max_speed: f64,
max_acceleration: f64,
max_deceleration: f64,
) -> Self {
self.vehicle_data.performance = Some(Performance {
max_speed: Double::literal(max_speed),
max_acceleration: Double::literal(max_acceleration),
max_deceleration: Double::literal(max_deceleration),
});
self
}
pub fn build(self) -> ScenarioObject {
let vehicle = Vehicle {
name: OSString::literal(
self.vehicle_data
.name
.unwrap_or_else(|| "DefaultVehicle".to_string()),
),
vehicle_category: self
.vehicle_data
.vehicle_category
.unwrap_or(VehicleCategory::Car),
bounding_box: self.vehicle_data.bounding_box.unwrap_or_default(),
performance: self.vehicle_data.performance.unwrap_or_default(),
axles: self.vehicle_data.axles.unwrap_or_else(|| Axles::car()),
properties: self.vehicle_data.properties,
};
ScenarioObject::new_vehicle(self.name.clone(), vehicle)
}
}