#egui #callback #views #async #messages #interior-mutability #update

egui_inbox

Utility to send messages to egui views from async functions, callbacks, etc. without having to use interior mutability.

5 releases (3 breaking)

0.4.0 Apr 2, 2024
0.3.0 Feb 7, 2024
0.2.0 Jan 21, 2024
0.1.1 Oct 19, 2023
0.1.0 Aug 20, 2023

#8 in #views

Download history 4/week @ 2024-01-19 9/week @ 2024-02-02 1/week @ 2024-02-09 14/week @ 2024-02-16 33/week @ 2024-02-23 17/week @ 2024-03-01 7/week @ 2024-03-08 4/week @ 2024-03-15 136/week @ 2024-03-29 32/week @ 2024-04-05 1/week @ 2024-04-12

169 downloads per month
Used in 4 crates

MIT license

34KB
341 lines

egui_inbox

egui_ver Latest version Documentation unsafe forbidden License

Channel to send messages to egui views from async functions, callbacks, etc. without having to use interior mutability. Will automatically call request_repaint() on the Ui when a message is received.

The goal of this crate is to make interfacing with egui from asynchronous code as easy as possible. Currently it is not optimized for performance, so if you expect to send 1000s of updates per frame you might want to use e.g. std::sync::mpsc instead. Performance might still be improved in the future though.

Example:

use eframe::egui;
use egui::CentralPanel;
use egui_inbox::UiInbox;

pub fn main() -> eframe::Result<()> {
    let inbox = UiInbox::new();
    let mut state = None;

    eframe::run_simple_native(
        "DnD Simple Example",
        Default::default(),
        move |ctx, _frame| {
            CentralPanel::default().show(ctx, |ui| {
                // `read` will return an iterator over all pending messages
                if let Some(last) = inbox.read(ui).last() {
                    state = last;
                }
                // There also is a `replace` method that you can use as a shorthand for the above:
                // inbox.replace(ui, &mut state);

                ui.label(format!("State: {:?}", state));
                if ui.button("Async Task").clicked() {
                    state = Some("Waiting for async task to complete".to_string());
                    let tx = inbox.sender();
                    std::thread::spawn(move || {
                        std::thread::sleep(std::time::Duration::from_secs(1));
                        // Send will return an error if the receiver has been dropped
                        // but unless you have a long running task that will send multiple messages
                        // you can just ignore the error
                        tx.send(Some("Hello from another thread!".to_string())).ok();
                    });
                }
            });
        },
    )
}

Dependencies

~4–12MB
~122K SLoC