Add Stream struct
This commit is contained in:
parent
e25c44a4a1
commit
0541bf8667
|
@ -16,9 +16,9 @@ use std::slice;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::sync::mpsc::{channel, Sender, Receiver};
|
use std::sync::mpsc::{channel, Sender, Receiver};
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
|
||||||
|
|
||||||
use std::sync::{Arc};
|
use std::{sync::{Arc},
|
||||||
|
thread::{self, JoinHandle}};
|
||||||
|
|
||||||
use BackendSpecificError;
|
use BackendSpecificError;
|
||||||
use BuildStreamError;
|
use BuildStreamError;
|
||||||
|
@ -31,16 +31,10 @@ use StreamError;
|
||||||
use UnknownTypeOutputBuffer;
|
use UnknownTypeOutputBuffer;
|
||||||
use UnknownTypeInputBuffer;
|
use UnknownTypeInputBuffer;
|
||||||
|
|
||||||
pub struct EventLoop {
|
pub struct Stream {
|
||||||
// Data used by the `run()` function implementation. The mutex is kept lock permanently by
|
/// The high-priority audio processing thread calling callbacks.
|
||||||
// `run()`. This ensures that two `run()` invocations can't run at the same time, and also
|
/// Option used for moving out in destructor.
|
||||||
// means that we shouldn't try to lock this field from anywhere else but `run()`.
|
thread: Option<JoinHandle<()>>,
|
||||||
run_context: Mutex<RunContext>,
|
|
||||||
|
|
||||||
// Identifier of the next stream to create. Each new stream increases this counter. If the
|
|
||||||
// counter overflows, there's a panic.
|
|
||||||
// TODO: use AtomicU64 instead
|
|
||||||
next_stream_id: AtomicUsize,
|
|
||||||
|
|
||||||
// Commands processed by the `run()` method that is currently running.
|
// Commands processed by the `run()` method that is currently running.
|
||||||
// `pending_scheduled_event` must be signalled whenever a command is added here, so that it
|
// `pending_scheduled_event` must be signalled whenever a command is added here, so that it
|
||||||
|
@ -93,25 +87,32 @@ pub (crate) struct StreamInner {
|
||||||
sample_format: SampleFormat,
|
sample_format: SampleFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoop {
|
impl Stream {
|
||||||
pub fn new() -> EventLoop {
|
fn new<D, E>(stream_inner: Arc<StreamInner>, mut data_callback: D, mut error_callback: E) -> Stream
|
||||||
|
where D: FnMut(StreamData) + Send + 'static, E: FnMut(StreamError) + Send + 'static {
|
||||||
let pending_scheduled_event =
|
let pending_scheduled_event =
|
||||||
unsafe { synchapi::CreateEventA(ptr::null_mut(), 0, 0, ptr::null()) };
|
unsafe { synchapi::CreateEventA(ptr::null_mut(), 0, 0, ptr::null()) };
|
||||||
|
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
|
||||||
EventLoop {
|
let run_context = RunContext {
|
||||||
pending_scheduled_event: pending_scheduled_event,
|
stream: Arc::new(stream_inner),
|
||||||
run_context: Mutex::new(RunContext {
|
handles: vec![pending_scheduled_event],
|
||||||
stream: Arc::new(),
|
commands: rx,
|
||||||
handles: vec![pending_scheduled_event],
|
};
|
||||||
commands: rx,
|
|
||||||
}),
|
let thread = thread::spawn(move || {
|
||||||
next_stream_id: AtomicUsize::new(0),
|
run_inner(run_context, &mut data_callback, &mut error_callback)
|
||||||
|
});
|
||||||
|
|
||||||
|
Stream {
|
||||||
|
thread: Some(thread),
|
||||||
commands: tx,
|
commands: tx,
|
||||||
|
pending_scheduled_event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventLoop {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn destroy_stream(&self, stream_id: StreamId) {
|
pub(crate) fn destroy_stream(&self, stream_id: StreamId) {
|
||||||
self.push_command(Command::DestroyStream(stream_id));
|
self.push_command(Command::DestroyStream(stream_id));
|
||||||
|
|
Loading…
Reference in New Issue