1use std::{
5 ops::Deref,
6 ptr,
7 rc::{Rc, Weak},
8};
9
10use spa::spa_interface_call_method;
11
12use crate::{registry::RegistryRc, Error};
13
14use super::{Core, CoreBox};
15
16#[derive(Debug)]
17struct CoreRcInner {
18 core: CoreBox<'static>,
19 _context: crate::context::ContextRc,
23}
24
25#[derive(Debug, Clone)]
26pub struct CoreRc {
27 inner: Rc<CoreRcInner>,
28}
29
30impl CoreRc {
31 pub fn from_raw(
32 ptr: ptr::NonNull<pw_sys::pw_core>,
33 context: crate::context::ContextRc,
34 ) -> Self {
35 let core = unsafe { CoreBox::from_raw(ptr) };
36
37 Self {
38 inner: Rc::new(CoreRcInner {
39 core,
40 _context: context,
41 }),
42 }
43 }
44
45 pub fn downgrade(&self) -> CoreWeak {
46 let weak = Rc::downgrade(&self.inner);
47 CoreWeak { weak }
48 }
49
50 pub fn get_registry_rc(&self) -> Result<RegistryRc, Error> {
51 unsafe {
52 let registry = spa_interface_call_method!(
53 self.as_raw_ptr(),
54 pw_sys::pw_core_methods,
55 get_registry,
56 pw_sys::PW_VERSION_REGISTRY,
57 0
58 );
59 let registry = ptr::NonNull::new(registry).ok_or(Error::CreationFailed)?;
60 Ok(RegistryRc::from_raw(registry, self.clone()))
61 }
62 }
63}
64
65impl Deref for CoreRc {
66 type Target = Core;
67
68 fn deref(&self) -> &Self::Target {
69 self.inner.core.deref()
70 }
71}
72
73impl AsRef<Core> for CoreRc {
74 fn as_ref(&self) -> &Core {
75 self.deref()
76 }
77}
78
79pub struct CoreWeak {
80 weak: Weak<CoreRcInner>,
81}
82
83impl CoreWeak {
84 pub fn upgrade(&self) -> Option<CoreRc> {
85 self.weak.upgrade().map(|inner| CoreRc { inner })
86 }
87}