1use crate::engine::ecs::component::style::SizeDimension;
2use crate::engine::ecs::component::{
3 AnimationState, ControllerHand, SelectionEntry, SelectionMode, XrAxisControl, XrButtonControl,
4};
5use crate::engine::ecs::{ComponentId, World};
6use std::sync::mpsc::Sender;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum TextInputCaretDirection {
10 Left,
11 Right,
12}
13
14pub type HttpHeaders = Vec<(String, String)>;
15
16#[derive(Debug, Clone)]
20pub struct Signal {
21 pub scope: ComponentId,
22 pub event: Option<EventSignal>,
23 pub intent: Option<IntentSignal>,
24}
25
26impl Signal {
27 pub fn event(scope: ComponentId, event: EventSignal) -> Self {
28 Self {
29 scope,
30 event: Some(event),
31 intent: None,
32 }
33 }
34
35 pub fn intent(scope: ComponentId, intent: IntentSignal) -> Self {
36 Self {
37 scope,
38 event: None,
39 intent: Some(intent),
40 }
41 }
42
43 pub fn kind(&self) -> Option<SignalKind> {
44 self.event.as_ref().map(|e| e.kind())
45 }
46}
47
48#[derive(Debug, Clone)]
50pub enum EventSignal {
51 ParentChanged {
53 child: ComponentId,
54 old_parent: Option<ComponentId>,
55 new_parent: Option<ComponentId>,
56 },
57
58 RayIntersected {
60 raycaster: ComponentId,
61 renderable: ComponentId,
62 t: f32,
63 origin: [f32; 3],
64 dir: [f32; 3],
65 },
66
67 CollisionStarted {
71 a: ComponentId,
72 b: ComponentId,
73 delta: [f32; 3],
74 },
75
76 CollisionEnded {
80 a: ComponentId,
81 b: ComponentId,
82 delta: [f32; 3],
83 },
84
85 DragStart {
87 raycaster: ComponentId,
88 renderable: ComponentId,
89 hit_point: [f32; 3],
90
91 ray_dir_world: [f32; 3],
97
98 screen_pos_px: Option<(f32, f32)>,
102 },
103
104 DragMove {
108 raycaster: ComponentId,
109 renderable: ComponentId,
110 hit_point: [f32; 3],
111 delta_world: [f32; 3],
112
113 screen_pos_px: Option<(f32, f32)>,
115
116 screen_delta_px: Option<(f32, f32)>,
121 },
122
123 DragEnd {
125 raycaster: ComponentId,
126 renderable: ComponentId,
127 hit_point: Option<[f32; 3]>,
128 },
129
130 Click {
140 raycaster: ComponentId,
141 renderable: ComponentId,
142 hit_point: [f32; 3],
143 screen_pos_px: Option<(f32, f32)>,
144 },
145
146 SelectionChanged {
148 selection_root: ComponentId,
149 mode: SelectionMode,
150 selected_entries: Vec<SelectionEntry>,
151 selected_component: Option<ComponentId>,
152 selected_payload: Option<ComponentId>,
153 },
154
155 SelectionAdded {
157 selection_root: ComponentId,
158 entry: SelectionEntry,
159 },
160
161 SelectionRemoved {
163 selection_root: ComponentId,
164 entry: SelectionEntry,
165 },
166
167 SelectionCleared { selection_root: ComponentId },
169
170 Scrolling {
175 scroll_component: ComponentId,
176 drag_scope: ComponentId,
177 delta_world: [f32; 3],
178 scroll_offset: f32,
179 max_scroll: f32,
180 viewport_height: f32,
181 content_height: f32,
182 },
183
184 TextInputFocusChanged {
185 old: Option<ComponentId>,
186 new: Option<ComponentId>,
187 },
188
189 TextInputChanged {
190 component_id: ComponentId,
191 text: String,
192 caret: usize,
193 },
194
195 LayoutRootSizeAvailable {
198 layout_id: ComponentId,
199 width_wu: f32,
200 height_wu: f32,
201 },
202
203 DataEvent {
209 name: String,
210 payload: Option<ComponentId>,
211 },
212
213 XrButtonDown {
214 source_component: ComponentId,
215 hand: ControllerHand,
216 control: XrButtonControl,
217 value: f32,
218 },
219 XrButtonUp {
220 source_component: ComponentId,
221 hand: ControllerHand,
222 control: XrButtonControl,
223 value: f32,
224 },
225 XrButtonChanged {
226 source_component: ComponentId,
227 hand: ControllerHand,
228 control: XrButtonControl,
229 value: f32,
230 },
231 XrAxisChanged {
232 source_component: ComponentId,
233 hand: ControllerHand,
234 control: XrAxisControl,
235 value: [f32; 2],
236 },
237
238 HttpRequest {
239 request_id: u64,
240 method: String,
241 path: String,
242 query: Option<String>,
243 url: String,
244 headers: HttpHeaders,
245 body_text: String,
246 remote_addr: Option<String>,
247 },
248 HttpResponse {
249 request_id: u64,
250 status: u16,
251 ok: bool,
252 headers: HttpHeaders,
253 body_text: String,
254 url: String,
255 },
256 HttpError {
257 request_id: Option<u64>,
258 phase: String,
259 message: String,
260 url: Option<String>,
261 bind_addr: Option<String>,
262 },
263}
264
265impl EventSignal {
266 pub fn kind(&self) -> SignalKind {
267 match self {
268 EventSignal::ParentChanged { .. } => SignalKind::ParentChanged,
269 EventSignal::RayIntersected { .. } => SignalKind::RayIntersected,
270 EventSignal::CollisionStarted { .. } => SignalKind::CollisionStarted,
271 EventSignal::CollisionEnded { .. } => SignalKind::CollisionEnded,
272 EventSignal::DragStart { .. } => SignalKind::DragStart,
273 EventSignal::DragMove { .. } => SignalKind::DragMove,
274 EventSignal::DragEnd { .. } => SignalKind::DragEnd,
275 EventSignal::Click { .. } => SignalKind::Click,
276 EventSignal::SelectionChanged { .. } => SignalKind::SelectionChanged,
277 EventSignal::SelectionAdded { .. } => SignalKind::SelectionAdded,
278 EventSignal::SelectionRemoved { .. } => SignalKind::SelectionRemoved,
279 EventSignal::SelectionCleared { .. } => SignalKind::SelectionCleared,
280 EventSignal::Scrolling { .. } => SignalKind::Scrolling,
281 EventSignal::TextInputFocusChanged { .. } => SignalKind::TextInputFocusChanged,
282 EventSignal::TextInputChanged { .. } => SignalKind::TextInputChanged,
283 EventSignal::LayoutRootSizeAvailable { .. } => SignalKind::LayoutRootSizeAvailable,
284 EventSignal::DataEvent { .. } => SignalKind::DataEvent,
285 EventSignal::XrButtonDown { .. } => SignalKind::XrButtonDown,
286 EventSignal::XrButtonUp { .. } => SignalKind::XrButtonUp,
287 EventSignal::XrButtonChanged { .. } => SignalKind::XrButtonChanged,
288 EventSignal::XrAxisChanged { .. } => SignalKind::XrAxisChanged,
289 EventSignal::HttpRequest { .. } => SignalKind::HttpRequest,
290 EventSignal::HttpResponse { .. } => SignalKind::HttpResponse,
291 EventSignal::HttpError { .. } => SignalKind::HttpError,
292 }
293 }
294}
295
296#[derive(Debug, Clone)]
298pub struct IntentSignal {
299 pub when: SignalWhen,
300 pub value: IntentValue,
301}
302
303impl IntentSignal {
304 pub fn now(value: IntentValue) -> Self {
305 Self {
306 when: SignalWhen::Now,
307 value,
308 }
309 }
310
311 pub fn at_beat(beat: f64, value: IntentValue) -> Self {
312 if !beat.is_finite() {
313 return Self::now(value);
314 }
315 Self {
316 when: SignalWhen::AtBeat(beat),
317 value,
318 }
319 }
320}
321
322#[derive(Debug, Clone)]
324pub enum IntentValue {
325 Noop,
326 RetryXrRuntime,
327
328 SpawnComponentTree {
331 root: Box<crate::scripting::object::MaterializedCE>,
332 parent: Option<ComponentId>,
333 },
334 Print {
335 message: String,
336 },
337
338 ReplExec {
342 command: String,
343 },
344
345 SetColor {
346 component_ids: Vec<ComponentId>,
347 rgba: [f32; 4],
348 },
349 SetText {
350 component_ids: Vec<ComponentId>,
351 text: String,
352 },
353 SetEmissiveIntensity {
354 component_ids: Vec<ComponentId>,
355 intensity: f32,
356 },
357 SetPosition {
358 component_ids: Vec<ComponentId>,
359 position: [f32; 3],
360 },
361 LookAt {
362 component_ids: Vec<ComponentId>,
363 target_world: [f32; 3],
364 },
365 GLTFArmatureVisible {
366 component_ids: Vec<ComponentId>,
367 visible: bool,
368 },
369 SetLayoutAvailableWidth {
370 component_ids: Vec<ComponentId>,
371 width: SizeDimension,
372 },
373 SetLayoutAvailableHeight {
374 component_ids: Vec<ComponentId>,
375 height: SizeDimension,
376 },
377 SetLayoutInspect {
378 component_ids: Vec<ComponentId>,
379 enabled: bool,
380 },
381 SelectionSet {
382 component_ids: Vec<ComponentId>,
383 entries: Vec<SelectionEntry>,
384 primary: Option<ComponentId>,
385 },
386
387 Attach {
388 parents: Vec<ComponentId>,
389 child: ComponentId,
390 },
391 QueryFindComponent {
392 root: ComponentId,
393 selector: String,
394 reply: Sender<Option<ComponentId>>,
395 },
396 QueryFindAllComponents {
397 root: ComponentId,
398 selector: String,
399 reply: Sender<Vec<ComponentId>>,
400 },
401 AttachClone {
402 parents: Vec<ComponentId>,
403 prefab_root: ComponentId,
404 },
405 Detach {
406 component_ids: Vec<ComponentId>,
407 },
408 RemoveChild {
409 parents: Vec<ComponentId>,
410 index: usize,
411 },
412 RemoveChildren {
413 parents: Vec<ComponentId>,
414 },
415 RemoveSubtree {
416 component_ids: Vec<ComponentId>,
417 },
418
419 AudioGraphRebuild {
420 component_ids: Vec<ComponentId>,
421 },
422 RequestRaycast {
423 component_ids: Vec<ComponentId>,
424 },
425
426 AudioLowPassSetCutoffHz {
427 component_ids: Vec<ComponentId>,
428 cutoff_hz: f32,
429 },
430 AudioBandPassSetCenterHz {
431 component_ids: Vec<ComponentId>,
432 center_hz: f32,
433 },
434 OscillatorSetEnabled {
435 component_ids: Vec<ComponentId>,
436 enabled: bool,
437 },
438 OscillatorSetPitch {
439 component_ids: Vec<ComponentId>,
440 frequency_hz: f32,
441 },
442
443 OscillatorScheduleSetPitch {
445 component_ids: Vec<ComponentId>,
446 beat_offset: f64,
447 beat_context: Option<f64>,
448 frequency_hz: f32,
449 },
450
451 AudioSchedulePlay {
460 component_ids: Vec<ComponentId>,
461 beat_offset: f64,
462 beat_context: Option<f64>,
463 note: Option<crate::engine::ecs::component::MusicNote>,
464 gain: Option<f32>,
465 rate: Option<f32>,
466 duration: Option<f64>,
467 },
468
469 RegisterRenderable {
470 component_ids: Vec<ComponentId>,
471 },
472 RemoveRenderable {
473 component_ids: Vec<ComponentId>,
474 },
475 RegisterStencilClip {
476 component_ids: Vec<ComponentId>,
477 },
478 UnregisterStencilClip {
479 component_ids: Vec<ComponentId>,
480 },
481
482 PoseCapture {
483 target: ComponentId,
484 pose_name: Option<String>,
485 },
486 PoseApply {
487 target: ComponentId,
488 pose: ComponentId,
489 },
490
491 RegisterRouter {
492 component_ids: Vec<ComponentId>,
493 },
494 RegisterHttpServer {
495 component_ids: Vec<ComponentId>,
496 },
497 RegisterHttpClient {
498 component_ids: Vec<ComponentId>,
499 },
500 HttpClientRequest {
501 component_id: ComponentId,
502 method: String,
503 url: String,
504 headers: HttpHeaders,
505 body_text: Option<String>,
506 },
507 HttpServerReply {
508 component_id: ComponentId,
509 request_id: u64,
510 status: u16,
511 headers: HttpHeaders,
512 body_text: String,
513 },
514 RegisterScrolling {
515 component_ids: Vec<ComponentId>,
516 },
517 RegisterTransform {
518 component_ids: Vec<ComponentId>,
519 },
520 UpdateTransformWorld {
524 component_ids: Vec<ComponentId>,
525 },
526 UpdateTransform {
527 component_ids: Vec<ComponentId>,
528 translation: [f32; 3],
529 rotation_quat_xyzw: [f32; 4],
530 scale: [f32; 3],
531 },
532 RemoveTransform {
533 component_ids: Vec<ComponentId>,
534 },
535
536 RegisterCamera3d {
537 component_ids: Vec<ComponentId>,
538 },
539 RegisterCamera2d {
540 component_ids: Vec<ComponentId>,
541 },
542 MakeActiveCamera {
543 component_ids: Vec<ComponentId>,
544 },
545
546 RegisterInput {
547 component_ids: Vec<ComponentId>,
548 },
549 RegisterUv {
550 component_ids: Vec<ComponentId>,
551 },
552
553 RegisterLight {
554 component_ids: Vec<ComponentId>,
555 },
556 RegisterColor {
557 component_ids: Vec<ComponentId>,
558 },
559 RegisterOpacity {
560 component_ids: Vec<ComponentId>,
561 },
562 RegisterTransparentCutout {
563 component_ids: Vec<ComponentId>,
564 },
565 RegisterBackgroundColor {
566 component_ids: Vec<ComponentId>,
567 },
568 RegisterRendererSettings {
569 component_ids: Vec<ComponentId>,
570 },
571 RegisterRenderGraph {
572 component_ids: Vec<ComponentId>,
573 },
574 RegisterAmbientLight {
575 component_ids: Vec<ComponentId>,
576 },
577 RegisterEmissive {
578 component_ids: Vec<ComponentId>,
579 },
580 RegisterLightQuantization {
581 component_ids: Vec<ComponentId>,
582 },
583
584 RegisterTexture {
585 component_ids: Vec<ComponentId>,
586 },
587 RegisterTextureFiltering {
588 component_ids: Vec<ComponentId>,
589 },
590
591 RegisterText {
592 component_ids: Vec<ComponentId>,
593 },
594 RegisterGLTF {
595 component_ids: Vec<ComponentId>,
596 },
597 RegisterTextInput {
598 component_ids: Vec<ComponentId>,
599 },
600
601 TextInputSetFocus {
602 component_id: ComponentId,
603 },
604 TextInputClearFocus,
605 TextInputInsertText {
606 text: String,
607 },
608 TextInputBackspace,
609 TextInputDeleteForward,
610 TextInputMoveCaret {
611 direction: TextInputCaretDirection,
612 amount: usize,
613 },
614 TextInputMoveCaretTo {
615 index: usize,
616 },
617
618 RegisterCollision {
619 component_ids: Vec<ComponentId>,
620 },
621 RemoveCollision {
622 component_ids: Vec<ComponentId>,
623 },
624 RegisterKineticResponse {
625 component_ids: Vec<ComponentId>,
626 },
627 RemoveKineticResponse {
628 component_ids: Vec<ComponentId>,
629 },
630 RegisterAvatarControl {
631 component_ids: Vec<ComponentId>,
632 },
633 RegisterAvatarBodyYaw {
634 component_ids: Vec<ComponentId>,
635 },
636 RegisterIkChain {
637 component_ids: Vec<ComponentId>,
638 },
639
640 RegisterXr {
641 component_ids: Vec<ComponentId>,
642 },
643 RegisterInputXr {
644 component_ids: Vec<ComponentId>,
645 },
646 RegisterControllerXr {
647 component_ids: Vec<ComponentId>,
648 },
649 RegisterInputXrGamepad {
650 component_ids: Vec<ComponentId>,
651 },
652 RemoveInputXr {
653 component_ids: Vec<ComponentId>,
654 },
655 RemoveControllerXr {
656 component_ids: Vec<ComponentId>,
657 },
658 RemoveInputXrGamepad {
659 component_ids: Vec<ComponentId>,
660 },
661
662 RegisterRaycast {
663 component_ids: Vec<ComponentId>,
664 },
665 RegisterRaycastable {
666 component_ids: Vec<ComponentId>,
667 },
668 RegisterPointer {
669 component_ids: Vec<ComponentId>,
670 },
671 RemoveRaycast {
672 component_ids: Vec<ComponentId>,
673 },
674 RemoveRaycastable {
675 component_ids: Vec<ComponentId>,
676 },
677
678 RegisterAnimation {
679 component_ids: Vec<ComponentId>,
680 },
681 SetAnimationState {
682 component_ids: Vec<ComponentId>,
683 state: AnimationState,
684 },
685 RegisterKeyframe {
686 component_ids: Vec<ComponentId>,
687 },
688
689 RegisterAudioOutput {
690 component_ids: Vec<ComponentId>,
691 },
692 AudioGraphDirtyImmediate {
693 component_ids: Vec<ComponentId>,
694 },
695 RegisterAudioOscillator {
696 component_ids: Vec<ComponentId>,
697 },
698 RegisterAudioClip {
699 component_ids: Vec<ComponentId>,
700 },
701 RegisterAudioBufferSize {
702 component_ids: Vec<ComponentId>,
703 },
704 RegisterClock {
705 component_ids: Vec<ComponentId>,
706 },
707 RegisterTransformGizmo {
708 component_ids: Vec<ComponentId>,
709 },
710 RegisterNormalVis {
711 component_ids: Vec<ComponentId>,
712 },
713
714 RegisterEditor {
715 component_ids: Vec<ComponentId>,
716 },
717
718 RegisterAction {
719 component_ids: Vec<ComponentId>,
720 },
721
722 RegisterSignalRouteUpward {
726 component_ids: Vec<ComponentId>,
727 },
728 RemoveSignalRouteUpward {
729 component_ids: Vec<ComponentId>,
730 },
731
732 ScheduleAudioOp {
733 component_ids: Vec<ComponentId>,
734 beat: f64,
735 op: crate::engine::ecs::system::audio_system::AudioOp,
736 },
737 ScheduleAudioGraphSwap {
738 component_ids: Vec<ComponentId>,
739 beat: f64,
740 },
741 ScheduleAudioPitchSetHz {
742 component_ids: Vec<ComponentId>,
743 beat: f64,
744 frequency_hz: f32,
745 },
746 ScheduleAudioOscillatorEnabled {
747 component_ids: Vec<ComponentId>,
748 beat: f64,
749 enabled: bool,
750 },
751 ScheduleAudioGainSet {
752 component_ids: Vec<ComponentId>,
753 beat: f64,
754 gain: f32,
755 },
756}
757
758impl IntentValue {
759 pub fn kind_name(&self) -> &'static str {
763 match self {
764 IntentValue::Noop => "noop",
765 IntentValue::RetryXrRuntime => "retry_xr_runtime",
766 IntentValue::SpawnComponentTree { .. } => "spawn_component_tree",
767 IntentValue::Print { .. } => "print",
768 IntentValue::ReplExec { .. } => "repl_exec",
769
770 IntentValue::SetColor { .. } => "set_color",
771 IntentValue::SetText { .. } => "set_text",
772 IntentValue::SetEmissiveIntensity { .. } => "set_emissive_intensity",
773 IntentValue::SetPosition { .. } => "set_position",
774 IntentValue::LookAt { .. } => "look_at",
775 IntentValue::SetLayoutAvailableWidth { .. } => "set_layout_available_width",
776 IntentValue::SetLayoutAvailableHeight { .. } => "set_layout_available_height",
777 IntentValue::SetLayoutInspect { .. } => "set_layout_inspect",
778 IntentValue::GLTFArmatureVisible { .. } => "gltf_armature_visible",
779 IntentValue::SelectionSet { .. } => "selection_set",
780
781 IntentValue::Attach { .. } => "attach",
782 IntentValue::QueryFindComponent { .. } => "query_find_component",
783 IntentValue::QueryFindAllComponents { .. } => "query_find_all_components",
784 IntentValue::AttachClone { .. } => "attach_clone",
785 IntentValue::Detach { .. } => "detach",
786 IntentValue::RemoveChild { .. } => "remove_child",
787 IntentValue::RemoveChildren { .. } => "remove_children",
788 IntentValue::RemoveSubtree { .. } => "remove_subtree",
789
790 IntentValue::AudioGraphRebuild { .. } => "audio_graph_rebuild",
791 IntentValue::RequestRaycast { .. } => "request_raycast",
792
793 IntentValue::AudioLowPassSetCutoffHz { .. } => "audio_low_pass_set_cutoff_hz",
794 IntentValue::AudioBandPassSetCenterHz { .. } => "audio_band_pass_set_center_hz",
795 IntentValue::OscillatorSetEnabled { .. } => "oscillator_set_enabled",
796 IntentValue::OscillatorSetPitch { .. } => "oscillator_set_pitch",
797 IntentValue::OscillatorScheduleSetPitch { .. } => "oscillator_schedule_set_pitch",
798 IntentValue::AudioSchedulePlay { .. } => "audio_schedule_play",
799
800 IntentValue::RegisterRenderable { .. } => "register_renderable",
801 IntentValue::RemoveRenderable { .. } => "remove_renderable",
802 IntentValue::RegisterStencilClip { .. } => "register_stencil_clip",
803 IntentValue::UnregisterStencilClip { .. } => "unregister_stencil_clip",
804 IntentValue::RegisterRouter { .. } => "register_router",
805 IntentValue::RegisterHttpServer { .. } => "register_http_server",
806 IntentValue::RegisterHttpClient { .. } => "register_http_client",
807 IntentValue::HttpClientRequest { .. } => "http_client_request",
808 IntentValue::HttpServerReply { .. } => "http_server_reply",
809 IntentValue::RegisterScrolling { .. } => "register_scrolling",
810 IntentValue::RegisterTransform { .. } => "register_transform",
811 IntentValue::UpdateTransformWorld { .. } => "update_transform_world",
812 IntentValue::UpdateTransform { .. } => "update_transform",
813 IntentValue::RemoveTransform { .. } => "remove_transform",
814
815 IntentValue::RegisterCamera3d { .. } => "register_camera3d",
816 IntentValue::RegisterCamera2d { .. } => "register_camera2d",
817 IntentValue::MakeActiveCamera { .. } => "make_active_camera",
818
819 IntentValue::RegisterInput { .. } => "register_input",
820 IntentValue::RegisterUv { .. } => "register_uv",
821
822 IntentValue::RegisterLight { .. } => "register_light",
823 IntentValue::RegisterColor { .. } => "register_color",
824 IntentValue::RegisterOpacity { .. } => "register_opacity",
825 IntentValue::RegisterTransparentCutout { .. } => "register_transparent_cutout",
826 IntentValue::RegisterBackgroundColor { .. } => "register_background_color",
827 IntentValue::RegisterRendererSettings { .. } => "register_renderer_settings",
828 IntentValue::RegisterRenderGraph { .. } => "register_render_graph",
829 IntentValue::RegisterAmbientLight { .. } => "register_ambient_light",
830 IntentValue::RegisterEmissive { .. } => "register_emissive",
831 IntentValue::RegisterLightQuantization { .. } => "register_light_quantization",
832
833 IntentValue::RegisterTexture { .. } => "register_texture",
834 IntentValue::RegisterTextureFiltering { .. } => "register_texture_filtering",
835
836 IntentValue::RegisterText { .. } => "register_text",
837 IntentValue::RegisterGLTF { .. } => "register_gltf",
838 IntentValue::RegisterTextInput { .. } => "register_text_input",
839 IntentValue::TextInputSetFocus { .. } => "text_input_set_focus",
840 IntentValue::TextInputClearFocus => "text_input_clear_focus",
841 IntentValue::TextInputInsertText { .. } => "text_input_insert_text",
842 IntentValue::TextInputBackspace => "text_input_backspace",
843 IntentValue::TextInputDeleteForward => "text_input_delete_forward",
844 IntentValue::TextInputMoveCaret { .. } => "text_input_move_caret",
845 IntentValue::TextInputMoveCaretTo { .. } => "text_input_move_caret_to",
846
847 IntentValue::RegisterCollision { .. } => "register_collision",
848 IntentValue::RemoveCollision { .. } => "remove_collision",
849 IntentValue::RegisterKineticResponse { .. } => "register_kinetic_response",
850 IntentValue::RemoveKineticResponse { .. } => "remove_kinetic_response",
851 IntentValue::RegisterAvatarControl { .. } => "register_avatar_control",
852 IntentValue::RegisterAvatarBodyYaw { .. } => "register_avatar_body_yaw",
853 IntentValue::RegisterIkChain { .. } => "register_ik_chain",
854
855 IntentValue::RegisterXr { .. } => "register_xr",
856 IntentValue::RegisterInputXr { .. } => "register_input_xr",
857 IntentValue::RegisterControllerXr { .. } => "register_controller_xr",
858 IntentValue::RegisterInputXrGamepad { .. } => "register_input_xr_gamepad",
859 IntentValue::RemoveInputXr { .. } => "remove_input_xr",
860 IntentValue::RemoveControllerXr { .. } => "remove_controller_xr",
861 IntentValue::RemoveInputXrGamepad { .. } => "remove_input_xr_gamepad",
862
863 IntentValue::RegisterRaycast { .. } => "register_raycast",
864 IntentValue::RegisterRaycastable { .. } => "register_raycastable",
865 IntentValue::RegisterPointer { .. } => "register_pointer",
866 IntentValue::RemoveRaycast { .. } => "remove_raycast",
867 IntentValue::RemoveRaycastable { .. } => "remove_raycastable",
868
869 IntentValue::RegisterAnimation { .. } => "register_animation",
870 IntentValue::SetAnimationState { .. } => "set_animation_state",
871 IntentValue::RegisterKeyframe { .. } => "register_keyframe",
872
873 IntentValue::RegisterAudioOutput { .. } => "register_audio_output",
874 IntentValue::AudioGraphDirtyImmediate { .. } => "audio_graph_dirty_immediate",
875 IntentValue::RegisterAudioOscillator { .. } => "register_audio_oscillator",
876 IntentValue::RegisterAudioClip { .. } => "register_audio_clip",
877 IntentValue::RegisterAudioBufferSize { .. } => "register_audio_buffer_size",
878 IntentValue::RegisterClock { .. } => "register_clock",
879 IntentValue::RegisterTransformGizmo { .. } => "register_transform_gizmo",
880 IntentValue::RegisterNormalVis { .. } => "register_normal_vis",
881 IntentValue::RegisterEditor { .. } => "register_editor",
882 IntentValue::RegisterAction { .. } => "register_action",
883
884 IntentValue::PoseCapture { .. } => "pose_capture",
885 IntentValue::PoseApply { .. } => "pose_apply",
886
887 IntentValue::RegisterSignalRouteUpward { .. } => "register_signal_route_upward",
888 IntentValue::RemoveSignalRouteUpward { .. } => "remove_signal_route_upward",
889
890 IntentValue::ScheduleAudioOp { .. } => "schedule_audio_op",
891 IntentValue::ScheduleAudioGraphSwap { .. } => "schedule_audio_graph_swap",
892 IntentValue::ScheduleAudioPitchSetHz { .. } => "schedule_audio_pitch_set_hz",
893 IntentValue::ScheduleAudioOscillatorEnabled { .. } => {
894 "schedule_audio_oscillator_enabled"
895 }
896 IntentValue::ScheduleAudioGainSet { .. } => "schedule_audio_gain_set",
897 }
898 }
899}
900
901#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
905pub enum SignalKind {
906 Any,
907 ParentChanged,
908 RayIntersected,
909 CollisionStarted,
910 CollisionEnded,
911 DragStart,
912 DragMove,
913 DragEnd,
914 Click,
915 SelectionChanged,
916 SelectionAdded,
917 SelectionRemoved,
918 SelectionCleared,
919 Scrolling,
920 TextInputFocusChanged,
921 TextInputChanged,
922 LayoutRootSizeAvailable,
923
924 DataEvent,
929 XrButtonDown,
930 XrButtonUp,
931 XrButtonChanged,
932 XrAxisChanged,
933 HttpRequest,
934 HttpResponse,
935 HttpError,
936}
937
938#[derive(Debug, Clone, Copy, PartialEq)]
944pub enum SignalWhen {
945 Now,
946 AtBeat(f64),
947}
948
949impl Default for SignalWhen {
950 fn default() -> Self {
951 Self::Now
952 }
953}
954
955impl SignalWhen {
956 pub fn at_beat(beat: f64) -> Self {
957 Self::AtBeat(beat)
958 }
959
960 pub fn beat(&self) -> Option<f64> {
961 match *self {
962 Self::Now => None,
963 Self::AtBeat(b) => Some(b),
964 }
965 }
966}
967
968pub trait SignalEmitter {
969 fn push_event(&mut self, scope: ComponentId, event: EventSignal);
970 fn push_intent(&mut self, scope: ComponentId, intent: IntentSignal);
971
972 fn push_intent_now(&mut self, scope: ComponentId, value: IntentValue) {
973 self.push_intent(scope, IntentSignal::now(value));
974 }
975
976 fn push_intent_at_beat(&mut self, scope: ComponentId, beat: f64, value: IntentValue) {
977 self.push_intent(scope, IntentSignal::at_beat(beat, value));
978 }
979}
980
981pub type SignalHandler = fn(&mut World, &mut dyn SignalEmitter, &Signal);