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}