165 lines
3.5 KiB
Rust
165 lines
3.5 KiB
Rust
use std::ops::{Index, IndexMut};
|
|
|
|
use crate::{
|
|
layout::UiRegion,
|
|
render::{Primitive, PrimitiveHandle, Primitives},
|
|
util::Id,
|
|
};
|
|
|
|
struct LayerNode<T> {
|
|
prev: Option<usize>,
|
|
next: Next,
|
|
child: Option<usize>,
|
|
data: T,
|
|
}
|
|
|
|
#[derive(Clone, Copy)]
|
|
enum Next {
|
|
/// continue on same level
|
|
Same(usize),
|
|
/// go back to parent
|
|
Parent(usize),
|
|
/// end
|
|
None,
|
|
}
|
|
|
|
pub struct Layers<T> {
|
|
vec: Vec<LayerNode<T>>,
|
|
}
|
|
|
|
impl<T: Default> Layers<T> {
|
|
pub fn new() -> Layers<T>
|
|
where
|
|
T: Default,
|
|
{
|
|
Self {
|
|
vec: vec![LayerNode::head()],
|
|
}
|
|
}
|
|
|
|
pub fn clear(&mut self)
|
|
where
|
|
T: Default,
|
|
{
|
|
self.vec.clear();
|
|
self.vec.push(LayerNode::head());
|
|
}
|
|
|
|
fn push(&mut self, node: LayerNode<T>) -> usize {
|
|
let i = self.vec.len();
|
|
self.vec.push(node);
|
|
i
|
|
}
|
|
|
|
pub fn next(&mut self, i: usize) -> usize {
|
|
if let Next::Same(i) = self.vec[i].next {
|
|
return i;
|
|
}
|
|
let i_next = self.push(LayerNode::new(T::default(), self.vec[i].next));
|
|
self.vec[i].next = Next::Same(i_next);
|
|
self.vec[i_next].prev = Some(i);
|
|
i_next
|
|
}
|
|
|
|
pub fn child(&mut self, i: usize) -> usize {
|
|
if let Some(i) = self.vec[i].child {
|
|
return i;
|
|
}
|
|
let i_next = self.push(LayerNode::new(T::default(), Next::Parent(i)));
|
|
self.vec[i].child = Some(i_next);
|
|
self.vec[i_next].prev = Some(i);
|
|
i_next
|
|
}
|
|
|
|
pub fn iter_mut(&mut self) -> LayerIteratorMut<'_, T> {
|
|
LayerIteratorMut {
|
|
next: Some(0),
|
|
vec: &mut self.vec,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Default> Default for Layers<T> {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl<T> Index<usize> for Layers<T> {
|
|
type Output = T;
|
|
|
|
fn index(&self, index: usize) -> &Self::Output {
|
|
&self.vec[index].data
|
|
}
|
|
}
|
|
|
|
impl<T> IndexMut<usize> for Layers<T> {
|
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
|
&mut self.vec[index].data
|
|
}
|
|
}
|
|
|
|
impl<T> LayerNode<T> {
|
|
pub fn new(data: T, next: Next) -> Self {
|
|
Self {
|
|
prev: None,
|
|
next,
|
|
child: None,
|
|
data,
|
|
}
|
|
}
|
|
|
|
pub fn head() -> Self
|
|
where
|
|
T: Default,
|
|
{
|
|
Self::new(T::default(), Next::None)
|
|
}
|
|
}
|
|
|
|
pub struct LayerIteratorMut<'a, T> {
|
|
next: Option<usize>,
|
|
vec: &'a mut Vec<LayerNode<T>>,
|
|
}
|
|
|
|
impl<'a, T> Iterator for LayerIteratorMut<'a, T> {
|
|
type Item = (usize, &'a mut T);
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
// chat are we cooked? (if it's not set up correctly this could be catastrophic)
|
|
let ret_i = self.next?;
|
|
let node: &mut LayerNode<T> = unsafe { std::mem::transmute(&mut self.vec[ret_i]) };
|
|
self.next = if let Some(i) = node.child {
|
|
Some(i)
|
|
} else if let Next::Same(i) = node.next {
|
|
Some(i)
|
|
} else if let Next::Parent(i) = node.next {
|
|
let node = &self.vec[i];
|
|
if let Next::Same(i) = node.next {
|
|
Some(i)
|
|
} else {
|
|
None
|
|
}
|
|
} else {
|
|
None
|
|
};
|
|
Some((ret_i, &mut node.data))
|
|
}
|
|
}
|
|
|
|
impl Layers<Primitives> {
|
|
pub fn write<P: Primitive>(
|
|
&mut self,
|
|
layer: usize,
|
|
id: Id,
|
|
primitive: P,
|
|
region: UiRegion,
|
|
) -> PrimitiveHandle {
|
|
self[layer].write(layer, id, primitive, region)
|
|
}
|
|
|
|
pub fn free(&mut self, h: &PrimitiveHandle) {
|
|
self[h.layer].free(h)
|
|
}
|
|
}
|