This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

1extern crate env_logger; 2 3use crate::vst::probe::Datapoint; 4 5use super::Probe; 6use anyhow::Result; 7use once_cell::sync::Lazy; 8use std::sync::{Mutex, MutexGuard}; 9use tungstenite; 10 11const BEACON_PORT: u16 = 8080; 12 13#[inline] 14pub fn beacon_url() -> String { 15 return format!("ws://localhost:{BEACON_PORT}"); 16} 17 18pub fn connect_to_beacon() -> Result< 19 tungstenite::WebSocket< 20 tungstenite::stream::MaybeTlsStream<std::net::TcpStream>, 21 >, 22> { 23 println!("Connecting to beacon at {}", beacon_url()); 24 let (socket, _response) = tungstenite::connect(beacon_url())?; 25 Ok(socket) 26} 27 28#[derive(Default)] 29pub struct Beacon { 30 pub probes: Vec<Probe>, 31} 32 33static BEACON: Lazy<Mutex<Beacon>> = Lazy::new(|| Mutex::new(Beacon::new())); 34 35pub fn get_beacon() -> MutexGuard<'static, Beacon> { 36 return BEACON.lock().unwrap(); 37} 38 39impl Beacon { 40 pub fn new() -> Self { 41 return Self::default(); 42 } 43 44 pub fn start() -> Result<()> { 45 ws::listen(format!("127.0.0.1:{BEACON_PORT}"), |out| { 46 println!("Opening beacon connection with a probe..."); 47 move |msg| { 48 println!("Received message: {:?}", msg); 49 match msg { 50 ws::Message::Text(text) => match text.split3() { 51 ("?", "hi", probe_json) => { 52 match serde_json::from_str::<Probe>(probe_json) { 53 Ok(probe) => { 54 let mut beacon = get_beacon(); 55 beacon.probes.push(probe); 56 out.send("{} probe added!") 57 } 58 Err(_) => out.send("? invalid JSON :/"), 59 } 60 } 61 (id_str, "hi", probe_json) => { 62 match serde_json::from_str::<Probe>(probe_json) { 63 Ok(probe) => { 64 let mut beacon = get_beacon(); 65 let probe_index = 66 beacon.probes.iter().position(|p| { 67 p.id == id_str.parse::<u32>().unwrap() 68 }); 69 if let None = probe_index { 70 return out.send(format!( 71 "{} not found :/", 72 probe.id 73 )); 74 } 75 beacon.probes[probe_index.unwrap()] = probe; 76 out.send("{} probe added!") 77 } 78 Err(_) => out.send("? invalid JSON :/"), 79 } 80 } 81 (id_str, "byebye", "") => { 82 let id = id_str.parse::<u32>().unwrap(); 83 let mut beacon = get_beacon(); 84 let probe_index = beacon 85 .probes 86 .iter() 87 .position(|probe| probe.id == id); 88 match probe_index { 89 Some(probe_index) => { 90 let removed_probe = 91 beacon.probes.remove(probe_index); 92 out.send(format!( 93 "{} probe removed!", 94 removed_probe.id 95 )) 96 } 97 None => out.send(format!("{id} not found :/")), 98 } 99 } 100 ("*", "wtf", "") => { 101 let beacon = get_beacon(); 102 let body = 103 serde_json::to_string(&beacon.probes).unwrap(); 104 out.send(body) 105 } 106 (id_str, "wtf", "") => { 107 let id = id_str.parse::<u32>().unwrap(); 108 let beacon = get_beacon(); 109 let probe = 110 beacon.probes.iter().find(|probe| probe.id == id); 111 match probe { 112 Some(probe) => { 113 out.send(format!( 114 "probe {} with {} datapoints stored", 115 probe.id, 116 probe.datapoints.len() 117 ))?; 118 out.send( 119 serde_json::to_string(probe).unwrap(), 120 ) 121 } 122 None => out.send(format!("{id} not found :/")), 123 } 124 } 125 (id_str, "say", msg) => { 126 let id = id_str.parse::<u32>().unwrap(); 127 let beacon = get_beacon(); 128 let probe = 129 beacon.probes.iter().find(|probe| probe.id == id); 130 match probe { 131 Some(probe) => { 132 println!("probe {}: {}", probe.id, msg); 133 out.send("ok") 134 } 135 None => out.send(format!("{id} not found :/")), 136 } 137 } 138 (probe_id, timestamp, msg) => { 139 let id = probe_id.parse::<u32>().unwrap(); 140 let mut beacon = get_beacon(); 141 let probe = beacon 142 .probes 143 .iter_mut() 144 .find(|probe| probe.id == id); 145 146 if let None = probe { 147 return out.send(format!("{id} not found :/")); 148 } 149 150 let probe = probe.unwrap(); 151 let timestamp: usize = 152 timestamp.parse().expect(&format!( 153 "{timestamp} to be a number (timestamp)" 154 )); 155 156 match msg.split2() { 157 ("%", data) => match data.split2() { 158 (paramname, paramvalue) => { 159 probe.store(Datapoint::Automation( 160 timestamp, 161 paramname.parse().expect(&format!( 162 "{paramname} to be a number" 163 )), 164 paramvalue.parse().expect(&format!( 165 "{paramvalue} to be a number" 166 )), 167 )) 168 } 169 }, 170 ("#", data) => probe.store(Datapoint::Midi( 171 timestamp, 172 data.as_bytes().to_vec(), 173 )), 174 ("~", data) => probe.store(Datapoint::Audio( 175 timestamp, 176 data.split(' ') 177 .map(|f| f.parse().unwrap()) 178 .collect(), 179 )), 180 _ => { 181 return out.send("invalid command :/"); 182 } 183 } 184 185 out.send("gotchu!") 186 } 187 }, 188 ws::Message::Binary(_) => todo!(), 189 } 190 } 191 })?; 192 Ok(()) 193 } 194} 195 196trait FixedSplits { 197 fn split3(&self) -> (&str, &str, &str); 198 fn split2(&self) -> (&str, &str); 199} 200impl FixedSplits for str { 201 fn split3(&self) -> (&str, &str, &str) { 202 let mut parts = self.splitn(3, ' '); 203 let first = parts.next().unwrap_or_default(); 204 let second = parts.next().unwrap_or_default(); 205 let third = parts.next().unwrap_or_default(); 206 return (first, second, third); 207 } 208 209 fn split2(&self) -> (&str, &str) { 210 let mut parts = self.splitn(2, ' '); 211 let first = parts.next().unwrap_or_default(); 212 let second = parts.next().unwrap_or_default(); 213 return (first, second); 214 } 215}