use enum_dispatch::enum_dispatch;
use nalgebra::{Point3, RealField, Vector3};
use crate::{
base::{DynClone, Transform},
crate_utils::need_std,
};
#[enum_dispatch]
pub trait Source<T: RealField>: Transform<T> + Send + Sync + DynClone {
#[allow(non_snake_case)]
fn compute_B(&self, point: Point3<T>) -> Vector3<T>;
#[allow(non_snake_case)]
#[cfg(feature = "alloc")]
fn compute_B_batch(&self, points: &[Point3<T>]) -> alloc::vec::Vec<Vector3<T>>;
fn format(&self, f: &mut core::fmt::Formatter<'_>, _: &str) -> core::fmt::Result {
write!(f, "Source at {}", self.pose())
}
}
#[cfg(feature = "std")]
impl<T: RealField> core::fmt::Display for dyn Source<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.format(f, "")
}
}
need_std!(
use core::fmt::Display;
use dyn_clone::clone_trait_object;
use delegate::delegate;
use crate::base::{Float, Pose};
impl<T: Float> Transform<T> for Box<dyn Source<T>> {
delegate!(
to (**self) {
fn pose(&self) -> &Pose<T>;
fn pose_mut(&mut self) -> &mut Pose<T>;
fn set_pose(&mut self, pose: Pose<T>);
}
);
}
clone_trait_object!(<T> Source<T> where T: Float);
impl<T: Float> core::fmt::Debug for Box<dyn Source<T>> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
(**self).fmt(f)
}
}
impl<T: Float> Source<T> for Box<dyn Source<T>> {
delegate!(
to (**self) {
fn compute_B(&self, point: Point3<T>) -> Vector3<T>;
#[cfg(feature = "alloc")]
fn compute_B_batch(&self, points: &[Point3<T>]) -> Vec<Vector3<T>>;
}
);
}
);