use kurbo::{BezPath, Vec2};
pub type Id = u32;
#[derive(Clone, Debug)]
pub struct Transform {
pub parent: Option<Id>,
pub offset: Vec2,
pub item: Option<(super::RunId, crate::tree::OrderKey)>,
}
#[derive(Clone)]
pub struct Clip {
pub parent: Option<Id>,
pub transform: Id,
pub path: BezPath,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Blend {
Opacity(f32),
Add,
}
#[derive(Clone)]
pub struct Effect {
pub parent: Option<Id>,
pub clip: Id,
pub transform: Id,
pub blend: Blend,
pub bounds: Option<BezPath>,
}
#[derive(Clone)]
pub struct Arena<T> {
pub(super) slots: Vec<Option<T>>,
pub(super) free: Vec<Id>,
}
impl<T> Default for Arena<T> {
fn default() -> Self {
Arena {
slots: Vec::new(),
free: Vec::new(),
}
}
}
impl<T> Arena<T> {
pub fn add(&mut self, t: T) -> Id {
match self.free.pop() {
Some(id) => {
self.slots[id as usize] = Some(t);
id
}
None => {
self.slots.push(Some(t));
(self.slots.len() - 1) as Id
}
}
}
pub fn remove(&mut self, id: Id) {
if self
.slots
.get_mut(id as usize)
.and_then(Option::take)
.is_some()
{
self.free.push(id);
}
}
pub fn live(&self) -> usize {
self.slots.len() - self.free.len()
}
pub fn get(&self, id: Id) -> &T {
self.slots[id as usize].as_ref().expect("a live node")
}
pub fn get_mut(&mut self, id: Id) -> &mut T {
self.slots[id as usize].as_mut().expect("a live node")
}
}
#[derive(Clone, Default)]
pub struct Trees {
pub transforms: Arena<Transform>,
pub clips: Arena<Clip>,
pub effects: Arena<Effect>,
}