Skip to main content

AsyncDispatcher

Struct AsyncDispatcher 

Source
pub struct AsyncDispatcher<E, R> { /* private fields */ }
Expand description

An asynchronous dispatcher that processes events in a dedicated thread pool and supports non-blocking operations with proper error handling and timeouts.

The AsyncDispatcher is particularly useful for:

  • Long-running background tasks that shouldn’t block the UI
  • Network requests and file I/O operations
  • Parallel processing of computationally intensive tasks
  • Operations that require timeouts or cancellation

§Type Parameters

  • E: The event type this dispatcher processes
  • R: The result type returned after processing

§Examples

§Basic Usage

use egui_mobius::dispatching::AsyncDispatcher;
use egui_mobius::factory::create_signal_slot;

// Create an async dispatcher for processing image data
let dispatcher = AsyncDispatcher::<Vec<u8>, String>::new();

// Set up signal/slot for image processing
let (signal, slot) = create_signal_slot::<Vec<u8>>();
let (result_signal, result_slot) = create_signal_slot::<String>();

// Attach async handler
dispatcher.attach_async(slot, result_signal, |image_data| async move {
    // Simulate image processing
    format!("Processed {} bytes of image data", image_data.len())
});

§With Timeouts and Error Handling

use egui_mobius::dispatching::AsyncDispatcher;
use egui_mobius::factory::create_signal_slot;
use std::time::Duration;
use tokio::time::timeout;

#[derive(Debug, Clone)]
enum ProcessError {
    Timeout,
    Failed(String),
}

let dispatcher = AsyncDispatcher::<String, Result<String, ProcessError>>::new();
let (signal, slot) = create_signal_slot::<String>();
let (result_signal, result_slot) = create_signal_slot::<Result<String, ProcessError>>();

dispatcher.attach_async(slot, result_signal, |input| async move {
    match timeout(Duration::from_secs(5), async {
        // Simulate long-running task
        tokio::time::sleep(Duration::from_secs(1)).await;
        Ok(format!("Processed: {}", input))
    }).await {
        Ok(result) => result,
        Err(_) => Err(ProcessError::Timeout),
    }
});

§Parallel Processing

use egui_mobius::dispatching::AsyncDispatcher;
use egui_mobius::factory::create_signal_slot;
use futures::future::join_all;

let dispatcher = AsyncDispatcher::<Vec<i32>, Vec<i32>>::new();
let (signal, slot) = create_signal_slot::<Vec<i32>>();
let (result_signal, result_slot) = create_signal_slot::<Vec<i32>>();

dispatcher.attach_async(slot, result_signal, |numbers| async move {
    let tasks: Vec<_> = numbers.into_iter()
        .map(|n| async move { n * n })
        .collect();
    join_all(tasks).await
});

Implementations§

Source§

impl<E: Send + 'static, R: Send + 'static> AsyncDispatcher<E, R>

Source

pub fn new() -> Self

Creates a new AsyncDispatcher with its own Tokio runtime.

Source

pub fn attach_async<F, Fut>(&self, slot: Slot<E>, signal: Signal<R>, handler: F)
where E: Clone + Send + 'static, R: Send + 'static, F: Fn(E) -> Fut + Send + Sync + 'static, Fut: Future<Output = R> + Send + 'static,

Attaches an async handler to the given Slot<E>, processing events asynchronously and sending results via Signal<R>. The handler runs in a dedicated thread pool managed by Tokio, ensuring non-blocking operation.

§Arguments
  • slot - The slot that will receive events to process
  • signal - The signal used to send processed results
  • handler - An async closure that processes events and returns results
§Type Parameters
  • F - The handler function type that takes an event and returns a Future
  • Fut - The Future type returned by the handler
§Notes
  • This can be called only once per Slot
  • The handler runs in a Tokio runtime with work-stealing scheduler
  • Results are sent asynchronously through the signal
  • If the signal send fails (e.g., no receivers), the error is silently ignored
§Example
use egui_mobius::dispatching::AsyncDispatcher;
use egui_mobius::factory::create_signal_slot;
use tokio::time::sleep;
use std::time::Duration;

async fn process_data(data: String) -> Result<String, String> {
    sleep(Duration::from_millis(100)).await; // Simulate work
    Ok(format!("Processed: {}", data))
}

let dispatcher = AsyncDispatcher::<String, Result<String, String>>::new();
let (signal, slot) = create_signal_slot::<String>();
let (result_signal, result_slot) = create_signal_slot::<Result<String, String>>();

dispatcher.attach_async(slot, result_signal, |input| async move {
    process_data(input).await
});

Trait Implementations§

Source§

impl<E: Send + 'static, R: Send + 'static> Default for AsyncDispatcher<E, R>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<E, R> Freeze for AsyncDispatcher<E, R>

§

impl<E, R> RefUnwindSafe for AsyncDispatcher<E, R>

§

impl<E, R> Send for AsyncDispatcher<E, R>
where E: Send, R: Send,

§

impl<E, R> Sync for AsyncDispatcher<E, R>
where E: Sync, R: Sync,

§

impl<E, R> Unpin for AsyncDispatcher<E, R>
where E: Unpin, R: Unpin,

§

impl<E, R> UnsafeUnpin for AsyncDispatcher<E, R>

§

impl<E, R> UnwindSafe for AsyncDispatcher<E, R>
where E: UnwindSafe, R: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.