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)]
32pub struct CoreRc {
33 inner: Rc<CoreRcInner>,
34}
35
36impl CoreRc {
37 pub fn from_raw(
38 ptr: ptr::NonNull<pw_sys::pw_core>,
39 context: crate::context::ContextRc,
40 ) -> Self {
41 let core = unsafe { CoreBox::from_raw(ptr) };
42
43 Self {
44 inner: Rc::new(CoreRcInner {
45 core,
46 _context: context,
47 }),
48 }
49 }
50
51 pub fn downgrade(&self) -> CoreWeak {
52 let weak = Rc::downgrade(&self.inner);
53 CoreWeak { weak }
54 }
55
56 pub fn get_registry_rc(&self) -> Result<RegistryRc, Error> {
57 unsafe {
58 let registry = spa_interface_call_method!(
59 self.as_raw_ptr(),
60 pw_sys::pw_core_methods,
61 get_registry,
62 pw_sys::PW_VERSION_REGISTRY,
63 0
64 );
65 let registry = ptr::NonNull::new(registry).ok_or(Error::CreationFailed)?;
66 Ok(RegistryRc::from_raw(registry, self.clone()))
67 }
68 }
69}
70
71impl Deref for CoreRc {
72 type Target = Core;
73
74 fn deref(&self) -> &Self::Target {
75 self.inner.core.deref()
76 }
77}
78
79impl AsRef<Core> for CoreRc {
80 fn as_ref(&self) -> &Core {
81 self.deref()
82 }
83}
84
85pub struct CoreWeak {
89 weak: Weak<CoreRcInner>,
90}
91
92impl CoreWeak {
93 pub fn upgrade(&self) -> Option<CoreRc> {
94 self.weak.upgrade().map(|inner| CoreRc { inner })
95 }
96}