Builtin Library
README.md
input
Event-driven listeners for whole categories of raw input, on top of
Zin.events.on. Sugar for the most-common filter shapes (onBegan /
onEnded / onChanged / onTextInput) plus a lastInputType()
accessor. Backs Zin.input.
These sit beneath the control model: they answer "any key went down"
rather than "the Jump control fired", which is what rebind capture, dev
tooling and text-adjacent UI need. Gameplay subscribes to controls through
an activated map — man topics/input covers that path.
Exports
M.lastInputType() -> string?— userInputType of the most recent input event ("Keyboard"/"Mouse"/"Touch"/nil).M.onBegan(fn, opts?) -> Handle— fires onkey.down/mouse.down.M.onEnded(fn, opts?) -> Handle— fires onkey.up/mouse.up.M.onChanged(fn, opts?) -> Handle— fires onmouse.move/mouse.wheel.M.onTextInput(fn, opts?) -> Handle— fires on committed text input; handler signature is(text, gpe).M.disconnect(handle: Handle) -> boolean— tear down a subscription; idempotent.M.subscriberCount() -> number— number of active composite subscriptions.M._reset()— test-only: clearlastInputType.M._disconnectAll()— test-only: tear down every subscription this session.M._observeEvent(ev: any)— internal observer driven byZin.tick.M._setAllocator(fn: () -> number)— internal: wire the shared handle-id allocator.M._owns(handle: number) -> boolean— internal: handle-ownership check for cross-API disconnect.
Types:
Filter = string | { [string]: any } | (any) -> booleanSubOpts = { priority: number?, context: string?, once: boolean? }Handle = number— composite-handle id, drawn from a shared allocator withZin.actions.
Usage
local Input = require("@builtin::modules.zinput.input")
local h = Input.onBegan(function(io, gpe)
if io.kind == "key.down" and io.code == "Space" then
print("jumped")
end
end, { priority = 10 })
Input.disconnect(h)
Notes
- Handler signatures:
fn(io, gpe)foronBegan/onEnded/onChanged;fn(text, gpe)foronTextInput.gpeis the event's ownconsumed_by_uimarker, stamped as the event arrived against the focus the UI holds over that event's surface: pointer focus for a mouse or touch event, keyboard focus for a key or text event, and never for a pad. - Return
"sink"from a handler to stop further (lower-priority) handlers receiving the same event. - A single
on*call installs N underlyingZin.events.onsubscribers but returns ONE composite handle —disconnecttears them all down together. - A composite handle also ends with the context that made it: one a
component registers ends when that component instance goes (removed,
hot-reloaded, or its entity despawned), one a module body registers at
the module's next run.
scopes.list()names each as aluaurow under the context it follows. - Handle ids share a namespace with
Zin.actions(_setAllocatorwires this at boot), soZin.actions.disconnectaccepts handles returned here. lastInputTypeis updated by the tick observer; text events do not bump it (the preceding key.* event already did).