use cvkg_core::Rect;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct LayerId(pub u64);
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum Material {
#[default]
Opaque,
Glass {
blur_radius: f32,
depth_index: u32,
},
Overlay,
Multiply,
Screen,
BlendOverlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
HardLight,
SoftLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity,
Isolated,
}
#[derive(Debug, Clone)]
pub struct DrawCommand {
pub texture_id: Option<u32>,
pub scissor_rect: Option<Rect>,
pub index_start: u32,
pub index_count: u32,
}
#[derive(Debug, Clone)]
pub struct Layer {
pub id: LayerId,
pub bounds: Rect,
pub transform: [f32; 16],
pub material: Material,
pub draw_list: Vec<DrawCommand>,
pub children: Vec<LayerId>,
pub visible: bool,
pub opacity: f32,
}
impl Default for Layer {
fn default() -> Self {
Self {
id: LayerId::default(),
bounds: Rect::zero(),
transform: [
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
],
material: Material::Opaque,
draw_list: Vec::new(),
children: Vec::new(),
visible: true,
opacity: 1.0,
}
}
}
pub struct LayerTree {
layers: HashMap<LayerId, Layer>,
roots: Vec<LayerId>,
next_id: u64,
generation: u64,
layer_generations: HashMap<LayerId, u64>,
}
impl Default for LayerTree {
fn default() -> Self {
Self::new()
}
}
impl LayerTree {
pub fn new() -> Self {
Self {
layers: HashMap::new(),
roots: Vec::new(),
next_id: 1,
generation: 0,
layer_generations: HashMap::new(),
}
}
pub fn allocate_id(&mut self) -> LayerId {
let id = LayerId(self.next_id);
self.next_id += 1;
id
}
pub fn insert_layer(&mut self, layer: Layer) {
let id = layer.id;
self.layer_generations.insert(id, self.generation);
self.layers.insert(id, layer);
}
pub fn remove_layer(&mut self, id: LayerId) -> Option<Layer> {
self.layer_generations.remove(&id);
self.layers.remove(&id)
}
pub fn get_layer(&self, id: LayerId) -> Option<&Layer> {
self.layers.get(&id)
}
pub fn get_layer_mut(&mut self, id: LayerId) -> Option<&mut Layer> {
self.layers.get_mut(&id)
}
pub fn roots(&self) -> &[LayerId] {
&self.roots
}
pub fn set_roots(&mut self, roots: Vec<LayerId>) {
self.roots = roots;
}
pub fn mark_dirty(&mut self, id: LayerId) {
self.layer_generations.insert(id, self.generation);
}
pub fn is_dirty(&self, id: LayerId, since_generation: u64) -> bool {
self.layer_generations
.get(&id)
.is_some_and(|&g| g > since_generation)
}
pub fn advance_generation(&mut self) {
self.generation += 1;
}
pub fn generation(&self) -> u64 {
self.generation
}
pub fn iter_layers(&self) -> impl Iterator<Item = &Layer> {
self.layers.values()
}
pub fn len(&self) -> usize {
self.layers.len()
}
pub fn is_empty(&self) -> bool {
self.layers.is_empty()
}
pub fn clear(&mut self) {
self.layers.clear();
self.roots.clear();
self.layer_generations.clear();
self.generation += 1;
}
}