use alloc::slice;
use core::iter::Copied;
use bevy::{
ecs::relationship::{RelatedSpawner, RelatedSpawnerCommands},
prelude::*,
};
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
use crate::prelude::*;
#[derive(Component, Deref, Reflect, Debug, PartialEq, Eq, Clone)]
#[relationship(relationship_target = Bindings)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
pub struct BindingOf(pub Entity);
#[derive(Component, Deref, Reflect, Debug, Default, PartialEq, Eq)]
#[relationship_target(relationship = BindingOf, linked_spawn)]
pub struct Bindings(Vec<Entity>);
impl<'a> IntoIterator for &'a Bindings {
type Item = Entity;
type IntoIter = Copied<slice::Iter<'a, Entity>>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub type BindingSpawner<'w> = RelatedSpawner<'w, BindingOf>;
pub type BindingSpawnerCommands<'w> = RelatedSpawnerCommands<'w, BindingOf>;
#[macro_export]
macro_rules! bindings {
[$($binding:expr),*$(,)?] => {
::bevy::prelude::related!($crate::prelude::Bindings[$($crate::prelude::IntoBindingBundle::into_binding_bundle($binding)),*])
};
}
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a valid binding bundle. The first element must be convertible into a `Binding`.",
label = "invalid binding bundle"
)]
pub trait IntoBindingBundle {
fn into_binding_bundle(self) -> impl Bundle;
}
impl<B: Into<Binding>> IntoBindingBundle for B {
fn into_binding_bundle(self) -> impl Bundle {
self.into()
}
}
macro_rules! impl_into_binding_bundle {
($($C:ident),*) => {
impl<B: Into<Binding>, $($C: Bundle,)*> IntoBindingBundle for (B, $($C),*) {
#[allow(non_snake_case, reason = "tuple unpack")]
fn into_binding_bundle(self) -> impl Bundle {
let (b, $($C),* ) = self;
(b.into(), $($C),*)
}
}
}
}
variadics_please::all_tuples!(impl_into_binding_bundle, 0, 14, C);