Skip to main content

goud_engine/core/providers/impls/
null_input.rs

1//! Null input provider -- silent no-op for headless testing.
2
3use crate::core::error::GoudResult;
4use crate::core::providers::input::InputProvider;
5use crate::core::providers::types::{
6    GamepadAxis, GamepadButton, GamepadId, InputCapabilities, KeyCode, MouseButton,
7};
8use crate::core::providers::Provider;
9
10/// An input provider that does nothing. Used for headless testing and as
11/// a default when no input system is available.
12pub struct NullInputProvider {
13    capabilities: InputCapabilities,
14}
15
16impl NullInputProvider {
17    /// Create a new null input provider.
18    pub fn new() -> Self {
19        Self {
20            capabilities: InputCapabilities {
21                supports_gamepad: false,
22                supports_touch: false,
23                max_gamepads: 0,
24            },
25        }
26    }
27}
28
29impl Default for NullInputProvider {
30    fn default() -> Self {
31        Self::new()
32    }
33}
34
35impl Provider for NullInputProvider {
36    fn name(&self) -> &str {
37        "null"
38    }
39
40    fn version(&self) -> &str {
41        "0.0.0"
42    }
43
44    fn capabilities(&self) -> Box<dyn std::any::Any> {
45        Box::new(self.capabilities.clone())
46    }
47}
48
49impl InputProvider for NullInputProvider {
50    fn input_capabilities(&self) -> &InputCapabilities {
51        &self.capabilities
52    }
53
54    fn update_input(&mut self) -> GoudResult<()> {
55        Ok(())
56    }
57
58    fn key_pressed(&self, _key: KeyCode) -> bool {
59        false
60    }
61
62    fn key_just_pressed(&self, _key: KeyCode) -> bool {
63        false
64    }
65
66    fn key_just_released(&self, _key: KeyCode) -> bool {
67        false
68    }
69
70    fn mouse_position(&self) -> [f32; 2] {
71        [0.0, 0.0]
72    }
73
74    fn mouse_delta(&self) -> [f32; 2] {
75        [0.0, 0.0]
76    }
77
78    fn mouse_button_pressed(&self, _button: MouseButton) -> bool {
79        false
80    }
81
82    fn scroll_delta(&self) -> [f32; 2] {
83        [0.0, 0.0]
84    }
85
86    fn gamepad_connected(&self, _id: GamepadId) -> bool {
87        false
88    }
89
90    fn gamepad_axis(&self, _id: GamepadId, _axis: GamepadAxis) -> f32 {
91        0.0
92    }
93
94    fn gamepad_button_pressed(&self, _id: GamepadId, _button: GamepadButton) -> bool {
95        false
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn test_null_input_construction() {
105        let provider = NullInputProvider::new();
106        assert_eq!(provider.name(), "null");
107        assert_eq!(provider.version(), "0.0.0");
108    }
109
110    #[test]
111    fn test_null_input_default() {
112        let provider = NullInputProvider::default();
113        assert_eq!(provider.name(), "null");
114    }
115
116    #[test]
117    fn test_null_input_capabilities() {
118        let provider = NullInputProvider::new();
119        let caps = provider.input_capabilities();
120        assert!(!caps.supports_gamepad);
121        assert!(!caps.supports_touch);
122        assert_eq!(caps.max_gamepads, 0);
123    }
124
125    #[test]
126    fn test_null_input_update() {
127        let mut provider = NullInputProvider::new();
128        assert!(provider.update_input().is_ok());
129    }
130
131    #[test]
132    fn test_null_input_keyboard() {
133        let provider = NullInputProvider::new();
134        assert!(!provider.key_pressed(KeyCode::Space));
135        assert!(!provider.key_just_pressed(KeyCode::Enter));
136        assert!(!provider.key_just_released(KeyCode::Escape));
137    }
138
139    #[test]
140    fn test_null_input_mouse() {
141        let provider = NullInputProvider::new();
142        assert_eq!(provider.mouse_position(), [0.0, 0.0]);
143        assert_eq!(provider.mouse_delta(), [0.0, 0.0]);
144        assert!(!provider.mouse_button_pressed(MouseButton::Left));
145        assert_eq!(provider.scroll_delta(), [0.0, 0.0]);
146    }
147
148    #[test]
149    fn test_null_input_gamepad() {
150        let provider = NullInputProvider::new();
151        let id = GamepadId(0);
152        assert!(!provider.gamepad_connected(id));
153        assert_eq!(provider.gamepad_axis(id, GamepadAxis::LeftStickX), 0.0);
154        assert!(!provider.gamepad_button_pressed(id, GamepadButton::South));
155    }
156}