wavecraft_dev_server/
host.rs1#[cfg(feature = "audio")]
9use std::sync::Arc;
10use wavecraft_bridge::{BridgeError, InMemoryParameterHost, ParameterHost};
11use wavecraft_protocol::{MeterFrame, ParameterInfo};
12
13#[cfg(feature = "audio")]
14use crate::audio::atomic_params::AtomicParameterBridge;
15
16pub struct DevServerHost {
28 inner: InMemoryParameterHost,
29 #[cfg(feature = "audio")]
30 param_bridge: Option<Arc<AtomicParameterBridge>>,
31}
32
33impl DevServerHost {
34 #[cfg_attr(feature = "audio", allow(dead_code))]
43 pub fn new(parameters: Vec<ParameterInfo>) -> Self {
44 let inner = InMemoryParameterHost::new(parameters);
45
46 Self {
47 inner,
48 #[cfg(feature = "audio")]
49 param_bridge: None,
50 }
51 }
52
53 #[cfg(feature = "audio")]
58 pub fn with_param_bridge(
59 parameters: Vec<ParameterInfo>,
60 bridge: Arc<AtomicParameterBridge>,
61 ) -> Self {
62 let inner = InMemoryParameterHost::new(parameters);
63
64 Self {
65 inner,
66 param_bridge: Some(bridge),
67 }
68 }
69
70 pub fn replace_parameters(&self, new_params: Vec<ParameterInfo>) -> Result<(), String> {
81 self.inner.replace_parameters(new_params)
82 }
83}
84
85impl ParameterHost for DevServerHost {
86 fn get_parameter(&self, id: &str) -> Option<ParameterInfo> {
87 self.inner.get_parameter(id)
88 }
89
90 fn set_parameter(&self, id: &str, value: f32) -> Result<(), BridgeError> {
91 let result = self.inner.set_parameter(id, value);
92
93 #[cfg(feature = "audio")]
95 if result.is_ok() && let Some(ref bridge) = self.param_bridge {
96 bridge.write(id, value);
97 }
98
99 result
100 }
101
102 fn get_all_parameters(&self) -> Vec<ParameterInfo> {
103 self.inner.get_all_parameters()
104 }
105
106 fn get_meter_frame(&self) -> Option<MeterFrame> {
107 None
110 }
111
112 fn request_resize(&self, _width: u32, _height: u32) -> bool {
113 self.inner.request_resize(_width, _height)
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120 use wavecraft_protocol::ParameterType;
121
122 fn test_params() -> Vec<ParameterInfo> {
123 vec![
124 ParameterInfo {
125 id: "gain".to_string(),
126 name: "Gain".to_string(),
127 param_type: ParameterType::Float,
128 value: 0.5,
129 default: 0.5,
130 unit: Some("dB".to_string()),
131 group: Some("Input".to_string()),
132 },
133 ParameterInfo {
134 id: "mix".to_string(),
135 name: "Mix".to_string(),
136 param_type: ParameterType::Float,
137 value: 1.0,
138 default: 1.0,
139 unit: Some("%".to_string()),
140 group: None,
141 },
142 ]
143 }
144
145 #[test]
146 fn test_get_parameter() {
147 let host = DevServerHost::new(test_params());
148
149 let param = host.get_parameter("gain").expect("should find gain");
150 assert_eq!(param.id, "gain");
151 assert_eq!(param.name, "Gain");
152 assert!((param.value - 0.5).abs() < f32::EPSILON);
153 }
154
155 #[test]
156 fn test_get_parameter_not_found() {
157 let host = DevServerHost::new(test_params());
158 assert!(host.get_parameter("nonexistent").is_none());
159 }
160
161 #[test]
162 fn test_set_parameter() {
163 let host = DevServerHost::new(test_params());
164
165 host.set_parameter("gain", 0.75).expect("should set gain");
166
167 let param = host.get_parameter("gain").expect("should find gain");
168 assert!((param.value - 0.75).abs() < f32::EPSILON);
169 }
170
171 #[test]
172 fn test_set_parameter_invalid_id() {
173 let host = DevServerHost::new(test_params());
174 let result = host.set_parameter("invalid", 0.5);
175 assert!(result.is_err());
176 }
177
178 #[test]
179 fn test_set_parameter_out_of_range() {
180 let host = DevServerHost::new(test_params());
181
182 let result = host.set_parameter("gain", 1.5);
183 assert!(result.is_err());
184
185 let result = host.set_parameter("gain", -0.1);
186 assert!(result.is_err());
187 }
188
189 #[test]
190 fn test_get_all_parameters() {
191 let host = DevServerHost::new(test_params());
192
193 let params = host.get_all_parameters();
194 assert_eq!(params.len(), 2);
195 assert!(params.iter().any(|p| p.id == "gain"));
196 assert!(params.iter().any(|p| p.id == "mix"));
197 }
198
199 #[test]
200 fn test_get_meter_frame() {
201 let host = DevServerHost::new(test_params());
202 assert!(host.get_meter_frame().is_none());
204 }
205}