use alloc::format;
use alloc::vec;
use alloc::vec::Vec;
use std::println;
use super::BehaviorSystem;
use super::eval::Snapshot;
use super::test_world::{TestWorld, world_with};
use crate::components::{
Behavior, BehaviorExpr, BehaviorNode, BehaviorSource, PropInstance, Transform,
};
use crate::ecs::System;
use crate::test_support::{Pace, bench};
const BEHAVIORS: usize = 256;
const SMALL_WORLD: usize = 1_000;
const LARGE_WORLD: usize = 20_000;
fn fixture(pace: Pace) -> (usize, [(usize, &'static str); 2]) {
match pace {
Pace::Timed => (BEHAVIORS, [(SMALL_WORLD, "1k"), (LARGE_WORLD, "20k")]),
Pace::Once => (4, [(8, "8"), (16, "16")]),
}
}
fn counter(i: usize) -> Behavior {
Behavior {
on: BehaviorSource::Tick,
body: vec![BehaviorNode::Set {
var: format!("acc{i}"),
value: BehaviorExpr::Int(1),
add: true,
}],
..Default::default()
}
}
fn padded_world(behaviors: usize, props: usize) -> TestWorld {
let mut world = world_with((0..behaviors).map(counter).collect::<Vec<_>>());
for i in 0..props {
let entity = world.components.push_typed(PropInstance);
world.components.insert_typed(
entity,
Transform {
position: [i as f32, 0.0, 0.0],
rotation_deg: [0.0; 3],
scale: [1.0; 3],
},
);
}
world
}
fn started(world: &mut TestWorld) -> BehaviorSystem {
let mut sys = BehaviorSystem::new();
sys.init(&mut world.ctx());
sys
}
fn run(pace: Pace) {
let (behaviors, worlds) = fixture(pace);
if pace == Pace::Timed {
println!("\nbehavior evaluation ({behaviors} tick behaviors)");
}
for (props, label) in worlds {
let mut world = padded_world(behaviors, props);
let mut sys = started(&mut world);
let mut elapsed = 0.0f32;
bench(
pace,
&format!("tick_world{label}"),
behaviors as u64,
|| {
elapsed += 0.016;
sys.tick(&mut world.ctx(), 0.016, elapsed);
},
);
}
for (props, label) in worlds {
let mut world = padded_world(behaviors, props);
let mut sys = started(&mut world);
let mut snapshot = Snapshot::default();
bench(
pace,
&format!("gather_world{label}"),
behaviors as u64,
|| sys.gather(&world.ctx(), &mut snapshot),
);
}
}
#[test]
#[ignore = "microbench; run it by name with --ignored --nocapture --test-threads=1"]
fn behavior_tick() {
run(Pace::Timed);
}
#[test]
fn behavior_tick_fixtures_build_and_run() {
run(Pace::Once);
}