use crate::{
self as behaviortree, Action, BehaviorDescription, BehaviorKind, BehaviorTreeFactory, EMPTY_STR,
behavior::{Behavior, BehaviorCreationFn, BehaviorData, BehaviorResult, BehaviorState},
inout_port, input_port,
port::PortList,
port_list,
tree::BehaviorTreeElementList,
};
use alloc::{boxed::Box, string::String, string::ToString};
use core::{fmt::Debug, marker::PhantomData, str::FromStr};
use databoard::check_board_pointer;
use tinyscript::SharedRuntime;
const OUTPUT_KEY: &str = "output_key";
const VALUE: &str = "value";
#[derive(Action, Debug, Default)]
#[behavior(no_create, no_register, no_register_with)]
pub struct SetBlackboard<T>
where
T: Clone + Debug + Default + FromStr + ToString + Send + Sync + 'static,
{
_marker: PhantomData<T>,
}
#[async_trait::async_trait]
impl<T> Behavior for SetBlackboard<T>
where
T: Clone + Debug + Default + FromStr + ToString + Send + Sync,
{
async fn tick(
&mut self,
behavior: &mut BehaviorData,
_children: &mut BehaviorTreeElementList,
_runtime: &SharedRuntime,
) -> BehaviorResult {
let value = behavior.get::<T>(VALUE)?;
let key = behavior.get::<String>(OUTPUT_KEY)?;
match check_board_pointer(&key) {
Ok(stripped_key) => behavior.set(stripped_key, value)?,
Err(original_key) => behavior.set(original_key, value)?,
};
Ok(BehaviorState::Success)
}
fn provided_ports() -> PortList {
port_list![
input_port!(T, VALUE, EMPTY_STR, "Value to be written into the output_key"),
inout_port!(
String,
OUTPUT_KEY,
EMPTY_STR,
"Name of the blackboard entry where the value should be written"
),
]
}
}
impl<T> SetBlackboard<T>
where
T: Clone + Debug + Default + FromStr + ToString + Send + Sync,
{
#[must_use]
pub fn create_fn() -> Box<BehaviorCreationFn> {
Box::new(move || Box::new(Self { _marker: PhantomData }))
}
pub fn register_with(
factory: &mut BehaviorTreeFactory,
name: &str,
groot2: bool,
) -> Result<(), crate::factory::error::Error> {
let bhvr_desc = BehaviorDescription::new(name, name, BehaviorKind::Action, groot2, Self::provided_ports());
let bhvr_creation_fn = Self::create_fn();
factory
.registry_mut()
.add_behavior(bhvr_desc, bhvr_creation_fn)
}
}