libobs_wrapper\scenes/
filter_traits.rs1use crate::data::object::ObsObjectTrait;
2use crate::run_with_obs;
3use crate::scenes::ObsSceneRef;
4use crate::sources::_ObsRemoveFilterOnDrop;
5use crate::sources::ObsFilterGuardPair;
6use crate::sources::ObsFilterRef;
7use crate::unsafe_send::SmartPointerSendable;
8use crate::utils::ObsError;
9use std::sync::Arc;
10
11pub trait ObsSceneExtFilter {
12 fn add_scene_filter(&self, filter_ref: &ObsFilterRef) -> Result<(), ObsError>;
14
15 fn remove_scene_filter(&self, filter_ref: &ObsFilterRef) -> Result<(), ObsError>;
17}
18
19impl ObsSceneExtFilter for ObsSceneRef {
20 fn add_scene_filter(&self, filter_ref: &ObsFilterRef) -> Result<(), ObsError> {
21 self.runtime.ensure_same_runtime(filter_ref.runtime())?;
22 let source_ptr = self.get_scene_source_ptr()?;
23 let filter_ptr = filter_ref.__native_handle();
24
25 let mut guard = self.attached_filters.write().map_err(|_| {
26 ObsError::LockError("Failed to acquire write lock on attached filters".into())
27 })?;
28
29 run_with_obs!(self.runtime, (source_ptr, filter_ptr), move || {
30 unsafe {
31 libobs::obs_source_filter_add(source_ptr.0, filter_ptr.get_ptr());
33 };
34 })?;
35
36 let drop_guard = _ObsRemoveFilterOnDrop::new(
37 SmartPointerSendable::new(
39 source_ptr.0,
40 Arc::new(super::_NoOpDropGuard),
41 self.runtime.native_registry(),
42 ),
43 filter_ref.__native_handle(),
44 Some(self.as_ptr()),
45 self.runtime.clone(),
46 );
47
48 guard.push(ObsFilterGuardPair::new(
49 filter_ref.clone(),
50 Arc::new(drop_guard),
51 ));
52
53 Ok(())
54 }
55
56 fn remove_scene_filter(&self, filter_ref: &ObsFilterRef) -> Result<(), ObsError> {
57 self.runtime.ensure_same_runtime(filter_ref.runtime())?;
58 self.attached_filters
59 .write()
60 .map_err(|_| {
61 ObsError::LockError("Failed to acquire write lock on attached filters".into())
62 })?
63 .retain(|f| {
64 f.get_inner().__native_handle().native_id()
66 != filter_ref.__native_handle().native_id()
67 });
68 Ok(())
69 }
70}