five_five_five/src/controller.rs

183 lines
5.1 KiB
Rust

/// No I/O, no blocking, no threads. One state machine that controls
/// everything.
use std::
{
time::Instant,
};
pub enum MsgFromController
{
RepaintGui (RgbaFrame),
StartJpegDecoder (JpegFrame),
StartNetworkSend (JpegFrame),
StartCapture,
}
#[derive (Clone)]
pub struct JpegFrame
{
pub data: Vec <u8>,
pub capture_time: Instant,
}
#[derive (Clone)]
pub struct RgbaFrame
{
pub data: Vec <u8>,
pub capture_time: Instant,
}
pub struct Controller
{
gui_has_new_frame: bool,
gui_needs_frame: bool,
jpeg_decoder_is_running: bool,
jpeg_decoder_has_new_frame: bool,
jpeg_decoder_needs_frame: bool,
network_send_is_running: bool,
network_send_has_new_frame: bool,
network_send_needs_frame: bool,
capture_is_running: bool,
rgba_frame: RgbaFrame,
jpeg_frame: JpegFrame,
}
impl Controller
{
pub fn new (now: Instant) -> Self
{
Self
{
gui_has_new_frame: false,
gui_needs_frame: false,
jpeg_decoder_has_new_frame: false,
jpeg_decoder_is_running: false,
jpeg_decoder_needs_frame: false,
network_send_has_new_frame: false,
network_send_is_running: false,
network_send_needs_frame: true,
capture_is_running: false,
rgba_frame: RgbaFrame
{
data: Default::default (),
capture_time: now,
},
jpeg_frame: JpegFrame
{
data: Default::default (),
capture_time: now,
},
}
}
pub fn handle_gui_needs_frame (&mut self)
{
// println! ("handle_gui_needs_frame");
self.gui_needs_frame = true;
}
pub fn handle_network_write_needs_frame (&mut self)
{
println! ("handle_network_write_needs_frame");
self.network_send_needs_frame = true;
}
pub fn handle_network_write_finished (&mut self)
{
println! ("handle_network_write_finished");
self.network_send_has_new_frame = false;
self.network_send_is_running = false;
}
pub fn handle_rgba_frame (&mut self, frame: RgbaFrame)
{
// println! ("handle_rgba_frame");
self.gui_has_new_frame = true;
self.jpeg_decoder_is_running = false;
self.jpeg_decoder_has_new_frame = false;
self.rgba_frame = frame;
}
pub fn handle_capture (&mut self, jpeg: JpegFrame)
{
// println! ("handle_capture");
self.capture_is_running = false;
self.jpeg_frame = jpeg;
self.jpeg_decoder_has_new_frame = true;
self.network_send_has_new_frame = true;
}
pub fn poll (&mut self) -> Option <MsgFromController>
{
let capture_for_jpeg_decoder = self.jpeg_decoder_needs_frame && ! self.jpeg_decoder_has_new_frame;
let capture_for_network_send = self.network_send_needs_frame && ! self.network_send_has_new_frame;
if self.gui_needs_frame && self.gui_has_new_frame
{
self.gui_has_new_frame = false;
self.gui_needs_frame = false;
// println! ("RepaintGui");
Some (MsgFromController::RepaintGui (self.rgba_frame.clone ()))
}
else if self.jpeg_decoder_has_new_frame && ! self.jpeg_decoder_is_running && self.jpeg_decoder_needs_frame
{
self.jpeg_decoder_is_running = true;
self.jpeg_decoder_needs_frame = false;
// println! ("StartJpegDecoder");
Some (MsgFromController::StartJpegDecoder (self.jpeg_frame.clone ()))
}
else if self.network_send_has_new_frame && ! self.network_send_is_running && self.network_send_needs_frame
{
self.network_send_is_running = true;
self.network_send_needs_frame = false;
Some (MsgFromController::StartNetworkSend (self.jpeg_frame.clone ()))
}
else if (capture_for_jpeg_decoder || capture_for_network_send) && ! self.capture_is_running
{
self.capture_is_running = true;
// println! ("StartCapture");
Some (MsgFromController::StartCapture)
}
else if self.gui_needs_frame && ! self.gui_has_new_frame
{
self.jpeg_decoder_needs_frame = true;
None
}
else
{
None
}
}
pub fn to_json (&self, start_time: Instant) -> serde_json::Value {
serde_json::json! ({
"gui_has_new_frame": self.gui_has_new_frame,
"gui_needs_frame": self.gui_needs_frame,
"jpeg_decoder_is_running": self.jpeg_decoder_is_running,
"jpeg_decoder_has_new_frame": self.jpeg_decoder_has_new_frame,
"jpeg_decoder_needs_frame": self.jpeg_decoder_needs_frame,
"network_send_is_running": self.network_send_is_running,
"network_send_has_new_frame": self.network_send_has_new_frame,
"network_send_needs_frame": self.network_send_needs_frame,
"capture_is_running": self.capture_is_running,
"rgba_frame_capture_time": (self.rgba_frame.capture_time - start_time).as_millis (),
"jpeg_frame_capture_time": (self.jpeg_frame.capture_time - start_time).as_millis (),
})
}
}