pipewire_native/proxy/
link.rs1use std::sync::{Arc, Mutex, RwLock};
6
7use bitflags::bitflags;
8use pipewire_native_macros as macros;
9use pipewire_native_spa as spa;
10
11use crate::{
12 core::Core,
13 new_refcounted,
14 properties::Properties,
15 proxy::{HasProxy, Proxy},
16 refcounted, types, HookId, Id,
17};
18
19refcounted! {
20 pub struct Link {
22 proxy: RwLock<Option<Proxy<Link>>>,
23 hooks: Arc<Mutex<spa::hook::HookList<LinkEvents>>>,
24 }
25}
26
27bitflags! {
28 #[repr(C)]
30 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
31 pub struct LinkChangeMask : u32 {
32 const PROPS = (1 << 0);
34 }
35}
36
37#[repr(u32)]
38#[derive(Clone, Copy, Debug, Eq, PartialEq, macros::EnumU32)]
39pub enum LinkState {
41 Error,
43 Unlinked,
45 Init,
47 Negotiation,
49 Allocating,
51 Paused,
53 Active,
55}
56
57pub struct LinkInfo<'a> {
59 pub id: Id,
61 pub output_node_id: Id,
63 pub output_port_id: Id,
65 pub input_node_id: Id,
67 pub input_port_id: Id,
69 pub mask: LinkChangeMask,
71 pub state: LinkState,
73 pub error: Option<&'a str>,
75 pub format: Option<&'a spa::pod::RawPodOwned>,
77 pub props: &'a Properties,
79}
80
81#[allow(clippy::type_complexity)]
83#[derive(Default)]
84pub struct LinkEvents {
85 pub info: Option<Box<dyn FnMut(&LinkInfo<'_>) + Send>>,
87}
88
89impl HasProxy for Link {
90 fn type_(&self) -> types::ObjectType {
91 types::interface::LINK
92 }
93
94 fn version(&self) -> u32 {
95 3
96 }
97
98 fn proxy(&self) -> Proxy<Self> {
99 self.inner
100 .proxy
101 .read()
102 .unwrap()
103 .as_ref()
104 .expect("Link proxy should be initialised on creation")
105 .clone()
106 }
107}
108
109impl Link {
110 pub(crate) fn new(core: &Core) -> Self {
111 let this = Self {
112 inner: new_refcounted(InnerLink::new()),
113 };
114
115 let id = core.next_proxy_id();
116 this.inner
117 .proxy
118 .write()
119 .unwrap()
120 .replace(Proxy::new(id, &this));
121 core.add_proxy(&this, id);
122
123 this
124 }
125
126 pub fn add_listener(&self, events: LinkEvents) -> HookId {
128 self.inner.hooks.lock().unwrap().append(events)
129 }
130
131 pub fn remove_listener(&self, hook_id: HookId) {
133 self.inner.hooks.lock().unwrap().remove(hook_id);
134 }
135
136 pub(crate) fn events(&self) -> Arc<Mutex<spa::hook::HookList<LinkEvents>>> {
137 self.inner.hooks.clone()
138 }
139}
140
141impl InnerLink {
142 fn new() -> Self {
143 Self {
144 proxy: RwLock::new(None),
145 hooks: spa::hook::HookList::new(),
146 }
147 }
148}