258 lines
6.0 KiB
Rust
258 lines
6.0 KiB
Rust
use std::ops::{Index, IndexMut};
|
|
|
|
use crate::{
|
|
layout::UiRegion,
|
|
render::{Primitive, PrimitiveHandle, Primitives},
|
|
util::Id,
|
|
};
|
|
|
|
struct LayerNode {
|
|
next: Ptr,
|
|
prev: Ptr,
|
|
child: Option<Child>,
|
|
data: Layer,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
enum Ptr {
|
|
/// continue on same level
|
|
Next(usize),
|
|
/// go back to parent
|
|
Parent(usize),
|
|
/// end
|
|
None,
|
|
}
|
|
|
|
/// TODO: currently this does not ever free layers
|
|
/// is that realistically desired?
|
|
pub struct Layers {
|
|
vec: Vec<LayerNode>,
|
|
}
|
|
|
|
/// TODO: this can be replaced with Primitives itself atm
|
|
#[derive(Default)]
|
|
pub struct Layer {
|
|
pub primitives: Primitives,
|
|
}
|
|
|
|
#[derive(Clone, Copy)]
|
|
struct Child {
|
|
head: usize,
|
|
tail: usize,
|
|
}
|
|
|
|
impl Layers {
|
|
pub fn new() -> Layers {
|
|
Self {
|
|
vec: vec![LayerNode::head()],
|
|
}
|
|
}
|
|
|
|
pub fn clear(&mut self) {
|
|
self.vec.clear();
|
|
self.vec.push(LayerNode::head());
|
|
}
|
|
|
|
fn push(&mut self, node: LayerNode) -> usize {
|
|
let i = self.vec.len();
|
|
self.vec.push(node);
|
|
i
|
|
}
|
|
|
|
pub fn next(&mut self, i: usize) -> usize {
|
|
if let Ptr::Next(i) = self.vec[i].next {
|
|
return i;
|
|
}
|
|
let i_new = self.push(LayerNode::new(
|
|
Layer::default(),
|
|
self.vec[i].next,
|
|
Ptr::Next(i),
|
|
));
|
|
self.vec[i].next = Ptr::Next(i_new);
|
|
self.vec[i_new].prev = Ptr::Next(i);
|
|
match self.vec[i_new].next {
|
|
Ptr::Next(i) => self.vec[i].prev = Ptr::Next(i_new),
|
|
Ptr::Parent(i) => self.vec[i].child.as_mut().unwrap().tail = i_new,
|
|
Ptr::None => (),
|
|
}
|
|
i_new
|
|
}
|
|
|
|
pub fn child(&mut self, i: usize) -> usize {
|
|
if let Some(c) = self.vec[i].child {
|
|
return c.head;
|
|
}
|
|
let i_child = self.push(LayerNode::new(
|
|
Layer::default(),
|
|
Ptr::Parent(i),
|
|
Ptr::Parent(i),
|
|
));
|
|
self.vec[i].child = Some(Child {
|
|
head: i_child,
|
|
tail: i_child,
|
|
});
|
|
i_child
|
|
}
|
|
|
|
pub fn iter_mut(&mut self) -> LayerIteratorMut<'_> {
|
|
LayerIteratorMut::new(&mut self.vec)
|
|
}
|
|
|
|
pub fn indices(&self) -> LayerIndexIterator<'_> {
|
|
LayerIndexIterator::new(&self.vec)
|
|
}
|
|
|
|
pub fn write<P: Primitive>(
|
|
&mut self,
|
|
layer: usize,
|
|
id: Id,
|
|
primitive: P,
|
|
region: UiRegion,
|
|
) -> PrimitiveHandle {
|
|
self[layer].primitives.write(layer, id, primitive, region)
|
|
}
|
|
|
|
pub fn free(&mut self, h: &PrimitiveHandle) {
|
|
self[h.layer].primitives.free(h)
|
|
}
|
|
}
|
|
|
|
impl Default for Layers {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl Index<usize> for Layers {
|
|
type Output = Layer;
|
|
|
|
fn index(&self, index: usize) -> &Self::Output {
|
|
&self.vec[index].data
|
|
}
|
|
}
|
|
|
|
impl IndexMut<usize> for Layers {
|
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
|
&mut self.vec[index].data
|
|
}
|
|
}
|
|
|
|
impl LayerNode {
|
|
pub fn new(data: Layer, next: Ptr, prev: Ptr) -> Self {
|
|
Self {
|
|
next,
|
|
prev,
|
|
child: None,
|
|
data,
|
|
}
|
|
}
|
|
|
|
pub fn head() -> Self {
|
|
Self::new(Layer::default(), Ptr::None, Ptr::None)
|
|
}
|
|
}
|
|
|
|
pub struct LayerIteratorMut<'a> {
|
|
inner: LayerIndexIterator<'a>,
|
|
}
|
|
|
|
impl<'a> Iterator for LayerIteratorMut<'a> {
|
|
type Item = (usize, &'a mut Layer);
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let i = self.inner.next()?;
|
|
// SAFETY: requires index iterator to work properly
|
|
#[allow(mutable_transmutes)]
|
|
let layer = unsafe { std::mem::transmute::<&Layer, &mut Layer>(&self.inner.vec[i].data) };
|
|
Some((i, layer))
|
|
}
|
|
}
|
|
|
|
impl<'a> DoubleEndedIterator for LayerIteratorMut<'a> {
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
let i = self.inner.next_back()?;
|
|
// SAFETY: requires index iterator to work properly
|
|
#[allow(mutable_transmutes)]
|
|
let layer = unsafe { std::mem::transmute::<&Layer, &mut Layer>(&self.inner.vec[i].data) };
|
|
Some((i, layer))
|
|
}
|
|
}
|
|
|
|
impl<'a> LayerIteratorMut<'a> {
|
|
fn new(vec: &'a mut Vec<LayerNode>) -> Self {
|
|
Self {
|
|
inner: LayerIndexIterator::new(vec),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct LayerIndexIterator<'a> {
|
|
next: Option<usize>,
|
|
next_back: Option<usize>,
|
|
vec: &'a Vec<LayerNode>,
|
|
}
|
|
|
|
impl<'a> Iterator for LayerIndexIterator<'a> {
|
|
type Item = usize;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let ret_i = self.next?;
|
|
let node = &self.vec[ret_i];
|
|
self.next = if let Some(c) = node.child {
|
|
Some(c.head)
|
|
} else if let Ptr::Next(i) = node.next {
|
|
Some(i)
|
|
} else if let Ptr::Parent(i) = node.next {
|
|
let node = &self.vec[i];
|
|
if let Ptr::Next(i) = node.next {
|
|
Some(i)
|
|
} else {
|
|
None
|
|
}
|
|
} else {
|
|
None
|
|
};
|
|
if self.next_back.unwrap() == ret_i {
|
|
self.next = None;
|
|
self.next_back = None;
|
|
}
|
|
Some(ret_i)
|
|
}
|
|
}
|
|
|
|
impl<'a> DoubleEndedIterator for LayerIndexIterator<'a> {
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
let ret_i = self.next_back?;
|
|
let node = &self.vec[ret_i];
|
|
self.next_back = if let Ptr::Next(mut i) = node.prev {
|
|
while let Some(c) = self.vec[i].child {
|
|
i = c.tail
|
|
}
|
|
Some(i)
|
|
} else if let Ptr::Parent(i) = node.prev {
|
|
Some(i)
|
|
} else {
|
|
None
|
|
};
|
|
if self.next.unwrap() == ret_i {
|
|
self.next = None;
|
|
self.next_back = None;
|
|
}
|
|
Some(ret_i)
|
|
}
|
|
}
|
|
|
|
impl<'a> LayerIndexIterator<'a> {
|
|
fn new(vec: &'a Vec<LayerNode>) -> Self {
|
|
let mut last = 0;
|
|
while let Some(c) = vec[last].child {
|
|
last = c.tail;
|
|
}
|
|
Self {
|
|
next: Some(0),
|
|
next_back: Some(last),
|
|
vec,
|
|
}
|
|
}
|
|
}
|