Builtin Library
README.md
context
The input context stack. Pushing a named context ("ui", "menu",
"vehicle", ...) stands down everything whose declared context doesn't
match the top of the stack; popping restores the previous mode. The bottom
is permanently "default" so unbalanced pops never leave the stack empty.
A control, an action, an axis or an event subscriber can declare one
context. Zin.scheme honours it on every live binding, so a
vehicle-context Brake neither fires nor draws its touch button while the
default context is on top.
A map standing another map's group down is the coarser instrument beside
this one: group / suppresses on an .inputMap decides which whole
schemes answer, while a context decides which entries within a live scheme
do.
Exports
M.default() -> string— the always-on context name ("default").M.push(name: string)— push a context. No-op whennameis not a non-empty string.M.pop() -> string?— pop the top context; returnsnilwhen onlydefaultremains.M.current() -> string— name at the top of the stack.M.contains(name: string) -> boolean— true ifnameis anywhere in the stack.M.stack() -> { string }— a copy of the live stack, bottom→top.M.reset()— pop everything exceptdefault.M.with<T...>(name: string, fn: () -> T...) -> T...— runfnwithnamepushed, pop guaranteed.
Usage
local Zin = require("@builtin::modules.zinput")
-- menuClose.inputBinding/init.luau declares `context = "ui"`, so it reads
-- only while "ui" is on top.
Zin.context.push("ui")
Zin.context.current() -- "ui"
Zin.context.pop()
Zin.context.with("ui", function()
-- inside this block the "ui" controls are the ones that read
end)
Notes
- The stack lives in the module's upvalues, so it persists across
Luau script runs that share the require cache. A
restart_instanceresets it (matches the standard caching contract). - Pushing the same context twice requires two pops to fully remove — matches typical UI nesting (a sub-menu pushes "ui" again).
- A declared context is compared strictly equal to
current(); there's no inheritance up the stack.