librashader_runtime/
ringbuffer.rs

1/// General trait for ring buffers.
2pub trait RingBuffer<T> {
3    /// Get a borrow the current item.
4    fn current(&self) -> &T;
5
6    /// Get a mutable borrow to the current item.
7    fn current_mut(&mut self) -> &mut T;
8
9    /// Move to the next item in the ring buffer.
10    fn next(&mut self);
11
12    fn current_index(&self) -> usize;
13}
14
15impl<T, const SIZE: usize> RingBuffer<T> for InlineRingBuffer<T, SIZE> {
16    fn current(&self) -> &T {
17        &self.items[self.index]
18    }
19
20    fn current_mut(&mut self) -> &mut T {
21        &mut self.items[self.index]
22    }
23
24    fn next(&mut self) {
25        self.index += 1;
26        if self.index >= SIZE {
27            self.index = 0
28        }
29    }
30
31    fn current_index(&self) -> usize {
32        self.index
33    }
34}
35
36/// A ring buffer that stores its contents inline.
37pub struct InlineRingBuffer<T, const SIZE: usize> {
38    items: [T; SIZE],
39    index: usize,
40}
41
42impl<T, const SIZE: usize> InlineRingBuffer<T, SIZE>
43where
44    T: Copy,
45    T: Default,
46{
47    pub fn new() -> Self {
48        Self {
49            items: [T::default(); SIZE],
50            index: 0,
51        }
52    }
53}
54
55impl<T, const SIZE: usize> InlineRingBuffer<T, SIZE>
56where
57    T: Copy,
58{
59    pub fn from_array(items: [T; SIZE]) -> Self {
60        Self { items, index: 0 }
61    }
62
63    /// Get a borrow to all the items in this ring buffer.
64    pub fn items(&self) -> &[T; SIZE] {
65        &self.items
66    }
67
68    /// Get a mutable borrow to all the items in this ring buffer.
69    pub fn items_mut(&mut self) -> &mut [T; SIZE] {
70        &mut self.items
71    }
72}
73
74/// A ring buffer that stores its contents in a box
75pub struct BoxRingBuffer<T> {
76    items: Box<[T]>,
77    index: usize,
78}
79
80impl<T> BoxRingBuffer<T>
81where
82    T: Copy,
83    T: Default,
84{
85    pub fn new(size: usize) -> Self {
86        Self {
87            items: vec![T::default(); size].into_boxed_slice(),
88            index: 0,
89        }
90    }
91}
92
93impl<T> BoxRingBuffer<T> {
94    pub fn from_vec(items: Vec<T>) -> Self {
95        Self {
96            items: items.into_boxed_slice(),
97            index: 0,
98        }
99    }
100
101    /// Get a borrow to all the items in this ring buffer.
102    pub fn items(&self) -> &[T] {
103        &self.items
104    }
105
106    /// Get a mutable borrow to all the items in this ring buffer.
107    pub fn items_mut(&mut self) -> &mut [T] {
108        &mut self.items
109    }
110}
111
112impl<T> From<Vec<T>> for BoxRingBuffer<T> {
113    fn from(value: Vec<T>) -> Self {
114        BoxRingBuffer::from_vec(value)
115    }
116}
117
118impl<T> RingBuffer<T> for BoxRingBuffer<T> {
119    fn current(&self) -> &T {
120        &self.items[self.index]
121    }
122
123    fn current_mut(&mut self) -> &mut T {
124        &mut self.items[self.index]
125    }
126
127    fn next(&mut self) {
128        self.index += 1;
129        if self.index >= self.items.len() {
130            self.index = 0
131        }
132    }
133
134    fn current_index(&self) -> usize {
135        self.index
136    }
137}