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_transmitted (&mut self, x: bool) { self.tx_pipe.handle_transmitted (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_congested: bool, transmitter_is_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_transmitted (&mut self, busy: bool) { self.network_congested = busy; self.transmitter_is_busy = false; } 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_congested && ! self.transmitter_is_busy { if let Some (buf_enc) = self.buf_enc.take () { self.transmitter_is_busy = true; 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, }