libobs_wrapper\data/
updater.rs1use std::sync::Arc;
2
3use libobs::obs_data;
4
5use crate::{
6 run_with_obs,
7 unsafe_send::Sendable,
8 utils::{ObsError, ObsString},
9};
10
11use super::_ObsDataDropGuard;
12
13#[derive(Debug)]
14pub enum ObsDataChange {
15 String(ObsString, ObsString),
16 Int(ObsString, i64),
17 Bool(ObsString, bool),
18 Double(ObsString, f64),
19}
20
21#[derive(Debug)]
22#[must_use = "The `update()` method must be called to apply changes."]
25pub struct ObsDataUpdater {
26 pub(crate) changes: Vec<ObsDataChange>,
27 pub(crate) obs_data: Sendable<*mut obs_data>,
28 pub(crate) _drop_guard: Arc<_ObsDataDropGuard>,
29}
30
31impl ObsDataUpdater {
32 pub fn set_string_ref(&mut self, key: impl Into<ObsString>, value: impl Into<ObsString>) {
33 let key = key.into();
34 let value = value.into();
35
36 log::trace!("Setting string: {:?} = {:?}", key, value);
37 self.changes.push(ObsDataChange::String(key, value));
38 }
39
40 pub fn set_string(mut self, key: impl Into<ObsString>, value: impl Into<ObsString>) -> Self {
41 self.set_string_ref(key, value);
42 self
43 }
44
45 pub fn set_int_ref(&mut self, key: impl Into<ObsString>, value: i64) {
46 let key = key.into();
47 self.changes.push(ObsDataChange::Int(key, value));
48 }
49
50 pub fn set_int(mut self, key: impl Into<ObsString>, value: i64) -> Self {
51 self.set_int_ref(key, value);
52 self
53 }
54
55 pub fn set_bool_ref(&mut self, key: impl Into<ObsString>, value: bool) {
56 let key = key.into();
57 self.changes.push(ObsDataChange::Bool(key, value));
58 }
59
60 pub fn set_bool(mut self, key: impl Into<ObsString>, value: bool) -> Self {
61 self.set_bool_ref(key, value);
62 self
63 }
64
65 pub fn update(self) -> Result<(), ObsError> {
66 let ObsDataUpdater {
67 changes,
68 obs_data,
69 _drop_guard,
70 } = self;
71
72 let obs_data = obs_data.clone();
73 run_with_obs!(_drop_guard.runtime, (obs_data), move || unsafe {
74 for change in changes {
75 match change {
76 ObsDataChange::String(key, value) => {
77 libobs::obs_data_set_string(obs_data, key.as_ptr().0, value.as_ptr().0)
78 }
79 ObsDataChange::Int(key, value) => {
80 libobs::obs_data_set_int(obs_data, key.as_ptr().0, value)
81 }
82 ObsDataChange::Bool(key, value) => {
83 libobs::obs_data_set_bool(obs_data, key.as_ptr().0, value)
84 }
85 ObsDataChange::Double(key, value) => {
86 libobs::obs_data_set_double(obs_data, key.as_ptr().0, value)
87 }
88 };
89 }
90 })
91 }
92}