simvx.core.input.contexts

Where a game’s bindings are declared, and which of them are live right now.

A game rarely wants one flat set of bindings for its whole run. Driving a car means move steers rather than walks; a pause menu means the player’s keys stop reaching the player. Both are the same mechanism: an

class:

InputContext on the node the mode belongs to.

class Vehicle(Node2D): input_context = InputContext({“move”: [Axis2D(up=Key.W, down=Key.S, left=Key.A, right=Key.D)], “honk”: [Key.H]}, name=”vehicle”)

A context is active exactly while its node can receive input, so nothing can leak one: an exception, an early return or a scene swap carries the node out and the context goes with it, and pausing the node stops it declaring and stops it hiding. Active contexts stack in activation order, later on top, and are flattened into one binding map when the stack changes rather than being walked on every query. A deaf node keeps its place in the stack, so waking it puts the context back where it was rather than on top of whatever arrived meanwhile.

Shadowing is by action name. A vehicle context defining move takes that name for as long as it is active and leaves every other name alone, so the walking controller’s jump still works while the car’s move steers.

hides is the stronger form. hides=InputContext.ALL takes every name below it, which is what a pause menu, a modal dialog or a minigame that wants a clean configuration needs: the game’s actions, its device aliases and its own redefinitions of engine entries all go, without the context having to know what the game bound. The ui_ actions never go dark, because a menu that hid ui_accept could not be dismissed, and neither do the engine’s entries (Controller.A, Pointer.PRIMARY and the rest), so a clean branch can still bind them. A tuple of names hides exactly those.

Entries are keyed by name or by control. A string key is an action or a device alias, and its sources may name other entries: {"throttle": [Controller.axis(2)], "engine_power": ["throttle"]}. A control key redefines an engine entry for as long as the context is live, {Controller.A: [Controller.button(1)]}, with exactly one control as its source.

Any node may declare one, and a plain dict is a context of its own entries: input_context = {"jump": [Key.SPACE]} on the root covers the whole tree. The base of the stack is the tree’s own context, which InputMap.add_action writes: it has the tree’s lifetime and never deactivates. Under it are the project’s entries from its settings, and under those the engine’s.

Module Contents

Classes

HideEverything

The hides=InputContext.ALL sentinel, spelled as the set it stands for.

InputContext

One named set of action bindings, live while its node can receive input.

Functions

remap_entry

A redefinition of the engine entry control: validated, with its one control as its source.

Data

API

simvx.core.input.contexts.__all__

[‘HideEverything’, ‘InputContext’]

class simvx.core.input.contexts.HideEverything[source]

The hides=InputContext.ALL sentinel, spelled as the set it stands for.

__slots__

()

__repr__() → str[source]
__contains__(name: object) → bool[source]
__bool__() → bool[source]
class simvx.core.input.contexts.InputContext(bindings: collections.abc.Mapping[str | simvx.core.input.controls.DeviceControl, collections.abc.Iterable[simvx.core.input.actions.SourceSpec] | simvx.core.input.actions.SourceSpec] | None = None, *, name: str | None = None, hides: collections.abc.Iterable[str] | simvx.core.input.contexts.HideEverything = ())[source]

One named set of action bindings, live while its node can receive input.

Args: bindings: What this context declares, {"jump": [Key.SPACE, Controller.A]}. Each value is one action’s sources in the same spelling a node’s input_context dict takes, and a bare source is wrapped. name: What to call it in Input.context_stack and in a diagnostic. Defaults to nothing, which reads as the position in the stack. hides: :attr:ALL to take every name below this context, or the names to take. ui_ actions are never hidden either way.

A context is frozen once built. A player rebinding a key writes the override layer (:meth:InputMap.rebind), which survives every rebuild of the stack and is reapplied to each flatten; it does not edit the context the game wrote.

Initialization

ALL

‘HideEverything(…)’

__slots__

(‘_actions’, ‘_remaps’, ‘_name’, ‘_hides’, ‘_hides_all’, ‘_frozen’)

__setattr__(name: str, value: object) → None[source]
__repr__() → str[source]
property name: str | None[source]

What this context is called, or None where it was not named.

property actions: tuple[str, ...][source]

The names this context declares: its actions and its device aliases.

property remaps: tuple[simvx.core.input.controls.DeviceControl, ...][source]

The engine entries this context redefines while it is live.

property hides: frozenset[str] | simvx.core.input.contexts.HideEverything[source]

What this context takes from below it: names, or :attr:ALL.

property hides_all: bool[source]

Whether this context takes every name below it.

sources(action: str) → tuple[simvx.core.input.actions.Source, ...][source]

What this context binds action to, empty where it does not declare it.

property bindings: collections.abc.Mapping[str, simvx.core.input.actions.Action][source]

The compiled actions, read-only. InputMap flattens these.

simvx.core.input.contexts.remap_entry(control: simvx.core.input.controls.DeviceControl, sources: list[simvx.core.input.actions.SourceSpec]) → simvx.core.input.actions.Action[source]

A redefinition of the engine entry control: validated, with its one control as its source.

An engine entry names a device control, so what it is redefined to is one control of the same kind: a button for a button, a whole axis for a whole axis, a raw index (Controller.button(1)) or another engine entry (Controller.B). A key is raw and has no entry, an index form is raw, and a unit, a half or a motion belongs on the binding that uses the entry.