use super::ConverterStrategy;
use super::ResultConverter;
use crate as bevior_tree;
use crate::node::prelude::*;
pub mod prelude {
pub use super::{ForceResult, Invert};
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug)]
struct InvertStrategy;
#[cfg_attr(feature = "serde", typetag::serde)]
impl ConverterStrategy for InvertStrategy {
fn convert(&self, result: NodeResult) -> NodeResult {
!result
}
}
#[delegate_node(delegate)]
pub struct Invert {
delegate: ResultConverter,
}
impl Invert {
pub fn new(child: impl Node) -> Self {
Self {
delegate: ResultConverter::new(child, InvertStrategy),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug)]
struct ForceResultStrategy {
result: NodeResult,
}
#[cfg_attr(feature = "serde", typetag::serde)]
impl ConverterStrategy for ForceResultStrategy {
fn convert(&self, _result: NodeResult) -> NodeResult {
self.result
}
}
#[delegate_node(delegate)]
pub struct ForceResult {
delegate: ResultConverter,
}
impl ForceResult {
pub fn new(child: impl Node, result: NodeResult) -> Self {
Self {
delegate: ResultConverter::new(child, ForceResultStrategy { result }),
}
}
}
#[cfg(test)]
mod tests {
use crate::tester_util::prelude::*;
#[test]
fn test_invert() {
let mut app = App::new();
app.add_plugins((TesterPlugin, BehaviorTreePlugin::default()));
let task = TesterTask0::new(1, NodeResult::Success);
let converter = Invert::new(task);
let tree = BehaviorTree::from_node(
converter,
&mut app.world_mut().resource_mut::<Assets<BehaviorTreeRoot>>(),
);
let entity = app.world_mut().spawn(tree).id();
app.update();
app.update();
let status = app.world().get::<TreeStatus>(entity);
assert!(
if let Some(TreeStatus(NodeStatus::Complete(result))) = status {
result == &NodeResult::Failure
} else {
false
},
"Invert should match the result."
);
}
#[test]
fn test_force_result() {
let mut app = App::new();
app.add_plugins((TesterPlugin, BehaviorTreePlugin::default()));
let task = TesterTask0::new(1, NodeResult::Success);
let converter = ForceResult::new(task, NodeResult::Failure);
let tree = BehaviorTree::from_node(
converter,
&mut app.world_mut().resource_mut::<Assets<BehaviorTreeRoot>>(),
);
let entity = app.world_mut().spawn(tree).id();
app.update();
app.update();
let status = app.world().get::<TreeStatus>(entity);
assert!(
if let Some(TreeStatus(NodeStatus::Complete(result))) = status {
result == &NodeResult::Failure
} else {
false
},
"ForceResult should match the result."
);
}
}