use nexus_rt::template::{Blueprint, CallbackBlueprint, CallbackTemplate, HandlerTemplate};
use nexus_rt::{Handler, ResMut, WorldBuilder, handler_blueprint, new_resource};
new_resource!(Counter(u64));
struct OnTick;
impl Blueprint for OnTick {
type Event = u32;
type Params = (ResMut<'static, Counter>,);
}
struct OnTimeout;
impl Blueprint for OnTimeout {
type Event = ();
type Params = (ResMut<'static, Counter>,);
}
impl CallbackBlueprint for OnTimeout {
type Context = TimerCtx;
}
struct TimerCtx {
order_id: u64,
fires: u64,
}
handler_blueprint!(OnEvent, Event = u64, Params = (ResMut<'static, Counter>,));
fn tick(mut counter: ResMut<Counter>, event: u32) {
**counter += event as u64;
}
fn on_timeout(ctx: &mut TimerCtx, mut counter: ResMut<Counter>, _event: ()) {
ctx.fires += 1;
**counter += ctx.order_id;
}
fn on_event(mut counter: ResMut<Counter>, event: u64) {
**counter += event;
}
fn main() {
println!("=== 1. HandlerTemplate ===\n");
let mut wb = WorldBuilder::new();
wb.register(Counter(0));
let mut world = wb.build();
let template = HandlerTemplate::<OnTick>::new(tick, world.registry());
let mut h1 = template.generate();
let mut h2 = template.generate();
let mut h3 = template.generate();
h1.run(&mut world, 10u32);
h2.run(&mut world, 20u32);
h3.run(&mut world, 30u32);
println!(" 3 handlers, total: {}", world.resource::<Counter>().0);
assert_eq!(world.resource::<Counter>().0, 60);
println!("\n=== 2. CallbackTemplate ===\n");
let mut wb = WorldBuilder::new();
wb.register(Counter(0));
let mut world = wb.build();
let cb_template = CallbackTemplate::<OnTimeout>::new(on_timeout, world.registry());
let mut cb1 = cb_template.generate(TimerCtx {
order_id: 100,
fires: 0,
});
let mut cb2 = cb_template.generate(TimerCtx {
order_id: 200,
fires: 0,
});
cb1.run(&mut world, ());
cb1.run(&mut world, ());
cb2.run(&mut world, ());
println!(" cb1 fires: {}", cb1.ctx().fires);
println!(" cb2 fires: {}", cb2.ctx().fires);
println!(" total: {}", world.resource::<Counter>().0);
assert_eq!(cb1.ctx().fires, 2);
assert_eq!(cb2.ctx().fires, 1);
assert_eq!(world.resource::<Counter>().0, 400);
println!("\n=== 3. handler_blueprint! macro ===\n");
let mut wb = WorldBuilder::new();
wb.register(Counter(0));
let mut world = wb.build();
let template = HandlerTemplate::<OnEvent>::new(on_event, world.registry());
let mut h = template.generate();
h.run(&mut world, 42u64);
println!(" result: {}", world.resource::<Counter>().0);
assert_eq!(world.resource::<Counter>().0, 42);
println!("\n=== 4. Move-out-fire pattern ===\n");
let mut wb = WorldBuilder::new();
wb.register(Counter(0));
let mut world = wb.build();
let template = HandlerTemplate::<OnTick>::new(tick, world.registry());
let mut handler = template.generate();
for i in 0..5u32 {
handler.run(&mut world, i + 1);
handler = template.generate();
}
println!(" after 5 rounds: {}", world.resource::<Counter>().0);
assert_eq!(world.resource::<Counter>().0, 15);
println!("\nDone.");
}