use std::{
ops::Deref,
ptr,
rc::{Rc, Weak},
};
use spa::spa_interface_call_method;
use crate::{registry::RegistryRc, Error};
use super::{Core, CoreBox};
#[derive(Debug)]
struct CoreRcInner {
core: CoreBox<'static>,
_context: crate::context::ContextRc,
}
#[derive(Debug, Clone)]
pub struct CoreRc {
inner: Rc<CoreRcInner>,
}
impl CoreRc {
pub fn from_raw(
ptr: ptr::NonNull<pw_sys::pw_core>,
context: crate::context::ContextRc,
) -> Self {
let core = unsafe { CoreBox::from_raw(ptr) };
Self {
inner: Rc::new(CoreRcInner {
core,
_context: context,
}),
}
}
pub fn downgrade(&self) -> CoreWeak {
let weak = Rc::downgrade(&self.inner);
CoreWeak { weak }
}
pub fn get_registry_rc(&self) -> Result<RegistryRc, Error> {
unsafe {
let registry = spa_interface_call_method!(
self.as_raw_ptr(),
pw_sys::pw_core_methods,
get_registry,
pw_sys::PW_VERSION_REGISTRY,
0
);
let registry = ptr::NonNull::new(registry).ok_or(Error::CreationFailed)?;
Ok(RegistryRc::from_raw(registry, self.clone()))
}
}
}
impl Deref for CoreRc {
type Target = Core;
fn deref(&self) -> &Self::Target {
self.inner.core.deref()
}
}
impl AsRef<Core> for CoreRc {
fn as_ref(&self) -> &Core {
self.deref()
}
}
pub struct CoreWeak {
weak: Weak<CoreRcInner>,
}
impl CoreWeak {
pub fn upgrade(&self) -> Option<CoreRc> {
self.weak.upgrade().map(|inner| CoreRc { inner })
}
}