libobs_wrapper\data\properties/
mod.rs

1mod enums;
2mod macros;
3pub mod prop_impl;
4pub mod types;
5
6use std::{collections::HashMap, ffi::CStr};
7
8use libobs::obs_properties;
9use macros::*;
10
11pub use enums::*;
12use types::*;
13
14use crate::{
15    run_with_obs,
16    runtime::ObsRuntime,
17    unsafe_send::Sendable,
18    utils::{ObsError, ObsString},
19};
20
21#[derive(Debug, Clone)]
22pub enum ObsProperty {
23    /// A property that is not valid
24    Invalid,
25    /// A boolean property
26    Bool,
27    /// An integer property
28    Int(ObsNumberProperty<i32>),
29    /// A float property
30    Float(ObsNumberProperty<f64>),
31    /// A text property
32    Text(ObsTextProperty),
33    /// A path property
34    Path(ObsPathProperty),
35    /// A list property
36    List(ObsListProperty),
37    /// A color property
38    Color(ObsColorProperty),
39    /// A button property
40    Button(ObsButtonProperty),
41    /// A font property
42    Font(ObsFontProperty),
43    /// An editable list property
44    EditableList(ObsEditableListProperty),
45    /// A frame rate property
46    FrameRate(ObsFrameRateProperty),
47    /// A group property
48    Group(ObsGroupProperty),
49    /// A color alpha property
50    ColorAlpha(ObsColorAlphaProperty),
51}
52
53pub trait ObsPropertyObjectPrivate {
54    fn get_properties_raw(&self) -> Result<Sendable<*mut libobs::obs_properties_t>, ObsError>;
55    fn get_properties_by_id_raw<T: Into<ObsString> + Sync + Send>(
56        id: T,
57        runtime: ObsRuntime,
58    ) -> Result<Sendable<*mut libobs::obs_properties_t>, ObsError>;
59}
60
61pub(crate) fn get_properties_inner(
62    properties_raw: Sendable<*mut obs_properties>,
63    runtime: ObsRuntime,
64) -> Result<HashMap<String, ObsProperty>, ObsError> {
65    let properties_raw = properties_raw.clone();
66    if properties_raw.0.is_null() {
67        let ptr_clone = properties_raw.clone();
68        run_with_obs!(runtime, (ptr_clone), move || {
69            unsafe { libobs::obs_properties_destroy(ptr_clone) };
70        })?;
71
72        return Ok(HashMap::new());
73    }
74
75    run_with_obs!(runtime, (properties_raw), move || {
76        let mut result = HashMap::new();
77        let mut property = unsafe { libobs::obs_properties_first(properties_raw) };
78        while !property.is_null() {
79            let name = unsafe { libobs::obs_property_name(property) };
80            let name = unsafe { CStr::from_ptr(name as _) };
81            let name = name.to_string_lossy().to_string();
82
83            let p_type = unsafe { libobs::obs_property_get_type(property) };
84
85            let p_type = crate::macros::enum_from_number!(ObsPropertyType, p_type);
86
87            log::trace!("Property: {:?}", name);
88            match p_type {
89                Some(p_type) => {
90                    result.insert(name, unsafe { p_type.to_property_struct(property) });
91                }
92                None => {
93                    result.insert(name, ObsProperty::Invalid);
94                }
95            }
96
97            // Move to the next property
98            unsafe { libobs::obs_property_next(&mut property) };
99        }
100
101        unsafe { libobs::obs_properties_destroy(properties_raw) };
102        result
103    })
104}
105
106/// This trait is implemented for all obs objects that can have properties
107pub trait ObsPropertyObject: ObsPropertyObjectPrivate {
108    /// Returns the properties of the object
109    fn get_properties(&self) -> Result<HashMap<String, ObsProperty>, ObsError>;
110    fn get_properties_by_id<T: Into<ObsString> + Sync + Send>(
111        id: T,
112        runtime: &ObsRuntime,
113    ) -> Result<HashMap<String, ObsProperty>, ObsError> {
114        let properties_raw = Self::get_properties_by_id_raw(id, runtime.clone())?;
115        get_properties_inner(properties_raw, runtime.clone())
116    }
117}