use crate::collision::DynCollision;
use crate::system::{update_collision, update_quadtree};
use crate::tree::QuadTree;
use crate::UpdateCollision;
use bevy::ecs::schedule::SystemConfigs;
use bevy::prelude::*;
#[derive(Debug)]
pub struct QuadTreePlugin<
P,
const N: usize,
const W: usize,
const H: usize,
const K: usize = 10,
const ID: usize = 1,
> where
P: TrackingPair,
{
_marker: std::marker::PhantomData<P>,
}
impl<P, const N: usize, const W: usize, const H: usize, const K: usize, const ID: usize> Default
for QuadTreePlugin<P, N, W, H, K, ID>
where
P: TrackingPair,
{
fn default() -> Self {
Self {
_marker: std::marker::PhantomData,
}
}
}
impl<P, const N: usize, const W: usize, const H: usize, const K: usize, const ID: usize> Plugin
for QuadTreePlugin<P, N, W, H, K, ID>
where
P: TrackingPair,
{
fn build(&self, app: &mut App) {
app.init_resource::<QuadTree<N, W, H, K, ID>>()
.add_systems(PreUpdate, P::update_collision())
.add_systems(Update, P::update_quadtree::<N, W, H, K, ID>());
#[cfg(feature = "gizmos")]
{
app.add_systems(PostUpdate, P::show_box::<N, W, H, K, ID>());
}
}
}
pub trait TrackingPair: Send + Sync + 'static {
fn update_collision() -> SystemConfigs;
fn update_quadtree<
const N: usize,
const W: usize,
const H: usize,
const K: usize,
const ID: usize,
>() -> SystemConfigs;
#[cfg(feature = "gizmos")]
fn show_box<const N: usize, const W: usize, const H: usize, const K: usize, const ID: usize>(
) -> SystemConfigs;
}
impl<S, C> TrackingPair for (S, C)
where
S: Component + DynCollision + UpdateCollision<C> + Clone,
C: Component,
{
fn update_collision() -> SystemConfigs {
(update_collision::<S, C>,).ambiguous_with_all()
}
fn update_quadtree<
const N: usize,
const W: usize,
const H: usize,
const K: usize,
const ID: usize,
>() -> SystemConfigs {
(update_quadtree::<S, N, W, H, K, ID>).ambiguous_with_all()
}
#[cfg(feature = "gizmos")]
fn show_box<const N: usize, const W: usize, const H: usize, const K: usize, const ID: usize>(
) -> SystemConfigs {
use crate::system::show_box;
(show_box::<S, N, W, H, K, ID>,).ambiguous_with_all()
}
}
macro_rules! impl_tracking_pair {
($($i: literal),+) => {
paste::paste! {
impl<$([<S $i>]),+, $([<C $i>]),+> TrackingPair for ($(([<S $i>], [<C $i>])),+,)
where
$([<S $i>]: Component + DynCollision + UpdateCollision<[<C $i>]> + Clone),+,
$([<C $i>]: Component),+
{
fn update_collision() -> SystemConfigs {
($(update_collision::<[<S $i>], [<C $i>]>),+,).chain()
}
fn update_quadtree<const N: usize, const W: usize, const H: usize, const K: usize, const ID: usize>(
) -> SystemConfigs {
($(update_quadtree::<[<S $i>], N, W, H, K, ID>),+,).chain()
}
#[cfg(feature = "gizmos")]
fn show_box<const N: usize, const W: usize, const H: usize, const K: usize, const ID: usize>(
) -> SystemConfigs {
use crate::system::show_box;
($(show_box::<[<S $i>], N, W, H, K, ID>),+,).chain()
}
}
}
};
}
impl_tracking_pair!(0);
impl_tracking_pair!(0, 1);
impl_tracking_pair!(0, 1, 2);
impl_tracking_pair!(0, 1, 2, 3);
impl_tracking_pair!(0, 1, 2, 3, 4);
impl_tracking_pair!(0, 1, 2, 3, 4, 5);
impl_tracking_pair!(0, 1, 2, 3, 4, 5, 6);
impl_tracking_pair!(0, 1, 2, 3, 4, 5, 6, 7);
impl_tracking_pair!(0, 1, 2, 3, 4, 5, 6, 7, 8);