use std::ops::{Index, IndexMut, RangeBounds};
use crate::layer::Layer;
#[derive(Default)]
pub struct LayerCollection(Vec<LayerEntry>);
struct LayerEntry {
layer: Box<dyn Layer>,
is_hidden: bool,
}
impl LayerCollection {
pub fn truncate(&mut self, length: usize) {
self.0.truncate(length)
}
pub fn clear(&mut self) {
self.0.clear()
}
pub fn swap_remove(&mut self, index: usize) -> Box<dyn Layer> {
self.0.swap_remove(index).layer
}
pub fn insert(&mut self, index: usize, layer: impl Layer + 'static) {
self.0.insert(index, layer.into());
}
pub fn remove(&mut self, index: usize) -> Box<dyn Layer> {
self.0.remove(index).layer
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&dyn Layer) -> bool,
{
self.0.retain(|entry| f(&*entry.layer))
}
pub fn push(&mut self, layer: impl Layer + 'static) {
self.0.push(layer.into())
}
pub fn pop(&mut self) -> Option<Box<dyn Layer>> {
self.0.pop().map(|entry| entry.layer)
}
pub fn drain<R>(&mut self, range: R) -> impl Iterator<Item = Box<dyn Layer>> + '_
where
R: RangeBounds<usize>,
{
self.0.drain(range).map(|entry| entry.layer)
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn get(&self, index: usize) -> Option<&dyn Layer> {
self.0.get(index).map(|entry| &*entry.layer)
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut Box<dyn Layer>> {
self.0.get_mut(index).map(|entry| &mut entry.layer)
}
pub fn swap(&mut self, a: usize, b: usize) {
self.0.swap(a, b)
}
pub fn iter(&self) -> impl Iterator<Item = &dyn Layer> + '_ {
self.0.iter().map(|entry| &*entry.layer)
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Box<dyn Layer>> + '_ {
self.0.iter_mut().map(|entry| &mut entry.layer)
}
pub fn hide(&mut self, index: usize) {
self.0[index].is_hidden = true;
}
pub fn show(&mut self, index: usize) {
self.0[index].is_hidden = false;
}
pub fn show_by<F>(&mut self, mut f: F)
where
F: FnMut(&dyn Layer) -> bool,
{
for entry in &mut self.0 {
entry.is_hidden = !f(&*entry.layer);
}
}
pub fn is_visible(&self, index: usize) -> bool {
!self.0[index].is_hidden
}
pub fn iter_visible(&self) -> impl Iterator<Item = &dyn Layer> + '_ {
self.0
.iter()
.filter(|entry| !entry.is_hidden)
.map(|entry| &*entry.layer)
}
pub fn get_typed<T: Layer + 'static>(&self, index: usize) -> Option<&T> {
self.0
.get(index)
.and_then(|layer| layer.layer.as_any().downcast_ref::<T>())
}
}
impl Index<usize> for LayerCollection {
type Output = dyn Layer;
fn index(&self, index: usize) -> &Self::Output {
&*self.0[index].layer
}
}
impl IndexMut<usize> for LayerCollection {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut *self.0[index].layer
}
}
impl<L: Into<LayerEntry>, T: IntoIterator<Item = L>> From<T> for LayerCollection {
fn from(value: T) -> Self {
Self(value.into_iter().map(|layer| layer.into()).collect())
}
}
impl<T: Layer + 'static> From<T> for LayerEntry {
fn from(value: T) -> Self {
Self {
layer: Box::new(value),
is_hidden: false,
}
}
}
impl From<Box<dyn Layer>> for LayerEntry {
fn from(value: Box<dyn Layer>) -> Self {
Self {
layer: value,
is_hidden: false,
}
}
}