pipewire/main_loop/
box_.rs

1// Copyright The pipewire-rs Contributors.
2// SPDX-License-Identifier: MIT
3
4use std::{ops::Deref, ptr};
5
6use crate::Error;
7
8use super::MainLoop;
9
10#[derive(Debug)]
11pub struct MainLoopBox {
12    ptr: std::ptr::NonNull<pw_sys::pw_main_loop>,
13}
14
15impl MainLoopBox {
16    /// Initialize Pipewire and create a new [`MainLoopBox`]
17    pub fn new(properties: Option<&spa::utils::dict::DictRef>) -> Result<Self, Error> {
18        crate::init();
19
20        unsafe {
21            let props = properties
22                .map_or(ptr::null(), |props| props.as_raw())
23                .cast_mut();
24
25            let raw = pw_sys::pw_main_loop_new(props);
26            let ptr = ptr::NonNull::new(raw).ok_or(Error::CreationFailed)?;
27
28            Ok(Self::from_raw(ptr))
29        }
30    }
31
32    /// Create a new main loop from a raw [`pw_main_loop`](`pw_sys::pw_main_loop`), taking ownership of it.
33    ///
34    /// # Safety
35    /// The provided pointer must point to a valid, well aligned [`pw_main_loop`](`pw_sys::pw_main_loop`).
36    ///
37    /// The raw loop should not be manually destroyed or moved, as the new [`MainLoopBox`] takes ownership of it.
38    pub unsafe fn from_raw(ptr: ptr::NonNull<pw_sys::pw_main_loop>) -> Self {
39        Self { ptr }
40    }
41
42    pub fn into_raw(self) -> std::ptr::NonNull<pw_sys::pw_main_loop> {
43        // Use ManuallyDrop to give up ownership of the managed struct and not run the destructor.
44        std::mem::ManuallyDrop::new(self).ptr
45    }
46}
47
48impl std::ops::Deref for MainLoopBox {
49    type Target = MainLoop;
50
51    fn deref(&self) -> &Self::Target {
52        unsafe { self.ptr.cast::<MainLoop>().as_ref() }
53    }
54}
55
56impl AsRef<MainLoop> for MainLoopBox {
57    fn as_ref(&self) -> &MainLoop {
58        self.deref()
59    }
60}
61
62impl std::ops::Drop for MainLoopBox {
63    fn drop(&mut self) {
64        unsafe {
65            pw_sys::pw_main_loop_destroy(self.as_raw_ptr());
66        }
67    }
68}