pipewire_native_spa/interface/
plugin.rs1use std::{any::TypeId, pin::Pin, sync::Arc};
6
7use crate::dict::Dict;
8
9use super::ffi::CInterface;
10
11pub const LOG_FACTORY: &str = "support.log";
12pub const SYSTEM_FACTORY: &str = "support.system";
13pub const CPU_FACTORY: &str = "support.cpu";
14pub const LOOP_FACTORY: &str = "support.loop";
15
16pub trait Interface {
17 unsafe fn make_native(&self) -> *mut CInterface;
22
23 unsafe fn free_native(cpu: *mut CInterface)
28 where
29 Self: Sized;
30
31 fn type_id(&self) -> TypeId
32 where
33 Self: 'static,
34 {
35 TypeId::of::<Self>()
36 }
37}
38
39impl std::fmt::Debug for dyn Interface {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.debug_struct("Interface")
42 .field("type_id", &self.type_id())
43 .finish()
44 }
45}
46
47type ArcPinBox<T> = Arc<Pin<Box<T>>>;
48
49impl dyn Interface {
50 pub fn is<T>(&self) -> bool
51 where
52 T: 'static,
53 {
54 TypeId::of::<T>() == self.type_id()
55 }
56
57 pub fn downcast_box<T>(self: Box<Self>) -> Result<Box<T>, Box<Self>>
58 where
59 T: 'static,
60 {
61 if self.is::<T>() {
62 Ok(unsafe { Box::from_raw(Box::into_raw(self) as *mut T) })
63 } else {
64 Err(self)
65 }
66 }
67
68 pub fn downcast_arc_pin_box<T>(self: ArcPinBox<Self>) -> Result<ArcPinBox<T>, ArcPinBox<Self>>
69 where
70 T: 'static,
71 {
72 if self.is::<T>() {
73 Ok(unsafe { Arc::from_raw(Arc::into_raw(self) as *mut Pin<Box<T>>) })
74 } else {
75 Err(self)
76 }
77 }
78}
79
80pub struct InterfaceInfo {
81 pub type_: String,
82}
83
84pub trait HandleFactory {
85 fn version(&self) -> u32;
87 fn name(&self) -> &str;
88 fn info(&self) -> Option<&Dict>;
89
90 fn init(
92 &self,
93 info: Option<Dict>,
94 support: &super::Support,
95 ) -> std::io::Result<Box<dyn Handle + Send + Sync>>;
96 fn enum_interface_info(&self) -> Vec<InterfaceInfo>;
97}
98
99pub trait Handle {
100 fn version(&self) -> u32;
102
103 fn get_interface(&self, type_: &str) -> Option<Box<dyn Interface>>;
109}