alisa/tree/
child_list.rs

1
2use crate::{LoadingPtr, Object, Project, Ptr, Recorder, RecreateObjectDelta, Serializable};
3
4use super::{Children, TreeObj};
5
6#[derive(Clone)]
7pub struct ChildList<O: Object> {
8    children: Vec<LoadingPtr<O>>
9}
10
11impl<O: Object> ChildList<O> {
12
13    pub fn new() -> Self {
14        Self {
15            children: Vec::new()
16        }
17    }
18    
19    pub fn iter(&self) -> impl Iterator<Item = Ptr<O>> + '_ {
20        self.children.iter().map(LoadingPtr::ptr)
21    }
22
23}
24
25impl<O: Object> Default for ChildList<O> {
26
27    fn default() -> Self {
28        Self::new()
29    }
30
31}
32
33impl<O: Object> Serializable<O::Project> for ChildList<O> {
34
35    fn serialize(&self, context: &crate::SerializationContext<O::Project>) -> rmpv::Value {
36        self.children.serialize(context)
37    }
38
39    fn deserialize(data: &rmpv::Value, context: &mut crate::DeserializationContext<O::Project>) -> Option<Self> {
40        let children = Vec::<LoadingPtr<O>>::deserialize(data, context)?;
41        Some(Self {
42            children
43        })
44    }
45
46}
47
48impl<O: Object> Children<O> for ChildList<O> {
49
50    type Index = usize;
51
52    fn n_children(&self) -> usize {
53        self.children.len()
54    }
55
56    fn insert(&mut self, idx: usize, child: Ptr<O>) {
57        let idx = idx.clamp(0, self.n_children());
58        self.children.insert(idx, LoadingPtr::new(child));
59    }
60
61    fn remove(&mut self, child: Ptr<O>) -> Option<usize> {
62        for i in 0..self.children.len() {
63            if self.children[i].ptr() == child {
64                self.children.remove(i);
65                return Some(i);
66            }
67        }
68        None
69    }
70
71    fn index_of(&self, child: Ptr<O>) -> Option<usize> {
72        for i in 0..self.children.len() {
73            if self.children[i].ptr() == child {
74                return Some(i);
75            }
76        }
77        None
78    }
79
80}
81
82pub struct ChildListTreeData<O: TreeObj> {
83    children: Vec<(Ptr<O>, O::TreeData)>
84}
85
86impl<O: TreeObj> Default for ChildListTreeData<O> {
87
88    fn default() -> Self {
89        Self { children: Vec::new() }
90    }
91
92} 
93
94impl<O: TreeObj> Serializable<<O as Object>::Project> for ChildListTreeData<O> {
95
96    fn serialize(&self, context: &crate::SerializationContext<<O as Object>::Project>) -> rmpv::Value {
97        rmpv::Value::Array(
98            self.children.iter()
99                .map(|(ptr, obj_data)| rmpv::Value::Array(vec![ptr.serialize(context), obj_data.serialize(context)]))
100                .collect()
101        )
102    }
103
104    fn deserialize(data: &rmpv::Value, context: &mut crate::DeserializationContext<<O as Object>::Project>) -> Option<Self> {
105        let data = data.as_array()?;
106        let mut children = Vec::new();
107        for child in data {
108            let Some(child) = child.as_array() else { continue; };
109            let Some(ptr_data) = child.get(0) else { continue; };
110            let Some(obj_data) = child.get(1) else { continue; };
111            let Some(ptr) = Ptr::deserialize(ptr_data, context) else { continue; };
112            let Some(obj_data) = O::TreeData::deserialize(obj_data, context) else { continue; };
113            children.push((ptr, obj_data));
114        }
115        Some(Self {
116            children,
117        })
118    }
119
120}
121
122impl<O: TreeObj> ChildList<O> {
123
124    pub fn collect_data(&self, objects: &<O::Project as Project>::Objects) -> ChildListTreeData<O> {
125        ChildListTreeData {
126            children: self.children.iter()
127                .map(|loading_ptr| loading_ptr.ptr())
128                .filter_map(|ptr| O::list(objects).get(ptr).map(|obj| (ptr, obj.collect_data(objects))))
129                .collect(),
130        }
131    }
132
133    pub fn destroy(&self, recorder: &mut Recorder<O::Project>) {
134        for child in &self.children {
135            let ptr = child.ptr();
136            if let Some(obj) = recorder.obj_list_mut().delete(ptr) {
137                obj.destroy(recorder);
138                recorder.push_delta(RecreateObjectDelta {
139                    ptr,
140                    obj,
141                });
142            }
143        }
144    }
145
146}
147
148impl<O: TreeObj> ChildListTreeData<O> {
149
150    pub fn instance(&self, parent: O::ParentPtr, recorder: &mut crate::Recorder<O::Project>) -> ChildList<O> {
151        for (ptr, obj_data) in &self.children { 
152            O::instance(obj_data, *ptr, parent.clone(), recorder);
153        }
154        ChildList {
155            children: self.children.iter().map(|(ptr, _)| LoadingPtr::new(*ptr)).collect(),
156        }
157    }
158
159}