Skip to content

Commit 97cb45e

Browse files
committed
first impl
1 parent df5e3a7 commit 97cb45e

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

crates/bevy_ecs/src/relationship/relationship_source_collection.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,61 @@ impl<const N: usize> RelationshipSourceCollection for SmallVec<[Entity; N]> {
116116
}
117117
}
118118

119+
impl RelationshipSourceCollection for Entity {
120+
type SourceIter<'a> = core::iter::Copied<core::iter::Once<Entity>>;
121+
122+
fn with_capacity(_capacity: usize) -> Self {
123+
Entity::PLACEHOLDER
124+
}
125+
126+
fn add(&mut self, entity: Entity) {
127+
*self = entity;
128+
}
129+
130+
fn remove(&mut self, entity: Entity) {
131+
if *self == entity {
132+
*self = Entity::PLACEHOLDER
133+
}
134+
}
135+
136+
fn iter(&self) -> Self::SourceIter<'_> {
137+
core::iter::once(*self)
138+
}
139+
140+
fn len(&self) -> usize {
141+
1
142+
}
143+
}
144+
145+
impl RelationshipSourceCollection for Option<Entity> {
146+
type SourceIter<'a> = core::iter::Copied<core::option::Iter<'a, Entity>>;
147+
148+
fn with_capacity(_capacity: usize) -> Self {
149+
None
150+
}
151+
152+
fn add(&mut self, entity: Entity) {
153+
*self = Some(entity);
154+
}
155+
156+
fn remove(&mut self, entity: Entity) {
157+
if self.is_none_or(|e| e == entity) {
158+
*self = None
159+
}
160+
}
161+
162+
fn iter(&self) -> Self::SourceIter<'_> {
163+
self.iter().copied()
164+
}
165+
166+
fn len(&self) -> usize {
167+
match self {
168+
Some(_) => 1,
169+
None => 0,
170+
}
171+
}
172+
}
173+
119174
#[cfg(test)]
120175
mod tests {
121176
use super::*;
@@ -184,4 +239,37 @@ mod tests {
184239
let collection = rel_target.collection();
185240
assert_eq!(collection, &SmallVec::from_buf([a]));
186241
}
242+
243+
#[test]
244+
fn option_entity_relationship_source_collection() {
245+
#[derive(Component)]
246+
#[relationship(relationship_target = Behind)]
247+
struct InFront(Entity);
248+
249+
#[derive(Component)]
250+
#[relationship_target(relationship = InFront)]
251+
struct Behind(Option<Entity>);
252+
253+
let mut world = World::new();
254+
let a = world.spawn_empty().id();
255+
let b = world.spawn_empty().id();
256+
257+
// in front test
258+
// world.entity_mut(a).insert(InFront(b));
259+
//
260+
// assert_eq!(world.get::<Behind>(b).unwrap().0, Some(a));
261+
// world.despawn(b);
262+
// assert!(world.get::<InFront>(a).is_none());
263+
//
264+
// let c = world.spawn_empty().id();
265+
// world.despawn(a);
266+
// assert!(world.get::<Behind>(c).is_none());
267+
268+
// test adding target and see if relationship gets added?
269+
world.entity_mut(b).insert(Behind(Some(a)));
270+
271+
assert_eq!(world.get::<InFront>(b).unwrap().0, a);
272+
// world.despawn(b);
273+
// assert!(world.get::<InFront>(a).is_none());
274+
}
187275
}

examples/ecs/relationships.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ fn main() {
3838
// is great for writing tests and teaching abstract concepts!
3939
let mut world = World::new();
4040

41+
// an entity can only target one other entity
42+
//
43+
// an entity can only point to one entity
44+
// an entity can be pointed to by many other entities
45+
//
46+
// an entity can be related to many other entities
47+
48+
let parent1 = world.spawn_empty().id();
49+
// let parent2 = world.spawn_empty().id();
50+
51+
// current impl cannot do many to one relationships
52+
// child of multiple parents
53+
let child = world.spawn((ChildOf(parent1))).id();
54+
let child2 = world.spawn((ChildOf(parent1))).id();
55+
56+
// try to get which entities the entity is a child of
57+
println!("{:?}", world.get::<Children>(parent1));
58+
4159
// We're going to spawn a few entities and relate them to each other in a complex way.
4260
// To start, Bob will target Alice, Charlie will target Bob,
4361
// and Alice will target Charlie. This creates a loop in the relationship graph.

0 commit comments

Comments
 (0)