// ============================================================
// Blackboard-driven routing policies
// ============================================================
///|
/// Route to one child using a string key on the blackboard.
pub fn route_node(
key : String,
routes : Map[String, Node],
fallback : Node,
) -> Node {
let tick = fn(bb : Blackboard) {
match bb.get_string(key) {
Some(route) =>
match routes.get(route) {
Some(child) => child.tick(bb)
None => fallback.tick(bb)
}
None => fallback.tick(bb)
}
}
let reset = fn() {
routes.each(fn(_, child) { child.reset() })
fallback.reset()
}
Node::new(tick, reset)
}
///|
/// Run a child only while a blackboard integer is within an inclusive range.
pub fn int_range_guard_node(
key : String,
minimum : Int,
maximum : Int,
child : Node,
) -> Node {
let tick = fn(bb : Blackboard) {
match bb.get_int(key) {
Some(value) =>
if value >= minimum && value <= maximum {
child.tick(bb)
} else {
child.reset()
Status::BTFailure
}
None => {
child.reset()
Status::BTFailure
}
}
}
let reset = fn() { child.reset() }
Node::new(tick, reset)
}
///|
/// Set a blackboard value after a child completes successfully.
pub fn set_int_on_success_node(key : String, value : Int, child : Node) -> Node {
let tick = fn(bb : Blackboard) {
let status = child.tick(bb)
if status == Status::BTSuccess {
bb.set_int(key, value)
}
status
}
let reset = fn() { child.reset() }
Node::new(tick, reset)
}
///|
/// Set a blackboard value after a child fails.
pub fn set_bool_on_failure_node(
key : String,
value : Bool,
child : Node,
) -> Node {
let tick = fn(bb : Blackboard) {
let status = child.tick(bb)
if status == Status::BTFailure {
bb.set_bool(key, value)
}
status
}
let reset = fn() { child.reset() }
Node::new(tick, reset)
}