Files
iris/src/layout/layer.rs

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,
}
}
}