Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

events

Frame-event readers and edge-event subscriptions. Wraps the internal __zero_input.events() FFI with per-kind filters and a push-style on/off API that fires from Zin.tick. Backs Zin.events.

__zero_input.events() returns the current frame's events in dispatch order; reading does not consume them. Subscription dispatch happens during Zin.tick (or Zin.autoTick.start()'s worker), so without a tick host on() callbacks never fire.

Exports

  • M.frame() -> { InputEvent } — this frame's events in dispatch order.
  • M.iter() -> iterator — ipairs over frame(); reads better at call sites.
  • M.keysDown / keysUp / mouseDowns / mouseUps / mouseMoves / mouseWheels / texts() -> { InputEvent } — per-kind filters.
  • M.on(filter: EventFilter, callback, opts: SubOpts?) -> SubHandle — register an edge subscriber, returns handle.
  • M.off(handle: SubHandle | number) — cancel a subscriber.
  • M.clearSubscribers() — drop all subscribers (test isolation).
  • M.subscriberCount() -> number — current subscriber count.
  • M._dispatch(events) — internal; called by Zin.tick.

Types:

  • InputEvent = { [string]: any } — one entry of the frame event log.
  • EventFilter = string | { [string]: any } | (any) -> boolean
  • SubOpts = { context: string?, once: boolean?, priority: number? }
  • SubHandle = { id: number, off: () -> () }

Usage

local Zin = require("@builtin::modules.zinput")

for _, ev in ipairs(Zin.events.frame()) do
    if ev.kind == "key.down" and ev.code == "Space" then
        -- jump on the press edge, not on every frame the key is held
    end
end

local h = Zin.events.on({ kind = "key.down", code = "Escape" }, function(ev, gpe)
    if not gpe then closeMenu() end
end, { context = "ui" })
-- later: h.off()

Notes

  • Reading frame() is non-destructive — multiple consumers can iterate the same frame's events. The log clears at end-of-frame and is rebuilt next frame.
  • Subscribers dispatch in priority-desc order; equal priorities preserve insertion order. Returning "sink" from a callback halts further dispatch for that single event (lower-priority subscribers skipped).
  • once = true subscribers auto-unsubscribe after their first matching dispatch.
  • A subscription ends with the context that made it as well as with off: one a component makes ends when that component instance goes (removed, hot-reloaded, or its entity despawned), one a module body makes at the module's next run. scopes.list() names each as a luau row under the context it follows.
  • Subscriber errors are caught and logged via log.warn; one bad handler doesn't break dispatch.