libobs_wrapper\data/
mod.rs1use std::{ffi::CString, sync::Arc};
2
3use crate::{
4 impl_obs_drop, run_with_obs,
5 runtime::ObsRuntime,
6 unsafe_send::Sendable,
7 utils::{ObsError, ObsString},
8};
9use libobs::obs_data;
10
11pub mod audio;
12pub mod immutable;
13mod lib_support;
14pub mod output;
15pub mod properties;
16pub mod video;
17pub use lib_support::*;
18mod updater;
19pub use updater::*;
20mod traits;
21pub use traits::*;
22
23#[derive(Debug)]
24pub(crate) struct _ObsDataDropGuard {
25 obs_data: Sendable<*mut obs_data>,
26 pub(crate) runtime: ObsRuntime,
27}
28
29#[derive(Debug)]
37pub struct ObsData {
38 obs_data: Sendable<*mut obs_data>,
39 pub(crate) runtime: ObsRuntime,
40 pub(crate) _drop_guard: Arc<_ObsDataDropGuard>,
41}
42
43impl ObsData {
44 pub fn new(runtime: ObsRuntime) -> Result<Self, ObsError> {
53 let obs_data = run_with_obs!(runtime, move || unsafe {
54 Sendable(libobs::obs_data_create())
55 })?;
56
57 Ok(ObsData {
58 obs_data: obs_data.clone(),
59 runtime: runtime.clone(),
60 _drop_guard: Arc::new(_ObsDataDropGuard { obs_data, runtime }),
61 })
62 }
63
64 pub fn bulk_update(&mut self) -> ObsDataUpdater {
65 ObsDataUpdater {
66 changes: Vec::new(),
67 obs_data: self.obs_data.clone(),
68 _drop_guard: self._drop_guard.clone(),
69 }
70 }
71
72 pub fn as_ptr(&self) -> Sendable<*mut obs_data> {
75 self.obs_data.clone()
76 }
77
78 pub fn set_string<T: Into<ObsString> + Send + Sync, K: Into<ObsString> + Send + Sync>(
81 &mut self,
82 key: T,
83 value: K,
84 ) -> Result<&mut Self, ObsError> {
85 let key = key.into();
86 let value = value.into();
87
88 let key_ptr = key.as_ptr();
89 let value_ptr = value.as_ptr();
90 let data_ptr = self.obs_data.clone();
91
92 run_with_obs!(
93 self.runtime,
94 (data_ptr, key_ptr, value_ptr),
95 move || unsafe { libobs::obs_data_set_string(data_ptr, key_ptr, value_ptr) }
96 )?;
97
98 Ok(self)
99 }
100
101 pub fn set_int<T: Into<ObsString> + Sync + Send>(
104 &mut self,
105 key: T,
106 value: i64,
107 ) -> Result<&mut Self, ObsError> {
108 let key = key.into();
109
110 let key_ptr = key.as_ptr();
111 let data_ptr = self.obs_data.clone();
112
113 run_with_obs!(self.runtime, (key_ptr, data_ptr), move || unsafe {
114 libobs::obs_data_set_int(data_ptr, key_ptr, value);
115 })?;
116
117 Ok(self)
118 }
119
120 pub fn set_bool<T: Into<ObsString> + Sync + Send>(
123 &mut self,
124 key: T,
125 value: bool,
126 ) -> Result<&mut Self, ObsError> {
127 let key = key.into();
128
129 let key_ptr = key.as_ptr();
130 let data_ptr = self.obs_data.clone();
131 run_with_obs!(self.runtime, (key_ptr, data_ptr), move || unsafe {
132 libobs::obs_data_set_bool(data_ptr, key_ptr, value);
133 })?;
134
135 Ok(self)
136 }
137
138 pub fn set_double<T: Into<ObsString> + Sync + Send>(
141 &mut self,
142 key: T,
143 value: f64,
144 ) -> Result<&mut Self, ObsError> {
145 let key = key.into();
146
147 let key_ptr = key.as_ptr();
148 let data_ptr = self.obs_data.clone();
149
150 run_with_obs!(self.runtime, (key_ptr, data_ptr), move || unsafe {
151 libobs::obs_data_set_double(data_ptr, key_ptr, value);
152 })?;
153
154 Ok(self)
155 }
156
157 pub fn from_json(json: &str, runtime: ObsRuntime) -> Result<Self, ObsError> {
158 let cstr = CString::new(json).map_err(|_| ObsError::JsonParseError)?;
159
160 let cstr_ptr = Sendable(cstr.as_ptr());
161 let result = run_with_obs!(runtime, (cstr_ptr), move || unsafe {
162 Sendable(libobs::obs_data_create_from_json(cstr_ptr))
163 })?;
164
165 if result.0.is_null() {
166 return Err(ObsError::JsonParseError);
167 }
168
169 Ok(ObsData {
170 obs_data: result.clone(),
171 runtime: runtime.clone(),
172 _drop_guard: Arc::new(_ObsDataDropGuard {
173 obs_data: result,
174 runtime,
175 }),
176 })
177 }
178}
179
180impl_obs_drop!(_ObsDataDropGuard, (obs_data), move || unsafe {
181 libobs::obs_data_release(obs_data)
182});
183
184impl Clone for ObsData {
185 fn clone(&self) -> Self {
186 let json = self.get_json().unwrap();
187 Self::from_json(json.as_str(), self.runtime.clone()).unwrap()
188 }
189}