clack_common/events/io/
implementation.rs1use crate::events::io::TryPushError;
2use crate::events::spaces::CoreEventSpace;
3use crate::events::{Event, UnknownEvent};
4use crate::utils::{handle_panic, usize_to_clap_size};
5use clap_sys::events::{clap_event_header, clap_input_events, clap_output_events};
6
7#[allow(clippy::len_without_is_empty)] pub trait InputEventBuffer: Sized {
16 fn len(&self) -> u32;
18 fn get(&self, index: u32) -> Option<&UnknownEvent>;
22}
23
24pub trait OutputEventBuffer: Sized {
32 fn try_push(&mut self, event: &UnknownEvent) -> Result<(), TryPushError>;
39}
40
41pub(crate) const fn raw_input_events<I: InputEventBuffer>(buffer: &I) -> clap_input_events {
42 clap_input_events {
43 ctx: buffer as *const I as *mut I as *mut _,
44 size: Some(size::<I>),
45 get: Some(get::<I>),
46 }
47}
48
49pub(crate) const fn raw_output_events<I: OutputEventBuffer>(buffer: &mut I) -> clap_output_events {
50 clap_output_events {
51 ctx: buffer as *mut _ as *mut _,
52 try_push: Some(try_push::<I>),
53 }
54}
55
56pub(crate) const fn void_output_events() -> clap_output_events {
57 clap_output_events {
58 ctx: core::ptr::null_mut(),
59 try_push: Some(void_push),
60 }
61}
62
63#[inline]
70unsafe fn get_input_buffer<'a, I: InputEventBuffer>(
71 input_events: *const clap_input_events,
72) -> &'a I {
73 let ctx = unsafe { (*input_events).ctx };
75 let buf_impl: *mut I = ctx.cast();
76 unsafe { &*buf_impl }
78}
79
80#[allow(clippy::missing_safety_doc)]
81unsafe extern "C" fn size<I: InputEventBuffer>(list: *const clap_input_events) -> u32 {
82 handle_panic(|| {
83 let buf = unsafe { get_input_buffer(list) };
85 I::len(buf)
86 })
87 .unwrap_or(0)
88}
89
90#[allow(clippy::missing_safety_doc)]
91unsafe extern "C" fn get<I: InputEventBuffer>(
92 list: *const clap_input_events,
93 index: u32,
94) -> *const clap_event_header {
95 handle_panic(|| {
96 let buf = unsafe { get_input_buffer(list) };
98 I::get(buf, index)
99 .map(|e| e.as_raw() as *const _)
100 .unwrap_or_else(core::ptr::null)
101 })
102 .unwrap_or(core::ptr::null())
103}
104
105#[inline]
112unsafe fn get_output_buffer<'a, O: OutputEventBuffer>(
113 output_events: *const clap_output_events,
114) -> &'a mut O {
115 let ctx = unsafe { (*output_events).ctx };
117 let buf_impl: *mut O = ctx.cast();
118 unsafe { &mut *buf_impl }
120}
121
122#[allow(clippy::missing_safety_doc)]
123unsafe extern "C" fn try_push<O: OutputEventBuffer>(
124 list: *const clap_output_events,
125 event: *const clap_event_header,
126) -> bool {
127 handle_panic(|| {
128 let buf = unsafe { get_output_buffer(list) };
130 let event = unsafe { UnknownEvent::from_raw(event) };
132
133 O::try_push(buf, event).is_ok()
134 })
135 .unwrap_or(false)
136}
137
138#[allow(clippy::missing_safety_doc)]
139unsafe extern "C" fn void_push(
140 _list: *const clap_output_events,
141 _event: *const clap_event_header,
142) -> bool {
143 true
144}
145
146impl InputEventBuffer for () {
147 #[inline]
148 fn len(&self) -> u32 {
149 0
150 }
151
152 #[inline]
153 fn get(&self, _index: u32) -> Option<&UnknownEvent> {
154 None
155 }
156}
157
158impl<T: Event> InputEventBuffer for T {
159 #[inline]
160 fn len(&self) -> u32 {
161 1
162 }
163
164 #[inline]
165 fn get(&self, index: u32) -> Option<&UnknownEvent> {
166 match index {
167 0 => Some(self.as_unknown()),
168 _ => None,
169 }
170 }
171}
172
173impl<T: InputEventBuffer, U: InputEventBuffer> InputEventBuffer for (&T, &U) {
174 #[inline]
175 fn len(&self) -> u32 {
176 self.0.len() + self.1.len()
177 }
178
179 #[inline]
180 fn get(&self, index: u32) -> Option<&UnknownEvent> {
181 let first_len = self.0.len();
182 if index < first_len {
183 self.0.get(index)
184 } else {
185 self.1.get(index - first_len)
187 }
188 }
189}
190
191impl<T: Event, const N: usize> InputEventBuffer for [T; N] {
192 #[inline]
193 fn len(&self) -> u32 {
194 const { usize_to_clap_size(N) }
195 }
196
197 #[inline]
198 fn get(&self, index: u32) -> Option<&UnknownEvent> {
199 self.as_slice().get(index as usize).map(|e| e.as_unknown())
200 }
201}
202
203impl<T: Event> InputEventBuffer for &[T] {
204 #[inline]
205 fn len(&self) -> u32 {
206 let len = <[T]>::len(self);
207 usize_to_clap_size(len)
208 }
209
210 #[inline]
211 fn get(&self, index: u32) -> Option<&UnknownEvent> {
212 <[T]>::get(self, index as usize).map(|e| e.as_unknown())
213 }
214}
215
216impl<T: Event> InputEventBuffer for Vec<T> {
217 #[inline]
218 fn len(&self) -> u32 {
219 let len = <[T]>::len(self);
220 usize_to_clap_size(len)
221 }
222
223 #[inline]
224 fn get(&self, index: u32) -> Option<&UnknownEvent> {
225 <[T]>::get(self, index as usize).map(|e| e.as_unknown())
226 }
227}
228
229impl InputEventBuffer for &UnknownEvent {
230 #[inline]
231 fn len(&self) -> u32 {
232 1
233 }
234
235 #[inline]
236 fn get(&self, index: u32) -> Option<&UnknownEvent> {
237 match index {
238 0 => Some(self),
239 _ => None,
240 }
241 }
242}
243
244impl<const N: usize> InputEventBuffer for [&UnknownEvent; N] {
245 #[inline]
246 fn len(&self) -> u32 {
247 const { usize_to_clap_size(N) }
248 }
249
250 #[inline]
251 fn get(&self, index: u32) -> Option<&UnknownEvent> {
252 self.as_slice().get(index as usize).copied()
253 }
254}
255
256impl InputEventBuffer for &[&UnknownEvent] {
257 #[inline]
258 fn len(&self) -> u32 {
259 let len = <[&UnknownEvent]>::len(self);
260 usize_to_clap_size(len)
261 }
262
263 #[inline]
264 fn get(&self, index: u32) -> Option<&UnknownEvent> {
265 <[&UnknownEvent]>::get(self, index as usize).copied()
266 }
267}
268
269impl InputEventBuffer for Vec<&UnknownEvent> {
270 #[inline]
271 fn len(&self) -> u32 {
272 let len = <[&UnknownEvent]>::len(self);
273 usize_to_clap_size(len)
274 }
275
276 #[inline]
277 fn get(&self, index: u32) -> Option<&UnknownEvent> {
278 <[&UnknownEvent]>::get(self, index as usize).copied()
279 }
280}
281
282impl<T: InputEventBuffer> InputEventBuffer for Option<T> {
283 #[inline]
284 fn len(&self) -> u32 {
285 match self {
286 Some(b) => b.len(),
287 None => 0,
288 }
289 }
290
291 #[inline]
292 fn get(&self, index: u32) -> Option<&UnknownEvent> {
293 match self {
294 None => None,
295 Some(b) => b.get(index),
296 }
297 }
298}
299
300impl<'a, T: Event<EventSpace<'a> = CoreEventSpace<'a>> + Clone> OutputEventBuffer for Option<T> {
301 fn try_push(&mut self, event: &UnknownEvent) -> Result<(), TryPushError> {
302 if self.is_some() {
303 return Err(TryPushError);
304 };
305
306 if let Some(event) = event.as_event::<T>() {
307 *self = Some(event.clone());
308 Ok(())
309 } else {
310 Err(TryPushError)
311 }
312 }
313}
314
315impl<'a, T: Event<EventSpace<'a> = CoreEventSpace<'a>> + Clone> OutputEventBuffer for Vec<T> {
316 fn try_push(&mut self, event: &UnknownEvent) -> Result<(), TryPushError> {
317 if let Some(event) = event.as_event::<T>() {
318 self.push(event.clone());
319 Ok(())
320 } else {
321 Err(TryPushError)
322 }
323 }
324}