#[cfg(feature = "native")]
use std::sync::Arc;
#[cfg(feature = "native")]
use anyhow::{anyhow, Context, Result};
#[cfg(feature = "native")]
use arora_bridge::Bridge;
#[cfg(feature = "native")]
use arora_hal::Hal;
#[cfg(feature = "native")]
use arora_simple_data_store::SimpleDataStore;
#[cfg(feature = "native")]
use crate::runtime::Runtime;
#[cfg(feature = "native")]
use crate::Arora;
#[cfg(feature = "native")]
pub fn launch(hal: Arc<dyn Hal>, bridge: Arc<dyn Bridge>, store: SimpleDataStore) -> Result<()> {
launch_with(hal, store, move || async move { Ok(bridge) })
}
#[cfg(feature = "native")]
pub fn launch_with<F, Fut>(hal: Arc<dyn Hal>, store: SimpleDataStore, make_bridge: F) -> Result<()>
where
F: FnOnce() -> Fut,
Fut: std::future::Future<Output = Result<Arc<dyn Bridge>>>,
{
let tokio = tokio::runtime::Runtime::new().context("failed to start Tokio runtime")?;
let (mut runtime, io) = tokio.block_on(async {
let bridge = make_bridge().await.context("failed to build the bridge")?;
let arora = Arora::start().await.context("failed to start Arora")?;
let store: Arc<dyn arora_types::data::DataStore> = Arc::new(store);
Ok::<_, anyhow::Error>(Runtime::with_io_in(arora, hal, bridge, store))
})?;
println!("arora: engine started; native behavior-tree control nodes ready.");
if let Some(path) = std::env::args().nth(1) {
let xml = std::fs::read_to_string(&path)
.with_context(|| format!("could not read Groot file {path}"))?;
runtime
.queue_groot_xml(&xml)
.map_err(|e| anyhow!("failed to queue behavior tree from {path}: {e}"))?;
println!("arora: queued behavior tree from {path}");
}
tokio.spawn(io);
println!("arora: running — Ctrl-C to stop.");
runtime.run().map_err(|e| anyhow!("runtime error: {e}"))
}