Skip to main content

mittens_engine/engine/ecs/component/
pointer.rs

1use crate::engine::ecs::ComponentId;
2use crate::engine::ecs::component::Component;
3
4/// User-facing pointer component.
5///
6/// Attach this under the pose-driving part of the topology (for example a desktop camera rig
7/// transform, an XR camera, or a controller-driven transform). At init time the engine spawns
8/// and owns a child `RayCastComponent`, so authoring only needs to describe the pointer itself.
9#[derive(Debug, Clone, Copy)]
10pub struct PointerComponent {
11    pub enabled: bool,
12
13    component: Option<ComponentId>,
14}
15
16impl PointerComponent {
17    pub fn new() -> Self {
18        Self {
19            enabled: true,
20            component: None,
21        }
22    }
23
24    pub fn disabled() -> Self {
25        Self {
26            enabled: false,
27            component: None,
28        }
29    }
30
31    pub fn with_enabled(mut self, enabled: bool) -> Self {
32        self.enabled = enabled;
33        self
34    }
35}
36
37impl Default for PointerComponent {
38    fn default() -> Self {
39        Self::new()
40    }
41}
42
43impl Component for PointerComponent {
44    fn name(&self) -> &'static str {
45        "pointer"
46    }
47
48    fn set_id(&mut self, component: ComponentId) {
49        self.component = Some(component);
50    }
51
52    fn as_any(&self) -> &dyn std::any::Any {
53        self
54    }
55
56    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
57        self
58    }
59
60    fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
61        self.component = Some(component);
62        emit.push_intent_now(
63            component,
64            crate::engine::ecs::IntentValue::RegisterPointer {
65                component_ids: vec![component],
66            },
67        );
68    }
69
70    fn to_mms_ast(
71        &self,
72        _world: &crate::engine::ecs::World,
73    ) -> crate::scripting::ast::ComponentExpression {
74        use crate::engine::ecs::component::ce_helpers::*;
75        if self.enabled {
76            ce("Pointer")
77        } else {
78            ce_call("Pointer", "disabled", vec![])
79        }
80    }
81}