use crate::{
error::ffi::with_ffi_error,
geom::BoundingBox,
road::{JuncId, LaneType},
};
use carla_sys::carla_rust::client::{FfiJunction, FfiWaypointPair};
use cxx::{CxxVector, SharedPtr, UniquePtr};
use derivative::Derivative;
use static_assertions::assert_impl_all;
use super::Waypoint;
#[derive(Clone, Derivative)]
#[derivative(Debug)]
#[repr(transparent)]
pub struct Junction {
#[derivative(Debug = "ignore")]
pub(crate) inner: SharedPtr<FfiJunction>,
}
impl Junction {
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Junction.id](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Junction.id)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Junction.id](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Junction.id)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Junction.id](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Junction.id)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn id(&self) -> JuncId {
self.inner.GetId().into()
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Junction.get_waypoints](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Junction.get_waypoints)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Junction.get_waypoints](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Junction.get_waypoints)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Junction.get_waypoints](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Junction.get_waypoints)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn waypoints(&self, type_: LaneType) -> crate::Result<WaypointPairList> {
let vec = with_ffi_error("waypoints", |e| self.inner.GetWaypoints(type_, e))?;
Ok(unsafe { WaypointPairList::from_cxx(vec).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Junction.bounding_box](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Junction.bounding_box)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Junction.bounding_box](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Junction.bounding_box)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Junction.bounding_box](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Junction.bounding_box)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn bounding_box(&self) -> crate::Result<BoundingBox> {
let bbox = with_ffi_error("bounding_box", |e| self.inner.GetBoundingBox(e))?;
Ok(BoundingBox::from_native(&bbox))
}
pub(crate) fn from_cxx(ptr: SharedPtr<FfiJunction>) -> Option<Self> {
if ptr.is_null() {
return None;
}
Some(Self { inner: ptr })
}
}
#[derive(Derivative)]
#[derivative(Debug)]
#[repr(transparent)]
pub struct WaypointPairList {
#[derivative(Debug = "ignore")]
inner: UniquePtr<CxxVector<FfiWaypointPair>>,
}
impl WaypointPairList {
pub fn len(&self) -> usize {
self.inner.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, index: usize) -> Option<(Waypoint, Waypoint)> {
let pair = self.inner.get(index)?;
Some(convert_pair(pair))
}
pub fn iter(&self) -> impl Iterator<Item = (Waypoint, Waypoint)> + '_ {
self.inner.iter().map(convert_pair)
}
fn from_cxx(ptr: UniquePtr<CxxVector<FfiWaypointPair>>) -> Option<Self> {
if ptr.is_null() {
return None;
}
Some(Self { inner: ptr })
}
}
fn convert_pair(from: &FfiWaypointPair) -> (Waypoint, Waypoint) {
let first = unsafe { Waypoint::from_cxx(from.first()).unwrap_unchecked() };
let second = unsafe { Waypoint::from_cxx(from.second()).unwrap_unchecked() };
(first, second)
}
assert_impl_all!(Junction: Send, Sync);