devpage_design/display/
trees.rs1use kurbo::{BezPath, Vec2};
6
7pub type Id = u32;
9
10#[derive(Clone, Debug)]
15pub struct Transform {
16 pub parent: Option<Id>,
17 pub offset: Vec2,
18 pub item: Option<(super::RunId, crate::tree::OrderKey)>,
19}
20
21#[derive(Clone)]
23pub struct Clip {
24 pub parent: Option<Id>,
25 pub transform: Id,
26 pub path: BezPath,
27}
28
29#[derive(Clone, Copy, Debug, PartialEq)]
31pub enum Blend {
32 Opacity(f32),
34 Add,
37}
38
39#[derive(Clone)]
43pub struct Effect {
44 pub parent: Option<Id>,
45 pub clip: Id,
46 pub transform: Id,
47 pub blend: Blend,
48 pub bounds: Option<BezPath>,
49}
50
51#[derive(Clone)]
53pub struct Arena<T> {
54 pub(super) slots: Vec<Option<T>>,
55 pub(super) free: Vec<Id>,
56}
57
58impl<T> Default for Arena<T> {
59 fn default() -> Self {
60 Arena {
61 slots: Vec::new(),
62 free: Vec::new(),
63 }
64 }
65}
66
67impl<T> Arena<T> {
68 pub fn add(&mut self, t: T) -> Id {
69 match self.free.pop() {
70 Some(id) => {
71 self.slots[id as usize] = Some(t);
72 id
73 }
74 None => {
75 self.slots.push(Some(t));
76 (self.slots.len() - 1) as Id
77 }
78 }
79 }
80
81 pub fn remove(&mut self, id: Id) {
82 if self
83 .slots
84 .get_mut(id as usize)
85 .and_then(Option::take)
86 .is_some()
87 {
88 self.free.push(id);
89 }
90 }
91
92 pub fn live(&self) -> usize {
94 self.slots.len() - self.free.len()
95 }
96
97 pub fn get(&self, id: Id) -> &T {
98 self.slots[id as usize].as_ref().expect("a live node")
99 }
100
101 pub fn get_mut(&mut self, id: Id) -> &mut T {
102 self.slots[id as usize].as_mut().expect("a live node")
103 }
104}
105
106#[derive(Clone, Default)]
108pub struct Trees {
109 pub transforms: Arena<Transform>,
110 pub clips: Arena<Clip>,
111 pub effects: Arena<Effect>,
112}