use std::{ffi::CString, sync::Arc};
use crate::{
impl_obs_drop, run_with_obs,
runtime::ObsRuntime,
unsafe_send::{Sendable, SmartPointerSendable},
utils::{ObsDropGuard, ObsError},
};
pub use immutable::ImmutableObsData;
pub mod audio;
mod immutable;
mod lib_support;
pub mod object;
pub mod output;
pub mod properties;
pub mod video;
pub use lib_support::*;
mod updater;
pub use updater::*;
mod traits;
pub use traits::*;
#[derive(Debug)]
pub(super) struct _ObsDataDropGuard {
data_ptr: Sendable<*mut libobs::obs_data_t>,
runtime: ObsRuntime,
}
impl_obs_drop!(_ObsDataDropGuard, (data_ptr), move || unsafe {
libobs::obs_data_release(data_ptr.0)
});
impl ObsDropGuard for _ObsDataDropGuard {}
#[derive(Debug)]
pub struct ObsData {
pub(crate) runtime: ObsRuntime,
ptr: SmartPointerSendable<*mut libobs::obs_data_t>,
}
impl ObsData {
pub fn new(runtime: ObsRuntime) -> Result<Self, ObsError> {
let obs_data = run_with_obs!(runtime, move || unsafe {
Sendable(libobs::obs_data_create())
})?;
let drop_guard = Arc::new(_ObsDataDropGuard {
data_ptr: obs_data.clone(),
runtime: runtime.clone(),
});
let ptr = SmartPointerSendable::new(obs_data.0, drop_guard.clone());
Ok(ObsData {
ptr,
runtime: runtime.clone(),
})
}
pub fn bulk_update(&mut self) -> ObsDataUpdater {
ObsDataUpdater::new(self.as_ptr(), self.runtime.clone())
}
pub fn from_json(json: &str, runtime: ObsRuntime) -> Result<Self, ObsError> {
let cstr = CString::new(json).map_err(|_| ObsError::JsonParseError)?;
let raw_ptr = run_with_obs!(runtime, (cstr), move || unsafe {
Sendable(libobs::obs_data_create_from_json(cstr.as_ptr()))
})?;
if raw_ptr.0.is_null() {
return Err(ObsError::JsonParseError);
}
let drop_guard = Arc::new(_ObsDataDropGuard {
data_ptr: raw_ptr.clone(),
runtime: runtime.clone(),
});
let ptr = SmartPointerSendable::new(raw_ptr.0, drop_guard.clone());
Ok(ObsData {
ptr,
runtime: runtime.clone(),
})
}
pub fn into_immutable(self) -> ImmutableObsData {
ImmutableObsData::from(self)
}
}
impl ObsDataPointers for ObsData {
fn runtime(&self) -> &ObsRuntime {
&self.runtime
}
fn as_ptr(&self) -> SmartPointerSendable<*mut libobs::obs_data_t> {
self.ptr.clone()
}
}
impl ObsDataGetters for ObsData {}
impl ObsDataSetters for ObsData {}
impl Clone for ObsData {
fn clone(&self) -> Self {
let json = self.get_json().unwrap();
Self::from_json(json.as_str(), self.runtime.clone()).unwrap()
}
}