libspa/utils/hook.rs
1// Copyright The pipewire-rs Contributors.
2// SPDX-License-Identifier: MIT
3
4//! SPA hook
5
6use crate::utils::list;
7
8/// Remove a hook
9pub fn remove(mut hook: spa_sys::spa_hook) {
10 list::remove(&hook.link);
11
12 if let Some(removed) = hook.removed {
13 unsafe {
14 removed(&mut hook as *mut _);
15 }
16 }
17}
18
19/// Call a method on a spa_interface.
20///
21/// This needs to be called from within an `unsafe` block.
22///
23/// The macro always takes at least three arguments:
24/// 1. A pointer to a C struct that can be casted to a spa_interface.
25/// 2. The type of the interfaces methods struct.
26/// 3. The name of the method that should be called.
27///
28/// All additional arguments are added as arguments to the call in the order they are provided.
29///
30/// The macro returns whatever the called method returns, for example an `i32`, or `()` if the method returns nothing.
31///
32/// # Examples
33/// Here we call the sync method on a `pipewire_sys::pw_core` object.
34/// ```
35/// use pipewire_sys as pw_sys;
36/// use libspa as spa;
37///
38/// struct Core {
39/// ptr: *mut pw_sys::pw_core
40/// }
41///
42/// impl Core {
43/// fn sync(&self, seq: i32) -> i32 {
44/// unsafe {
45/// spa::spa_interface_call_method!(
46/// &self.ptr, pw_sys::pw_core_methods, sync, pipewire::core::PW_ID_CORE, seq
47/// )
48/// }
49/// }
50/// }
51/// ```
52#[macro_export]
53macro_rules! spa_interface_call_method {
54 ($interface_ptr:expr, $methods_struct:ty, $method:ident, $( $arg:expr ),*) => {{
55 let iface: *mut spa_sys::spa_interface = $interface_ptr.cast();
56 let funcs: *const $methods_struct = (*iface).cb.funcs.cast();
57 let f = (*funcs).$method.unwrap();
58
59 f((*iface).cb.data, $($arg),*)
60 }};
61}