libobs_wrapper\scenes\scene_item/
traits.rs1use crate::scenes::{ObsSceneItemRef, ObsSceneRef, SceneItemTrait};
2use crate::sources::{ObsSourceRef, ObsSourceTrait};
3use crate::utils::{ObsError, SourceInfo};
4use std::sync::Arc;
5
6pub trait SceneItemExtSceneTrait {
7 fn add_source<T: ObsSourceTrait + Clone + 'static>(
10 &mut self,
11 source: T,
12 ) -> Result<ObsSceneItemRef<T>, ObsError>;
13
14 fn add_and_create_source(
17 &mut self,
18 info: SourceInfo,
19 ) -> Result<ObsSceneItemRef<ObsSourceRef>, ObsError>;
20
21 fn get_source(&self, name: &str) -> Result<Option<Arc<dyn ObsSourceTrait>>, ObsError>;
23
24 #[deprecated = "Use get_source; the returned shared handle was never a mutable reference"]
25 fn get_source_mut(&self, name: &str) -> Result<Option<Arc<dyn ObsSourceTrait>>, ObsError> {
26 self.get_source(name)
27 }
28
29 fn remove_every_item_of_source<T: ObsSourceTrait>(&mut self, source: T)
31 -> Result<(), ObsError>;
32
33 fn remove_item<K: SceneItemTrait + ?Sized>(&mut self, scene_item: &K) -> Result<(), ObsError>;
35
36 #[deprecated = "Use remove_item; it removes the native scene item immediately without consuming the handle"]
37 fn remove_scene_item<K: SceneItemTrait>(&mut self, scene_item: K) -> Result<(), ObsError> {
38 self.remove_item(&scene_item)
39 }
40
41 fn remove_all_sources(&mut self) -> Result<(), ObsError>;
43
44 fn items_for_source<T: ObsSourceTrait + Clone>(
48 &self,
49 source: &T,
50 ) -> Result<Vec<Arc<dyn SceneItemTrait>>, ObsError>;
51
52 #[deprecated = "Use items_for_source; scene item handles are managed objects, not raw pointers"]
53 fn get_scene_item_ptr<T: ObsSourceTrait + Clone>(
54 &self,
55 source: &T,
56 ) -> Result<Vec<Arc<dyn SceneItemTrait>>, ObsError> {
57 self.items_for_source(source)
58 }
59}
60
61impl SceneItemExtSceneTrait for ObsSceneRef {
62 fn add_source<T: ObsSourceTrait + Clone + 'static>(
63 &mut self,
64 source: T,
65 ) -> Result<ObsSceneItemRef<T>, ObsError> {
66 self.runtime.ensure_same_runtime(source.runtime())?;
67 let scene_item = ObsSceneItemRef::new(self, source.clone(), self.runtime.clone())?;
68
69 let scene_clone = scene_item.clone();
70 self.attached_scene_items
71 .write()
72 .map_err(|e| ObsError::LockError(format!("{:?}", e)))?
73 .entry(source.__native_handle().native_id())
74 .or_insert_with(|| (Arc::new(source), Vec::new()))
75 .1
76 .push(Arc::new(scene_clone));
77
78 Ok(scene_item)
79 }
80
81 fn add_and_create_source(
82 &mut self,
83 info: SourceInfo,
84 ) -> Result<ObsSceneItemRef<ObsSourceRef>, ObsError> {
85 let source = crate::sources::ObsSourceRef::new(
86 info.id,
87 info.name,
88 info.settings,
89 info.hotkey_data,
90 self.runtime.clone(),
91 )?;
92
93 let scene_item = self.add_source(source.clone())?;
94 Ok(scene_item)
95 }
96
97 fn get_source(&self, name: &str) -> Result<Option<Arc<dyn ObsSourceTrait>>, ObsError> {
98 let guard = self
99 .attached_scene_items
100 .read()
101 .map_err(|e| ObsError::LockError(format!("{:?}", e)))?;
102 Ok(guard
103 .values()
104 .find(|(source, _)| source.name() == name)
105 .map(|(source, _)| source.clone()))
106 }
107
108 fn remove_every_item_of_source<T: ObsSourceTrait>(
109 &mut self,
110 source: T,
111 ) -> Result<(), ObsError> {
112 self.runtime.ensure_same_runtime(source.runtime())?;
113 let source_id = source.__native_handle().native_id();
114
115 let mut guard = self
116 .attached_scene_items
117 .write()
118 .map_err(|e| ObsError::LockError(format!("{:?}", e)))?;
119 let items = guard
120 .get(&source_id)
121 .map(|(_, items)| items.clone())
122 .unwrap_or_default();
123 for item in items {
124 item.remove_from_scene()?;
125 }
126 guard.remove(&source_id);
127
128 Ok(())
129 }
130
131 fn remove_item<K: SceneItemTrait + ?Sized>(&mut self, scene_item: &K) -> Result<(), ObsError> {
132 self.runtime.ensure_same_runtime(&scene_item.runtime())?;
133 scene_item.remove_from_scene()?;
136 let mut guard = self
137 .attached_scene_items
138 .write()
139 .map_err(|e| ObsError::LockError(format!("{:?}", e)))?;
140
141 guard.retain(|_, (_, items)| {
142 items.retain(|item| {
143 item.object_id() != scene_item.object_id()
145 });
146 !items.is_empty()
148 });
149 drop(guard);
150 self.attached_groups
151 .write()
152 .map_err(|e| ObsError::LockError(format!("{e:?}")))?
153 .retain(|group| group.object_id() != scene_item.object_id());
154 Ok(())
155 }
156
157 fn remove_all_sources(&mut self) -> Result<(), ObsError> {
158 let mut guard = self
159 .attached_scene_items
160 .write()
161 .map_err(|e| ObsError::LockError(format!("{:?}", e)))?;
162 let items = guard
163 .values()
164 .flat_map(|(_, items)| items.iter().cloned())
165 .collect::<Vec<_>>();
166 for item in items {
167 item.remove_from_scene()?;
168 }
169 guard.clear();
170
171 Ok(())
172 }
173
174 fn items_for_source<T: ObsSourceTrait + Clone>(
175 &self,
176 source: &T,
177 ) -> Result<Vec<Arc<dyn SceneItemTrait>>, ObsError> {
178 self.runtime.ensure_same_runtime(source.runtime())?;
179 let guard = self
180 .attached_scene_items
181 .read()
182 .map_err(|e| ObsError::LockError(format!("{:?}", e)))?;
183
184 let res = guard
185 .get(&source.__native_handle().native_id())
186 .map(|(_, scene_items)| scene_items.clone())
187 .unwrap_or_default();
188
189 Ok(res)
190 }
191}