From fdec833fd0015dc8268b1e5735f35671be443b03 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Sat, 9 Sep 2023 04:00:14 -0500 Subject: [PATCH] :shirt: refactor --- src/controller.rs | 295 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 288 ++------------------------------------------ 2 files changed, 307 insertions(+), 276 deletions(-) create mode 100644 src/controller.rs diff --git a/src/controller.rs b/src/controller.rs new file mode 100644 index 0000000..b62c28a --- /dev/null +++ b/src/controller.rs @@ -0,0 +1,295 @@ +use std::fmt; + +use thiserror::Error; + +#[derive (Default)] +pub struct Controller +{ + /// Pipeline for pulling data from the network, decoding it, + /// and displaying it. + + rx_pipe: RxPipeline, + + /// Pipeline for pulling data from capture devices, encoding it, + /// and sending it over the network. + + tx_pipe: TxPipeline, +} + +#[derive (Debug)] +pub struct ControlEvent +{ + pub rx: Option , + pub tx: Option , +} + +impl Controller +{ + pub fn handle_capture_frame (&mut self, buf_raw: BufRaw) + -> Result <(), ControlError> + { + self.tx_pipe.handle_capture_frame (buf_raw) + } + + pub fn handle_encoder_finished (&mut self) + { + self.tx_pipe.encoder_is_busy = false; + } + + pub fn handle_encoded_packet (&mut self, buf_enc: Option ) -> Result <(), ControlError> + { + self.tx_pipe.handle_encoded_packet (buf_enc) + } + + pub fn handle_network_busy (&mut self, x: bool) + { + self.tx_pipe.handle_network_busy (x) + } + + pub fn poll (&mut self) -> ControlEvent + { + let rx = self.rx_pipe.poll (); + let tx = self.tx_pipe.poll (); + + ControlEvent { + rx, + tx, + } + } +} + +#[derive (Default)] +struct RxPipeline +{ + buf_enc: Option , + buf_raw: Option , +} + +#[derive (Debug)] +pub enum RxPipelineEvent +{ + DisplayRaw (BufRaw), + Decode (BufEncoded), + Receive, +} + +#[derive (Debug, Error)] +enum RxPipeError +{ + #[error ("already have encoded data")] + AlreadyHaveEncodedData, + #[error ("already have raw data")] + AlreadyHaveRawData, +} + +impl RxPipeline +{ + + fn handle_encoder_polled (&mut self, has_data: bool) + { + + } + + fn handle_raw_frame (&mut self, buf_raw: BufRaw) -> Result <(), RxPipeError> + { + if self.has_raw_data () + { + return Err (RxPipeError::AlreadyHaveRawData); + } + + self.buf_raw = Some (buf_raw); + + Ok (()) + } + + fn poll (&mut self) -> Option + { + if let Some (buf_raw) = self.buf_raw.take () + { + return Some (RxPipelineEvent::DisplayRaw (buf_raw)); + } + + if ! self.has_raw_data () + { + if let Some (buf_enc) = self.buf_enc.take () + { + return Some (RxPipelineEvent::Decode (buf_enc)); + } + } + + if ! self.has_encoded_data () + { + return Some (RxPipelineEvent::Receive); + } + + None + } + + /// True if we have a buffer of received data, ready + /// to be decoded. + + fn has_encoded_data (&self) -> bool + { + self.buf_enc.is_some () + } + + fn has_raw_data (&self) -> bool + { + self.buf_raw.is_some () + } +} + +#[derive (Default)] +struct TxPipeline +{ + buf_enc: Option , + buf_raw: Option , + capture_is_busy: bool, + encoder_has_data: bool, + encoder_is_busy: bool, + network_busy: bool, +} + +#[derive (Debug)] +pub enum TxPipelineEvent +{ + /// Capture a raw frame and pass it to handle_capture_frame + Capture, + + /// Poll the encoder. If it returns a packet, pass it to + /// handle_encoded_packet. + PollEncoder, + + /// Encode this raw frame and pass the encoded frame to + /// handle_encoded_packet + Encode (BufRaw), + + /// Transmit this encoded frame to the network + Transmit (BufEncoded), +} + +impl TxPipeline +{ + fn handle_capture_frame (&mut self, buf_raw: BufRaw) + -> Result <(), ControlError> + { + self.capture_is_busy = false; + + if self.has_raw_frame () + { + return Err (ControlError::AlreadyHaveRawData); + } + + self.buf_raw = Some (buf_raw); + + Ok (()) + } + + fn handle_encoded_packet (&mut self, buf_enc: Option ) -> Result <(), ControlError> + { + self.encoder_has_data = buf_enc.is_some (); + let buf_enc = match buf_enc + { + None => return Ok (()), + Some (x) => x, + }; + + self.encoder_is_busy = false; + + if self.has_encoded_packet () + { + return Err (ControlError::AlreadyHaveEncodedData); + } + + self.buf_enc = Some (buf_enc); + + Ok (()) + } + + fn handle_network_busy (&mut self, busy: bool) + { + self.network_busy = busy; + } + + fn has_encoded_packet (&self) -> bool + { + self.buf_enc.is_some () + } + + fn has_raw_frame (&self) -> bool + { + self.buf_raw.is_some () + } + + fn poll (&mut self) -> Option + { + if ! self.network_busy + { + if let Some (buf_enc) = self.buf_enc.take () + { + return Some (TxPipelineEvent::Transmit (buf_enc)); + } + } + + if ! self.has_encoded_packet () && ! self.encoder_is_busy + { + if self.encoder_has_data + { + return Some (TxPipelineEvent::PollEncoder); + } + + if let Some (buf_raw) = self.buf_raw.take () + { + self.encoder_has_data = true; + self.encoder_is_busy = true; + return Some (TxPipelineEvent::Encode (buf_raw)); + } + } + + if ! self.has_raw_frame () + { + if ! self.capture_is_busy + { + self.capture_is_busy = true; + return Some (TxPipelineEvent::Capture); + } + } + + None + } +} + +pub struct BufEncoded +{ + pub buf: Vec +} + +impl fmt::Debug for BufEncoded { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f + .debug_struct("BufEncoded") + .finish() + } +} + +pub struct BufRaw +{ + pub buf: Vec +} + +impl fmt::Debug for BufRaw { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f + .debug_struct("BufRaw") + .finish() + } +} + +#[derive (Debug, Error)] +pub enum ControlError +{ + #[error ("already have encoded data")] + AlreadyHaveEncodedData, + #[error ("already have raw data")] + AlreadyHaveRawData, +} diff --git a/src/main.rs b/src/main.rs index 22088b8..d87da5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,10 @@ use std::{ }; use rayon::ThreadPool; -use thiserror::Error; + +use crate::controller::*; + +mod controller; fn main() { @@ -89,7 +92,7 @@ impl <'a> Driver <'_> _ => panic! ("tried to finish an already finished capture"), }; - self.ctl.tx_pipe.handle_capture_frame (buf_raw).unwrap (); + self.ctl.handle_capture_frame (buf_raw).unwrap (); }, TaskOutput::TxEncode (enc) => { @@ -99,7 +102,7 @@ impl <'a> Driver <'_> _ => panic! ("tried to finish an already finished encode"), }; - self.ctl.tx_pipe.encoder_is_busy = false; + self.ctl.handle_encoder_finished (); }, TaskOutput::TxTransmit ((tx, busy)) => { @@ -109,7 +112,7 @@ impl <'a> Driver <'_> _ => panic! ("tried to finish an already finished transmit"), }; - self.ctl.tx_pipe.handle_network_busy (busy); + self.ctl.handle_network_busy (busy); } } } @@ -157,9 +160,12 @@ impl <'a> Driver <'_> let may_have_data = encoder.poll_encoded (&mut buf); if may_have_data { - self.ctl.tx_pipe.handle_encoded_packet (BufEncoded {buf}).unwrap (); + self.ctl.handle_encoded_packet (Some (BufEncoded {buf})).unwrap (); + } + else + { + self.ctl.handle_encoded_packet (None).unwrap (); } - self.ctl.tx_pipe.encoder_has_data = may_have_data; } TxPipelineEvent::Encode (buf_raw) => { @@ -223,241 +229,6 @@ impl fmt::Debug for TaskOutput { } } -#[derive (Default)] -struct Controller -{ - /// Pipeline for pulling data from the network, decoding it, - /// and displaying it. - - rx_pipe: RxPipeline, - - /// Pipeline for pulling data from capture devices, encoding it, - /// and sending it over the network. - - tx_pipe: TxPipeline, -} - -#[derive (Debug)] -struct ControlEvent -{ - rx: Option , - tx: Option , -} - -impl Controller -{ - fn poll (&mut self) -> ControlEvent - { - let rx = self.rx_pipe.poll (); - let tx = self.tx_pipe.poll (); - - ControlEvent { - rx, - tx, - } - } -} - -#[derive (Default)] -struct RxPipeline -{ - buf_enc: Option , - buf_raw: Option , -} - -#[derive (Debug)] -enum RxPipelineEvent -{ - DisplayRaw (BufRaw), - Decode (BufEncoded), - Receive, -} - -#[derive (Debug, Error)] -enum RxPipeError -{ - #[error ("already have encoded data")] - AlreadyHaveEncodedData, - #[error ("already have raw data")] - AlreadyHaveRawData, -} - -impl RxPipeline -{ - fn handle_encoded_packet (&mut self, buf_enc: BufEncoded) -> Result <(), RxPipeError> - { - if self.has_encoded_data () - { - return Err (RxPipeError::AlreadyHaveEncodedData); - } - - self.buf_enc = Some (buf_enc); - - Ok (()) - } - - fn handle_raw_frame (&mut self, buf_raw: BufRaw) -> Result <(), RxPipeError> - { - if self.has_raw_data () - { - return Err (RxPipeError::AlreadyHaveRawData); - } - - self.buf_raw = Some (buf_raw); - - Ok (()) - } - - fn poll (&mut self) -> Option - { - if let Some (buf_raw) = self.buf_raw.take () - { - return Some (RxPipelineEvent::DisplayRaw (buf_raw)); - } - - if ! self.has_raw_data () - { - if let Some (buf_enc) = self.buf_enc.take () - { - return Some (RxPipelineEvent::Decode (buf_enc)); - } - } - - if ! self.has_encoded_data () - { - return Some (RxPipelineEvent::Receive); - } - - None - } - - /// True if we have a buffer of received data, ready - /// to be decoded. - - fn has_encoded_data (&self) -> bool - { - self.buf_enc.is_some () - } - - fn has_raw_data (&self) -> bool - { - self.buf_raw.is_some () - } -} - -#[derive (Default)] -struct TxPipeline -{ - buf_enc: Option , - buf_raw: Option , - capture_is_busy: bool, - encoder_has_data: bool, - encoder_is_busy: bool, - network_busy: bool, -} - -#[derive (Debug)] -enum TxPipelineEvent -{ - /// Capture a raw frame and pass it to handle_capture_frame - Capture, - - /// Poll the encoder. If it returns a packet, pass it to - /// handle_encoded_packet. - PollEncoder, - - /// Encode this raw frame and pass the encoded frame to - /// handle_encoded_packet - Encode (BufRaw), - - /// Transmit this encoded frame to the network - Transmit (BufEncoded), -} - -impl TxPipeline -{ - fn handle_capture_frame (&mut self, buf_raw: BufRaw) - -> Result <(), ControlError> - { - self.capture_is_busy = false; - - if self.has_raw_frame () - { - return Err (ControlError::AlreadyHaveRawData); - } - - self.buf_raw = Some (buf_raw); - - Ok (()) - } - - fn handle_encoded_packet (&mut self, buf_enc: BufEncoded) -> Result <(), ControlError> - { - self.encoder_is_busy = false; - - if self.has_encoded_packet () - { - return Err (ControlError::AlreadyHaveEncodedData); - } - - self.buf_enc = Some (buf_enc); - - Ok (()) - } - - fn handle_network_busy (&mut self, busy: bool) - { - self.network_busy = busy; - } - - fn has_encoded_packet (&self) -> bool - { - self.buf_enc.is_some () - } - - fn has_raw_frame (&self) -> bool - { - self.buf_raw.is_some () - } - - fn poll (&mut self) -> Option - { - if ! self.network_busy - { - if let Some (buf_enc) = self.buf_enc.take () - { - return Some (TxPipelineEvent::Transmit (buf_enc)); - } - } - - if ! self.has_encoded_packet () && ! self.encoder_is_busy - { - if self.encoder_has_data - { - return Some (TxPipelineEvent::PollEncoder); - } - - if let Some (buf_raw) = self.buf_raw.take () - { - self.encoder_has_data = true; - self.encoder_is_busy = true; - return Some (TxPipelineEvent::Encode (buf_raw)); - } - } - - if ! self.has_raw_frame () - { - if ! self.capture_is_busy - { - self.capture_is_busy = true; - return Some (TxPipelineEvent::Capture); - } - } - - None - } -} - /// Wraps non-thread-safe capture device like a v4l webcam #[derive (Default)] @@ -562,38 +333,3 @@ impl Transmitter false } } - -struct BufEncoded -{ - buf: Vec -} - -impl fmt::Debug for BufEncoded { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f - .debug_struct("BufEncoded") - .finish() - } -} - -struct BufRaw -{ - buf: Vec -} - -impl fmt::Debug for BufRaw { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f - .debug_struct("BufRaw") - .finish() - } -} - -#[derive (Debug, Error)] -enum ControlError -{ - #[error ("already have encoded data")] - AlreadyHaveEncodedData, - #[error ("already have raw data")] - AlreadyHaveRawData, -}