use crate::daq::{
InQueues, InStreamData, InStreamMsg, InputStreamCommand, PreCaptureBuffer, StreamMetaData,
};
use crate::{daq::error::StreamMgrError, *};
use crossbeam::channel::{Receiver, Sender, unbounded};
use std::collections::VecDeque;
use std::sync::Arc;
use std::time::Duration;
type Result<T> = std::result::Result<T, StreamMgrError>;
pub fn startInputStreamThread(
meta: Arc<StreamMetaData>,
rx: Receiver<InStreamMsg>,
mut iqueues: InQueues,
) -> (
JoinHandle<InQueues>,
Sender<InputStreamCommand>,
Receiver<Result<()>>,
) {
let (commtx_ret, commrx) = unbounded();
let (commtx, commrx_ret) = unbounded();
let precap_capacity = (PRECAP_DURATION.as_secs_f64() * *meta.samplerate
/ meta.framesPerBlock as f64)
.ceil() as usize;
let threadhandle = spawn(
move || {
let mut precap_buf: VecDeque<Arc<InStreamData>> =
VecDeque::with_capacity(precap_capacity);
let mut precap_wrapped = false;
'infy: loop {
if let Ok(comm_msg) = commrx.try_recv() {
match comm_msg {
InputStreamCommand::AddInQueue(queue) => {
let precap = if precap_wrapped && !precap_buf.is_empty() {
PreCaptureBuffer::Loaded(precap_buf.iter().cloned().collect())
} else {
PreCaptureBuffer::NotLoaded
};
match queue.send(InStreamMsg::StreamStarted(meta.clone(), precap)) {
Ok(()) => {
iqueues.push(queue);
}
Err(e) => {
eprintln!("Cannot push to queue: {e}. Object destructed?");
}
}
commtx.send(Ok(())).unwrap();
}
InputStreamCommand::StopThread => {
sendMsgToAllQueuesRemoveUnused(
&mut iqueues,
InStreamMsg::StreamStopped,
);
commtx.send(Ok(())).unwrap();
break 'infy;
}
}
}
if let Ok(msg) = rx.recv_timeout(Duration::from_millis(10)) {
if let InStreamMsg::InStreamData(ref data) = msg {
if precap_buf.len() >= precap_capacity {
precap_buf.pop_front();
precap_wrapped = true;
}
precap_buf.push_back(data.clone());
}
sendMsgToAllQueuesRemoveUnused(&mut iqueues, msg);
}
}
iqueues
},
ThreadPriority::High,
);
(threadhandle, commtx_ret, commrx_ret)
}
pub fn sendMsgToAllQueuesRemoveUnused(iqueues: &mut InQueues, msg: InStreamMsg) {
iqueues.retain(|q| q.try_send(msg.clone()).is_ok());
}