pipewire/registry/rc.rs
1// Copyright The pipewire-rs Contributors.
2// SPDX-License-Identifier: MIT
3
4use std::{
5 ops::Deref,
6 ptr,
7 rc::{Rc, Weak},
8};
9
10use super::{Registry, RegistryBox};
11
12#[derive(Debug)]
13struct RegistryRcInner {
14 registry: RegistryBox<'static>,
15 // Store the core here, so that the registry is not dropped before the core,
16 // which may lead to undefined behaviour. Rusts drop order of struct fields
17 // (from top to bottom) ensures that this is always destroyed _after_ the registry.
18 _core: crate::core::CoreRc,
19}
20
21/// Reference counting smart pointer providing shared ownership of a PipeWire [registry](super).
22///
23/// For the non-owning variant, see [`RegistryWeak`].
24/// For unique ownership, see [`RegistryBox`].
25///
26/// For an explanation of these, see [Smart pointers to PipeWire objects](crate#smart-pointers-to-pipewire-objects).
27#[derive(Debug, Clone)]
28pub struct RegistryRc {
29 inner: Rc<RegistryRcInner>,
30}
31
32impl RegistryRc {
33 /// Create a `RegistryRc` by taking ownership of a raw `pw_registry`.
34 ///
35 /// # Safety
36 /// The provided pointer must point to a valid, well aligned [`pw_registry`](`pw_sys::pw_registry`).
37 ///
38 /// The raw registry must not be manually destroyed or moved, as the new [`RegistryRc`] takes
39 /// ownership of it.
40 pub unsafe fn from_raw(
41 ptr: ptr::NonNull<pw_sys::pw_registry>,
42 core: crate::core::CoreRc,
43 ) -> Self {
44 let registry = unsafe { RegistryBox::from_raw(ptr) };
45
46 Self {
47 inner: Rc::new(RegistryRcInner {
48 registry,
49 _core: core,
50 }),
51 }
52 }
53
54 pub fn downgrade(&self) -> RegistryWeak {
55 let weak = Rc::downgrade(&self.inner);
56 RegistryWeak { weak }
57 }
58}
59
60impl Deref for RegistryRc {
61 type Target = Registry;
62
63 fn deref(&self) -> &Self::Target {
64 self.inner.registry.deref()
65 }
66}
67
68impl AsRef<Registry> for RegistryRc {
69 fn as_ref(&self) -> &Registry {
70 self.deref()
71 }
72}
73
74/// Non-owning reference to a [registry](super) managed by [`RegistryRc`].
75///
76/// The registry can be accessed by calling [`upgrade`](Self::upgrade).
77pub struct RegistryWeak {
78 weak: Weak<RegistryRcInner>,
79}
80
81impl RegistryWeak {
82 pub fn upgrade(&self) -> Option<RegistryRc> {
83 self.weak.upgrade().map(|inner| RegistryRc { inner })
84 }
85}