use crate::collider2::*;
use crate::surface_set2::*;
use crate::vector2::Vector2D;
use std::sync::{RwLock, Arc};
pub type OnBeginUpdateCallback = fn(&mut ColliderSet2, f64, f64);
pub struct ColliderSet2 {
_colliders: Vec<Collider2Ptr>,
_surface: SurfaceSet2Ptr,
_collider_data: Collider2Data,
_on_update_callback: Option<OnBeginUpdateCallback>,
}
impl ColliderSet2 {
pub fn new_default() -> ColliderSet2 {
let set = SurfaceSet2::builder().make_shared();
return ColliderSet2 {
_colliders: vec![],
_surface: set.clone(),
_collider_data: Collider2Data::new(Some(set)),
_on_update_callback: None,
};
}
pub fn new(others: Vec<Collider2Ptr>) -> ColliderSet2 {
let mut collider_set = ColliderSet2::new_default();
for collider in others {
collider_set.add_collider(collider);
}
return collider_set;
}
pub fn builder() -> Builder {
return Builder::new();
}
pub fn add_collider(&mut self, collider: Collider2Ptr) {
self._colliders.push(collider.clone());
self._surface.write().unwrap().add_surface(collider.read().unwrap().surface());
}
pub fn number_of_colliders(&self) -> usize {
return self._colliders.len();
}
pub fn collider(&self, i: usize) -> Collider2Ptr {
return self._colliders[i].clone();
}
pub fn set_on_begin_update_callback(&mut self, callback: OnBeginUpdateCallback) {
self._on_update_callback = Some(callback);
}
}
impl Collider2 for ColliderSet2 {
fn velocity_at(&self, point: &Vector2D) -> Vector2D {
let mut closest_collider = usize::MAX;
let mut closest_dist = f64::MAX;
for i in 0..self._colliders.len() {
let dist = self._colliders[i].read().unwrap().surface().read().unwrap().closest_distance(point);
if dist < closest_dist {
closest_dist = dist;
closest_collider = i;
}
}
return if closest_collider != usize::MAX {
self._colliders[closest_collider].read().unwrap().velocity_at(point)
} else {
Vector2D::new_default()
};
}
fn update(&mut self, current_time_in_seconds: f64,
time_interval_in_seconds: f64) where Self: Sized {
if !self.surface().read().unwrap().is_valid_geometry() {
return;
}
self.surface().read().unwrap().update_query_engine();
if let Some(callback) = self._on_update_callback {
(callback)(self, current_time_in_seconds, time_interval_in_seconds);
}
}
fn view(&self) -> &Collider2Data {
return &self._collider_data;
}
fn view_mut(&mut self) -> &mut Collider2Data {
return &mut self._collider_data;
}
}
pub type ColliderSet2Ptr = Arc<RwLock<ColliderSet2>>;
pub struct Builder {
_colliders: Vec<Collider2Ptr>,
}
impl Builder {
pub fn with_colliders(&mut self, others: Vec<Collider2Ptr>) -> &mut Self {
self._colliders = others;
return self;
}
pub fn build(&mut self) -> ColliderSet2 {
return ColliderSet2::new(self._colliders.clone());
}
pub fn make_shared(&mut self) -> ColliderSet2Ptr {
return ColliderSet2Ptr::new(RwLock::new(self.build()));
}
pub fn new() -> Builder {
return Builder {
_colliders: vec![]
};
}
}