tuio_rs/
osc_receiver.rs

1use std::{
2    net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket},
3    sync::{
4        Arc,
5    }, error::Error,
6};
7
8use rosc::{OscPacket};
9
10use crate::errors::OscReceiverError;
11
12/// Base trait to implement receiving OSC over various transport methods
13pub trait OscReceiver<P, E: Error> {
14    /// Returns a true if the connection is established
15    fn is_connected(&self) -> bool;
16
17    /// Establishes connection
18    fn connect(&self) -> Result<(), std::io::Error>;
19
20    /// Stops connection
21    fn disconnect(&self);
22
23    /// Receives a single OSC packet.
24    fn recv(&self) -> Result<P, E>;
25}
26
27pub struct UdpReceiver {
28    socket: Arc<UdpSocket>
29}
30
31impl UdpReceiver {
32    /// Creates an [UdpReceiver] binded to the port 3333
33    pub fn new() -> Result<Self, std::io::Error> {
34        Self::from_port(3333)
35    }
36    
37    /// Creates an [UdpReceiver] binded to the provided port
38    pub fn from_port(port: u16) -> Result<Self, std::io::Error> {
39        Ok(Self {
40            socket: Arc::new(UdpSocket::bind(SocketAddr::new(
41                IpAddr::V4(Ipv4Addr::LOCALHOST),
42                port,
43            ))?)
44        })
45    }
46}
47
48pub type RoscReceiver = dyn OscReceiver<OscPacket, OscReceiverError> + Send + Sync;
49
50impl OscReceiver<OscPacket, OscReceiverError> for UdpReceiver {
51    fn connect(&self) -> Result<(), std::io::Error> {
52        Ok(())
53    }
54
55    fn disconnect(&self) {}
56
57    /// Always returns true because UDP is connectionless
58    fn is_connected(&self) -> bool {
59        true
60    }
61
62    fn recv(&self) -> Result<OscPacket, OscReceiverError> {
63        let mut buf = [0u8; rosc::decoder::MTU];
64
65        let (size, _) = self.socket.recv_from(&mut buf).map_err(OscReceiverError::Receive)?;
66        let (_, packet) = rosc::decoder::decode_udp(&buf[..size]).map_err(OscReceiverError::Decode)?;
67
68        Ok(packet)
69    }
70}