use super::*;
use core::ptr::NonNull;
#[repr(transparent)]
pub(crate) struct MyPtr<T: ?Sized>(NonNull<T>);
impl<T: ?Sized> Clone for MyPtr<T> {
fn clone(&self) -> Self {
MyPtr(self.0)
}
}
impl<T: ?Sized> Copy for MyPtr<T> {}
impl<T: ?Sized> MyPtr<T> {
pub unsafe fn as_mut(&mut self) -> &mut T {
self.0.as_mut()
}
pub fn as_ptr(&self) -> *const T {
self.0.as_ptr()
}
}
unsafe impl<T: ?Sized> Send for MyPtr<T> {}
unsafe impl<T: ?Sized> Sync for MyPtr<T> {}
pub(crate) fn myptr<T: ?Sized>(a: &mut T) -> MyPtr<T> {
MyPtr(unsafe { NonNull::new_unchecked(a as *mut _) })
}
unsafe impl<T: Aabb> Send for NodePtr<T> {}
unsafe impl<T: Aabb> Sync for NodePtr<T> {}
pub(crate) struct NodePtr<T: Aabb> {
_range: PMutPtr<[T]>,
_cont: Option<axgeom::Range<T::Num>>,
_div: Option<T::Num>,
}
fn make_owned<A: Axis, T: Aabb>(axis: A, bots: &mut [T]) -> DinoTreeOwn<A, T> {
let inner = DinoTree::with_axis(axis, bots);
let inner: Vec<_> = inner
.inner
.into_nodes()
.drain(..)
.map(|mut node| NodePtr {
_range: node.range.as_ptr(),
_cont: node.cont,
_div: node.div,
})
.collect();
let inner = compt::dfs_order::CompleteTreeContainer::from_preorder(inner).unwrap();
DinoTreeOwn {
axis,
_inner: inner,
_bots: PMut::new(bots).as_ptr(),
}
}
fn make_owned_par<A: Axis, T: Aabb + Send + Sync>(axis: A, bots: &mut [T]) -> DinoTreeOwn<A, T> {
let inner = DinoTree::with_axis_par(axis, bots);
let inner: Vec<_> = inner
.inner
.into_nodes()
.drain(..)
.map(|mut node| NodePtr {
_range: node.range.as_ptr(),
_cont: node.cont,
_div: node.div,
})
.collect();
let inner = compt::dfs_order::CompleteTreeContainer::from_preorder(inner).unwrap();
DinoTreeOwn {
axis,
_inner: inner,
_bots: PMut::new(bots).as_ptr(),
}
}
pub struct DinoTreeOwnedBBoxPtr<A: Axis, N: Num, T> {
tree: DinoTreeOwned<A, BBox<N, MyPtr<T>>>,
bots: Vec<T>,
}
impl<N: Num, T: Send + Sync> DinoTreeOwnedBBoxPtr<DefaultA, N, T> {
pub fn new_par(bots: Vec<T>, func: impl FnMut(&T) -> Rect<N>) -> Self {
Self::with_axis_par(default_axis(), bots, func)
}
}
impl<N: Num, T> DinoTreeOwnedBBoxPtr<DefaultA, N, T> {
pub fn new(bots: Vec<T>, func: impl FnMut(&T) -> Rect<N>) -> Self {
Self::with_axis(default_axis(), bots, func)
}
}
impl<A: Axis, N: Num, T: Send + Sync> DinoTreeOwnedBBoxPtr<A, N, T> {
pub fn with_axis_par(axis: A, mut bots: Vec<T>, mut func: impl FnMut(&T) -> Rect<N>) -> Self {
let bbox = bots
.iter_mut()
.map(|b| BBox::new(func(b), myptr(b)))
.collect();
let tree = DinoTreeOwned::with_axis_par(axis, bbox);
DinoTreeOwnedBBoxPtr { bots, tree }
}
}
impl<A: Axis, N: Num, T> DinoTreeOwnedBBoxPtr<A, N, T> {
pub fn with_axis(axis: A, mut bots: Vec<T>, mut func: impl FnMut(&T) -> Rect<N>) -> Self {
let bbox = bots
.iter_mut()
.map(|b| BBox::new(func(b), myptr(b)))
.collect();
let tree = DinoTreeOwned::with_axis(axis, bbox);
DinoTreeOwnedBBoxPtr { bots, tree }
}
}
impl<A: Axis, N: Num, T> DinoTreeOwnedBBoxPtr<A, N, T> {
pub fn as_owned(&self) -> &DinoTreeOwned<A, BBox<N, &T>> {
let a = &self.tree as *const _;
let b = a as *const DinoTreeOwned<A, BBox<N, &T>>;
unsafe { &*b }
}
pub fn as_owned_mut(&mut self) -> &mut DinoTreeOwned<A, BBox<N, &mut T>> {
let a = &mut self.tree as *mut _;
let b = a as *mut DinoTreeOwned<A, BBox<N, &mut T>>;
unsafe { &mut *b }
}
pub fn get_bots(&self) -> &[T] {
&self.bots
}
pub fn get_bots_mut(&mut self) -> &mut [T] {
&mut self.bots
}
}
pub(crate) struct DinoTreeOwn<A: Axis, T: Aabb> {
axis: A,
_inner: compt::dfs_order::CompleteTreeContainer<NodePtr<T>, compt::dfs_order::PreOrder>,
_bots: PMutPtr<[T]>,
}
pub struct DinoTreeOwned<A: Axis, T: Aabb> {
tree: DinoTreeOwn<A, T>,
bots: Vec<T>,
}
impl<T: Aabb> DinoTreeOwned<DefaultA, T> {
pub fn new(bots: Vec<T>) -> DinoTreeOwned<DefaultA, T> {
Self::with_axis(default_axis(), bots)
}
}
impl<T: Aabb + Send + Sync> DinoTreeOwned<DefaultA, T> {
pub fn new_par(bots: Vec<T>) -> DinoTreeOwned<DefaultA, T> {
Self::with_axis_par(default_axis(), bots)
}
}
impl<A: Axis, T: Aabb + Send + Sync> DinoTreeOwned<A, T> {
pub fn with_axis_par(axis: A, mut bots: Vec<T>) -> DinoTreeOwned<A, T> {
DinoTreeOwned {
tree: make_owned_par(axis, &mut bots),
bots,
}
}
}
impl<A: Axis, T: Aabb> DinoTreeOwned<A, T> {
pub fn with_axis(axis: A, mut bots: Vec<T>) -> DinoTreeOwned<A, T> {
DinoTreeOwned {
tree: make_owned(axis, &mut bots),
bots,
}
}
pub fn as_tree(&self) -> &DinoTree<A, T> {
unsafe { &*(&self.tree as *const _ as *const _) }
}
pub fn as_tree_mut(&mut self) -> &mut DinoTree<A, T> {
unsafe { &mut *(&mut self.tree as *mut _ as *mut _) }
}
pub fn get_bots(&self) -> &[T] {
&self.bots
}
pub fn rebuild(&mut self, mut func: impl FnMut(&mut [T])) {
func(&mut self.bots);
let axis = self.tree.axis;
self.tree = make_owned(axis, &mut self.bots);
}
pub fn get_bots_mut(&mut self) -> PMut<[T]> {
PMut::new(&mut self.bots)
}
}