Skip to main content

rill_core/buffer/
registry.rs

1//! # Buffer registry — named buffers
2//!
3//! [`BufferRegistry`] — a temporary registry used during graph assembly.
4//! Each node that requires a resource buffer receives a pointer through
5//! the registry during `GraphBuilder::build()`.
6//! After assembly the registry is retained in `Graph` to manage
7//! buffer lifetimes.
8
9use std::collections::HashMap;
10
11use super::Buffer;
12
13/// Registry of named buffers.
14///
15/// Used in `GraphBuilder::build()` to allocate resources and distribute
16/// pointers to graph nodes.
17pub struct BufferRegistry<T> {
18    buffers: HashMap<String, Box<dyn Buffer<T> + Send>>,
19}
20
21impl<T> BufferRegistry<T> {
22    /// Create an empty registry.
23    pub fn new() -> Self {
24        Self {
25            buffers: HashMap::new(),
26        }
27    }
28
29    /// Register a named buffer.
30    pub fn register(&mut self, name: impl Into<String>, buffer: Box<dyn Buffer<T> + Send>) {
31        self.buffers.insert(name.into(), buffer);
32    }
33
34    /// Get a raw pointer to a buffer by name.
35    ///
36    /// Used to distribute pointers to graph nodes during build.
37    pub fn get_ptr(&self, name: &str) -> Option<*const (dyn Buffer<T> + Send)> {
38        self.buffers
39            .get(name)
40            .map(|b| &**b as *const (dyn Buffer<T> + Send))
41    }
42
43    /// Take ownership of a buffer by name, removing it from the registry.
44    pub fn take(&mut self, name: &str) -> Option<Box<dyn Buffer<T> + Send>> {
45        self.buffers.remove(name)
46    }
47
48    /// Leak a buffer by name, returning a raw mutable pointer.
49    /// The leaked buffer will live for the remainder of the program
50    /// (or until manually re‑boxed and dropped).
51    pub fn leak(&mut self, name: &str) -> Option<*mut (dyn Buffer<T> + Send)> {
52        self.buffers.remove(name).map(Box::into_raw)
53    }
54
55    /// Consume the registry and return all owned buffers.
56    pub fn into_inner(self) -> Vec<Box<dyn Buffer<T> + Send>> {
57        self.buffers.into_values().collect()
58    }
59
60    /// Number of registered buffers.
61    pub fn len(&self) -> usize {
62        self.buffers.len()
63    }
64
65    /// Whether no buffers are registered.
66    pub fn is_empty(&self) -> bool {
67        self.buffers.is_empty()
68    }
69}
70
71impl<T> Default for BufferRegistry<T> {
72    fn default() -> Self {
73        Self::new()
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80    use crate::buffer::HeapBuffer;
81
82    #[test]
83    fn test_registry() {
84        let mut reg = BufferRegistry::<f32>::new();
85        reg.register("tape_0", Box::new(HeapBuffer::new(1024)));
86        assert_eq!(reg.len(), 1);
87        assert!(reg.get_ptr("tape_0").is_some());
88        assert!(reg.get_ptr("nonexistent").is_none());
89    }
90}