Skip to main content

mittens_engine/engine/ecs/rx/
signal_pipeline_processor.rs

1use crate::engine::ecs::RxWorld;
2use crate::engine::ecs::rx::signal_pipeline::SignalPipelineOp;
3use crate::engine::ecs::{ComponentId, IntentValue, Signal, World};
4
5/// Pre-execution processor for intent signals.
6///
7/// This is intended to become the hook point for intent routing/forwarding based on
8/// per-target “pipeline” components in the ECS topology.
9///
10/// Current behavior: no-op passthrough.
11#[derive(Debug, Default)]
12pub struct SignalPipelineProcessor;
13
14impl SignalPipelineProcessor {
15    pub fn new() -> Self {
16        Self::default()
17    }
18
19    /// Process an intent-containing signal envelope before it is executed.
20    ///
21    /// This is a no-op for now (returns `env` unchanged).
22    pub fn process_intent(&mut self, world: &World, rx: &RxWorld, mut env: Signal) -> Signal {
23        let Some(intent) = env.intent.as_mut() else {
24            return env;
25        };
26
27        let kind_name = intent.value.kind_name();
28
29        let Some(component_ids) = Self::recipient_component_ids_mut(&mut intent.value) else {
30            return env;
31        };
32
33        if component_ids.is_empty() {
34            return env;
35        }
36
37        let mut out: Vec<ComponentId> = Vec::with_capacity(component_ids.len());
38        for &cid in component_ids.iter() {
39            let mut cur = cid;
40
41            for pipeline in rx.pipelines_for_component(cid).iter() {
42                for op in pipeline.ops.iter() {
43                    match op {
44                        SignalPipelineOp::RouteUpward(r) => {
45                            if r.applies_to_intent_kind(kind_name) {
46                                cur = r.route(world, cur);
47                            }
48                        }
49                    }
50                }
51            }
52
53            out.push(cur);
54        }
55
56        out.sort();
57        out.dedup();
58        *component_ids = out;
59
60        env
61    }
62
63    /// Returns the standardized intent recipients, if the intent variant has them.
64    pub fn recipient_component_ids(value: &IntentValue) -> Option<&[ComponentId]> {
65        match value {
66            IntentValue::SetColor { component_ids, .. }
67            | IntentValue::SetText { component_ids, .. }
68            | IntentValue::SetEmissiveIntensity { component_ids, .. }
69            | IntentValue::SetPosition { component_ids, .. }
70            | IntentValue::LookAt { component_ids, .. }
71            | IntentValue::GLTFArmatureVisible { component_ids, .. }
72            | IntentValue::SetLayoutAvailableWidth { component_ids, .. }
73            | IntentValue::SetLayoutAvailableHeight { component_ids, .. }
74            | IntentValue::SetLayoutInspect { component_ids, .. }
75            | IntentValue::SelectionSet { component_ids, .. }
76            | IntentValue::Detach { component_ids }
77            | IntentValue::RemoveSubtree { component_ids }
78            | IntentValue::AudioGraphRebuild { component_ids }
79            | IntentValue::RequestRaycast { component_ids }
80            | IntentValue::AudioLowPassSetCutoffHz { component_ids, .. }
81            | IntentValue::AudioBandPassSetCenterHz { component_ids, .. }
82            | IntentValue::OscillatorSetEnabled { component_ids, .. }
83            | IntentValue::OscillatorSetPitch { component_ids, .. }
84            | IntentValue::OscillatorScheduleSetPitch { component_ids, .. }
85            | IntentValue::AudioSchedulePlay { component_ids, .. }
86            | IntentValue::RegisterRenderable { component_ids }
87            | IntentValue::RemoveRenderable { component_ids }
88            | IntentValue::RegisterStencilClip { component_ids }
89            | IntentValue::UnregisterStencilClip { component_ids }
90            | IntentValue::RegisterRouter { component_ids }
91            | IntentValue::RegisterHttpServer { component_ids }
92            | IntentValue::RegisterHttpClient { component_ids }
93            | IntentValue::RegisterScrolling { component_ids }
94            | IntentValue::RegisterTransform { component_ids }
95            | IntentValue::UpdateTransform { component_ids, .. }
96            | IntentValue::RemoveTransform { component_ids }
97            | IntentValue::RegisterCamera3d { component_ids }
98            | IntentValue::RegisterCamera2d { component_ids }
99            | IntentValue::MakeActiveCamera { component_ids }
100            | IntentValue::RegisterInput { component_ids }
101            | IntentValue::RegisterUv { component_ids }
102            | IntentValue::RegisterLight { component_ids }
103            | IntentValue::RegisterColor { component_ids }
104            | IntentValue::RegisterOpacity { component_ids }
105            | IntentValue::RegisterTransparentCutout { component_ids }
106            | IntentValue::RegisterBackgroundColor { component_ids }
107            | IntentValue::RegisterRendererSettings { component_ids }
108            | IntentValue::RegisterRenderGraph { component_ids }
109            | IntentValue::RegisterAmbientLight { component_ids }
110            | IntentValue::RegisterEmissive { component_ids }
111            | IntentValue::RegisterLightQuantization { component_ids }
112            | IntentValue::RegisterTexture { component_ids }
113            | IntentValue::RegisterTextureFiltering { component_ids }
114            | IntentValue::RegisterText { component_ids }
115            | IntentValue::RegisterGLTF { component_ids }
116            | IntentValue::RegisterTextInput { component_ids }
117            | IntentValue::RegisterCollision { component_ids }
118            | IntentValue::RemoveCollision { component_ids }
119            | IntentValue::RegisterKineticResponse { component_ids }
120            | IntentValue::RemoveKineticResponse { component_ids }
121            | IntentValue::RegisterAvatarControl { component_ids }
122            | IntentValue::RegisterAvatarBodyYaw { component_ids }
123            | IntentValue::RegisterIkChain { component_ids }
124            | IntentValue::RegisterXr { component_ids }
125            | IntentValue::RegisterInputXr { component_ids }
126            | IntentValue::RegisterControllerXr { component_ids }
127            | IntentValue::RegisterInputXrGamepad { component_ids }
128            | IntentValue::RemoveInputXr { component_ids }
129            | IntentValue::RemoveControllerXr { component_ids }
130            | IntentValue::RemoveInputXrGamepad { component_ids }
131            | IntentValue::RegisterRaycast { component_ids }
132            | IntentValue::RegisterRaycastable { component_ids }
133            | IntentValue::RegisterPointer { component_ids }
134            | IntentValue::RemoveRaycast { component_ids }
135            | IntentValue::RemoveRaycastable { component_ids }
136            | IntentValue::RegisterAnimation { component_ids }
137            | IntentValue::SetAnimationState { component_ids, .. }
138            | IntentValue::RegisterKeyframe { component_ids }
139            | IntentValue::RegisterAudioOutput { component_ids }
140            | IntentValue::AudioGraphDirtyImmediate { component_ids }
141            | IntentValue::RegisterAudioOscillator { component_ids }
142            | IntentValue::RegisterAudioClip { component_ids }
143            | IntentValue::RegisterAudioBufferSize { component_ids }
144            | IntentValue::RegisterClock { component_ids }
145            | IntentValue::RegisterTransformGizmo { component_ids }
146            | IntentValue::RegisterNormalVis { component_ids }
147            | IntentValue::RegisterEditor { component_ids }
148            | IntentValue::RegisterAction { component_ids }
149            | IntentValue::ScheduleAudioOp { component_ids, .. }
150            | IntentValue::ScheduleAudioGraphSwap { component_ids, .. }
151            | IntentValue::ScheduleAudioPitchSetHz { component_ids, .. }
152            | IntentValue::ScheduleAudioOscillatorEnabled { component_ids, .. }
153            | IntentValue::ScheduleAudioGainSet { component_ids, .. } => Some(component_ids),
154
155            IntentValue::Noop
156            | IntentValue::RetryXrRuntime
157            | IntentValue::Print { .. }
158            | IntentValue::ReplExec { .. }
159            | IntentValue::Attach { .. }
160            | IntentValue::AttachClone { .. }
161            | IntentValue::QueryFindComponent { .. }
162            | IntentValue::QueryFindAllComponents { .. }
163            | IntentValue::RemoveChild { .. }
164            | IntentValue::RemoveChildren { .. }
165            | IntentValue::UpdateTransformWorld { .. }
166            | IntentValue::TextInputSetFocus { .. }
167            | IntentValue::TextInputClearFocus
168            | IntentValue::TextInputInsertText { .. }
169            | IntentValue::TextInputBackspace
170            | IntentValue::TextInputDeleteForward
171            | IntentValue::TextInputMoveCaret { .. }
172            | IntentValue::TextInputMoveCaretTo { .. }
173            | IntentValue::RegisterSignalRouteUpward { .. }
174            | IntentValue::RemoveSignalRouteUpward { .. }
175            | IntentValue::SpawnComponentTree { .. }
176            | IntentValue::PoseCapture { .. }
177            | IntentValue::PoseApply { .. }
178            | IntentValue::HttpClientRequest { .. }
179            | IntentValue::HttpServerReply { .. } => None,
180        }
181    }
182
183    fn recipient_component_ids_mut(value: &mut IntentValue) -> Option<&mut Vec<ComponentId>> {
184        match value {
185            IntentValue::SetColor { component_ids, .. }
186            | IntentValue::SetText { component_ids, .. }
187            | IntentValue::SetEmissiveIntensity { component_ids, .. }
188            | IntentValue::SetPosition { component_ids, .. }
189            | IntentValue::LookAt { component_ids, .. }
190            | IntentValue::GLTFArmatureVisible { component_ids, .. }
191            | IntentValue::SetLayoutAvailableWidth { component_ids, .. }
192            | IntentValue::SetLayoutAvailableHeight { component_ids, .. }
193            | IntentValue::SetLayoutInspect { component_ids, .. }
194            | IntentValue::SelectionSet { component_ids, .. }
195            | IntentValue::Detach { component_ids }
196            | IntentValue::RemoveSubtree { component_ids }
197            | IntentValue::AudioGraphRebuild { component_ids }
198            | IntentValue::RequestRaycast { component_ids }
199            | IntentValue::AudioLowPassSetCutoffHz { component_ids, .. }
200            | IntentValue::AudioBandPassSetCenterHz { component_ids, .. }
201            | IntentValue::OscillatorSetEnabled { component_ids, .. }
202            | IntentValue::OscillatorSetPitch { component_ids, .. }
203            | IntentValue::OscillatorScheduleSetPitch { component_ids, .. }
204            | IntentValue::AudioSchedulePlay { component_ids, .. }
205            | IntentValue::RegisterRenderable { component_ids }
206            | IntentValue::RemoveRenderable { component_ids }
207            | IntentValue::RegisterStencilClip { component_ids }
208            | IntentValue::UnregisterStencilClip { component_ids }
209            | IntentValue::RegisterRouter { component_ids }
210            | IntentValue::RegisterHttpServer { component_ids }
211            | IntentValue::RegisterHttpClient { component_ids }
212            | IntentValue::RegisterScrolling { component_ids }
213            | IntentValue::RegisterTransform { component_ids }
214            | IntentValue::UpdateTransform { component_ids, .. }
215            | IntentValue::RemoveTransform { component_ids }
216            | IntentValue::RegisterCamera3d { component_ids }
217            | IntentValue::RegisterCamera2d { component_ids }
218            | IntentValue::MakeActiveCamera { component_ids }
219            | IntentValue::RegisterInput { component_ids }
220            | IntentValue::RegisterUv { component_ids }
221            | IntentValue::RegisterLight { component_ids }
222            | IntentValue::RegisterColor { component_ids }
223            | IntentValue::RegisterOpacity { component_ids }
224            | IntentValue::RegisterTransparentCutout { component_ids }
225            | IntentValue::RegisterBackgroundColor { component_ids }
226            | IntentValue::RegisterRendererSettings { component_ids }
227            | IntentValue::RegisterRenderGraph { component_ids }
228            | IntentValue::RegisterAmbientLight { component_ids }
229            | IntentValue::RegisterEmissive { component_ids }
230            | IntentValue::RegisterLightQuantization { component_ids }
231            | IntentValue::RegisterTexture { component_ids }
232            | IntentValue::RegisterTextureFiltering { component_ids }
233            | IntentValue::RegisterText { component_ids }
234            | IntentValue::RegisterGLTF { component_ids }
235            | IntentValue::RegisterTextInput { component_ids }
236            | IntentValue::RegisterCollision { component_ids }
237            | IntentValue::RemoveCollision { component_ids }
238            | IntentValue::RegisterKineticResponse { component_ids }
239            | IntentValue::RemoveKineticResponse { component_ids }
240            | IntentValue::RegisterAvatarControl { component_ids }
241            | IntentValue::RegisterAvatarBodyYaw { component_ids }
242            | IntentValue::RegisterIkChain { component_ids }
243            | IntentValue::RegisterXr { component_ids }
244            | IntentValue::RegisterInputXr { component_ids }
245            | IntentValue::RegisterControllerXr { component_ids }
246            | IntentValue::RegisterInputXrGamepad { component_ids }
247            | IntentValue::RemoveInputXr { component_ids }
248            | IntentValue::RemoveControllerXr { component_ids }
249            | IntentValue::RemoveInputXrGamepad { component_ids }
250            | IntentValue::RegisterRaycast { component_ids }
251            | IntentValue::RegisterRaycastable { component_ids }
252            | IntentValue::RegisterPointer { component_ids }
253            | IntentValue::RemoveRaycast { component_ids }
254            | IntentValue::RemoveRaycastable { component_ids }
255            | IntentValue::RegisterAnimation { component_ids }
256            | IntentValue::SetAnimationState { component_ids, .. }
257            | IntentValue::RegisterKeyframe { component_ids }
258            | IntentValue::RegisterAudioOutput { component_ids }
259            | IntentValue::AudioGraphDirtyImmediate { component_ids }
260            | IntentValue::RegisterAudioOscillator { component_ids }
261            | IntentValue::RegisterAudioClip { component_ids }
262            | IntentValue::RegisterAudioBufferSize { component_ids }
263            | IntentValue::RegisterClock { component_ids }
264            | IntentValue::RegisterTransformGizmo { component_ids }
265            | IntentValue::RegisterNormalVis { component_ids }
266            | IntentValue::RegisterEditor { component_ids }
267            | IntentValue::RegisterAction { component_ids }
268            | IntentValue::ScheduleAudioOp { component_ids, .. }
269            | IntentValue::ScheduleAudioGraphSwap { component_ids, .. }
270            | IntentValue::ScheduleAudioPitchSetHz { component_ids, .. }
271            | IntentValue::ScheduleAudioOscillatorEnabled { component_ids, .. }
272            | IntentValue::ScheduleAudioGainSet { component_ids, .. } => Some(component_ids),
273
274            IntentValue::RegisterSignalRouteUpward { .. }
275            | IntentValue::RemoveSignalRouteUpward { .. }
276            | IntentValue::Noop
277            | IntentValue::RetryXrRuntime
278            | IntentValue::Print { .. }
279            | IntentValue::ReplExec { .. }
280            | IntentValue::Attach { .. }
281            | IntentValue::AttachClone { .. }
282            | IntentValue::QueryFindComponent { .. }
283            | IntentValue::QueryFindAllComponents { .. }
284            | IntentValue::RemoveChild { .. }
285            | IntentValue::RemoveChildren { .. } => None,
286
287            IntentValue::UpdateTransformWorld { .. } => None,
288            IntentValue::TextInputSetFocus { .. } => None,
289            IntentValue::TextInputClearFocus => None,
290            IntentValue::TextInputInsertText { .. } => None,
291            IntentValue::TextInputBackspace => None,
292            IntentValue::TextInputDeleteForward => None,
293            IntentValue::TextInputMoveCaret { .. } => None,
294            IntentValue::TextInputMoveCaretTo { .. } => None,
295            IntentValue::SpawnComponentTree { .. }
296            | IntentValue::PoseCapture { .. }
297            | IntentValue::PoseApply { .. }
298            | IntentValue::HttpClientRequest { .. }
299            | IntentValue::HttpServerReply { .. } => None,
300        }
301    }
302}