Compare commits

..

2 Commits

Author SHA1 Message Date
Axel Meyer
26a38c74e2 docs(input): README fixups — spec link + lib-centric changelog (P.3.10 follow-up)
Code-quality-review-follow-up for commit 837dc3c:
- Add Spec v0.4.0 entry to header spec-link list (was missing).
- Rephrase v0.4.0 changelog to drop Selection-Lib reference;
  lib-core.input changelog should describe its own surface, not
  cross-lib consumer workarounds.
2026-05-15 21:29:44 +02:00
Axel Meyer
837dc3cbc7 feat(input): v0.4.0 — was_action_released release-edge (P.3.10)
Additive, backward-compatible. Mirrors was_action_pressed dispatch
pattern. Selection-Lib's prev_click_down workaround now obsolete.
Engine bindings (was_released + was_mouse_released) added in
sporel-engine commit covering P.3.10 Task 1.

Removes was_released-edge entry from DEPRECATED-MVP list.
2026-05-15 21:26:24 +02:00
3 changed files with 43 additions and 11 deletions

View File

@@ -1,17 +1,19 @@
# lib-core.input # lib-core.input
P.0 action-mapping lib. Decouples physical keys from logical actions. P.0 action-mapping lib. Decouples physical keys from logical actions.
Polling-based (`is_action_down`) + edge-based (`was_action_pressed`). Polling-based (`is_action_down`) + edge-based (`was_action_pressed`, `was_action_released`).
Direction-vector helper composes 4 actions into `{x, y}` ∈ {-1, 0, +1}². Direction-vector helper composes 4 actions into `{x, y}` ∈ {-1, 0, +1}².
- Lib-ID: `lib-core.input` - Lib-ID: `lib-core.input`
- Version: `0.2.0` (breaking change from v0.1.0 — string-keys only, see §Migration) - Version: `0.4.0`
- Spec v0.4.0 (P.3.10): `meta/docs/superpowers/specs/2026-05-15-p3-housekeeping-design.md`
- Spec v0.3.0 (P.3.3): `meta/docs/superpowers/specs/2026-05-12-p3-3-mouse-input-design.md`
- Spec v0.2.0 (P.2.6): `meta/docs/superpowers/specs/2026-05-11-engine-input-symbolic-keys-design.md` - Spec v0.2.0 (P.2.6): `meta/docs/superpowers/specs/2026-05-11-engine-input-symbolic-keys-design.md`
- Spec v0.1.0 (P.0): `meta/docs/superpowers/specs/2026-05-09-p0-lib-input-design.md` - Spec v0.1.0 (P.0): `meta/docs/superpowers/specs/2026-05-09-p0-lib-input-design.md`
Forward-compat stubs (DEPRECATED-MVP) for mouse-button actions, gamepad Forward-compat stubs (DEPRECATED-MVP) for mouse-button actions, gamepad
bindings, action-context-stack, key-rebinding-config, modifier-combos, bindings, action-context-stack, key-rebinding-config, modifier-combos,
analog-axis, was_action_released edge, right-modifier-keys, function-keys, analog-axis, right-modifier-keys, function-keys,
special-keys (delete/insert/home/end/pageup/pagedown). special-keys (delete/insert/home/end/pageup/pagedown).
## API ## API
@@ -19,7 +21,8 @@ special-keys (delete/insert/home/end/pageup/pagedown).
- `input.bind(action_name, {"keyname1", "keyname2", ...})` — bind multi-key array (string-keys only, see §Key-Names) - `input.bind(action_name, {"keyname1", "keyname2", ...})` — bind multi-key array (string-keys only, see §Key-Names)
- `input.unbind(action_name)` — remove binding - `input.unbind(action_name)` — remove binding
- `input.is_action_down(action) → bool` — any bound key currently down - `input.is_action_down(action) → bool` — any bound key currently down
- `input.was_action_pressed(action) → bool` — any bound key just-pressed - `input.was_action_pressed(action) → bool` — any bound key just-pressed (press-edge; true for exactly one frame per key-down event)
- `input.was_action_released(action) → bool` — any bound key just-released (release-edge; true for exactly one frame per key-up event; triggers once per press-release cycle)
- `input.direction(left, right, up, down) → {x, y}` — vec in {-1,0,+1}², Y-down-positive - `input.direction(left, right, up, down) → {x, y}` — vec in {-1,0,+1}², Y-down-positive
- `input.action_count() → number` — bound-actions count - `input.action_count() → number` — bound-actions count
@@ -74,3 +77,18 @@ end
| `bind("move", { engine.input.KEY_A, engine.input.KEY_LEFT })` | `bind("move", { "a", "left" })` | | `bind("move", { engine.input.KEY_A, engine.input.KEY_LEFT })` | `bind("move", { "a", "left" })` |
`engine.input.KEY_*` constants remain available for direct engine-input use (e.g. `engine.input.is_key_down(engine.input.KEY_F1)` for edge-cases without bind), but `lib-core.input.bind` strict-rejects them. `engine.input.KEY_*` constants remain available for direct engine-input use (e.g. `engine.input.is_key_down(engine.input.KEY_F1)` for edge-cases without bind), but `lib-core.input.bind` strict-rejects them.
## CHANGELOG
## v0.4.0 (P.3.10, 2026-05-15)
- Added `was_action_released(action_name)` — release-edge detection per action.
Consumers can now detect key-up edges without per-frame state tracking.
- Engine surface: `engine.input.was_released` + `was_mouse_released`.
## v0.3.0 (P.3.3, 2026-05-12)
- `bind()` now accepts unified key+mouse strings via BIND_MAP with kind-tagged entries.
- Mixed bindings supported (e.g. `{"e", "mouse_left"}`).
- Backward-compatible with v0.2.0 callsites.
## v0.2.0 (P.2.6, 2026-05-11)
- `bind()` accepts string-key-names only. Integer `engine.input.KEY_*` args are rejected.

View File

@@ -1,7 +1,12 @@
-- ===================================================================== -- =====================================================================
-- lib-core.input — Action-Mapping + Direction-Vector (v0.3.0) -- lib-core.input — Action-Mapping + Direction-Vector (v0.4.0)
-- See: meta/docs/superpowers/specs/2026-05-12-p3-3-mouse-input-design.md -- See: meta/docs/superpowers/specs/2026-05-12-p3-3-mouse-input-design.md
-- --
-- v0.4.0 (P.3.10 2026-05-15): was_action_released added — release-edge
-- detection parallel to was_action_pressed. Engine-Surface:
-- engine.input.was_released + was_mouse_released. Selection-Lib's
-- prev_click_down workaround promoted.
--
-- v0.3.0 (P.3.3 2026-05-12): bind() now accepts unified key+mouse -- v0.3.0 (P.3.3 2026-05-12): bind() now accepts unified key+mouse
-- strings via BIND_MAP with kind-tagged entries ({kind="key"|"mouse", -- strings via BIND_MAP with kind-tagged entries ({kind="key"|"mouse",
-- code=<engine-int>}). Mixed bindings supported: e.g. -- code=<engine-int>}). Mixed bindings supported: e.g.
@@ -12,10 +17,10 @@
-- v0.2.0 (P.2.6 2026-05-11): bind() accepts string-key-names only. -- v0.2.0 (P.2.6 2026-05-11): bind() accepts string-key-names only.
-- Integer engine.input.KEY_* args are rejected. -- Integer engine.input.KEY_* args are rejected.
-- --
-- Scope v0.3.0: action-mapping (string-key+mouse-arrays per action) + -- Scope v0.4.0: action-mapping (string-key+mouse-arrays per action) +
-- direction-vector helper. DEPRECATED-MVP: mouse-wheel, was_released -- press-edge + release-edge detection + direction-vector helper.
-- edge, mouse-delta helper, side-buttons, gamepad bindings, -- DEPRECATED-MVP: mouse-wheel, mouse-delta helper, side-buttons,
-- action-context-stack, key-rebinding config. -- gamepad bindings, action-context-stack, key-rebinding config.
-- ===================================================================== -- =====================================================================
-- Unified string → {kind, code} mapping. Lowercase convention. -- Unified string → {kind, code} mapping. Lowercase convention.
@@ -126,6 +131,16 @@ function M.was_action_pressed(action_name)
return false return false
end end
function M.was_action_released(action_name)
local entries = bindings[action_name]
if not entries then return false end
for _, e in ipairs(entries) do
if e.kind == "key" and engine.input.was_released(e.code) then return true end
if e.kind == "mouse" and engine.input.was_mouse_released(e.code) then return true end
end
return false
end
-- Direction-vector helper: returns {x, y} in {-1, 0, +1} each axis. -- Direction-vector helper: returns {x, y} in {-1, 0, +1} each axis.
-- Y-down-positive per Sporel pixel-convention (ADR-0031). -- Y-down-positive per Sporel pixel-convention (ADR-0031).
function M.direction(left_action, right_action, up_action, down_action) function M.direction(left_action, right_action, up_action, down_action)
@@ -144,7 +159,6 @@ end
-- DEPRECATED-MVP (P.3.3-introduced): -- DEPRECATED-MVP (P.3.3-introduced):
-- mouse-wheel binding (wheel_up/wheel_down) — P.3-future-slice (post-P.3.4); continuous-vs-edge brainstorming needed -- mouse-wheel binding (wheel_up/wheel_down) — P.3-future-slice (post-P.3.4); continuous-vs-edge brainstorming needed
-- was_action_released(action) — lift-detection-edge (both key + mouse atomic)
-- mouse-delta helper (engine.input.get_mouse_delta) — P.3.5/6 drag-pan / drag-box -- mouse-delta helper (engine.input.get_mouse_delta) — P.3.5/6 drag-pan / drag-box
-- mouse-button side-buttons (mouse_4 / mouse_5) — additive extension -- mouse-button side-buttons (mouse_4 / mouse_5) — additive extension
-- mouse-position lib-wrapper (input.mouse_pos() → {x,y}) — convenience layer -- mouse-position lib-wrapper (input.mouse_pos() → {x,y}) — convenience layer

View File

@@ -1 +1 @@
{"id":"lib-core.input","version":"0.3.0","api_min":"0.1"} {"id":"lib-core.input","version":"0.4.0","api_min":"0.1"}