use alloc::boxed::Box;
use core::{any::Any, ops::Range};
use dataport::PortList;
#[cfg(feature = "std")]
use libloading::Library;
use tinyscript::SharedRuntime;
#[cfg(feature = "std")]
use crate::Arc;
use crate::{
BehaviorCreationFn, BehaviorResult, ConstString, behavior_data::BehaviorData, behavior_description::BehaviorDescription,
behavior_kind::BehaviorKind, behavior_state::BehaviorState, error::Error, tree::BehaviorTreeElementList,
};
pub trait BehaviorExecution: Any + Behavior {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
fn kind(&self) -> BehaviorKind;
fn portlist(&self) -> &dyn PortList;
fn portlist_mut(&mut self) -> &mut dyn PortList;
}
#[async_trait::async_trait]
pub trait Behavior: Send + Sync {
fn on_halt(&mut self) -> Result<(), Error> {
Ok(())
}
fn on_start(
&mut self,
_behavior: &mut BehaviorData,
_children: &mut BehaviorTreeElementList,
_runtime: &SharedRuntime,
) -> Result<(), Error> {
Ok(())
}
async fn start(
&mut self,
behavior: &mut BehaviorData,
children: &mut BehaviorTreeElementList,
runtime: &SharedRuntime,
) -> BehaviorResult {
self.on_start(behavior, children, runtime)?;
self.tick(behavior, children, runtime).await
}
async fn tick(
&mut self,
behavior: &mut BehaviorData,
children: &mut BehaviorTreeElementList,
runtime: &SharedRuntime,
) -> BehaviorResult;
fn halt(
&mut self,
_behavior: &mut BehaviorData,
children: &mut BehaviorTreeElementList,
runtime: &SharedRuntime,
) -> BehaviorResult {
children.halt(runtime)?;
self.on_halt()?;
Ok(BehaviorState::Idle)
}
}
pub trait BehaviorRegistry {
fn add_behavior(&mut self, desc: BehaviorDescription, creation_fn: Box<BehaviorCreationFn>) -> Result<(), Error>;
fn add_tree_defintion(&mut self, id: &str, tree_definition: ConstString, range: Range<usize>) -> Result<(), Error>;
#[cfg(feature = "std")]
#[must_use]
fn libraries(&self) -> &alloc::vec::Vec<Arc<Library>>;
#[must_use]
fn runtime(&self) -> &tinyscript::Runtime;
fn register_enum_tuple(&mut self, key: &str, value: i8) -> Result<(), Error>;
}