use anyhow::Context;
use flax::{
components::{child_of, name},
*,
};
use glam::{vec2, Mat4, Vec2};
use rand::{rngs::StdRng, Rng, SeedableRng};
use tracing_subscriber::{prelude::*, registry};
use tracing_tree::HierarchicalLayer;
fn main() -> anyhow::Result<()> {
registry().with(HierarchicalLayer::default()).init();
component! {
position: Vec2,
}
let mut world = World::new();
let mut cmd = CommandBuffer::new();
cmd.spawn(Entity::builder().set(name(), "a".into()));
cmd.apply(&mut world)?;
let id = Query::new(entity_ids())
.filter(name().eq("a"))
.borrow(&world)
.iter()
.next()
.context("Missing entity")?;
cmd.set(id, position(), vec2(32.0, 2.6));
let id2 = world.spawn();
cmd.spawn_at(
id,
EntityBuilder::new()
.set(name(), "b".into())
.set(position(), vec2(4.6, 8.4)),
);
cmd.remove(id2, position());
cmd.apply(&mut world)?;
cmd.set(id2, child_of(id), ());
cmd.defer(move |w| {
w.despawn_recursive(id, child_of)?;
Ok(())
});
cmd.apply(&mut world)?;
component! {
world_matrix: Mat4 => [Debuggable],
}
let mut rng = StdRng::seed_from_u64(42);
let spawner = System::builder()
.with_name("spawn_entities")
.with_query(Query::new(()))
.with_cmd_mut()
.build(move |mut q: QueryBorrow<()>, cmd: &mut CommandBuffer| {
let count = q.count();
for _ in count..64 {
tracing::info!("Spawning new entity");
cmd.spawn(
Entity::builder()
.set(name(), "entity".to_string())
.set(position(), rng.gen()),
);
}
});
let add_world_matrix = System::builder()
.with_name("add_world_matrix")
.with_query(Query::new((entity_ids(), position())).without(world_matrix()))
.with_cmd_mut()
.build(
|mut q: QueryBorrow<(EntityIds, Component<Vec2>), _>, cmd: &mut CommandBuffer| {
for (id, pos) in &mut q {
tracing::info!("Adding world matrix to {id}");
cmd.set(id, world_matrix(), Mat4::from_translation(pos.extend(0.0)));
}
},
);
let update_world_matrix = System::builder()
.with_name("update_world_matrix")
.with_query(
Query::new((entity_ids(), position(), world_matrix().as_mut()))
.filter(position().modified()),
)
.for_each(|(id, pos, ltw)| {
tracing::info!("Updating world matrix for {id}");
*ltw = Mat4::from_translation(pos.extend(0.0));
});
let mut schedule = Schedule::builder()
.with_system(spawner)
.flush()
.with_system(add_world_matrix)
.flush()
.with_system(update_world_matrix)
.build();
schedule
.execute_par(&mut world)
.context("Failed to run schedule")?;
Ok(())
}