diff options
Diffstat (limited to 'src/osc.rs')
| -rw-r--r-- | src/osc.rs | 60 |
1 files changed, 31 insertions, 29 deletions
@@ -1,11 +1,6 @@ use std::net::UdpSocket; -use rosc::{OscMessage, OscPacket, OscType}; - -pub enum OscCommand { - Shader(String), - Uniform { path: String, args: Vec<OscType> }, -} +use rosc::{OscMessage, OscPacket}; pub struct OscServer { socket: UdpSocket, @@ -23,15 +18,19 @@ impl OscServer { }) } - pub fn poll(&mut self, mut on_command: impl FnMut(OscCommand)) { + /// Drains all pending OSC messages, calling `on_message` for each. + /// Returns `true` if any messages were dispatched. + pub fn poll(&mut self, mut on_message: impl FnMut(OscMessage)) -> bool { + let mut received = false; loop { match self.socket.recv_from(&mut self.buf) { Ok((size, _addr)) => { let data = &self.buf[..size]; match rosc::decoder::decode_udp(data) { - Ok((_, packet)) => dispatch(packet, &mut on_command), + Ok((_, packet)) => dispatch(packet, &mut on_message), Err(e) => log::warn!("OSC decode error: {}", e), } + received = true; } Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break, Err(e) => { @@ -40,34 +39,37 @@ impl OscServer { } } } + received } -} -fn dispatch(packet: OscPacket, on_command: &mut impl FnMut(OscCommand)) { - match packet { - OscPacket::Message(msg) => dispatch_message(msg, on_command), - OscPacket::Bundle(bundle) => { - for p in bundle.content { - dispatch(p, on_command); + /// Blocks until at least one OSC message arrives, then drains all pending. + pub fn recv(&mut self, mut on_message: impl FnMut(OscMessage)) -> bool { + self.socket.set_nonblocking(false).expect("set blocking"); + match self.socket.recv_from(&mut self.buf) { + Ok((size, _addr)) => { + let data = &self.buf[..size]; + match rosc::decoder::decode_udp(data) { + Ok((_, packet)) => dispatch(packet, &mut on_message), + Err(e) => log::warn!("OSC decode error: {}", e), + } + } + Err(e) => { + log::warn!("OSC recv error: {}", e); } } + self.socket.set_nonblocking(true).expect("set nonblocking"); + self.poll(on_message); + true } } -fn dispatch_message(msg: OscMessage, on_command: &mut impl FnMut(OscCommand)) { - let path = &msg.addr; - - if path == "/shader" { - match &msg.args[..] { - [OscType::String(code)] => on_command(OscCommand::Shader(code.clone())), - _ => log::warn!("/shader: expected single string argument"), +fn dispatch(packet: OscPacket, on_message: &mut impl FnMut(OscMessage)) { + match packet { + OscPacket::Message(msg) => on_message(msg), + OscPacket::Bundle(bundle) => { + for p in bundle.content { + dispatch(p, on_message); + } } - } else if let Some(rest) = path.strip_prefix("/uniform/") { - on_command(OscCommand::Uniform { - path: rest.to_string(), - args: msg.args, - }); - } else { - log::debug!("unhandled OSC message: {}", path); } } |
