libobs_wrapper\data\properties/
mod.rs1mod enums;
8mod macros;
9pub mod prop_impl;
10pub mod types;
11
12use std::{collections::HashMap, ffi::CStr};
13
14use libobs::obs_properties;
15use macros::*;
16
17pub use enums::*;
18use types::*;
19
20use crate::{
21 impl_obs_drop, run_with_obs,
22 runtime::ObsRuntime,
23 unsafe_send::{Sendable, SmartPointerSendable},
24 utils::{ObsDropGuard, ObsError, ObsString},
25};
26
27#[derive(Debug)]
28pub(crate) struct _ObsPropertiesDropGuard {
29 properties: Sendable<*mut obs_properties>,
30 runtime: ObsRuntime,
31}
32
33impl ObsDropGuard for _ObsPropertiesDropGuard {}
34
35impl_obs_drop!(_ObsPropertiesDropGuard, (properties), move || unsafe {
36 libobs::obs_properties_destroy(properties.0);
38});
39
40impl _ObsPropertiesDropGuard {
41 pub(crate) fn new(properties: Sendable<*mut obs_properties>, runtime: ObsRuntime) -> Self {
42 Self {
43 properties,
44 runtime,
45 }
46 }
47}
48
49#[derive(Debug, Clone)]
50pub enum ObsProperty {
51 Invalid,
53 Bool,
55 Int(ObsNumberProperty<i32>),
57 Float(ObsNumberProperty<f64>),
59 Text(ObsTextProperty),
61 Path(ObsPathProperty),
63 List(ObsListProperty),
65 Color(ObsColorProperty),
67 Button(ObsButtonProperty),
69 Font(ObsFontProperty),
71 EditableList(ObsEditableListProperty),
73 FrameRate(ObsFrameRateProperty),
75 Group(ObsGroupProperty),
77 ColorAlpha(ObsColorAlphaProperty),
79}
80
81pub trait ObsPropertyObjectPrivate {
82 fn get_properties_raw(
83 &self,
84 ) -> Result<SmartPointerSendable<*mut libobs::obs_properties_t>, ObsError>;
85 fn get_properties_by_id_raw<T: Into<ObsString> + Sync + Send>(
86 id: T,
87 runtime: ObsRuntime,
88 ) -> Result<SmartPointerSendable<*mut libobs::obs_properties_t>, ObsError>;
89}
90
91pub(crate) fn property_ptr_to_struct(
92 properties_raw: SmartPointerSendable<*mut obs_properties>,
93 runtime: ObsRuntime,
94) -> Result<HashMap<String, ObsProperty>, ObsError> {
95 let runtime_clone = runtime.clone();
96 run_with_obs!(runtime, (properties_raw, runtime_clone), move || {
97 let mut result = HashMap::new();
98 let mut property = unsafe {
99 libobs::obs_properties_first(properties_raw.get_ptr())
101 };
102 while !property.is_null() {
103 let name = unsafe { libobs::obs_property_name(property) };
104 if name.is_null() {
105 let success = unsafe {
106 libobs::obs_property_next(&mut property)
108 };
109
110 if !success {
111 break;
112 }
113 continue;
114 }
115
116 let name = unsafe {
117 CStr::from_ptr(name as _)
119 };
120 let name = name.to_string_lossy().to_string();
121
122 let p_type = unsafe {
123 libobs::obs_property_get_type(property)
125 };
126
127 let p_type = crate::macros::enum_from_number!(ObsPropertyType, p_type);
128
129 log::trace!("Property: {:?}", name);
130 match p_type {
131 Some(p_type) => {
132 let prop_struct = unsafe {
133 p_type.get_property_struct(&runtime_clone, Sendable(property))
135 };
136 if let Ok(r) = prop_struct {
137 result.insert(name, r);
138 }
139 }
140 None => {
141 result.insert(name, ObsProperty::Invalid);
142 }
143 }
144
145 let has_next = unsafe {
147 libobs::obs_property_next(&mut property)
149 };
150
151 if !has_next {
152 break;
153 }
154 }
155
156 result
157 })
158}
159
160pub trait ObsPropertyObject: ObsPropertyObjectPrivate {
162 fn get_properties(&self) -> Result<HashMap<String, ObsProperty>, ObsError>;
164 fn get_properties_by_source_id<T: Into<ObsString> + Sync + Send>(
165 id: T,
166 runtime: &ObsRuntime,
167 ) -> Result<HashMap<String, ObsProperty>, ObsError> {
168 let properties_raw = Self::get_properties_by_id_raw(id, runtime.clone())?;
169 property_ptr_to_struct(properties_raw, runtime.clone())
170 }
171}