#![allow(unused, unreachable_code)]
use core::{
any::{Any, TypeId},
fmt::Debug,
str::FromStr,
};
use alloc::{
borrow::ToOwned,
boxed::Box,
string::{String, ToString},
vec::Vec,
};
use databoard::{Databoard, Error, RemappingList};
use dataport::{
BoundValueReadGuard, BoundValueWriteGuard, PortCollection, PortCollectionAccessors, PortCollectionAccessorsCommon,
};
use tinyscript::{Environment, ScriptingValue};
use crate::{BehaviorTickCallback, ConstString, behavior_description::BehaviorDescription, behavior_state::BehaviorState};
#[derive(Default)]
pub struct BehaviorData {
uid: u16,
state: BehaviorState,
blackboard: Databoard,
description: Box<BehaviorDescription>,
pre_state_change_hooks: Vec<(ConstString, Box<BehaviorTickCallback>)>,
}
impl BehaviorData {
#[must_use]
pub fn create(uid: u16, blackboard: Databoard, description: BehaviorDescription) -> Self {
Self {
uid,
state: BehaviorState::default(),
blackboard,
description: Box::new(description),
pre_state_change_hooks: Vec::default(),
}
}
#[must_use]
pub const fn blackboard(&self) -> &Databoard {
&self.blackboard
}
#[must_use]
pub const fn blackboard_mut(&mut self) -> &mut Databoard {
&mut self.blackboard
}
#[must_use]
pub const fn description(&self) -> &BehaviorDescription {
&self.description
}
#[must_use]
pub const fn description_mut(&mut self) -> &mut BehaviorDescription {
&mut self.description
}
#[must_use]
pub fn is_active(&self) -> bool {
self.state != BehaviorState::Idle && self.state != BehaviorState::Skipped
}
#[must_use]
pub const fn name(&self) -> &ConstString {
self.description.name()
}
#[must_use]
pub const fn uid(&self) -> u16 {
self.uid
}
#[must_use]
pub const fn state(&self) -> BehaviorState {
self.state
}
pub fn set_state(&mut self, state: BehaviorState) {
if state != self.state {
let mut state = state;
for (_, callback) in &self.pre_state_change_hooks {
callback(self, &mut state);
}
self.state = state;
}
}
pub fn add_pre_state_change_callback<T>(&mut self, name: ConstString, callback: T)
where
T: Fn(&Self, &mut BehaviorState) + Send + Sync + 'static,
{
self.pre_state_change_hooks
.push((name, Box::new(callback)));
}
pub fn remove_pre_state_change_callback(&mut self, name: &str) {
self.pre_state_change_hooks
.retain(|(cb_name, _)| cb_name.as_ref() != name);
}
#[must_use]
pub const fn full_path(&self) -> &ConstString {
self.description.groot2_path()
}
}