Skip to main content

mittens_engine/engine/ecs/component/
input_xr_gamepad.rs

1use crate::engine::ecs::ComponentId;
2use crate::engine::ecs::component::Component;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum XrHandPreference {
6    Default,
7    Left,
8    Right,
9    Either,
10}
11
12impl Default for XrHandPreference {
13    fn default() -> Self {
14        Self::Default
15    }
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub enum XrAxisControl {
20    LeftStick,
21    RightStick,
22    LeftTrigger,
23    RightTrigger,
24    LeftGrip,
25    RightGrip,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29pub enum XrButtonControl {
30    LeftTrigger,
31    RightTrigger,
32    LeftGrip,
33    RightGrip,
34    ButtonA,
35    ButtonB,
36    ButtonX,
37    ButtonY,
38}
39
40#[derive(Debug, Clone)]
41pub struct InputXRGamepadComponent {
42    pub enabled: bool,
43    pub hand: XrHandPreference,
44    pub locomotion: bool,
45    pub speed: f32,
46    pub deadzone: f32,
47    pub component_id: Option<ComponentId>,
48}
49
50impl InputXRGamepadComponent {
51    pub fn new() -> Self {
52        Self {
53            enabled: true,
54            hand: XrHandPreference::Default,
55            locomotion: true,
56            speed: 3.0,
57            deadzone: 0.2,
58            component_id: None,
59        }
60    }
61
62    pub fn enabled(mut self, enabled: bool) -> Self {
63        self.enabled = enabled;
64        self
65    }
66
67    pub fn hand(mut self, hand: XrHandPreference) -> Self {
68        self.hand = hand;
69        self
70    }
71
72    pub fn locomotion(mut self) -> Self {
73        self.locomotion = true;
74        self
75    }
76
77    pub fn locomotion_enabled(mut self, enabled: bool) -> Self {
78        self.locomotion = enabled;
79        self
80    }
81
82    pub fn speed(mut self, speed: f32) -> Self {
83        self.speed = speed;
84        self
85    }
86
87    pub fn deadzone(mut self, deadzone: f32) -> Self {
88        self.deadzone = deadzone;
89        self
90    }
91}
92
93impl Default for InputXRGamepadComponent {
94    fn default() -> Self {
95        Self::new()
96    }
97}
98
99impl Component for InputXRGamepadComponent {
100    fn name(&self) -> &'static str {
101        "input_vr_gamepad"
102    }
103
104    fn as_any(&self) -> &dyn std::any::Any {
105        self
106    }
107
108    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
109        self
110    }
111
112    fn set_id(&mut self, component: ComponentId) {
113        self.component_id = Some(component);
114    }
115
116    fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
117        self.component_id = Some(component);
118        emit.push_intent_now(
119            component,
120            crate::engine::ecs::IntentValue::RegisterInputXrGamepad {
121                component_ids: vec![component],
122            },
123        );
124    }
125
126    fn cleanup(
127        &mut self,
128        emit: &mut dyn crate::engine::ecs::SignalEmitter,
129        component: ComponentId,
130    ) {
131        emit.push_intent_now(
132            component,
133            crate::engine::ecs::IntentValue::RemoveInputXrGamepad {
134                component_ids: vec![component],
135            },
136        );
137    }
138
139    fn to_mms_ast(
140        &self,
141        _world: &crate::engine::ecs::World,
142    ) -> crate::scripting::ast::ComponentExpression {
143        use crate::engine::ecs::component::ce_helpers::*;
144
145        let hand = match self.hand {
146            XrHandPreference::Default => "default",
147            XrHandPreference::Left => "left",
148            XrHandPreference::Right => "right",
149            XrHandPreference::Either => "either",
150        };
151
152        let mut ce = ce_call("InputXRGamepad", "new", vec![])
153            .with_call("enabled", vec![b(self.enabled)])
154            .with_call("hand", vec![s(hand)]);
155        if !self.locomotion {
156            ce = ce.with_call("locomotion", vec![b(false)]);
157        }
158        if (self.speed - 3.0).abs() > f32::EPSILON {
159            ce = ce.with_call("speed", vec![num(self.speed as f64)]);
160        }
161        if (self.deadzone - 0.2).abs() > f32::EPSILON {
162            ce = ce.with_call("deadzone", vec![num(self.deadzone as f64)]);
163        }
164        ce
165    }
166}