Mob.Event (mob v0.6.8)

Copy Markdown View Source

The unified event emission API for Mob.

See guides/event_model.md for the full event model.

Two responsibilities:

  1. Emit — given an %Address{}, an event atom, and a payload, deliver the canonical envelope {:mob_event, addr, event, payload} to the right pid (resolving in-tree or external targets).

  2. Match — small helpers (is_event?/1, match_address?/2) for handler code that wants to filter incoming events by address fields.

This module is the single doorway between native event sources and user-level handler code. Every emitter (taps, gestures, lifecycle, custom components) eventually calls Mob.Event.emit/4 (or dispatch/4, for pre-resolved pids).

Summary

Types

The shape of every event message delivered to a handler.

Functions

Send the event to an already-resolved pid.

Resolve target and deliver the event.

True if msg matches the canonical event envelope shape.

True if addr matches all the given filters.

Synthesize an event delivery to pid. Useful for tests — bypasses the native side entirely.

Types

envelope()

@type envelope() :: {:mob_event, Mob.Event.Address.t(), atom(), term()}

The shape of every event message delivered to a handler.

Functions

dispatch(pid, addr, event, payload)

@spec dispatch(pid(), Mob.Event.Address.t(), atom(), term()) :: :ok

Send the event to an already-resolved pid.

Used when the renderer pre-resolved the target at registration time and passes the pid directly. Skips re-resolution.

Also broadcasts to any Mob.Event.Trace subscribers (zero cost when no tracers are registered).

emit(addr, event, payload, target, scope)

Resolve target and deliver the event.

Best-effort delivery: if the target can't be resolved (dead pid, unknown registered name, component not in the ancestor chain), logs a debug message and drops the event.

Returns :ok always. Errors from resolution are logged, not raised — losing one event from a stale handle should never crash the BEAM.

is_event?(arg1)

@spec is_event?(term()) :: boolean()

True if msg matches the canonical event envelope shape.

iex> Mob.Event.is_event?({:mob_event, %Mob.Event.Address{screen: S, widget: :x, id: :y}, :tap, nil})
true

iex> Mob.Event.is_event?({:tap, :something})
false

match_address?(addr, filters)

@spec match_address?(
  Mob.Event.Address.t(),
  keyword()
) :: boolean()

True if addr matches all the given filters.

Filters is a keyword list of address fields and the values they must equal. Useful for one-off matches in handle_info/2 clauses where you don't want to write a full struct pattern.

iex> addr = %Mob.Event.Address{screen: S, widget: :button, id: :save}
iex> Mob.Event.match_address?(addr, widget: :button)
true

iex> addr = %Mob.Event.Address{screen: S, widget: :button, id: :save}
iex> Mob.Event.match_address?(addr, widget: :button, id: :cancel)
false

send_test(pid, screen, widget, id, event, payload \\ nil, opts \\ [])

@spec send_test(
  pid(),
  atom() | pid(),
  atom(),
  Mob.Event.Address.id(),
  atom(),
  term(),
  keyword()
) :: :ok

Synthesize an event delivery to pid. Useful for tests — bypasses the native side entirely.

Mob.Event.send_test(self(), MyScreen, :button, :save, :tap, nil)
assert_receive {:mob_event, %Address{id: :save}, :tap, nil}