use anput::{
commands::{CommandBuffer, SpawnCommand},
entity::Entity,
query::Query,
scheduler::{GraphScheduler, GraphSchedulerPlugin, SystemParallelize},
systems::SystemContext,
universe::{Res, Universe},
world::{Relation, World},
};
use moirai::jobs::Jobs;
use std::error::Error;
#[derive(Debug, Default, Clone, Copy)]
struct Energy(pub usize);
#[derive(Debug, Default, Clone, Copy)]
struct Water(pub usize);
#[derive(Debug, Default, Clone, Copy)]
struct Age(pub usize);
struct Parent;
fn main() -> Result<(), Box<dyn Error>> {
let mut universe = Universe::default().with_basics(10240, 10240)?.with_plugin(
GraphSchedulerPlugin::<true>::default()
.plugin_setup(|plugin| {
plugin
.system_setup(consume_energy, |system| {
system
.name("consume_energy")
.local(SystemParallelize::AnyWorker)
})
.system_setup(consume_water, |system| {
system
.name("consume_water")
.local(SystemParallelize::AnyWorker)
})
.system_setup(age, |system| {
system.name("age").local(SystemParallelize::AnyWorker)
})
})
.system_setup(reproduce, |system| {
system.name("reproduce").local(SystemParallelize::AnyWorker)
}),
);
let jobs = Jobs::default();
let scheduler = GraphScheduler::<true>;
universe.simulation.spawn((
Energy::default(),
Water::default(),
Age::default(),
Relation::<Parent>::default(),
))?;
for _ in 0..5 {
scheduler.run(&jobs, &mut universe)?;
}
for (entity, energy, water, age, parent) in
universe
.simulation
.query::<true, (Entity, &Energy, &Water, &Age, &Relation<Parent>)>()
{
println!(
"- Tree: {} | Energy: {} | Water: {} | Age: {} | Parent: {}",
entity,
energy.0,
water.0,
age.0,
parent.entities().next().unwrap_or_default()
);
}
Ok(())
}
fn consume_energy(context: SystemContext) -> Result<(), Box<dyn Error>> {
let (world, query) = context.fetch::<(&World, Query<true, &mut Energy>)>()?;
for energy in query.query(world) {
energy.0 += 2;
}
Ok(())
}
fn consume_water(context: SystemContext) -> Result<(), Box<dyn Error>> {
let (world, query) = context.fetch::<(&World, Query<true, &mut Water>)>()?;
for water in query.query(world) {
water.0 += 1;
}
Ok(())
}
fn age(context: SystemContext) -> Result<(), Box<dyn Error>> {
let (world, query) = context.fetch::<(&World, Query<true, &mut Age>)>()?;
for age in query.query(world) {
age.0 += 1;
}
Ok(())
}
fn reproduce(context: SystemContext) -> Result<(), Box<dyn Error>> {
let (world, mut commands, query) = context.fetch::<(
&World,
Res<true, &mut CommandBuffer>,
Query<true, (Entity, &mut Energy, &mut Water)>,
)>()?;
for (entity, energy, water) in query.query(world) {
while energy.0 >= 4 && water.0 >= 2 {
energy.0 -= 4;
water.0 -= 2;
commands.command(SpawnCommand::new((
Energy(2),
Water(1),
Age::default(),
Relation::new(Parent, entity),
)));
}
}
Ok(())
}