Expand description
§Crate orbit_input_core
Protocolo de traits para construir sistemas de input compatibles con Orbit Engine.
Este crate define únicamente las interfaces (traits) necesarias para implementar
un runtime de entrada compatible con el ecosistema de Orbit Engine.
No contiene implementaciones concretas — solo el contrato que deben cumplir.
§¿Para quién es este crate?
§👥 Para usuarios finales de Orbit Engine
Si solo quieres usar el sistema de input en tu juego, NO necesitas este crate.
Usa directamente la implementación oficial:
[dependencies]
orbit_input = "0.1"§🔧 Para implementadores de backends personalizados
Si quieres crear tu propio runtime de input compatible con Orbit Engine (por ejemplo, para un dispositivo custom, sistema embebido, o un backend experimental), este es el crate que necesitas:
[dependencies]
orbit_input_core = "0.1"§Filosofía de diseño
orbit_input_core sigue el principio de inversión de dependencias:
- Orbit Engine depende de
orbit_input_core(los traits), no de implementaciones concretas - Cualquier runtime que implemente estos traits es compatible con Orbit Engine
- Los usuarios pueden elegir entre la implementación oficial (
orbit_input) o crear la suya
Esto permite:
- ✅ Máxima flexibilidad para casos de uso especializados
- ✅ Testing más sencillo (mocks que implementan los traits)
- ✅ Soporte para dispositivos no estándar
- ✅ Backends experimentales sin modificar el motor
§Contenido del crate
Este crate solo define traits, sin tipos concretos:
§Traits de conversión
KeyExt<B, N>: Convierte entre teclas del backend nativo y teclas normalizadasKeyStateExt<I, O>: Convierte entre estados del backend y estados normalizados
§Traits de gestión de estado
InputStateExt<K, S>: Interfaz para consultar el estado actual del input (frame actual)WithHistoryExt<K, S, T>: ExtiendeInputStateExtcon sistema de historial temporalInputEvent: Representa un evento individual en el historial
§Ejemplo: Implementación básica
use orbit_input_core::{InputStateExt, KeyExt};
use std::collections::HashMap;
// 1. Define tus propios tipos
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum MyKeyCode { Jump, Crouch, Attack, Unknown }
#[derive(Copy, Clone, PartialEq)]
pub enum MyKeyState { Down, Up }
// 2. Implementa la conversión desde tu backend nativo
impl KeyExt<u32, MyKeyCode> for u32 {
fn from_backend_key(native: u32) -> MyKeyCode {
match native {
0x20 => MyKeyCode::Jump,
0x43 => MyKeyCode::Crouch,
0x41 => MyKeyCode::Attack,
_ => MyKeyCode::Unknown,
}
}
fn to_backend_key(code: MyKeyCode) -> u32 {
match code {
MyKeyCode::Jump => 0x20,
MyKeyCode::Crouch => 0x43,
MyKeyCode::Attack => 0x41,
MyKeyCode::Unknown => 0x00,
}
}
}
// 3. Crea tu estructura de estado
pub struct MyInputSystem {
keys: HashMap<MyKeyCode, MyKeyState>,
}
// 4. Implementa el trait principal
impl InputStateExt<MyKeyCode, MyKeyState> for MyInputSystem {
fn set_key(&mut self, key: MyKeyCode, state: MyKeyState) {
self.keys.insert(key, state);
}
fn is_pressed(&self, key: MyKeyCode) -> bool {
self.keys.get(&key) == Some(&MyKeyState::Down)
}
// ... implementa el resto de métodos
}¡Y listo! Tu runtime ya es compatible con cualquier parte de Orbit Engine que
acepte impl InputStateExt<K, S>.
§Casos de uso
§🎮 Gamepad personalizado
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
enum GamepadButton { A, B, X, Y, Start, Select }
impl InputStateExt<GamepadButton, ButtonState> for MyGamepad {
// Tu implementación...
}§🕹️ Arcade stick
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
enum ArcadeInput { Up, Down, Left, Right, Button1, Button2 }
impl InputStateExt<ArcadeInput, StickState> for ArcadeStick {
// Tu implementación...
}§🖱️ Input combinado (teclado + mouse)
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
enum UnifiedInput {
Key(KeyCode),
Mouse(MouseButton),
}
impl InputStateExt<UnifiedInput, InputState> for HybridInput {
// Tu implementación...
}§🧪 Testing y mocks
pub struct MockInput {
pressed_keys: HashSet<KeyCode>,
}
impl InputStateExt<KeyCode, KeyState> for MockInput {
// Implementación simplificada para tests
}§Implementación oficial
Para la mayoría de casos de uso, la implementación oficial orbit_input
es suficiente. Incluye:
- ✅ Soporte nativo para Linux (evdev) y Windows (winapi)
- ✅ Tipos
KeyCodeyKeyStatepredefinidos - ✅ Sistema de historial completo (
WithHistoryExt) - ✅ Detección de combos, secuencias y doble tap
- ✅ Runtime asíncrono con Tokio
- ✅ API ergonómica lista para usar
§Características
- 🔌 Arquitectura plugin — cualquier backend puede implementar los traits
- 🎯 Type-safe — los tipos genéricos previenen errores en tiempo de compilación
- 🔄 Versionado semántico estricto — cambios breaking solo en versiones mayores
§Convenciones de tipos genéricos
Los traits usan nombres consistentes para sus parámetros genéricos:
-
KeyExt<B, N>:B= Backend (tipo nativo del sistema, ej:evdev::Key,u16)N= Normalized (tipo normalizado del runtime, ej:KeyCode)
-
KeyStateExt<I, O>:I= Input (estado externo/nativo del sistema)O= Output (estado interno/normalizado del runtime)
-
InputStateExt<K, S>:K= Key (tipo de tecla, debe serCopy + PartialEq + Hash)S= State (tipo de estado, debe serCopy + PartialEq)
-
WithHistoryExt<K, S, T>:K= Key (mismo que arriba)S= State (mismo que arriba)T= Type (tipo de evento, debe implementarInputEvent)
§Roadmap
Futuras versiones del protocolo incluirán:
- 🎮 Traits para otros dispositivos (mouse, gamepad, touch)
- 📝 Trait para interpretación de texto y layouts de teclado
- 🔊 Trait para feedback háptico
- 🎯 Trait para gestión de contextos de input (menú, gameplay, diálogo)
§Módulos
traits: Todos los traits disponibles para implementación
Re-exports§
pub use traits::keys::KeyExt;pub use traits::keys::KeyStateExt;pub use traits::runtime::RuntimeExt;pub use traits::state::InputEvent;pub use traits::state::InputStateExt;pub use traits::state::WithHistoryExt;pub use traits::*;