Skip to main content

Emitter

Struct Emitter 

Source
pub struct Emitter<Event: EventTrait>(/* private fields */);
Expand description

Event emitter that can be embedded in Props.

Clone this handle to create callbacks in your Props that can trigger events when invoked (e.g., by user interaction).

Emitter wraps a lock-free MPMC channel sender, making it cheap to clone and thread-safe without any locking overhead.

§Performance Characteristics

Cloning an Emitter is a cheap operation (equivalent to cloning an Arc). It increments a reference count using an atomic operation rather than allocating new memory. This makes it safe to clone frequently without significant performance cost.

However, atomic operations do have some overhead (memory barriers, cache coherency), so the following patterns are recommended for optimal performance:

When creating multiple callbacks in your view() function, clone the emitter once and reuse it:

fn view(&self, model: &Model, emitter: &Emitter<Event>) -> Props {
    // GOOD: Clone once, reuse for all callbacks
    let emitter = emitter.clone();
    Props {
        on_click: Box::new({
            let e = emitter.clone();
            move || { e.try_emit(Event::Click); }
        }),
        on_hover: Box::new({
            let e = emitter.clone();
            move || { e.try_emit(Event::Hover); }
        }),
        on_focus: Box::new({
            let e = emitter.clone();
            move || { e.try_emit(Event::Focus); }
        }),
    }
}

This pattern minimizes atomic operations while maintaining clean code structure.

§Example

use oxide_mvu::{Emitter, MvuLogic, Effect};

#[derive(Clone)]
enum Event { Click }

#[derive(Clone)]
struct Model { clicks: u32 }

struct Props {
    clicks: u32,
    on_click: Box<dyn Fn()>,
}

struct MyApp;

impl MvuLogic<Event, Model, Props> for MyApp {
    fn init(&self, model: Model) -> (Model, Effect<Event>) {
        (model, Effect::none())
    }

    fn update(&self, event: Event, model: &Model) -> (Model, Effect<Event>) {
        match event {
            Event::Click => {
                let new_model = Model {
                    clicks: model.clicks + 1,
                    ..model.clone()
                };
                (new_model, Effect::none())
            }
        }
    }

    fn view(&self, model: &Model, emitter: &Emitter<Event>) -> Props {
        let emitter = emitter.clone();
        Props {
            clicks: model.clicks,
            on_click: Box::new(move || {
                emitter.try_emit(Event::Click);
            }),
        }
    }
}

Implementations§

Source§

impl<Event: EventTrait> Emitter<Event>

Source

pub fn try_emit(&self, event: Event) -> bool

Emit an event without blocking.

This attempts to queue the event for processing by the runtime. If the event queue is full, the event will be dropped and false is returned.

Multiple threads can safely call this method concurrently via the lock-free channel.

Source

pub async fn emit(&self, event: Event)

Emit an event, waiting until space is available.

This queues the event for processing by the runtime. If the queue is full, this method will await until space becomes available.

Multiple threads can safely call this method concurrently via the lock-free channel.

Trait Implementations§

Source§

impl<Event: EventTrait> Clone for Emitter<Event>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<Event> Freeze for Emitter<Event>

§

impl<Event> RefUnwindSafe for Emitter<Event>

§

impl<Event> Send for Emitter<Event>

§

impl<Event> Sync for Emitter<Event>

§

impl<Event> Unpin for Emitter<Event>

§

impl<Event> UnwindSafe for Emitter<Event>

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<T> Event for T
where T: Send + Sync + Clone + 'static,