Skip to content

Commit

Permalink
entity_hierarchy example + function renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
Indra-db committed Mar 4, 2024
1 parent 3f2ef29 commit 670b04b
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 13 deletions.
93 changes: 93 additions & 0 deletions flecs_ecs/examples/entity_hierarchy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
mod common;
use common::*;

#[derive(Debug, Default, Clone, Component)]
struct Star;

#[derive(Debug, Default, Clone, Component)]
struct Planet;

#[derive(Debug, Default, Clone, Component)]
struct Moon;

fn iterate_tree(entity: Entity, position_parent: &Position) {
// Print hierarchical name of entity & the entity type
println!(
"{} [{}]",
entity.get_hierarchy_path().unwrap(),
entity.get_archetype()
);

// Get the position of the entity
let pos = entity.get::<Position>().unwrap();

// Calculate actual position
let pos_actual = Position {
x: pos.x + position_parent.x,
y: pos.y + position_parent.y,
};

// Print the position
println!("{:?}", pos_actual);

entity.for_each_child_of(|child| {
iterate_tree(child, &pos_actual);
});
}
fn main() {
let world = World::new();

// Create a simple hierarchy.
// Hierarchies use ECS relationships and the builtin flecs::ChildOf relationship to
// create entities as children of other entities.

let sun = world
.new_entity_named(CStr::from_bytes_with_nul(b"Sun\0").unwrap())
.set(Position { x: 1.0, y: 1.0 });

world
.new_entity_named(CStr::from_bytes_with_nul(b"Mercury\0").unwrap())
.set(Position { x: 1.0, y: 1.0 })
.add::<Planet>()
.child_of(&sun); // Shortcut for add(flecs::ChildOf, sun)

world
.new_entity_named(CStr::from_bytes_with_nul(b"Venus\0").unwrap())
.set(Position { x: 2.0, y: 2.0 })
.add::<Planet>()
.child_of(&sun);

let earth = world
.new_entity_named(CStr::from_bytes_with_nul(b"Earth\0").unwrap())
.set(Position { x: 3.0, y: 3.0 })
.add::<Planet>()
.child_of(&sun);

let moon = world
.new_entity_named(CStr::from_bytes_with_nul(b"Moon\0").unwrap())
.set(Position { x: 0.1, y: 0.1 })
.add::<Moon>()
.child_of(&earth);

// Is the Moon a child of the Earth?
println!(
"Is the Moon a child of the Earth? {}",
moon.has_pair_ids(ECS_CHILD_OF, earth.raw_id)
);

// Do a depth-first traversal of the tree
iterate_tree(sun, &Position { x: 0.0, y: 0.0 });

// Output
// Is the Moon a child of the Earth? true
// ::Sun [Position, (Identifier,Name)]
// Position { x: 1.0, y: 1.0 }
// ::Sun::Mercury [Position, Planet, (Identifier,Name), (ChildOf,Sun)]
// Position { x: 2.0, y: 2.0 }
// ::Sun::Venus [Position, Planet, (Identifier,Name), (ChildOf,Sun)]
// Position { x: 3.0, y: 3.0 }
// ::Sun::Earth [Position, Planet, (Identifier,Name), (ChildOf,Sun)]
// Position { x: 4.0, y: 4.0 }
// ::Sun::Earth::Moon [Component, Position, Sun.Earth.Moon, (Identifier,Name), (Identifier,Symbol), (ChildOf,Sun.Earth), (OnDelete,Panic)]
// Position { x: 4.1, y: 4.1 }
}
16 changes: 15 additions & 1 deletion flecs_ecs/src/core/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,11 +704,25 @@ impl Entity {
///
/// * C++ API: `entity_builder::child_of`
#[doc(alias = "entity_builder::child_of")]
pub fn child_of<T: CachedComponentData>(self) -> Self {
pub fn child_of_type<T: CachedComponentData>(self) -> Self {
let world = self.world;
self.child_of_id(T::get_id(world))
}

/// Shortcut for add(ChildOf, entity).
///
/// # Arguments
///
/// * `parent`: The second element of the pair.
///
/// # See also
///
/// * C++ API: `entity_builder::child_of`
#[doc(alias = "entity_builder::child_of")]
pub fn child_of(self, parent: &Entity) -> Self {
self.child_of_id(parent.raw_id)
}

/// Shortcut for add(DependsOn, entity).
///
/// # Arguments
Expand Down
2 changes: 1 addition & 1 deletion flecs_ecs/src/core/entity_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,7 @@ impl EntityView {
///
/// * C++ API: `entity_view::has`
#[doc(alias = "entity_view::has")]
pub fn has_pair_by_ids(&self, first: IdT, second: IdT) -> bool {
pub fn has_pair_ids(&self, first: IdT, second: IdT) -> bool {
ecs_has_pair(self.world, self.raw_id, first, second)
}

Expand Down
2 changes: 1 addition & 1 deletion flecs_ecs/src/core/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ impl Table {
///
/// * C++ API: `table::has`
#[doc(alias = "table::has")]
pub fn has_pair_by_ids(&self, first: EntityT, second: EntityT) -> bool {
pub fn has_pair_ids(&self, first: EntityT, second: EntityT) -> bool {
self.find_type_index_pair_ids(first, second).is_some()
}

Expand Down
2 changes: 1 addition & 1 deletion flecs_ecs/src/core/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ impl World {
#[doc(alias = "world::has")]
#[inline(always)]
pub fn has_pair_by_id(&self, first: EntityT, second: EntityT) -> bool {
Entity::new_from_existing_raw(self.raw_world, first).has_pair_by_ids(first, second)
Entity::new_from_existing_raw(self.raw_world, first).has_pair_ids(first, second)
}

/// Add a singleton component.
Expand Down
18 changes: 9 additions & 9 deletions flecs_ecs/tests/entity_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ fn entity_add_childof() {
assert!(entity.is_valid());

entity.add_pair_ids(ECS_CHILD_OF, parent.raw_id);
assert!(entity.has_pair_by_ids(ECS_CHILD_OF, parent.raw_id));
assert!(entity.has_pair_ids(ECS_CHILD_OF, parent.raw_id));
}

#[test]
Expand All @@ -250,7 +250,7 @@ fn entity_add_instanceof() {
assert!(entity.is_valid());

entity.add_pair_ids(ECS_IS_A, base.raw_id);
assert!(entity.has_pair_by_ids(ECS_IS_A, base.raw_id));
assert!(entity.has_pair_ids(ECS_IS_A, base.raw_id));
}

#[test]
Expand Down Expand Up @@ -317,10 +317,10 @@ fn entity_remove_childof() {
assert!(entity.is_valid());

entity.add_pair_ids(ECS_CHILD_OF, parent.raw_id);
assert!(entity.has_pair_by_ids(ECS_CHILD_OF, parent.raw_id));
assert!(entity.has_pair_ids(ECS_CHILD_OF, parent.raw_id));

entity.remove_pair_ids(ECS_CHILD_OF, parent.raw_id);
assert!(!entity.has_pair_by_ids(ECS_CHILD_OF, parent.raw_id));
assert!(!entity.has_pair_ids(ECS_CHILD_OF, parent.raw_id));
}

#[test]
Expand All @@ -334,10 +334,10 @@ fn entity_remove_instanceof() {
assert!(entity.is_valid());

entity.add_pair_ids(ECS_IS_A, base.raw_id);
assert!(entity.has_pair_by_ids(ECS_IS_A, base.raw_id));
assert!(entity.has_pair_ids(ECS_IS_A, base.raw_id));

entity.remove_pair_ids(ECS_IS_A, base.raw_id);
assert!(!entity.has_pair_by_ids(ECS_IS_A, base.raw_id));
assert!(!entity.has_pair_ids(ECS_IS_A, base.raw_id));
}

#[test]
Expand Down Expand Up @@ -582,7 +582,7 @@ fn entity_has_childof() {

let child = world.new_entity().add_pair_ids(ECS_CHILD_OF, parent.raw_id);

assert!(child.has_pair_by_ids(ECS_CHILD_OF, parent.raw_id));
assert!(child.has_pair_ids(ECS_CHILD_OF, parent.raw_id));
}

#[test]
Expand All @@ -593,7 +593,7 @@ fn entity_has_instanceof() {

let instance = world.new_entity().add_pair_ids(ECS_IS_A, base.raw_id);

assert!(instance.has_pair_by_ids(ECS_IS_A, base.raw_id));
assert!(instance.has_pair_ids(ECS_IS_A, base.raw_id));
}

#[test]
Expand All @@ -607,7 +607,7 @@ fn entity_has_instanceof_indirect() {

let instance = world.new_entity().add_pair_ids(ECS_IS_A, base.raw_id);

assert!(instance.has_pair_by_ids(ECS_IS_A, base_of_base.raw_id));
assert!(instance.has_pair_ids(ECS_IS_A, base_of_base.raw_id));
}

#[test]
Expand Down

0 comments on commit 670b04b

Please sign in to comment.