rt: take ringbuffer out for reuse
This commit is contained in:
parent
22f87aa7f8
commit
e7351207cf
|
@ -40,7 +40,6 @@ pub struct FilterMutable {
|
||||||
pub(crate) parameters: FxHashMap<String, f32>,
|
pub(crate) parameters: FxHashMap<String, f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: get rid of preset
|
|
||||||
type ShaderPassMeta = (
|
type ShaderPassMeta = (
|
||||||
ShaderPassConfig,
|
ShaderPassConfig,
|
||||||
ShaderSource,
|
ShaderSource,
|
||||||
|
|
|
@ -35,7 +35,7 @@ impl UniformLocation<GLint> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type BufferStorage = UniformStorage<GlUniformBinder, UniformLocation<GLint>>;
|
pub(crate) type GlUniformStorage = UniformStorage<GlUniformBinder, UniformLocation<GLint>>;
|
||||||
|
|
||||||
pub trait GlUniformScalar: UniformScalar {
|
pub trait GlUniformScalar: UniformScalar {
|
||||||
const FACTORY: unsafe fn(GLint, Self) -> ();
|
const FACTORY: unsafe fn(GLint, Self) -> ();
|
||||||
|
|
|
@ -12,7 +12,7 @@ use librashader_common::{FilterMode, Size, WrapMode};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use crate::{error, GLImage, util, Viewport};
|
use crate::{error, GLImage, util, Viewport};
|
||||||
use crate::binding::{BufferStorage, UniformLocation, VariableLocation};
|
use crate::binding::{GlUniformStorage, UniformLocation, VariableLocation};
|
||||||
use crate::error::FilterChainError;
|
use crate::error::FilterChainError;
|
||||||
use crate::filter_pass::FilterPass;
|
use crate::filter_pass::FilterPass;
|
||||||
use crate::gl::{DrawQuad, Framebuffer, FramebufferInterface, GLInterface, LoadLut, UboRing};
|
use crate::gl::{DrawQuad, Framebuffer, FramebufferInterface, GLInterface, LoadLut, UboRing};
|
||||||
|
@ -288,7 +288,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let uniform_storage = BufferStorage::new(
|
let uniform_storage = GlUniformStorage::new(
|
||||||
reflection
|
reflection
|
||||||
.ubo
|
.ubo
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
|
@ -11,7 +11,7 @@ use librashader_reflect::reflect::semantics::{
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::binding::{BufferStorage, UniformLocation, VariableLocation};
|
use crate::binding::{GlUniformStorage, UniformLocation, VariableLocation};
|
||||||
use crate::filter_chain::FilterCommon;
|
use crate::filter_chain::FilterCommon;
|
||||||
use crate::gl::{BindTexture, GLInterface, UboRing};
|
use crate::gl::{BindTexture, GLInterface, UboRing};
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
|
@ -25,7 +25,7 @@ pub struct FilterPass<T: GLInterface> {
|
||||||
pub program: GLuint,
|
pub program: GLuint,
|
||||||
pub ubo_location: UniformLocation<GLuint>,
|
pub ubo_location: UniformLocation<GLuint>,
|
||||||
pub ubo_ring: Option<T::UboRing>,
|
pub ubo_ring: Option<T::UboRing>,
|
||||||
pub(crate) uniform_storage: BufferStorage,
|
pub(crate) uniform_storage: GlUniformStorage,
|
||||||
pub uniform_bindings: FxHashMap<UniformBinding, (VariableLocation, MemberOffset)>,
|
pub uniform_bindings: FxHashMap<UniformBinding, (VariableLocation, MemberOffset)>,
|
||||||
pub source: ShaderSource,
|
pub source: ShaderSource,
|
||||||
pub config: ShaderPassConfig,
|
pub config: ShaderPassConfig,
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::binding::UniformLocation;
|
use crate::binding::UniformLocation;
|
||||||
use crate::gl::UboRing;
|
use crate::gl::UboRing;
|
||||||
use crate::util::{InlineRingBuffer, RingBuffer};
|
use librashader_runtime::ringbuffer::InlineRingBuffer;
|
||||||
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
||||||
use librashader_reflect::reflect::semantics::UboReflection;
|
use librashader_reflect::reflect::semantics::UboReflection;
|
||||||
|
use librashader_runtime::ringbuffer::RingBuffer;
|
||||||
use librashader_runtime::uniforms::UniformStorageAccess;
|
use librashader_runtime::uniforms::UniformStorageAccess;
|
||||||
|
|
||||||
pub struct Gl3UboRing<const SIZE: usize> {
|
pub struct Gl3UboRing<const SIZE: usize> {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::binding::UniformLocation;
|
use crate::binding::UniformLocation;
|
||||||
use crate::gl::UboRing;
|
use crate::gl::UboRing;
|
||||||
use crate::util::{InlineRingBuffer, RingBuffer};
|
use librashader_runtime::ringbuffer::InlineRingBuffer;
|
||||||
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
||||||
use librashader_reflect::reflect::semantics::UboReflection;
|
use librashader_reflect::reflect::semantics::UboReflection;
|
||||||
|
use librashader_runtime::ringbuffer::RingBuffer;
|
||||||
use librashader_runtime::uniforms::UniformStorageAccess;
|
use librashader_runtime::uniforms::UniformStorageAccess;
|
||||||
|
|
||||||
pub struct Gl46UboRing<const SIZE: usize> {
|
pub struct Gl46UboRing<const SIZE: usize> {
|
||||||
|
|
|
@ -2,55 +2,6 @@ use gl::types::{GLenum, GLuint};
|
||||||
|
|
||||||
use librashader_reflect::back::cross::GlslVersion;
|
use librashader_reflect::back::cross::GlslVersion;
|
||||||
|
|
||||||
pub trait RingBuffer<T> {
|
|
||||||
fn current(&self) -> &T;
|
|
||||||
fn current_mut(&mut self) -> &mut T;
|
|
||||||
fn next(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, const SIZE: usize> RingBuffer<T> for InlineRingBuffer<T, SIZE> {
|
|
||||||
fn current(&self) -> &T {
|
|
||||||
&self.items[self.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_mut(&mut self) -> &mut T {
|
|
||||||
&mut self.items[self.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next(&mut self) {
|
|
||||||
self.index += 1;
|
|
||||||
if self.index >= SIZE {
|
|
||||||
self.index = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct InlineRingBuffer<T, const SIZE: usize> {
|
|
||||||
items: [T; SIZE],
|
|
||||||
index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, const SIZE: usize> InlineRingBuffer<T, SIZE>
|
|
||||||
where
|
|
||||||
T: Copy,
|
|
||||||
T: Default,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
items: [T::default(); SIZE],
|
|
||||||
index: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn items(&self) -> &[T; SIZE] {
|
|
||||||
&self.items
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn items_mut(&mut self) -> &mut [T; SIZE] {
|
|
||||||
&mut self.items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint {
|
pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint {
|
||||||
let shader = gl::CreateShader(stage);
|
let shader = gl::CreateShader(stage);
|
||||||
gl::ShaderSource(
|
gl::ShaderSource(
|
||||||
|
|
3
librashader-runtime-vk/src/error.rs
Normal file
3
librashader-runtime-vk/src/error.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
182
librashader-runtime-vk/src/filter_chain.rs
Normal file
182
librashader-runtime-vk/src/filter_chain.rs
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
use std::error::Error;
|
||||||
|
use std::path::Path;
|
||||||
|
use ash::vk;
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
use librashader_preprocess::ShaderSource;
|
||||||
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
|
use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation};
|
||||||
|
use librashader_reflect::back::targets::SpirV;
|
||||||
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
|
use librashader_reflect::reflect::semantics::{Semantic, ShaderSemantics, TextureSemantics, UniformBinding, UniformSemantic, UniqueSemantics};
|
||||||
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
|
use crate::error;
|
||||||
|
use crate::filter_pass::FilterPass;
|
||||||
|
|
||||||
|
pub struct Vulkan {
|
||||||
|
physical_device: vk::PhysicalDevice,
|
||||||
|
device: vk::Device,
|
||||||
|
queue: vk::Queue,
|
||||||
|
command_pool: vk::CommandPool,
|
||||||
|
pipelines: vk::PipelineCache,
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShaderPassMeta = (
|
||||||
|
ShaderPassConfig,
|
||||||
|
ShaderSource,
|
||||||
|
CompilerBackend<
|
||||||
|
impl CompileShader<SpirV, Options = Option<()>, Context =()> + ReflectShader,
|
||||||
|
>,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct VulkanInfo<'a> {
|
||||||
|
physical_device: &'a vk::PhysicalDevice,
|
||||||
|
device: &'a vk::Device,
|
||||||
|
queue: &'a vk::Queue,
|
||||||
|
memory_properties: &'a vk::PhysicalDeviceMemoryProperties
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FilterChainVulkan {
|
||||||
|
pub(crate) common: FilterCommon,
|
||||||
|
pub(crate) passes: Vec<FilterPass>,
|
||||||
|
// pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
|
// pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
|
// pub(crate) history_framebuffers: VecDeque<OwnedFramebuffer>,
|
||||||
|
// pub(crate) draw_quad: DrawQuad,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct FilterCommon {
|
||||||
|
// pub(crate) luts: FxHashMap<usize, LutTexture>,
|
||||||
|
// pub samplers: SamplerSet,
|
||||||
|
// pub output_textures: Box<[Option<Texture>]>,
|
||||||
|
// pub feedback_textures: Box<[Option<Texture>]>,
|
||||||
|
// pub history_textures: Box<[Option<Texture>]>,
|
||||||
|
// pub config: FilterMutable,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FilterChainOptionsVulkan = ();
|
||||||
|
|
||||||
|
impl FilterChainVulkan {
|
||||||
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
|
pub fn load_from_path(
|
||||||
|
vulkan: VulkanInfo,
|
||||||
|
path: impl AsRef<Path>,
|
||||||
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
|
) -> error::Result<FilterChainVulkan> {
|
||||||
|
// load passes from preset
|
||||||
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
|
Self::load_from_preset(vulkan, preset, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_from_preset(
|
||||||
|
vulkan: VulkanInfo,
|
||||||
|
preset: ShaderPreset,
|
||||||
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
|
) -> error::Result<FilterChainVulkan> {
|
||||||
|
let (passes, semantics) = FilterChainVulkan::load_preset(preset.shaders, &preset.textures)?;
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_preset(
|
||||||
|
passes: Vec<ShaderPassConfig>,
|
||||||
|
textures: &[TextureConfig],
|
||||||
|
) -> error::Result<(Vec<ShaderPassMeta>, ShaderSemantics)> {
|
||||||
|
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
||||||
|
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
|
||||||
|
Default::default();
|
||||||
|
|
||||||
|
let passes = passes
|
||||||
|
.into_iter()
|
||||||
|
.map(|shader| {
|
||||||
|
eprintln!("[vk] loading {}", &shader.name.display());
|
||||||
|
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
||||||
|
|
||||||
|
let spirv = GlslangCompilation::compile(&source)?;
|
||||||
|
let reflect = SpirV::from_compilation(spirv)?;
|
||||||
|
|
||||||
|
for parameter in source.parameters.iter() {
|
||||||
|
uniform_semantics.insert(
|
||||||
|
parameter.id.clone(),
|
||||||
|
UniformSemantic::Unique(Semantic {
|
||||||
|
semantics: UniqueSemantics::FloatParameter,
|
||||||
|
index: (),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok::<_, Box<dyn Error>>((shader, source, reflect))
|
||||||
|
})
|
||||||
|
.into_iter()
|
||||||
|
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>()?;
|
||||||
|
|
||||||
|
for details in &passes {
|
||||||
|
librashader_runtime::semantics::insert_pass_semantics(
|
||||||
|
&mut uniform_semantics,
|
||||||
|
&mut texture_semantics,
|
||||||
|
&details.0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
librashader_runtime::semantics::insert_lut_semantics(
|
||||||
|
textures,
|
||||||
|
&mut uniform_semantics,
|
||||||
|
&mut texture_semantics,
|
||||||
|
);
|
||||||
|
|
||||||
|
let semantics = ShaderSemantics {
|
||||||
|
uniform_semantics,
|
||||||
|
texture_semantics,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((passes, semantics))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_passes(
|
||||||
|
passes: Vec<ShaderPassMeta>,
|
||||||
|
semantics: &ShaderSemantics,
|
||||||
|
) -> error::Result<Box<[FilterPass]>> {
|
||||||
|
let mut filters = Vec::new();
|
||||||
|
|
||||||
|
// initialize passes
|
||||||
|
for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() {
|
||||||
|
let reflection = reflect.reflect(index, semantics)?;
|
||||||
|
let spirv_words = reflect.compile(None)?;
|
||||||
|
|
||||||
|
let uniform_storage = UniformStorage::new(
|
||||||
|
reflection
|
||||||
|
.ubo
|
||||||
|
.as_ref()
|
||||||
|
.map(|ubo| ubo.size as usize)
|
||||||
|
.unwrap_or(0),
|
||||||
|
reflection
|
||||||
|
.push_constant
|
||||||
|
.as_ref()
|
||||||
|
.map(|push| push.size as usize)
|
||||||
|
.unwrap_or(0),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut uniform_bindings = FxHashMap::default();
|
||||||
|
for param in reflection.meta.parameter_meta.values() {
|
||||||
|
uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), param.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (semantics, param) in &reflection.meta.unique_meta {
|
||||||
|
uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), param.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (semantics, param) in &reflection.meta.texture_size_meta {
|
||||||
|
uniform_bindings.insert(UniformBinding::TextureSize(*semantics), param.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
filters.push(FilterPass {
|
||||||
|
compiled: spirv_words,
|
||||||
|
uniform_storage,
|
||||||
|
uniform_bindings,
|
||||||
|
source,
|
||||||
|
config,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
14
librashader-runtime-vk/src/filter_pass.rs
Normal file
14
librashader-runtime-vk/src/filter_pass.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
use librashader_preprocess::ShaderSource;
|
||||||
|
use librashader_presets::ShaderPassConfig;
|
||||||
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
|
use librashader_reflect::reflect::semantics::{MemberOffset, UniformBinding};
|
||||||
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
|
|
||||||
|
pub struct FilterPass {
|
||||||
|
pub(crate) compiled: ShaderCompilerOutput<Vec<u32>>,
|
||||||
|
pub(crate) uniform_storage: UniformStorage,
|
||||||
|
pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
|
||||||
|
pub source: ShaderSource,
|
||||||
|
pub config: ShaderPassConfig,
|
||||||
|
}
|
|
@ -369,7 +369,7 @@ pub(crate) fn main() {
|
||||||
let clear_values = [
|
let clear_values = [
|
||||||
vk::ClearValue {
|
vk::ClearValue {
|
||||||
color: vk::ClearColorValue {
|
color: vk::ClearColorValue {
|
||||||
float32: [0.0, 0.0, 0.0, 0.0],
|
float32: [0.3, 0.3, 0.5, 0.0],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
vk::ClearValue {
|
vk::ClearValue {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
mod hello_triangle;
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
use ash::vk::Framebuffer;
|
mod hello_triangle;
|
||||||
|
mod filter_chain;
|
||||||
|
mod filter_pass;
|
||||||
|
mod error;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -17,3 +17,6 @@ pub mod filter_chain;
|
||||||
|
|
||||||
/// Image handling helpers.
|
/// Image handling helpers.
|
||||||
pub mod image;
|
pub mod image;
|
||||||
|
|
||||||
|
/// Ringbuffer helpers
|
||||||
|
pub mod ringbuffer;
|
||||||
|
|
137
librashader-runtime/src/ringbuffer.rs
Normal file
137
librashader-runtime/src/ringbuffer.rs
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/// General trait for ring buffers.
|
||||||
|
pub trait RingBuffer<T> {
|
||||||
|
/// Get a borrow the current item.
|
||||||
|
fn current(&self) -> &T;
|
||||||
|
|
||||||
|
/// Get a mutable borrow to the current item.
|
||||||
|
fn current_mut(&mut self) -> &mut T;
|
||||||
|
|
||||||
|
/// Move to the next item in the ring buffer.
|
||||||
|
fn next(&mut self);
|
||||||
|
|
||||||
|
fn current_index(&self) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, const SIZE: usize> RingBuffer<T> for InlineRingBuffer<T, SIZE> {
|
||||||
|
fn current(&self) -> &T {
|
||||||
|
&self.items[self.index]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.items[self.index]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(&mut self) {
|
||||||
|
self.index += 1;
|
||||||
|
if self.index >= SIZE {
|
||||||
|
self.index = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_index(&self) -> usize {
|
||||||
|
self.index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A ring buffer that stores its contents inline.
|
||||||
|
pub struct InlineRingBuffer<T, const SIZE: usize> {
|
||||||
|
items: [T; SIZE],
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, const SIZE: usize> InlineRingBuffer<T, SIZE>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
T: Default,
|
||||||
|
{
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
items: [T::default(); SIZE],
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a borrow to all the items in this ring buffer.
|
||||||
|
pub fn items(&self) -> &[T; SIZE] {
|
||||||
|
&self.items
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable borrow to all the items in this ring buffer.
|
||||||
|
pub fn items_mut(&mut self) -> &mut [T; SIZE] {
|
||||||
|
&mut self.items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A ring buffer that stores its contents in a box
|
||||||
|
pub struct BoxRingBuffer<T> {
|
||||||
|
items: Box<[T]>,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> BoxRingBuffer<T>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
T: Default,
|
||||||
|
{
|
||||||
|
pub fn new(size: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
items: vec![T::default(); size].into_boxed_slice(),
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a borrow to all the items in this ring buffer.
|
||||||
|
pub fn items(&self) -> &[T; SIZE] {
|
||||||
|
&self.items
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable borrow to all the items in this ring buffer.
|
||||||
|
pub fn items_mut(&mut self) -> &mut [T; SIZE] {
|
||||||
|
&mut self.items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<T> BoxRingBuffer<T> {
|
||||||
|
pub fn from_vec(items: Vec<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
items: items.into_boxed_slice(),
|
||||||
|
index: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn items(&self) -> &[T] {
|
||||||
|
&self.items
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn items_mut(&mut self) -> &mut [T] {
|
||||||
|
&mut self.items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<Vec<T>> for BoxRingBuffer<T> {
|
||||||
|
fn from(value: Vec<T>) -> Self {
|
||||||
|
BoxRingBuffer::from_vec(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> RingBuffer<T> for BoxRingBuffer<T> {
|
||||||
|
fn current(&self) -> &T {
|
||||||
|
&self.items[self.index]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.items[self.index]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(&mut self) {
|
||||||
|
self.index += 1;
|
||||||
|
if self.index >= SIZE {
|
||||||
|
self.index = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_index(&self) -> usize {
|
||||||
|
self.index
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue