lgui_core/core/component/
context.rs1use super::{
2 AnimProperty, AnimationRegistry, ComponentId, ComponentState, ComponentStateStore,
3 ComponentTree, CompositingLayerAnimation, CompositingLayerSpec, ContextRegistry,
4 EffectRegistry, HookId, HookSlotKind, HookStateStore, InteractionFlags, UiId,
5 UiInteractionState, UiRect, UiScale, UiScope, UiTaskSpawner, UiUpdateQueue,
6};
7use std::sync::Arc;
8
9#[derive(Clone, Copy)]
10pub struct UiRenderContext<'a> {
11 interaction: &'a UiInteractionState,
12 animations: &'a AnimationRegistry,
13 component_states: &'a ComponentStateStore,
14 component_tree: &'a ComponentTree,
15 contexts: &'a ContextRegistry,
16 hook_states: &'a HookStateStore,
17 hook_updates: &'a Arc<UiUpdateQueue>,
18 task_spawner: Option<&'a UiTaskSpawner>,
19 effects: &'a EffectRegistry,
20 viewport: UiRect,
21 scale: UiScale,
22}
23
24impl<'a> UiRenderContext<'a> {
25 pub fn new(
26 interaction: &'a UiInteractionState,
27 animations: &'a AnimationRegistry,
28 component_states: &'a ComponentStateStore,
29 component_tree: &'a ComponentTree,
30 contexts: &'a ContextRegistry,
31 hook_states: &'a HookStateStore,
32 hook_updates: &'a Arc<UiUpdateQueue>,
33 task_spawner: Option<&'a UiTaskSpawner>,
34 effects: &'a EffectRegistry,
35 viewport: UiRect,
36 scale: UiScale,
37 ) -> Self {
38 Self {
39 interaction,
40 animations,
41 component_states,
42 component_tree,
43 contexts,
44 hook_states,
45 hook_updates,
46 task_spawner,
47 effects,
48 viewport,
49 scale,
50 }
51 }
52
53 pub fn viewport(&self) -> UiRect {
54 self.viewport
55 }
56
57 pub fn scale(&self) -> UiScale {
58 self.scale
59 }
60
61 pub fn interaction_flags(&self, id: &UiId) -> InteractionFlags {
62 self.interaction.flags_for(id)
63 }
64
65 pub fn animation_value(&self, id: &UiId, property: AnimProperty) -> f32 {
66 self.animations.value(id.clone(), property)
67 }
68
69 pub fn component_state_mut<T, R>(&self, id: &UiId, f: impl FnOnce(&mut T) -> R) -> R
70 where
71 T: ComponentState + Clone + Default + 'static,
72 {
73 self.component_states.with_mut(id, f)
74 }
75
76 pub(crate) fn component_state_mut_for_component<T, R>(
77 &self,
78 id: &UiId,
79 owner: ComponentId,
80 invalidation_id: UiId,
81 f: impl FnOnce(&mut T) -> R,
82 ) -> R
83 where
84 T: ComponentState + Clone + Default + 'static,
85 {
86 self.component_states
87 .with_mut_for_component(id, owner, invalidation_id, f)
88 }
89
90 pub(crate) fn compositing_layer_animation_mut<T, R>(
91 &self,
92 id: &UiId,
93 f: impl FnOnce(&mut T) -> R,
94 ) -> (R, CompositingLayerSpec, bool)
95 where
96 T: CompositingLayerAnimation,
97 {
98 self.component_states
99 .with_mut_for_compositing_layer(id, id.clone(), f)
100 }
101
102 pub fn preserve_component_state_scope(&self, scope: &UiScope) {
103 self.component_states.preserve_scope(scope);
104 }
105
106 pub fn component_tree(&self) -> &ComponentTree {
107 self.component_tree
108 }
109
110 pub fn contexts(&self) -> &ContextRegistry {
111 self.contexts
112 }
113
114 pub fn hook_state<T>(&self, id: HookId, initial: impl FnOnce() -> T) -> T
115 where
116 T: Clone + 'static,
117 {
118 self.hook_states.value(id, initial)
119 }
120
121 pub fn hook_updates(&self) -> Arc<UiUpdateQueue> {
122 Arc::clone(self.hook_updates)
123 }
124
125 pub fn task_spawner(&self) -> Option<UiTaskSpawner> {
126 self.task_spawner.cloned()
127 }
128
129 pub fn effect<D, F, R>(&self, id: HookId, deps: D, effect: F)
130 where
131 D: Clone + PartialEq + 'static,
132 F: FnOnce() -> R + 'static,
133 R: super::IntoEffectCleanup,
134 {
135 self.effects.register(id, deps, effect);
136 }
137
138 #[doc(hidden)]
139 pub fn element_effect<D, F, R>(&self, parent: ComponentId, owner: UiId, deps: D, effect: F)
140 where
141 D: Clone + PartialEq + 'static,
142 F: FnOnce() -> R + 'static,
143 R: super::IntoEffectCleanup,
144 {
145 let component = self.component_tree.element_effect_child(parent, &owner);
146 self.component_tree.begin_component_execution(component);
147 self.component_tree
148 .record_hook(component, HookSlotKind::Effect);
149 self.effects.register(
150 HookId::new(component, 0, HookSlotKind::Effect),
151 deps,
152 effect,
153 );
154 self.component_tree.finish_component(component);
155 }
156}