use crate::{
self as behaviortree, Condition, ConstString, EMPTY_STR,
behavior::{Behavior, BehaviorData, BehaviorError, BehaviorResult, BehaviorState},
input_port,
port::PortList,
port_list,
tree::BehaviorTreeElementList,
};
use alloc::{
boxed::Box,
string::{String, ToString},
};
use tinyscript::SharedRuntime;
const ENTRY: &str = "entry";
#[derive(Condition, Debug, Default)]
#[behavior(groot2)]
pub struct WasEntryUpdated {
sequence_id: usize,
entry_key: ConstString,
}
#[async_trait::async_trait]
impl Behavior for WasEntryUpdated {
fn on_start(
&mut self,
behavior: &mut BehaviorData,
_children: &mut BehaviorTreeElementList,
_runtime: &SharedRuntime,
) -> Result<(), BehaviorError> {
self.sequence_id = 0;
match behavior.remappings().find(ENTRY) {
databoard::RemappingTarget::BoardPointer(board_pointer)
| databoard::RemappingTarget::LocalPointer(board_pointer)
| databoard::RemappingTarget::RootPointer(board_pointer)
| databoard::RemappingTarget::StringAssignment(board_pointer) => {
self.entry_key = board_pointer;
Ok(())
}
databoard::RemappingTarget::None(_) => Err(BehaviorError::PortNotDeclared {
port: "entry".into(),
behavior: behavior.name().clone(),
}),
}
}
async fn tick(
&mut self,
behavior: &mut BehaviorData,
_children: &mut BehaviorTreeElementList,
_runtime: &SharedRuntime,
) -> BehaviorResult {
let sequence_id = behavior.sequence_id(&self.entry_key)?;
if sequence_id == self.sequence_id {
Ok(BehaviorState::Failure)
} else {
self.sequence_id = sequence_id;
Ok(BehaviorState::Success)
}
}
fn provided_ports() -> PortList {
port_list![input_port!(
String,
ENTRY,
EMPTY_STR,
"The blackboard entry to check."
)]
}
}