behaviortree 0.8.0

A #![no_std] compatible behavior tree library similar to BehaviorTree.CPP.
Documentation
# behaviortree

'behaviortree' implements a behavior tree library similar to [BehaviorTree.CPP](https://www.behaviortree.dev/) but in `Rust`.

Examples implementing the BehaviorTree.CPP [tutorials](https://www.behaviortree.dev/docs/intro)
can be found [here](https://codeberg.org/dibbots/behaviortree/src/branch/main/examples).
For __embedded__ devices similar examples are available [here](https://codeberg.org/dibbots/behaviortree/src/branch/main/embedded)

⚠️ INFO ⚠️
This crate is still in development.

## Usage

Below is a very simple example using functions as `Actions`.
For more examples see: 
- [Linux/Mac-OS/Windows]https://codeberg.org/dibbots/behaviortree/src/branch/main/examples, 
- [embedded]https://codeberg.org/dibbots/behaviortree/src/branch/main/embedded

```rust
use behaviortree::prelude::*;

const XML: &str = r#"
<root BTCPP_format="4">
    <BehaviorTree ID="MyBehavior">
        <Sequence>
			<MyAction1/>
			<MyAction2/>
        </Sequence>
    </BehaviorTree>
</root>
"#;

fn action_1() -> BehaviorResult {
    // your activity
    // ...

    // In case of Failure    
    //return Ok(BehaviorState::Failure);

    // In case of Success    
    Ok(BehaviorState::Success)
}

fn action_2() -> BehaviorResult {
    // your activity
    // ...
    Ok(BehaviorState::Success)
}

#[tokio::main]
async fn main() {
    // create a behavior factory
    let mut factory = BehaviorTreeFactory::new().unwrap();

    // register your behaviors
    register_simple_behavior!(factory, action_1, "MyAction1", BehaviorKind::Action).unwrap();
    register_simple_behavior!(factory, action_2, "MyAction2", BehaviorKind::Action).unwrap();

    // create the tree
    let mut tree = factory.create_from_text(XML).unwrap();
    
    // run the tree until Success or Failure
    tree.tick_while_running().await.unwrap();
}
```

For implementation of your own behaviors, there is a set of 
derive macros: `Action`, `Condition`, `Control` and `Decorator`.

```rust
use behaviortree::prelude::*;

const XML: &str = r#"
<root BTCPP_format="4">
    <BehaviorTree ID="MyBehavior">
        <MyAction message = "hello world!"/>
    </BehaviorTree>
</root>
"#;

#[derive(Action, Debug)]
pub struct SaySomething {
	/// The ports
	#[behavior(portlist)]
	portlist: PortArray<1>,
}

#[async_trait::async_trait]
impl Behavior for SaySomething {
	async fn tick(
		&mut self,
		_behavior: &mut BehaviorData,
		_children: &mut BehaviorTreeElementList,
		_runtime: &SharedRuntime,
	) -> BehaviorResult {
		let msg = self.portlist.get::<String>("message")?;
		println!("Robot says: {msg}");
		Ok(BehaviorState::Success)
	}
}

impl SaySomething {
	port_array_init! {1,
		create_inbound_entry_parseable!("message", String)
	}
}

#[tokio::main]
async fn main() {
    // create a behavior factory
    let mut factory = BehaviorTreeFactory::new().unwrap();

    // register the behavior
    SaySomething::register(&mut factory, "MyAction").unwrap();

    // create the tree
    let mut tree = factory.create_from_text(XML).unwrap();
    
    // run the tree until Success or Failure
    tree.tick_while_running().await.unwrap();
}
```

## Capabilities

 ✅: Supported<br>
 ☑️: Supported with some caveats<br>
 🚦: Needs testing but basically works<br>
 🔴: Not yet supported<br>
 ??: Unclear if it can be supported<br>
 ❌: Will not be supported

### General capabilities

| Capability              | std OS | Embedded | Caveats                   |
| ----------------------- | ------ | -------- | ------------------------- |
| XML                     |        |          |                           |
| - parsing               || ☑️       | embedded tree depth limited |
| - generation            |||                           |
|                         |        |          |                           |
| Ports                   |        |          |                           |
| - remapping             |||                           |
| - access by ref         |||                           |
|                         |        |          |                           |
| Subtrees                |        |          |                           |
| - structure             |||                           |
| - remapping             |||                           |
| - 'include' from file   |||                           |
|                         |        |          |                           |
| Blackboard              |        |          |                           |
| - hierarchy             |||                           |
| - remapping             |||                           |
| - access by ref         |||                           |
| - backup                | 🔴     | ??       |                           |
|                         |        |          |                           |
| Pre-/post-conditions    |||                           |
| Scripting               |||                           |
|                         |        |          |                           |
| Loggers/Observers       ||| embedded basically works, no time info |
| Substitution rules      | 🚦     | 🚦       | no delay in embedded, currently no functions possible |
|                         |        |          |                           |
| Using Groot2 for:       |        |          |                           |
| - XML Create/Edit       | ☑️     | ☑️       | different type systems    |
| - Live Monitoring       | ☑️     | ☑️       | different type systems, Ethernet over USB    |
| - Pro Features          | 🔴     | ??       |                           |

### Built-in behaviors

| Names as in BehaviorTree.CPP        | std OS | Embedded |
| ----------------------------------- | ------ | -------- |
| __Actions__                         |        |          |
| `AlwaysFailure`, `AlwaysSuccess`    |||
| `Script`                            |||
| `SetBlackboard`, `UnsetBlackboard`  |||
| `PopFromQueue<T>`                   |||
| `Sleep`                             || 🔴       |
|                                     |        |          |
| __Conditions__                      |        |          |
| `ScriptCondition`                   |||
| `WasEntryUpdated`                   |||
|                                     |        |          |
| __Controls__                        |        |          |
| `Fallback`                          |||
| `AsyncFallback`, `ReactiveFallback` |||
| `Sequence`, `SequenceWithMemory`    |||
| `AsyncSequence`, `ReactiveSequence` |||
| `Parallel`, `ParallelAll`           |||
| `IfThenElse`, `WhileDoElse`         |||
| `Switch<u8>`                        |||
| `ManualSelector`                    | 🔴     | ??       |
|                                     |        |          |
| __Decorators__                      |        |          |
| `ForceFailure`, `ForceSuccess`      |||
| `Inverter`                          |||
| `KeepRunningUntilFailure`           |||
| `Repeat`                            |||
| `RetryUntilSuccessful`              |||
| `EntryUpdated`                      |||
| `LoopQueue<T>`                      |||
| `RunOnce`                           |||
| `Precondition`                      |||
| `Delay`                             || 🔴       |
| `Timeout`                           || 🔴       |
 
## License

Licensed with the fair use "NGMC" license, see [license file](https://codeberg.org/dibbots/behaviortree/src/branch/main/LICENSE)

## Contribution

Any contribution intentionally submitted for inclusion in the work by you,
shall be licensed with the same "NGMC" license, without any additional terms or conditions.