use crate::prelude::*;
use bevy::prelude::*;
use bevy::ecs::system::SystemParam;
use core::ops::Deref;
pub trait ReactComponent: Send + Sync + 'static {}
#[derive(Component)]
pub struct React<C: ReactComponent>
{
pub(crate) entity : Entity,
pub(crate) component : C,
}
impl<C: ReactComponent> React<C>
{
pub fn get(&self) -> &C
{
&self.component
}
pub fn get_mut<'a>(&'a mut self, c: &mut Commands) -> &'a mut C
{
c.syscall(self.entity, ReactCache::schedule_mutation_reaction::<C>);
&mut self.component
}
pub fn trigger_mutation(entity: Entity, world: &mut World)
{
world.syscall(entity, ReactCache::schedule_mutation_reaction::<C>);
}
pub fn get_noreact(&mut self) -> &mut C
{
&mut self.component
}
pub fn set_if_neq(&mut self, c: &mut Commands, new: C) -> Option<C>
where
C: PartialEq
{
if new == self.component { return None; }
c.syscall(self.entity, ReactCache::schedule_mutation_reaction::<C>);
let old = std::mem::replace(&mut self.component, new);
Some(old)
}
pub fn take(self) -> C
{
self.component
}
}
impl<C: ReactComponent> Deref for React<C>
{
type Target = C;
fn deref(&self) -> &C
{
&self.component
}
}
#[derive(SystemParam)]
pub struct Reactive<'w, 's, T: ReactComponent>
{
components: Query<'w, 's, (Entity, &'static React<T>)>,
}
impl<'w, 's, T: ReactComponent> Reactive<'w, 's, T>
{
pub fn get(&self, entity: Entity) -> Option<&T>
{
self.components.get(entity).ok().map(|(_, c)| c.get())
}
pub fn single(&self) -> (Entity, &T)
{
let (e, x) = self.components.single();
(e, x.get())
}
}
#[derive(SystemParam)]
pub struct ReactiveMut<'w, 's, T: ReactComponent>
{
components: Query<'w, 's, (Entity, &'static mut React<T>)>,
}
impl<'w, 's, T: ReactComponent> ReactiveMut<'w, 's, T>
{
pub fn get(&self, entity: Entity) -> Option<&T>
{
self.components.get(entity).ok().map(|(_, c)| c.get())
}
pub fn single(&self) -> (Entity, &T)
{
let (e, x) = self.components.single();
(e, x.get())
}
pub fn get_mut(&mut self, c: &mut Commands, entity: Entity) -> Option<&mut T>
{
let (_, x) = self.components.get_mut(entity).ok()?;
Some(x.into_inner().get_mut(c))
}
pub fn single_mut(&mut self, c: &mut Commands) -> (Entity, &mut T)
{
let (e, x) = self.components.single_mut();
(e, x.into_inner().get_mut(c))
}
pub fn get_noreact(&mut self, entity: Entity) -> Option<&mut T>
{
let (_, x) = self.components.get_mut(entity).ok()?;
Some(x.into_inner().get_noreact())
}
pub fn single_noreact(&mut self) -> (Entity, &mut T)
{
let (e, x) = self.components.single_mut();
(e, x.into_inner().get_noreact())
}
pub fn set_if_neq(&mut self, c: &mut Commands, entity: Entity, new: T) -> Option<T>
where
T: PartialEq
{
let (_, mut x) = self.components.get_mut(entity).ok()?;
(*x).set_if_neq(c, new)
}
pub fn set_single_if_not_eq(&mut self, c: &mut Commands, new: T) -> (Entity, Option<T>)
where
T: PartialEq
{
let (e, mut x) = self.components.single_mut();
(e, (*x).set_if_neq(c, new))
}
}