Skip to main content

rill_core/buffer/
buffer_trait.rs

1//! # Buffer trait — common interface for all signal buffer types
2//!
3//! Unified trait covering both storage buffers (fixed-size, heap-allocated)
4//! and queue-style buffers (pipe, delay, fan-out, fan-in, ring).
5//!
6//! Generic over [`crate::math::Scalar`] — supports f32, f64, and integer types.
7
8use core::ops::{Deref, DerefMut};
9
10use crate::buffer::BufferStats;
11use crate::math::Scalar;
12
13/// Common interface for all buffer types used in the signal graph.
14pub trait Buffer<T: Scalar> {
15    /// Maximum number of elements the buffer can hold.
16    fn capacity(&self) -> usize;
17
18    /// Current number of elements in the buffer.
19    fn len(&self) -> usize;
20
21    /// Whether the buffer is empty (`len() == 0`).
22    fn is_empty(&self) -> bool {
23        self.len() == 0
24    }
25
26    /// Whether the buffer is full (`len() == capacity()`).
27    fn is_full(&self) -> bool {
28        self.len() == self.capacity()
29    }
30
31    /// Read-only access to the buffer data.
32    fn as_slice(&self) -> &[T];
33
34    /// Mutable access to the buffer data.
35    fn as_mut_slice(&mut self) -> &mut [T];
36
37    /// Fill the entire buffer with a value.
38    fn fill(&mut self, value: T);
39
40    /// Copy data from a slice. Copies `min(src.len(), self.len())` samples.
41    fn copy_from(&mut self, src: &[T]);
42
43    /// Remove all items from the buffer.
44    fn clear(&mut self);
45
46    /// Snapshot of performance statistics.
47    fn stats(&self) -> BufferStats {
48        BufferStats::new()
49    }
50
51    /// Reset performance counters (not the data).
52    fn reset_stats(&mut self) {}
53}
54
55// ============================================================================
56// FixedBuffer — compile-time fixed size, stack-allocated
57// ============================================================================
58
59/// Fixed-size buffer on the stack — default per-port buffer.
60#[derive(Debug, Clone)]
61pub struct FixedBuffer<T, const SIZE: usize> {
62    data: [T; SIZE],
63}
64
65impl<T: Scalar, const SIZE: usize> FixedBuffer<T, SIZE> {
66    /// Create a new buffer filled with `T::default()`.
67    pub fn new() -> Self {
68        Self {
69            data: [T::default(); SIZE],
70        }
71    }
72
73    /// Create a buffer from a fixed-size array.
74    pub fn from_array(data: [T; SIZE]) -> Self {
75        Self { data }
76    }
77
78    /// Create a buffer from a slice, truncating or padding with `T::default()` as needed.
79    pub fn from_slice(slice: &[T]) -> Self {
80        let mut data = [T::default(); SIZE];
81        let len = slice.len().min(SIZE);
82        data[..len].copy_from_slice(&slice[..len]);
83        Self { data }
84    }
85
86    /// Return a reference to the inner array.
87    pub fn as_array(&self) -> &[T; SIZE] {
88        &self.data
89    }
90
91    /// Return a mutable reference to the inner array.
92    pub fn as_mut_array(&mut self) -> &mut [T; SIZE] {
93        &mut self.data
94    }
95}
96
97impl<T: Scalar, const SIZE: usize> Default for FixedBuffer<T, SIZE> {
98    fn default() -> Self {
99        Self::new()
100    }
101}
102
103impl<T: Scalar, const SIZE: usize> Deref for FixedBuffer<T, SIZE> {
104    type Target = [T; SIZE];
105    fn deref(&self) -> &Self::Target {
106        &self.data
107    }
108}
109
110impl<T: Scalar, const SIZE: usize> DerefMut for FixedBuffer<T, SIZE> {
111    fn deref_mut(&mut self) -> &mut Self::Target {
112        &mut self.data
113    }
114}
115
116impl<T: Scalar, const SIZE: usize> From<[T; SIZE]> for FixedBuffer<T, SIZE> {
117    fn from(data: [T; SIZE]) -> Self {
118        Self::from_array(data)
119    }
120}
121
122impl<T: Scalar, const SIZE: usize> Buffer<T> for FixedBuffer<T, SIZE> {
123    fn capacity(&self) -> usize {
124        SIZE
125    }
126
127    fn len(&self) -> usize {
128        SIZE
129    }
130
131    fn as_slice(&self) -> &[T] {
132        &self.data
133    }
134
135    fn as_mut_slice(&mut self) -> &mut [T] {
136        &mut self.data
137    }
138
139    fn fill(&mut self, value: T) {
140        self.data.fill(value);
141    }
142
143    fn copy_from(&mut self, src: &[T]) {
144        let len = src.len().min(SIZE);
145        self.data[..len].copy_from_slice(&src[..len]);
146    }
147
148    fn clear(&mut self) {
149        self.data.fill(T::default());
150    }
151}
152
153// ============================================================================
154// HeapBuffer — runtime-sized, heap-allocated
155// ============================================================================
156
157/// Heap-allocated buffer with runtime-determined size.
158///
159/// Used for resources whose size is determined from data
160/// (loaded samples, configuration).
161#[derive(Debug, Clone)]
162pub struct HeapBuffer<T> {
163    data: Vec<T>,
164}
165
166impl<T: Scalar> HeapBuffer<T> {
167    /// Create a new buffer with `size` samples, all initialized to `T::default()`.
168    pub fn new(size: usize) -> Self {
169        Self {
170            data: vec![T::default(); size],
171        }
172    }
173
174    /// Create a buffer from an existing `Vec`, taking ownership.
175    pub fn from_vec(data: Vec<T>) -> Self {
176        Self { data }
177    }
178}
179
180impl<T: Scalar> Buffer<T> for HeapBuffer<T> {
181    fn capacity(&self) -> usize {
182        self.data.capacity()
183    }
184
185    fn len(&self) -> usize {
186        self.data.len()
187    }
188
189    fn as_slice(&self) -> &[T] {
190        &self.data
191    }
192
193    fn as_mut_slice(&mut self) -> &mut [T] {
194        &mut self.data
195    }
196
197    fn fill(&mut self, value: T) {
198        self.data.fill(value);
199    }
200
201    fn copy_from(&mut self, src: &[T]) {
202        let len = src.len().min(self.data.len());
203        self.data[..len].copy_from_slice(&src[..len]);
204    }
205
206    fn clear(&mut self) {
207        self.data.clear();
208    }
209}