Created
October 24, 2021 06:25
-
-
Save HackerFoo/ca1983b2642de0292adf7ca26d482a15 to your computer and use it in GitHub Desktop.
WIP Bevy Relations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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