PC Music Generator - a Virtual Modular Synthesizer
at main 172 lines 3.9 kB view raw
1use std::{ 2 collections::{ 3 BTreeMap, 4 VecDeque, 5 }, 6 fs, 7 path::Path, 8 sync::Arc, 9}; 10 11use devices::description::DeviceKind; 12use egui::{ 13 Context, 14 DragValue, 15 Pos2, 16 Ui, 17 Vec2, 18 Window, 19}; 20use serde::{ 21 Deserialize, 22 Deserializer, 23 Serialize, 24 Serializer, 25}; 26use uuid::Uuid; 27use visuals::templates::WidgetTemplate; 28 29pub mod container; 30pub mod devices; 31pub mod graph; 32pub mod module_description; 33pub mod visuals; 34pub mod widgets; 35 36pub fn widget_prefabs( 37 path: impl AsRef<Path>, 38) -> Result<BTreeMap<Uuid, WidgetTemplate>, Box<dyn std::error::Error>> { 39 fs::read_to_string(path).map_err(Into::into).and_then(|s| { 40 let prefabs = serde_yaml::from_str(&s)?; 41 Ok(prefabs) 42 }) 43} 44 45pub fn widget_name(uuid: Option<Uuid>, widgets: &BTreeMap<Uuid, WidgetTemplate>) -> String { 46 if let Some(uuid) = uuid { 47 format!("{}: {}", uuid, widgets[&uuid].name) 48 } else { 49 "None".into() 50 } 51} 52 53pub fn pos_drag_value(ui: &mut Ui, label: impl AsRef<str>, pos: &mut Pos2) { 54 two_drag_value(ui, label.as_ref(), "X", "Y", &mut pos.x, &mut pos.y) 55} 56 57pub fn vec_drag_value(ui: &mut Ui, label: impl AsRef<str>, vec: &mut Vec2) { 58 two_drag_value(ui, label.as_ref(), "X", "Y", &mut vec.x, &mut vec.y) 59} 60 61pub fn two_drag_value( 62 ui: &mut Ui, 63 label: impl AsRef<str>, 64 l1: impl AsRef<str>, 65 l2: impl AsRef<str>, 66 v1: &mut f32, 67 v2: &mut f32, 68) { 69 ui.horizontal(|ui| { 70 ui.label(label.as_ref()); 71 ui.label(l1.as_ref()); 72 ui.add(DragValue::new(v1)); 73 ui.label(l2.as_ref()); 74 ui.add(DragValue::new(v2)); 75 }); 76} 77 78pub fn error_window(error: &mut Option<Box<dyn std::error::Error>>, ctx: &Context) { 79 Window::new("Error").resizable(false).show(ctx, |ui| { 80 ui.vertical_centered(|ui| { 81 ui.label(error.as_ref().unwrap().to_string()); 82 if ui.button("Ok").clicked() { 83 error.take(); 84 } 85 }) 86 }); 87} 88 89fn ser_btree_as_vec<S, T>(map: &BTreeMap<usize, T>, ser: S) -> Result<S::Ok, S::Error> 90where 91 S: Serializer, 92 T: Serialize, 93{ 94 map.values().collect::<Vec<_>>().serialize(ser) 95} 96 97fn de_vec_as_btree<'de, D, T>(de: D) -> Result<BTreeMap<usize, T>, D::Error> 98where 99 D: Deserializer<'de>, 100 T: Deserialize<'de>, 101{ 102 let vec: Vec<T> = Vec::deserialize(de)?; 103 Ok(vec.into_iter().enumerate().collect()) 104} 105 106pub fn ser_device_description<S>(dd: &usize, ser: S) -> Result<S::Ok, S::Error> 107where 108 S: Serializer, 109{ 110 DeviceKind::Audio(*dd).name().serialize(ser) 111} 112 113pub fn de_device_description<'de, D>(de: D) -> Result<usize, D::Error> 114where 115 D: Deserializer<'de>, 116 D::Error: serde::de::Error, 117{ 118 let s = String::deserialize(de)?; 119 120 devices::DEVICES 121 .iter() 122 .enumerate() 123 .find_map(|(id, dd)| if dd.name == s { Some(id) } else { None }) 124 .ok_or(serde::de::Error::custom(format!( 125 "{s} is not a known device name, I only know these devices: {:?}", 126 DeviceKind::all() 127 .iter() 128 .map(DeviceKind::name) 129 .collect::<Vec<_>>() 130 ))) 131} 132pub struct STQueue<T> { 133 inner: Arc<eframe::epaint::mutex::Mutex<VecDeque<T>>>, 134} 135 136impl<T> Clone for STQueue<T> { 137 fn clone(&self) -> Self { 138 Self { 139 inner: Arc::clone(&self.inner), 140 } 141 } 142} 143 144impl<T> STQueue<T> { 145 pub fn new() -> Self { 146 Self { 147 inner: Default::default(), 148 } 149 } 150 151 pub fn put(&self, msg: T) { 152 self.inner.lock().push_front(msg) 153 } 154 155 pub fn get(&self) -> Option<T> { 156 self.inner.lock().pop_back() 157 } 158} 159 160impl<T> Default for STQueue<T> { 161 fn default() -> Self { 162 Self::new() 163 } 164} 165 166pub trait Uuidentified { 167 fn uuid(&self) -> Uuid; 168} 169 170pub trait Tooltipable { 171 fn tooltip(&self) -> String; 172}