use std::cell::{Ref, RefCell};
use crate::{BufferDataAccessor, BufferIndexAccessor};
use crate::{Renderable, VertexAttr};
#[derive(Debug)]
pub struct Vertices<'vertices, R: Renderable> {
indices: Option<&'vertices BufferIndexAccessor<'vertices, R>>,
attrs: Vec<&'vertices BufferDataAccessor<'vertices, R>>,
rc_client: RefCell<R::Vertices>,
}
impl<'vertices, R: Renderable> std::fmt::Display for Vertices<'vertices, R>
where
R: Renderable,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
writeln!(fmt, "Vertices:")?;
writeln!(fmt, " indices: {:?}", self.indices)?;
for a in &self.attrs {
writeln!(fmt, " {a:?}")?;
}
Ok(())
}
}
impl<'vertices, R: Renderable> Vertices<'vertices, R> {
pub fn new(
indices: Option<&'vertices BufferIndexAccessor<'vertices, R>>,
position: &'vertices BufferDataAccessor<'vertices, R>,
) -> Self {
let attrs = vec![position];
let rc_client = RefCell::new(R::Vertices::default());
Self {
indices,
attrs,
rc_client,
}
}
pub fn add_attr(&mut self, accessor: &'vertices BufferDataAccessor<'vertices, R>) {
if let Some(p) = self
.attrs
.iter()
.position(|a| a.vertex_attr() == accessor.vertex_attr())
{
self.attrs[p] = accessor;
} else {
self.attrs.push(accessor);
}
}
pub fn borrow_indices<'a>(&'a self) -> Option<&'a BufferIndexAccessor<'vertices, R>> {
self.indices
}
pub fn borrow_attr<'a>(
&'a self,
attr: VertexAttr,
) -> Option<&'a BufferDataAccessor<'vertices, R>> {
self.attrs
.iter()
.position(|a| a.vertex_attr() == attr)
.map(|p| self.attrs[p])
}
pub fn iter_attrs(&self) -> std::slice::Iter<&BufferDataAccessor<'vertices, R>> {
self.attrs.iter()
}
pub fn create_client(&self, renderer: &mut R) {
if let Some(i) = self.indices {
i.create_client(renderer)
}
for data_accessor in self.iter_attrs() {
data_accessor.create_client(renderer);
}
*(self.rc_client.borrow_mut()) = renderer.create_vertices_client(self);
}
pub fn borrow_client(&self) -> Ref<R::Vertices> {
self.rc_client.borrow()
}
}