Skip to content

Instantly share code, notes, and snippets.

@HackerFoo
Created October 24, 2021 06:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HackerFoo/ca1983b2642de0292adf7ca26d482a15 to your computer and use it in GitHub Desktop.
Save HackerFoo/ca1983b2642de0292adf7ca26d482a15 to your computer and use it in GitHub Desktop.
WIP Bevy Relations
use crate::*;
pub trait Relation
where Self: Component + From<Self::Entities>,
for<'a> &'a Self::Entities: IntoIterator<Item = &'a Entity>,
{
type Entities: PartialEq;
fn entities(&self) -> &Self::Entities;
fn disassociate(&mut self, _entity: Entity) {}
fn set_entities(&mut self, entities: Self::Entities);
fn insert_indicies(&self,
entity: Entity,
query: &mut Query<&mut RelationIndex>) {
for e in self.entities() {
query.insert_index(*e, entity);
}
}
fn remove_indicies(&self,
entity: Entity,
query: &mut Query<&mut RelationIndex>) {
for e in self.entities() {
query.remove_index(*e, entity);
}
}
}
#[derive(Debug, Clone, Deref, DerefMut, Component)]
pub struct RelationIndex(HashSet<Entity>);
impl RelationIndex
{
pub fn new() -> Self {
Self(HashSet::new())
}
pub fn disassociate<T>(&mut self, entity: Entity, query: &mut Query<(Entity, &mut T)>)
where T: Relation,
for<'a> &'a <T as Relation>::Entities: IntoIterator<Item = &'a Entity>
{
for e in self.clone().iter() {
if let Ok((e, mut rel)) = query.get_mut(*e) {
rel.disassociate(entity);
self.remove(&e);
}
}
}
pub fn relations<T, B>(&self,
q_rel: &Query<&T>) -> B
where T: Relation,
B: FromIterator<Entity>,
for<'a> &'a <T as Relation>::Entities: IntoIterator<Item = &'a Entity>
{
self.iter().filter_map(move |e| q_rel.get(*e).ok().map(|_| *e)).collect()
}
pub fn remove_relations<T>(&mut self,
q_rel: &Query<&T>)
where T: Relation,
for<'a> &'a <T as Relation>::Entities: IntoIterator<Item = &'a Entity>
{
self.retain(|e| q_rel.get(*e).is_ok())
}
pub fn remove_relations_mut<T>(&mut self,
q_rel: &mut Query<&mut T>)
where T: Relation,
for<'a> &'a <T as Relation>::Entities: IntoIterator<Item = &'a Entity>
{
self.retain(|e| q_rel.get_mut(*e).is_ok())
}
pub fn has_relation<T>(&self,
q_rel: &Query<(Entity, &T)>) -> bool
where T: Relation,
for<'a> &'a <T as Relation>::Entities: IntoIterator<Item = &'a Entity>
{
self.iter().any(move |e| q_rel.get(*e).is_ok())
}
pub fn has_relation_mut<T>(&self,
q_rel: &mut Query<(Entity, &mut T)>) -> bool
where T: Relation,
for<'a> &'a <T as Relation>::Entities: IntoIterator<Item = &'a Entity>
{
self.iter().any(move |e| q_rel.get_mut(*e).is_ok())
}
}
trait RelationIndexQuery {
fn remove_index(&mut self, src: Entity, dst: Entity);
fn insert_index(&mut self, src: Entity, dst: Entity);
}
impl RelationIndexQuery for Query<'_, '_, &mut RelationIndex> {
fn remove_index(&mut self, src: Entity, dst: Entity) {
if let Ok(mut index) = self.get_mut(src) {
index.remove(&dst);
}
}
fn insert_index(&mut self, src: Entity, dst: Entity) {
if let Ok(mut index) = self.get_mut(src) {
index.insert(dst);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment