mittens_engine/engine/ecs/component/
raycastable.rs1use crate::engine::ecs::component::Component;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
15pub enum PointerEvents {
16 #[default]
18 All,
19 DragOnly,
21 ClickOnly,
23 PassThrough,
26}
27
28impl PointerEvents {
29 pub fn captures_drag(self) -> bool {
30 matches!(self, Self::All | Self::DragOnly)
31 }
32 pub fn captures_click(self) -> bool {
33 matches!(self, Self::All | Self::ClickOnly)
34 }
35}
36
37#[derive(Debug, Default, Clone, Copy)]
42pub struct RaycastableComponent {
43 pub enable: bool,
45 pub pointer_events: PointerEvents,
47 pub interaction_priority: u8,
49}
50
51impl RaycastableComponent {
52 pub fn new(enable: bool) -> Self {
53 Self {
54 enable,
55 pointer_events: PointerEvents::All,
56 interaction_priority: 0,
57 }
58 }
59
60 pub fn enabled() -> Self {
61 Self::new(true)
62 }
63
64 pub fn disabled() -> Self {
65 Self::new(false)
66 }
67
68 pub fn drag_only() -> Self {
70 Self {
71 enable: true,
72 pointer_events: PointerEvents::DragOnly,
73 interaction_priority: 0,
74 }
75 }
76
77 pub fn click_only() -> Self {
79 Self {
80 enable: true,
81 pointer_events: PointerEvents::ClickOnly,
82 interaction_priority: 0,
83 }
84 }
85
86 pub fn with_interaction_priority(mut self, interaction_priority: u8) -> Self {
87 self.interaction_priority = interaction_priority;
88 self
89 }
90}
91
92impl Component for RaycastableComponent {
93 fn init(
94 &mut self,
95 emit: &mut dyn crate::engine::ecs::SignalEmitter,
96 component: crate::engine::ecs::ComponentId,
97 ) {
98 emit.push_intent(
99 component,
100 crate::engine::ecs::IntentSignal::now(
101 crate::engine::ecs::IntentValue::RegisterRaycastable {
102 component_ids: vec![component],
103 },
104 ),
105 );
106 }
107
108 fn cleanup(
109 &mut self,
110 emit: &mut dyn crate::engine::ecs::SignalEmitter,
111 component: crate::engine::ecs::ComponentId,
112 ) {
113 emit.push_intent(
114 component,
115 crate::engine::ecs::IntentSignal::now(
116 crate::engine::ecs::IntentValue::RemoveRaycastable {
117 component_ids: vec![component],
118 },
119 ),
120 );
121 }
122
123 fn as_any(&self) -> &dyn std::any::Any {
124 self
125 }
126
127 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
128 self
129 }
130
131 fn name(&self) -> &'static str {
132 "raycastable"
133 }
134
135 fn to_mms_ast(
136 &self,
137 _world: &crate::engine::ecs::World,
138 ) -> crate::scripting::ast::ComponentExpression {
139 use crate::engine::ecs::component::ce_helpers::*;
140 let ctor = match (self.enable, self.pointer_events) {
141 (false, _) => "disabled",
142 (true, PointerEvents::DragOnly) => "drag_only",
143 (true, PointerEvents::ClickOnly) => "click_only",
144 (true, _) => "enabled",
145 };
146 let mut ce = ce_call("Raycastable", ctor, vec![]);
147 if self.enable && matches!(self.pointer_events, PointerEvents::PassThrough) {
148 ce = ce.with_call("pointer_events", vec![s("pass_through")]);
149 }
150 if self.enable && self.interaction_priority > 0 {
151 ce = ce.with_call(
152 "interaction_priority",
153 vec![num(self.interaction_priority as f64)],
154 );
155 }
156 ce
157 }
158}