use ::behavior_tree_lite::{ boxify, load, parse_file, BehaviorCallback, BehaviorNode, BehaviorResult, Context, Lazy, Registry, Symbol, }; use behavior_tree_lite::PortSpec; use std::fs; #[derive(Clone, Debug)] struct Arm { name: String, } #[derive(Debug)] struct Body { left_arm: Arm, right_arm: Arm, } struct PrintArmNode; impl BehaviorNode for PrintArmNode { fn provided_ports(&self) -> Vec { vec![PortSpec::new_in("arm")] } fn tick(&mut self, _arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult { static ARM_SYM: Lazy = Lazy::new(|| "arm".into()); if let Some(arm) = ctx.get::(*ARM_SYM) { println!("PrintArmNode: {}", arm.name); } BehaviorResult::Success } } struct PrintStringNode; impl BehaviorNode for PrintStringNode { fn provided_ports(&self) -> Vec { vec![PortSpec::new_in("input")] } fn tick(&mut self, _arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult { static INPUT: Lazy = Lazy::new(|| "input".into()); if let Some(s) = ctx.get::(*INPUT) { println!("PrintStringNode: {s}"); } else { println!("PrintStringNode: didn't get string"); } BehaviorResult::Success } } struct PrintBodyNode; impl BehaviorNode for PrintBodyNode { fn provided_ports(&self) -> Vec { vec![ PortSpec::new_in("body"), PortSpec::new_out("left_arm"), PortSpec::new_out("right_arm"), ] } fn tick(&mut self, _: BehaviorCallback, ctx: &mut Context) -> BehaviorResult { static BODY_SYM: Lazy = Lazy::new(|| "body".into()); static LEFT_ARM_SYM: Lazy = Lazy::new(|| "left_arm".into()); static RIGHT_ARM_SYM: Lazy = Lazy::new(|| "right_arm".into()); if let Some(body) = ctx.get::(*BODY_SYM) { let left_arm = body.left_arm.clone(); let right_arm = body.right_arm.clone(); println!("PrintBodyNode: {body:?}"); ctx.set(*LEFT_ARM_SYM, left_arm); ctx.set(*RIGHT_ARM_SYM, right_arm); BehaviorResult::Success } else { println!("No body!"); BehaviorResult::Fail } } } fn main() -> anyhow::Result<()> { let mut registry = Registry::default(); registry.register("PrintArmNode", boxify(|| PrintArmNode)); registry.register("PrintBodyNode", boxify(|| PrintBodyNode)); registry.register("PrintStringNode", boxify(|| PrintStringNode)); let file = String::from_utf8(fs::read("test.txt")?).unwrap(); let (_, tree_source) = parse_file(&file).map_err(|e| anyhow::format_err!("parse error: {e:?}"))?; println!("tree_source: {tree_source:#?}"); // if let Some(main) = trees.get_mut("main") { let body = Body { left_arm: Arm { name: "left_arm".to_string(), }, right_arm: Arm { name: "right_arm".to_string(), }, }; let mut ctx = Context::default(); ctx.set("body", body); let mut root = load(&tree_source, ®istry, true).map_err(|e| anyhow::format_err!("parse error: {e}"))?; let mut null = |_: &dyn std::any::Any| -> Option> { None }; println!("root: {:?}", root.tick(&mut null, &mut ctx)); println!("Total symbols: {}", Symbol::count()); Ok(()) }