rodio/source/
done.rs

1use std::sync::atomic::{AtomicUsize, Ordering};
2use std::sync::Arc;
3use std::time::Duration;
4
5use crate::{Sample, Source};
6
7use super::SeekError;
8
9/// When the inner source is empty this decrements a `AtomicUsize`.
10#[derive(Debug, Clone)]
11pub struct Done<I> {
12    input: I,
13    signal: Arc<AtomicUsize>,
14    signal_sent: bool,
15}
16
17impl<I> Done<I> {
18    /// When the inner source is empty the AtomicUsize passed in is decremented.
19    /// If it was zero it will overflow negatively.
20    #[inline]
21    pub fn new(input: I, signal: Arc<AtomicUsize>) -> Done<I> {
22        Done {
23            input,
24            signal,
25            signal_sent: false,
26        }
27    }
28
29    /// Returns a reference to the inner source.
30    #[inline]
31    pub fn inner(&self) -> &I {
32        &self.input
33    }
34
35    /// Returns a mutable reference to the inner source.
36    #[inline]
37    pub fn inner_mut(&mut self) -> &mut I {
38        &mut self.input
39    }
40
41    /// Returns the inner source.
42    #[inline]
43    pub fn into_inner(self) -> I {
44        self.input
45    }
46}
47
48impl<I: Source> Iterator for Done<I>
49where
50    I: Source,
51    I::Item: Sample,
52{
53    type Item = I::Item;
54
55    #[inline]
56    fn next(&mut self) -> Option<I::Item> {
57        let next = self.input.next();
58        if !self.signal_sent && next.is_none() {
59            self.signal.fetch_sub(1, Ordering::Relaxed);
60            self.signal_sent = true;
61        }
62        next
63    }
64
65    fn size_hint(&self) -> (usize, Option<usize>) {
66        self.input.size_hint()
67    }
68}
69
70impl<I> Source for Done<I>
71where
72    I: Source,
73    I::Item: Sample,
74{
75    #[inline]
76    fn current_frame_len(&self) -> Option<usize> {
77        self.input.current_frame_len()
78    }
79
80    #[inline]
81    fn channels(&self) -> u16 {
82        self.input.channels()
83    }
84
85    #[inline]
86    fn sample_rate(&self) -> u32 {
87        self.input.sample_rate()
88    }
89
90    #[inline]
91    fn total_duration(&self) -> Option<Duration> {
92        self.input.total_duration()
93    }
94
95    #[inline]
96    fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
97        self.input.try_seek(pos)
98    }
99}