use crate::scenes::{ObsSceneItemRef, ObsSceneRef, SceneItemTrait};
use crate::sources::{ObsSourceRef, ObsSourceTrait};
use crate::utils::{ObsError, SourceInfo};
use std::sync::Arc;
pub trait SceneItemExtSceneTrait {
fn add_source<T: ObsSourceTrait + Clone + 'static>(
&mut self,
source: T,
) -> Result<ObsSceneItemRef<T>, ObsError>;
fn add_and_create_source(
&mut self,
info: SourceInfo,
) -> Result<ObsSceneItemRef<ObsSourceRef>, ObsError>;
fn get_source_mut(&self, name: &str) -> Result<Option<Arc<Box<dyn ObsSourceTrait>>>, ObsError>;
fn remove_every_item_of_source<T: ObsSourceTrait>(&mut self, source: T)
-> Result<(), ObsError>;
fn remove_scene_item<K: SceneItemTrait>(&mut self, scene_item: K) -> Result<(), ObsError>;
fn remove_all_sources(&mut self) -> Result<(), ObsError>;
fn get_scene_item_ptr<T: ObsSourceTrait + Clone>(
&self,
source: &T,
) -> Result<Vec<Arc<Box<dyn SceneItemTrait>>>, ObsError>;
}
impl SceneItemExtSceneTrait for ObsSceneRef {
fn add_source<T: ObsSourceTrait + Clone + 'static>(
&mut self,
source: T,
) -> Result<ObsSceneItemRef<T>, ObsError> {
let scene_item = ObsSceneItemRef::new(self, source.clone(), self.runtime.clone())?;
let scene_clone = scene_item.clone();
self.attached_scene_items
.write()
.map_err(|e| ObsError::LockError(format!("{:?}", e)))?
.entry(Arc::new(Box::new(source)))
.or_insert_with(Vec::new)
.push(Arc::new(Box::new(scene_clone)));
Ok(scene_item)
}
fn add_and_create_source(
&mut self,
info: SourceInfo,
) -> Result<ObsSceneItemRef<ObsSourceRef>, ObsError> {
let source = crate::sources::ObsSourceRef::new(
info.id,
info.name,
info.settings,
info.hotkey_data,
self.runtime.clone(),
)?;
let scene_item = self.add_source(source.clone())?;
Ok(scene_item)
}
fn get_source_mut(&self, name: &str) -> Result<Option<Arc<Box<dyn ObsSourceTrait>>>, ObsError> {
let r = self
.attached_scene_items
.read()
.map_err(|e| ObsError::LockError(format!("{:?}", e)))?
.keys()
.find(|s| s.name() == name)
.cloned();
Ok(r)
}
fn remove_every_item_of_source<T: ObsSourceTrait>(
&mut self,
source: T,
) -> Result<(), ObsError> {
let source_ptr = source.as_ptr().get_ptr();
self.attached_scene_items
.write()
.map_err(|e| ObsError::LockError(format!("{:?}", e)))?
.retain(|s, _| {
s.as_ptr().get_ptr() != source_ptr
});
Ok(())
}
fn remove_scene_item<K: SceneItemTrait>(&mut self, scene_item: K) -> Result<(), ObsError> {
let mut guard = self
.attached_scene_items
.write()
.map_err(|e| ObsError::LockError(format!("{:?}", e)))?;
guard.retain(|_, items| {
items.retain(|item| {
item.as_ptr().get_ptr() != scene_item.as_ptr().get_ptr()
});
!items.is_empty()
});
Ok(())
}
fn remove_all_sources(&mut self) -> Result<(), ObsError> {
self.attached_scene_items
.write()
.map_err(|e| ObsError::LockError(format!("{:?}", e)))?
.clear();
Ok(())
}
fn get_scene_item_ptr<T: ObsSourceTrait + Clone>(
&self,
source: &T,
) -> Result<Vec<Arc<Box<dyn SceneItemTrait>>>, ObsError> {
let guard = self
.attached_scene_items
.read()
.map_err(|e| ObsError::LockError(format!("{:?}", e)))?;
let res = guard
.iter()
.find_map(|(s, scene_item_pointers)| {
if s.as_ptr().get_ptr() == source.as_ptr().get_ptr() {
Some(scene_item_pointers.clone())
} else {
None
}
})
.unwrap_or_else(Vec::new);
Ok(res)
}
}