1mod endpoints;
4
5pub use endpoints::{
6 event::{InputEvent, OutputEvent},
7 stream::{InputStream, OutputStream},
8 value::{InputValue, OutputValue},
9 Endpoint,
10};
11use {
12 crate::{
13 endpoint::{EndpointHandle, EndpointInfo},
14 ffi::PerformerPtr,
15 performer::endpoints::{
16 event::{fetch_events, post_event},
17 stream::{read_stream, write_stream, StreamType},
18 value::{GetOutputValue, SetInputValue},
19 },
20 value::{StringHandle, ValueRef},
21 },
22 sealed::sealed,
23 std::collections::HashMap,
24};
25
26pub struct Performer {
28 ptr: PerformerPtr,
29 endpoints: HashMap<EndpointHandle, EndpointInfo>,
30 buffer: Vec<u8>,
31 console: Option<Endpoint<OutputEvent>>,
32}
33
34impl Performer {
35 pub(crate) fn new(
36 performer: PerformerPtr,
37 endpoints: HashMap<EndpointHandle, EndpointInfo>,
38 console: Option<Endpoint<OutputEvent>>,
39 ) -> Self {
40 let size_of_largest_type = endpoints
41 .values()
42 .flat_map(|endpoint| endpoint.types().iter().map(|ty| ty.size()).max())
43 .max()
44 .unwrap_or(0);
45
46 Performer {
47 ptr: performer,
48 endpoints,
49 buffer: vec![0; size_of_largest_type],
50 console,
51 }
52 }
53}
54
55impl Performer {
56 pub fn set_block_size(&mut self, num_frames: u32) {
58 self.ptr.set_block_size(num_frames);
59 }
60
61 pub fn advance(&mut self) {
63 self.ptr.advance();
64
65 if let Some(console) = self.console {
66 let _ = fetch_events(self, console, |_, value| match value {
67 ValueRef::String(StringHandle(handle)) => {
68 println!("{}", self.ptr.get_string_for_handle(handle).unwrap_or("?"));
69 }
70 value => println!("{value:?}"),
71 });
72 }
73 }
74
75 pub fn endpoint_info<T>(&self, Endpoint(endpoint): Endpoint<T>) -> Option<&EndpointInfo>
77 where
78 T: EndpointType,
79 {
80 self.endpoints.get(&endpoint.handle())
81 }
82
83 pub fn set<T>(&mut self, endpoint: Endpoint<InputValue<T>>, value: T) -> T::Output
85 where
86 T: SetInputValue,
87 {
88 SetInputValue::set_input_value(self, endpoint, value)
89 }
90
91 pub fn get<T>(&mut self, endpoint: Endpoint<OutputValue<T>>) -> T::Output<'_>
93 where
94 T: GetOutputValue,
95 {
96 T::get_output_value(self, endpoint)
97 }
98
99 pub fn post<'a>(
101 &mut self,
102 endpoint: Endpoint<InputEvent>,
103 event: impl Into<ValueRef<'a>>,
104 ) -> Result<(), EndpointError> {
105 post_event(self, endpoint, event.into())
106 }
107
108 pub fn fetch(
110 &mut self,
111 endpoint: Endpoint<OutputEvent>,
112 callback: impl FnMut(usize, ValueRef<'_>),
113 ) -> Result<(), EndpointError> {
114 fetch_events(self, endpoint, callback)
115 }
116
117 pub fn read<T>(&self, endpoint: Endpoint<OutputStream<T>>, buffer: &mut [T])
119 where
120 T: StreamType,
121 {
122 read_stream(self, endpoint, buffer)
123 }
124
125 pub fn write<T>(&self, endpoint: Endpoint<InputStream<T>>, buffer: &[T])
127 where
128 T: StreamType,
129 {
130 write_stream(self, endpoint, buffer)
131 }
132
133 pub fn get_xruns(&self) -> usize {
135 self.ptr.get_xruns()
136 }
137
138 pub fn get_max_block_size(&self) -> u32 {
140 self.ptr.get_max_block_size()
141 }
142
143 pub fn get_latency(&self) -> f64 {
145 self.ptr.get_latency()
146 }
147
148 pub fn get_string(&self, StringHandle(value): StringHandle) -> Option<&str> {
150 self.ptr.get_string_for_handle(value)
151 }
152}
153
154#[derive(Debug, thiserror::Error)]
156pub enum EndpointError {
157 #[error("no such endpoint")]
159 EndpointDoesNotExist,
160
161 #[error("direction mismatch")]
163 DirectionMismatch,
164
165 #[error("type mismatch")]
167 EndpointTypeMismatch,
168
169 #[error("data type mismatch")]
171 DataTypeMismatch,
172}
173
174#[doc(hidden)]
175#[sealed(pub(crate))]
176pub trait EndpointType {
177 fn make(
178 handle: EndpointHandle,
179 endpoint: EndpointInfo,
180 ) -> Result<Endpoint<Self>, EndpointError>
181 where
182 Self: Sized;
183
184 fn handle(&self) -> EndpointHandle;
185}