Async and Anathema

Since the UI Runtime is blocking, spawn a secondary thread for our async runtime to run on.

The Runtime can not move between threads as the Values are not send. That's why it's easier, if access to component ids and emitters are required, to run the async code on a separate thread from the main thread.

Setting up for async

Create a function that starts an async runtime in a new thread.

Using a component id and an emitter it is possible to send messages into the Anathema runtime.

In this example we assume there is a component that accepts a usize as its Message type.

pub fn run_async(emitter: Emitter, component: ComponentId<usize>) {
    thread::spawn(move || {
        tokio::runtime::Builder::new_multi_thread()
            .enable_all()
            .build()
            .unwrap()
            .block_on(async move {
                // async code here
                emitter.emit_async(component, 123).await;
            });
    });
}

Setup the UI

Setup the Anathema runtime on the main thread, generate component ids and emitters and pass them to the async runtime via the aforementioned function.

use anathema::component::*;
use anathema::prelude::*;

fn main() {
    // -----------------------------------------------------------------------------
    //   - Setup UI -
    // -----------------------------------------------------------------------------
    let doc = Document::new("@index");

    let mut backend = TuiBackend::full_screen();
    let mut builder = Runtime::builder(doc, &backend);
    
    let component_id = builder.default::<MyComponent>("index", "templates/index.aml").unwrap();
    let emitter = builder.emitter();

    // -----------------------------------------------------------------------------
    //   - Setup async -
    // -----------------------------------------------------------------------------
    run_async(emitter, component_id);

    // -----------------------------------------------------------------------------
    //   - Start UI -
    // -----------------------------------------------------------------------------
    builder.finish(&mut backend, |runtime, backend| runtime.run(backend)).unwrap();
}