Macro gecs::ecs_find_borrow

source ·
macro_rules! ecs_find_borrow {
    (...) => { ... };
}
Expand description

Variant of ecs_find! that runtime-borrows data, for use with a non-mut world reference.

See the ecs_find! macro for more information on find queries.

This version borrows each archetype’s data on a component-by-component basis at runtime rather than at compile-time, allowing for situations where compile-time borrow checking isn’t sufficient. This is typically used for nested queries, where an ecs_iter! or an ecs_find! needs to happen in the body of another query. This operation is backed by std::cell::RefCell operations, and will panic if you attempt to mutably borrow an archetype’s component row while any other borrow is currently active.

Example

use gecs::prelude::*;

pub struct CompA(pub u32);
pub struct CompB(pub u32);
pub struct Parent(pub Option<Entity<ArchFoo>>);

ecs_world! {
    ecs_archetype!(ArchFoo, 100, CompA, CompB, Parent);
}

fn main() {
    let mut world = EcsWorld::default();

    let parent = world.create::<ArchFoo>((CompA(0), CompB(0), Parent(None)));
    let child = world.create::<ArchFoo>((CompA(1), CompB(0), Parent(Some(parent))));

    // Assert that we found the parent, and that its CompB value is 0.
    assert!(ecs_find!(world, parent, |b: &CompB| assert_eq!(b.0, 0)).is_some());

    ecs_iter_borrow!(world, |child_a: &CompA, parent: &Parent| {
        if let Some(parent_entity) = parent.0 {
            // Note: We can't mutably borrow the CompA or Parent component data here!
            ecs_find_borrow!(world, parent_entity, |parent_b: &mut CompB| {
                // Copy the value from the child's CompA to the parent's CompB
                parent_b.0 = child_a.0;
            });
        }
    });

    // Assert that we found the parent, and that its CompB value is now 1.
    assert!(ecs_find!(world, parent, |b: &CompB| assert_eq!(b.0, 1)).is_some());
}