Import Oxide engine (Stages 0–10) under MIT license
Full project snapshot migrated to new Gitea remote without history: engine, editor, physics, script, examples, tests, docs, and assets. Relicensed from GPLv3 to MIT and updated repo URLs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
//! Per-frame input — raw state, edges, and remappable named actions.
|
||||
//!
|
||||
//! Stage 7 builds the engine's input abstraction in three layers:
|
||||
//!
|
||||
//! 1. [`InputState`] (piece 1) — the per-frame snapshot of keyboard, mouse,
|
||||
//! cursor, and scroll, with `pressed` / `released` edge detection and a
|
||||
//! persistent `held` state. The windowing runner pumps raw `WindowEvent`s
|
||||
//! into it and clears edges between frames; game/editor code reads it via
|
||||
//! [`AppCtx::input`](crate::window::AppCtx::input).
|
||||
//! 2. [`Binding`] + [`ActionMap`] (piece 2) — named actions like `"Jump"`
|
||||
//! bound to one or more physical inputs, each carrying a **default**
|
||||
//! binding and a (possibly remapped) **current** binding. Game code
|
||||
//! queries actions by name, so a user-facing remap never touches game
|
||||
//! code. Current bindings round-trip through RON for persistence
|
||||
//! (typically via the [`Settings`](crate::settings::Settings) framework).
|
||||
//! 3. [`AxisBinding`] + [`Axis2DBinding`] (piece 3) — directional inputs
|
||||
//! composed from `Binding` direction sets (e.g. `WASD` → `Vec2 "Move"`),
|
||||
//! stored alongside button actions in the same [`ActionMap`] and
|
||||
//! persisted through the same [`ActionOverrides`] payload.
|
||||
//!
|
||||
//! # Why edges and state are tracked separately
|
||||
//!
|
||||
//! Game logic typically wants three distinct things from a physical input:
|
||||
//! the moment it became pressed (a jump fires once on key-down, never on
|
||||
//! subsequent frames while held), the moment it was released (a charged
|
||||
//! shot fires on key-up), and whether it is currently down (a sprint key
|
||||
//! accelerates while held). Tracking all three explicitly makes the
|
||||
//! semantics robust against OS key auto-repeat — a held key produces a
|
||||
//! single `pressed` edge no matter how many times the OS re-sends the
|
||||
//! event — and avoids the per-callsite bookkeeping every action would
|
||||
//! otherwise need.
|
||||
//!
|
||||
//! # Quick reference
|
||||
//!
|
||||
//! ```
|
||||
//! use oxide_engine::input::{ActionMap, Binding, InputState};
|
||||
//! use oxide_engine::winit::keyboard::KeyCode;
|
||||
//!
|
||||
//! let mut input = InputState::new();
|
||||
//! input.press_key(KeyCode::Space);
|
||||
//! assert!(input.pressed(KeyCode::Space)); // edge — true only this frame
|
||||
//! assert!(input.held(KeyCode::Space)); // state — true while held
|
||||
//!
|
||||
//! // Layer named actions on top — game code never names the physical key.
|
||||
//! let mut actions = ActionMap::new();
|
||||
//! actions.register("Jump", [Binding::Key(KeyCode::Space)]);
|
||||
//! assert!(actions.action_pressed("Jump", &input));
|
||||
//!
|
||||
//! input.end_frame();
|
||||
//! assert!(!input.pressed(KeyCode::Space)); // edge cleared
|
||||
//! assert!(input.held(KeyCode::Space)); // held persists
|
||||
//! ```
|
||||
//!
|
||||
//! # Synthesized-event API
|
||||
//!
|
||||
//! The mutators on [`InputState`] (`press_key`, `release_mouse`,
|
||||
//! `set_cursor`, `add_mouse_delta`, `add_scroll`, `forget_cursor`,
|
||||
//! `release_all_held`) are the same path `handle_event` uses, and are
|
||||
//! intentionally public so tests can drive input directly without
|
||||
//! constructing `winit` events (winit 0.30's `DeviceId` cannot be
|
||||
//! fabricated outside an event loop, so most `WindowEvent` variants are
|
||||
//! unreachable from synthesized events).
|
||||
|
||||
mod action;
|
||||
mod axis;
|
||||
mod binding;
|
||||
mod state;
|
||||
|
||||
pub use action::{ActionMap, ActionOverrides};
|
||||
pub use axis::{Axis2DBinding, AxisBinding};
|
||||
pub use binding::Binding;
|
||||
pub use state::InputState;
|
||||
Reference in New Issue
Block a user