layer_shika_composition/
surface_registry.rs

1use crate::Result;
2use layer_shika_adapters::platform::slint_interpreter::ComponentInstance;
3use layer_shika_domain::config::SurfaceConfig;
4use layer_shika_domain::value_objects::handle::SurfaceHandle;
5use layer_shika_domain::value_objects::output_handle::OutputHandle;
6use std::collections::HashMap;
7use std::rc::Rc;
8
9/// Definition of a surface including component name and configuration
10///
11/// Pairs a Slint component with its layer-shell settings.
12#[derive(Debug, Clone)]
13pub struct SurfaceDefinition {
14    pub component: String,
15    pub config: SurfaceConfig,
16}
17
18/// Metadata tracked for each registered surface
19///
20/// Includes spawn order for deterministic iteration and creation timestamps.
21#[derive(Clone, Default)]
22pub struct SurfaceMetadata {
23    pub spawn_order: usize,
24    pub creation_timestamp: u64,
25}
26
27/// Registry entry for a surface with handle, name, and output instances
28///
29/// Tracks all instances of a surface across multiple outputs and maintains
30/// the component definition and metadata.
31pub struct SurfaceEntry {
32    pub handle: SurfaceHandle,
33    pub name: String,
34    pub component: String,
35    pub definition: SurfaceDefinition,
36    pub output_instances: HashMap<OutputHandle, Rc<ComponentInstance>>,
37    pub metadata: SurfaceMetadata,
38}
39
40impl SurfaceEntry {
41    /// Creates a new surface entry
42    pub fn new(handle: SurfaceHandle, name: String, definition: SurfaceDefinition) -> Self {
43        let component = definition.component.clone();
44        Self {
45            handle,
46            name,
47            component,
48            definition,
49            output_instances: HashMap::new(),
50            metadata: SurfaceMetadata::default(),
51        }
52    }
53
54    /// Adds a component instance for a specific output
55    pub fn add_output_instance(&mut self, output: OutputHandle, instance: Rc<ComponentInstance>) {
56        self.output_instances.insert(output, instance);
57    }
58
59    /// Removes and returns a component instance for a specific output
60    pub fn remove_output_instance(
61        &mut self,
62        output: OutputHandle,
63    ) -> Option<Rc<ComponentInstance>> {
64        self.output_instances.remove(&output)
65    }
66
67    /// Returns a component instance for a specific output
68    pub fn get_output_instance(&self, output: OutputHandle) -> Option<&Rc<ComponentInstance>> {
69        self.output_instances.get(&output)
70    }
71
72    /// Returns all output handles for this surface
73    pub fn outputs(&self) -> Vec<OutputHandle> {
74        self.output_instances.keys().copied().collect()
75    }
76}
77
78/// Central registry for managing surface entries and lookups
79///
80/// Maintains indices for efficient lookup by handle, name, or component.
81pub struct SurfaceRegistry {
82    entries: HashMap<SurfaceHandle, SurfaceEntry>,
83    by_name: HashMap<String, Vec<SurfaceHandle>>,
84    by_component: HashMap<String, Vec<SurfaceHandle>>,
85    next_spawn_order: usize,
86}
87
88impl SurfaceRegistry {
89    /// Creates a new empty surface registry
90    pub fn new() -> Self {
91        Self {
92            entries: HashMap::new(),
93            by_name: HashMap::new(),
94            by_component: HashMap::new(),
95            next_spawn_order: 0,
96        }
97    }
98
99    /// Inserts a new surface entry into the registry
100    pub fn insert(&mut self, mut entry: SurfaceEntry) -> Result<()> {
101        entry.metadata.spawn_order = self.next_spawn_order;
102        self.next_spawn_order += 1;
103
104        let handle = entry.handle;
105        let name = entry.name.clone();
106        let component = entry.component.clone();
107
108        self.by_name.entry(name).or_default().push(handle);
109
110        self.by_component.entry(component).or_default().push(handle);
111
112        self.entries.insert(handle, entry);
113
114        Ok(())
115    }
116
117    /// Removes and returns a surface entry by handle
118    pub fn remove(&mut self, handle: SurfaceHandle) -> Option<SurfaceEntry> {
119        let entry = self.entries.remove(&handle)?;
120
121        if let Some(handles) = self.by_name.get_mut(&entry.name) {
122            handles.retain(|&h| h != handle);
123            if handles.is_empty() {
124                self.by_name.remove(&entry.name);
125            }
126        }
127
128        if let Some(handles) = self.by_component.get_mut(&entry.component) {
129            handles.retain(|&h| h != handle);
130            if handles.is_empty() {
131                self.by_component.remove(&entry.component);
132            }
133        }
134
135        Some(entry)
136    }
137
138    /// Returns a reference to a surface entry by handle
139    pub fn get(&self, handle: SurfaceHandle) -> Option<&SurfaceEntry> {
140        self.entries.get(&handle)
141    }
142
143    /// Alias for `get`
144    pub fn by_handle(&self, handle: SurfaceHandle) -> Option<&SurfaceEntry> {
145        self.entries.get(&handle)
146    }
147
148    /// Returns a mutable reference to a surface entry by handle
149    pub fn get_mut(&mut self, handle: SurfaceHandle) -> Option<&mut SurfaceEntry> {
150        self.entries.get_mut(&handle)
151    }
152
153    /// Alias for `get_mut`
154    pub fn by_handle_mut(&mut self, handle: SurfaceHandle) -> Option<&mut SurfaceEntry> {
155        self.entries.get_mut(&handle)
156    }
157
158    /// Returns all surface entries with the given name
159    pub fn by_name(&self, name: &str) -> Vec<&SurfaceEntry> {
160        self.by_name
161            .get(name)
162            .map(|handles| handles.iter().filter_map(|h| self.entries.get(h)).collect())
163            .unwrap_or_default()
164    }
165
166    /// Returns mutable references to all surface entries with the given name
167    pub fn by_name_mut(&mut self, name: &str) -> Vec<&mut SurfaceEntry> {
168        let handles: Vec<SurfaceHandle> = self.by_name.get(name).cloned().unwrap_or_default();
169
170        let entries_ptr = std::ptr::addr_of_mut!(self.entries);
171
172        handles
173            .iter()
174            .filter_map(|h| unsafe { (*entries_ptr).get_mut(h) })
175            .collect()
176    }
177
178    /// Returns the first surface handle with the given name
179    pub fn handle_by_name(&self, name: &str) -> Option<SurfaceHandle> {
180        self.by_name
181            .get(name)
182            .and_then(|handles| handles.first().copied())
183    }
184
185    /// Returns all surface handles with the given name
186    pub fn handles_by_name(&self, name: &str) -> Vec<SurfaceHandle> {
187        self.by_name.get(name).cloned().unwrap_or_default()
188    }
189
190    /// Returns the name for a surface handle
191    pub fn name_by_handle(&self, handle: SurfaceHandle) -> Option<&str> {
192        self.entries.get(&handle).map(|e| e.name.as_str())
193    }
194
195    /// Returns all surface entries for the given component
196    pub fn by_component(&self, component: &str) -> Vec<&SurfaceEntry> {
197        self.by_component
198            .get(component)
199            .map(|handles| handles.iter().filter_map(|h| self.entries.get(h)).collect())
200            .unwrap_or_default()
201    }
202
203    /// Returns an iterator over all surface entries
204    pub fn all(&self) -> impl Iterator<Item = &SurfaceEntry> {
205        self.entries.values()
206    }
207
208    /// Returns an iterator over all mutable surface entries
209    pub fn all_mut(&mut self) -> impl Iterator<Item = &mut SurfaceEntry> {
210        self.entries.values_mut()
211    }
212
213    /// Returns an iterator over all surface handles
214    pub fn handles(&self) -> impl Iterator<Item = SurfaceHandle> + '_ {
215        self.entries.keys().copied()
216    }
217
218    /// Returns all output handles for a surface
219    pub fn outputs_for_surface(&self, handle: SurfaceHandle) -> Vec<OutputHandle> {
220        self.entries
221            .get(&handle)
222            .map(SurfaceEntry::outputs)
223            .unwrap_or_default()
224    }
225
226    /// Returns all surface names in the registry
227    pub fn surface_names(&self) -> Vec<&str> {
228        self.by_name.keys().map(String::as_str).collect()
229    }
230
231    /// Returns all component names in the registry
232    pub fn component_names(&self) -> Vec<&str> {
233        self.by_component.keys().map(String::as_str).collect()
234    }
235
236    /// Returns the number of surfaces in the registry
237    pub fn len(&self) -> usize {
238        self.entries.len()
239    }
240
241    /// Checks if the registry is empty
242    pub fn is_empty(&self) -> bool {
243        self.entries.is_empty()
244    }
245
246    /// Checks if a surface handle exists in the registry
247    pub fn contains(&self, handle: SurfaceHandle) -> bool {
248        self.entries.contains_key(&handle)
249    }
250
251    /// Checks if a surface name exists in the registry
252    pub fn contains_name(&self, name: &str) -> bool {
253        self.by_name.contains_key(name)
254    }
255}
256
257impl Default for SurfaceRegistry {
258    fn default() -> Self {
259        Self::new()
260    }
261}