/// 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 , pub capture_time: Instant, } #[derive (Clone)] pub struct RgbaFrame { pub data: Vec , 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 { 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 (), }) } }