five_five_five/src/controller.rs

299 lines
6.3 KiB
Rust

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 <RxPipelineEvent>,
pub tx: Option <TxPipelineEvent>,
}
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 <BufEncoded>) -> 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 <BufEncoded>,
buf_raw: Option <BufRaw>,
}
#[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 <RxPipelineEvent>
{
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 <BufEncoded>,
buf_raw: Option <BufRaw>,
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 <BufEncoded>) -> 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 <TxPipelineEvent>
{
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 <u8>
}
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 <u8>
}
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,
}