TheEmeraldBee / widgetui

A bevy systems like widget system for ratatui and crossterm
MIT License
38 stars 5 forks source link

Asynchronous Events #9

Closed AlexanderARodin closed 4 weeks ago

AlexanderARodin commented 4 weeks ago

Could you show some minimal example for attaching custom async events from another thread.

Usually I use separate thread for working with inputs and timers and send events via channel. But it requires explicit dealing with boiler plates. Or if it's complicated, I'll probably just continue using own templates.

Thank you in advance for answer.

TheEmeraldBee commented 4 weeks ago

I'd look into creating the thread at start, and then putting a channel reader into a state, then reading it through a widget.

Here's a simple example of using a channel within a state.

use std::{
    error::Error,
    sync::mpsc::{channel, Receiver},
    thread,
    time::Duration,
};

use widgetui::*;

#[derive(State)]
pub struct MyEventReceiver {
    channel: Receiver<bool>,
}

fn handler(reciever: ResMut<MyEventReceiver>, mut events: ResMut<Events>) -> WidgetResult {
    if let Ok(true) = reciever.channel.try_recv() {
        events.register_exit();
    }
    Ok(())
}

fn main() -> Result<(), Box<dyn Error>> {
    let mut app = App::new(100)?;

    let (sender, reciever) = channel();

    app = app.states(MyEventReceiver { channel: reciever });

    thread::spawn(move || {
        thread::sleep(Duration::from_millis(1500));
        sender.send(true).unwrap();
    });

    app = app.widgets(handler);

    app.run()?;

    Ok(())
}

Is this what you are looking for?

AlexanderARodin commented 4 weeks ago

probably it is! I must check it by hands. thank you!!

AlexanderARodin commented 4 weeks ago

Had some practice with basic concepts of Widgetui. After it I have re-read example and understand it. It is obviously working way. But it leads to another question: is it possible to set off somehow internal input_handler? I'd probably like to use my own event source for input processing (and less CPU usage).

TheEmeraldBee commented 4 weeks ago

There isn't currently a way to disable the internal input handler, but if you wanted to add your own on top, you could do so with a widget and state, where the state stores those inputs.

AlexanderARodin commented 4 weeks ago

understood. thank you for your time. There needs to compare pros and cos. the crate is very cool. Your example works fine.