///|
pub enum FrameType {
Seq
Sel
Par(ParallelPolicy)
Inv
Suc
Rep(Int)
Lim(Int)
DelayFrm(Int)
LimSeq(Int)
}
///|
pub struct Builder {
stack : Array[(FrameType, Array[Node])]
mut root : Node?
}
///|
pub fn Builder::new() -> Builder {
{ stack: [], root: None }
}
///|
fn Builder::add_child(self : Builder, child : Node) -> Unit {
if self.stack.length() > 0 {
let (_, children) = self.stack[self.stack.length() - 1]
children.push(child)
} else {
self.root = Some(child)
}
}
///|
pub fn Builder::action(self : Builder, act : (Blackboard) -> Status) -> Builder {
self.add_child(action_node(act))
self
}
///|
pub fn Builder::condition(
self : Builder,
cond : (Blackboard) -> Bool,
) -> Builder {
self.add_child(condition_node(cond))
self
}
///|
pub fn Builder::wait_until(
self : Builder,
cond : (Blackboard) -> Bool,
) -> Builder {
self.add_child(wait_until_node(cond))
self
}
///|
pub fn Builder::sequence(self : Builder) -> Builder {
self.stack.push((FrameType::Seq, []))
self
}
///|
pub fn Builder::selector(self : Builder) -> Builder {
self.stack.push((FrameType::Sel, []))
self
}
///|
pub fn Builder::parallel(self : Builder, policy : ParallelPolicy) -> Builder {
self.stack.push((FrameType::Par(policy), []))
self
}
///|
pub fn Builder::limited_sequence(self : Builder, limit : Int) -> Builder {
self.stack.push((FrameType::LimSeq(limit), []))
self
}
///|
pub fn Builder::inverter(self : Builder) -> Builder {
self.stack.push((FrameType::Inv, []))
self
}
///|
pub fn Builder::succeeder(self : Builder) -> Builder {
self.stack.push((FrameType::Suc, []))
self
}
///|
pub fn Builder::repeater(self : Builder, max_repeats : Int) -> Builder {
self.stack.push((FrameType::Rep(max_repeats), []))
self
}
///|
pub fn Builder::limiter(self : Builder, min_ticks : Int) -> Builder {
self.stack.push((FrameType::Lim(min_ticks), []))
self
}
///|
pub fn Builder::delay(self : Builder, delay_ticks : Int) -> Builder {
self.stack.push((FrameType::DelayFrm(delay_ticks), []))
self
}
///|
pub fn Builder::end(self : Builder) -> Builder {
match self.stack.pop() {
Some((frame_type, children)) => {
let node = match frame_type {
FrameType::Seq => sequence_node(children)
FrameType::Sel => selector_node(children)
FrameType::Par(policy) => parallel_node(children, policy)
FrameType::LimSeq(limit) => limited_sequence(children, limit)
FrameType::Inv =>
if children.length() == 0 {
inverter_node(action_node(fn(_) { Status::BTFailure }))
} else {
inverter_node(children[0])
}
FrameType::Suc =>
if children.length() == 0 {
succeeder_node(action_node(fn(_) { Status::BTFailure }))
} else {
succeeder_node(children[0])
}
FrameType::Rep(repeats) =>
if children.length() == 0 {
repeater_node(action_node(fn(_) { Status::BTFailure }), repeats)
} else {
repeater_node(children[0], repeats)
}
FrameType::Lim(min_ticks) =>
if children.length() == 0 {
limiter_node(action_node(fn(_) { Status::BTFailure }), min_ticks)
} else {
limiter_node(children[0], min_ticks)
}
FrameType::DelayFrm(delay_ticks) =>
if children.length() == 0 {
delay_node(action_node(fn(_) { Status::BTFailure }), delay_ticks)
} else {
delay_node(children[0], delay_ticks)
}
}
self.add_child(node)
}
None => ()
}
self
}
///|
pub fn Builder::build(self : Builder) -> Node {
while self.stack.length() > 0 {
let _ = self.end()
}
match self.root {
Some(node) => node
None => action_node(fn(_) { Status::BTFailure })
}
}