use std::{
io::Write,
net::TcpListener,
sync::mpsc::{self, Sender},
};
pub mod data;
pub mod friendly;
use data::TelemetryFrame;
use std::thread;
struct State {
new_frame: Option<TelemetryFrame>,
running: bool,
}
pub struct SerialStudioSource {
running: bool,
chan_to_thread: Option<Sender<State>>,
}
impl SerialStudioSource {
pub fn new() -> Self {
Self {
running: false,
chan_to_thread: None,
}
}
pub fn start(&mut self, bind_addr: String) {
let (tx, rx) = mpsc::channel();
self.chan_to_thread = Some(tx);
let _ = self
.chan_to_thread
.as_ref()
.unwrap()
.send(State {
new_frame: None,
running: true,
})
.unwrap();
self.running = true;
thread::spawn(move || {
let listener = TcpListener::bind(bind_addr).unwrap();
loop {
println!("Waiting for a SerialStudio session to attach");
let stream = listener.accept();
if stream.is_ok() {
let mut stream = stream.unwrap();
println!("Connection established!");
loop {
let new_data: State = rx.recv().unwrap();
if !new_data.running {
return;
}
if new_data.new_frame.is_some() {
let obj = new_data.new_frame.unwrap();
let json = serde_json::to_string(&obj).unwrap();
let result = stream.0.write(format!("/*{}*/\n", json).as_bytes());
if result.is_err() {
println!("Failed to write telemetry update over TCP");
break;
}
}
}
}
println!("SerialStudio disconnected");
}
});
}
pub fn stop(&mut self) {
self.running = false;
let _ = self
.chan_to_thread
.as_ref()
.unwrap()
.send(State {
new_frame: None,
running: false,
})
.unwrap();
}
pub fn publish(&mut self, frame: TelemetryFrame) {
if self.running && self.chan_to_thread.is_some() {
let _ = self
.chan_to_thread
.as_ref()
.unwrap()
.send(State {
new_frame: Some(frame),
running: true,
})
.unwrap();
}
}
}