use bevy_ecs::prelude::*;
use bevy_entity_ptr::{EntityHandle, EntityPtr, WorldExt};
#[derive(Component)]
struct Name(&'static str);
#[derive(Component)]
struct Health(i32);
#[derive(Component)]
struct Armor(i32);
#[derive(Component)]
struct Children(Vec<EntityHandle>);
#[derive(Component)]
struct RootMarker;
fn sum_health(node: EntityPtr) -> i32 {
let my_health = node.get::<Health>().map(|h| h.0).unwrap_or(0);
let children_health: i32 = node
.get::<Children>()
.map(|c| c.0.iter().map(|h| sum_health(node.follow_handle(*h))).sum())
.unwrap_or(0);
my_health + children_health
}
fn sum_armor(node: EntityPtr) -> i32 {
let my_armor = node.get::<Armor>().map(|a| a.0).unwrap_or(0);
let children_armor: i32 = node
.get::<Children>()
.map(|c| c.0.iter().map(|h| sum_armor(node.follow_handle(*h))).sum())
.unwrap_or(0);
my_armor + children_armor
}
fn compute_health_system(world: &World, query: Query<(Entity, &Name), With<RootMarker>>) {
for (entity, name) in &query {
let root_ptr = world.entity_ptr(entity);
let total_health = sum_health(root_ptr);
println!("[Health System] {} total health: {}", name.0, total_health);
}
}
fn compute_armor_system(world: &World, query: Query<(Entity, &Name), With<RootMarker>>) {
for (entity, name) in &query {
let root_ptr = world.entity_ptr(entity);
let total_armor = sum_armor(root_ptr);
println!("[Armor System] {} total armor: {}", name.0, total_armor);
}
}
fn main() {
let mut world = World::new();
println!("Building entity hierarchies...\n");
let a1 = world.spawn((Name("a1"), Health(50), Armor(20))).id();
let a2 = world.spawn((Name("a2"), Health(50), Armor(20))).id();
let alpha = world
.spawn((
Name("Squad Alpha"),
Health(100),
Armor(50),
RootMarker,
Children(vec![EntityHandle::new(a1), EntityHandle::new(a2)]),
))
.id();
let b1 = world.spawn((Name("b1"), Health(40), Armor(15))).id();
let b2 = world.spawn((Name("b2"), Health(40), Armor(15))).id();
let _beta = world
.spawn((
Name("Squad Beta"),
Health(80),
Armor(30),
RootMarker,
Children(vec![EntityHandle::new(b1), EntityHandle::new(b2)]),
))
.id();
println!("Simulating concurrent system execution:\n");
println!("(In a real Bevy app, these would run in parallel)\n");
let mut schedule = Schedule::default();
schedule.add_systems((compute_health_system, compute_armor_system));
schedule.run(&mut world);
println!("\n--- Verification ---");
let alpha_ptr = world.entity_ptr(alpha);
let alpha_health = sum_health(alpha_ptr);
let alpha_armor = sum_armor(alpha_ptr);
println!(
"Squad Alpha: health={}, armor={}",
alpha_health, alpha_armor
);
assert_eq!(alpha_health, 200); assert_eq!(alpha_armor, 90);
println!("\nAll assertions passed!");
println!("\nKey takeaway: Use world.entity_ptr() in each system.");
println!("EntityPtr is NOT shared between systems - each system has");
println!("independent instances that are safe for concurrent reads.");
}