Mob.Event.NativeInput (mob v0.9.7)

Copy Markdown View Source

Which messages are native input, and what each one is called outside the screen it was meant for.

Native input never goes through Mob.Event.dispatch/4. The NIF delivers the legacy tuples listed in Mob.Listener — {:tap, tag}, {:change, tag, value}, {event, tag}, {event, tag, payload} — and the listener forwards them to the screen as they are. So the two things that observe actions, Mob.Agent.Receipts and Mob.Event.Trace, have to recognise them where they land: in Mob.Screen.Server, and in Mob.Listener when the screen is gone. This module is the one place that says which tuples those are.

Discrete and stream

KindMessagesReceiptTrace
:discrete:tap (list-row select included), :focus, :blur, :submit, :select, :dismiss, :long_press, :double_tap, :swipe_left/_right/_up/_down, {:swipe, tag, direction}, {:change, tag, value} except a floatyesyes
:stream:scroll, :drag, :pinch, :rotate, :pointer_move, :compose, a float :change, and the scroll lifecycle (:scroll_began, :scroll_ended, :scroll_settled, :top_reached, :scrolled_past)noyes

A stream fires at up to display rate, or several times per gesture. The receipt store keeps 256, so one scroll would evict the tap an agent is about to ask about, and a receipt costs an assigns comparison and an ETS write per frame. A float :change is a slider — the only native sender of a float value — which reports every step of a drag. Text, toggle and tab changes stay discrete: one per keystroke or flip is the rate a person acts at.

Naming

An input is named by its canonical address and event atom, from Mob.Event.Bridge.legacy_to_canonical/3 where the Bridge models the shape. Where it does not, the same rule applies with the widget kind the event implies (:text_field for focus, blur and submit, :sheet for dismiss, :button otherwise, as for a tap). A :change takes its widget from the value's type, which is all native tells us about the control: a boolean is a :toggle, a binary a :text_field (anything else keeps the Bridge's default). A tag that is not a valid address id (Mob.Event.Address.validate_id/1) is named :opaque.

A receipt carries the name and never the payload: a text field's value is user data, and a receipt is written to ETS and handed to telemetry. A trace carries the payload, as Mob.Event.dispatch/4 always has — subscribing is an explicit debugging act.

Summary

Functions

The canonical {address, event, payload} for a native input message, with :opaque in place of the address when the tag is not a valid id.

Whether message is discrete native input, a stream, or not native input.

What a receipt records for a native input: {event, address}, or {event, :opaque}. Never the payload.

Types

kind()

@type kind() :: :discrete | :stream | :none

Functions

canonical(message, screen)

@spec canonical(tuple(), term()) :: {Mob.Event.Address.t() | :opaque, atom(), term()}

The canonical {address, event, payload} for a native input message, with :opaque in place of the address when the tag is not a valid id.

kind(arg1)

@spec kind(term()) :: kind()

Whether message is discrete native input, a stream, or not native input.

receipt_event(message, screen)

@spec receipt_event(tuple(), term()) :: {atom(), Mob.Event.Address.t() | :opaque}

What a receipt records for a native input: {event, address}, or {event, :opaque}. Never the payload.