use std::{
io,
sync::mpsc::{self, Receiver},
thread,
};
use crate::core::{
osc_receiver::{OscReceiver, UdpOscReceiver},
processor::TuioProcessor,
};
pub struct Client<P: TuioProcessor> {
receiver: Box<dyn OscReceiver>,
processor: P,
}
impl<P: TuioProcessor> Client<P> {
pub fn new(receiver: impl OscReceiver + 'static) -> Self {
Self {
receiver: Box::new(receiver),
processor: P::default(),
}
}
pub fn spawn(receiver: impl OscReceiver + 'static) -> Receiver<P::Events>
where
P: Send + 'static,
{
let (tx, rx) = mpsc::channel();
let mut client: Client<P> = Client::new(receiver);
thread::spawn(move || {
loop {
let packet = match client.receiver.recv() {
Ok(packet) => packet,
Err(error) => {
log::error!("OSC receiver error: {error}");
break;
}
};
if let Some(events) = client.processor.update(packet)
&& tx.send(events).is_err()
{
break;
}
}
});
rx
}
pub fn update(&mut self) -> Result<P::Events, io::Error> {
let packet = self.receiver.recv()?;
self.processor.update(packet).ok_or(io::Error::new(
io::ErrorKind::InvalidData,
"No valid Tuio Bundle",
))
}
}
impl<P: TuioProcessor> Default for Client<P> {
fn default() -> Self {
Self::new(UdpOscReceiver::default())
}
}