use anput::{
entity::Entity,
processor::WorldProcessor,
query::Query,
systems::{SystemContext, Systems},
universe::Universe,
world::World,
};
use intuicio_derive::IntuicioStruct;
use rand::{Rng, rng};
use serde::{Deserialize, Serialize};
use std::error::Error;
#[derive(IntuicioStruct, Debug, Default, Clone, Copy, Serialize, Deserialize)]
struct Health {
value: usize,
}
#[derive(IntuicioStruct, Debug, Default, Clone, Copy, Serialize, Deserialize)]
struct Strength {
value: usize,
}
#[derive(IntuicioStruct, Debug, Default, Clone, Copy, Serialize, Deserialize)]
struct Monster;
#[derive(IntuicioStruct, Debug, Default, Clone, Copy, Serialize, Deserialize)]
struct Animal;
#[derive(IntuicioStruct, Debug, Default, Clone, Copy, Serialize, Deserialize)]
struct WorldChunk {
index: usize,
}
fn main() -> Result<(), Box<dyn Error>> {
let mut universe = Universe::default().with_basics(10240, 10240)?;
println!("--- Game started with chunk #0");
let world_chunk = make_world_chunk(0)?;
apply_world_chunk(&mut universe, world_chunk)?;
Systems::run_one_shot::<true>(&universe, report_world_state)?;
println!("--- Loaded chunk #1");
let world_chunk = make_world_chunk(1)?;
apply_world_chunk(&mut universe, world_chunk)?;
Systems::run_one_shot::<true>(&universe, report_world_state)?;
println!("--- Unloaded chunk #0");
release_world_chunk(&mut universe, 0)?;
Systems::run_one_shot::<true>(&universe, report_world_state)?;
Ok(())
}
fn make_world_chunk(index: usize) -> Result<World, Box<dyn Error>> {
let mut world = World::default();
let mut rng = rng();
for _ in 0..rng.random_range(2..4) {
let health = Health {
value: rng.random_range(1..10),
};
let strength = Strength {
value: rng.random_range(1..10),
};
if rng.random_bool(0.5) {
world.spawn((Monster, health, strength, WorldChunk { index }))?;
} else {
world.spawn((Animal, health, strength, WorldChunk { index }))?;
}
}
Ok(world)
}
fn apply_world_chunk(universe: &mut Universe, world: World) -> Result<(), Box<dyn Error>> {
Ok(universe
.simulation
.merge::<true>(world, &*universe.resources.get::<true, WorldProcessor>()?)?)
}
fn release_world_chunk(universe: &mut Universe, index: usize) -> Result<(), Box<dyn Error>> {
let to_remove = universe
.simulation
.query::<true, (Entity, &WorldChunk)>()
.filter(|(_, chunk)| chunk.index == index)
.map(|(entity, _)| entity)
.collect::<Vec<_>>();
for entity in to_remove {
universe.simulation.despawn(entity)?;
}
Ok(())
}
fn report_world_state(context: SystemContext) -> Result<(), Box<dyn Error>> {
let (world, query) = context.fetch::<(
&World,
Query<
true,
(
&WorldChunk,
Option<&Monster>,
Option<&Animal>,
&Health,
&Strength,
),
>,
)>()?;
for (chunk, monster, animal, health, strength) in query.query(world) {
println!(
"Chunk: {chunk:?} | Monster: {monster:?} | Animal: {animal:?} | Health: {health:?} | Strength: {strength:?}"
);
}
Ok(())
}