1use crate::cx::*;
2use std::collections::HashMap;
3
4#[derive(Clone, Default)]
23pub struct ElementsRedraw<T> {
24 redraw_id: u64,
25 item: T
26}
27
28#[derive(Clone, Default)]
30pub struct Elements<ID, T, TEMPL>
31where ID: std::cmp::Ord + std::hash::Hash {
32 pub template: TEMPL,
33 pub element_list: Vec<ID>,
34 pub element_map: HashMap<ID, ElementsRedraw<T>>,
35 pub redraw_id: u64
36}
37
38pub struct ElementsIterator<'a, ID, T, TEMPL>
39where ID: std::cmp::Ord + std::hash::Hash {
40 elements: &'a mut Elements<ID, T, TEMPL>,
41 counter: usize
42}
43
44impl<'a, T, ID, TEMPL> ElementsIterator<'a, ID, T, TEMPL>
45where ID: std::cmp::Ord + std::hash::Hash {
46 fn new(elements: &'a mut Elements<ID, T, TEMPL>) -> Self {
47 ElementsIterator {
48 elements: elements,
49 counter: 0
50 }
51 }
52}
53
54impl<'a, ID, T, TEMPL> Iterator for ElementsIterator<'a, ID, T, TEMPL>
55where ID: std::cmp::Ord + std::hash::Hash + Clone
56{
57 type Item = &'a mut T;
58
59 fn next(&mut self) -> Option<Self::Item> {
60 loop {
61 if self.counter >= self.elements.element_list.len() {
62 return None
63 }
64 let element_id = &self.elements.element_list[self.counter];
65 let element = self.elements.element_map.get_mut(&element_id).unwrap();
66 self.counter += 1;
67 if element.redraw_id == self.elements.redraw_id {
68 return Some(unsafe {std::mem::transmute(&mut element.item)});
69 }
70 }
71 }
72}
73
74
75pub struct ElementsIteratorNamed<'a, ID, T, TEMPL>
76where ID: std::cmp::Ord + std::hash::Hash {
77 elements: &'a mut Elements<ID, T, TEMPL>,
78 counter: usize
79}
80
81impl<'a, ID, T, TEMPL> ElementsIteratorNamed<'a, ID, T, TEMPL>
82where ID: std::cmp::Ord + std::hash::Hash {
83 fn new(elements: &'a mut Elements<ID, T, TEMPL>) -> Self {
84 ElementsIteratorNamed {
85 elements: elements,
86 counter: 0
87 }
88 }
89}
90
91impl<'a, ID, T, TEMPL> Iterator for ElementsIteratorNamed<'a, ID, T, TEMPL>
92where ID: std::cmp::Ord + std::hash::Hash + Clone
93{
94 type Item = (&'a ID, &'a mut T);
95
96 fn next(&mut self) -> Option<Self::Item> {
97 loop {
98 if self.counter >= self.elements.element_list.len() {
99 return None
100 }
101 let element_id = &mut self.elements.element_list[self.counter];
102 let element = self.elements.element_map.get_mut(&element_id).unwrap();
103 self.counter += 1;
104 if element.redraw_id == self.elements.redraw_id {
105 return Some((unsafe {std::mem::transmute(element_id)}, unsafe {std::mem::transmute(&mut element.item)}));
106 }
107 }
108 }
109}
110
111impl<ID, T, TEMPL> Elements<ID, T, TEMPL>
112where ID: std::cmp::Ord + std::hash::Hash + Clone
113{
114 pub fn new(template: TEMPL) -> Elements<ID, T, TEMPL> {
115 Elements::<ID, T, TEMPL> {
116 template: template,
117 redraw_id: 0,
118 element_list: Vec::new(),
119 element_map: HashMap::new(),
120 }
121 }
122
123 pub fn mark(&mut self, cx: &Cx) {
126 if !cx.is_in_redraw_cycle {
127 panic!("Cannot call mark outside of redraw cycle!")
128 }
129 self.redraw_id = cx.redraw_id;
130 }
131
132 pub fn sweep<F>(&mut self, cx: &mut Cx, mut destruct_callback: F)
134 where F: FnMut(&mut Cx, &mut T) {
135 if !cx.is_in_redraw_cycle {
136 panic!("Cannot call sweep outside of redraw cycle!")
137 }
138 let mut i = 0;
139 loop {
140 if i >= self.element_list.len() {
141 break;
142 }
143 let elem_id = self.element_list[i].clone();
144 let elem = self.element_map.get(&elem_id).unwrap();
145 if elem.redraw_id != self.redraw_id {
146 self.element_list.remove(i);
147 let mut elem = self.element_map.remove(&elem_id).unwrap();
148 destruct_callback(cx, &mut elem.item);
149 }
150 else {
151 i = i + 1;
152 }
153 }
154 }
155
156 pub fn clear<F>(&mut self, cx: &mut Cx, mut destruct_callback: F)
158 where F: FnMut(&mut Cx, &mut T) {
159 for elem_id in &self.element_list {
160 let mut elem = self.element_map.remove(&elem_id).unwrap();
161 destruct_callback(cx, &mut elem.item);
162 }
163 self.element_list.truncate(0);
164 }
165
166 pub fn iter<'a>(&'a mut self) -> ElementsIterator<'a, ID, T, TEMPL> {
180 return ElementsIterator::new(self)
181 }
182
183 pub fn enumerate<'a>(&'a mut self) -> ElementsIteratorNamed<'a, ID, T, TEMPL> {
185 return ElementsIteratorNamed::new(self)
186 }
187
188 pub fn get<'a>(&'a mut self, index: ID) -> Option<&mut T> {
190 let elem = self.element_map.get_mut(&index);
191 if let Some(elem) = elem {
192 return Some(&mut elem.item)
193 }
194 else {
195 return None
196 }
197 }
198
199 pub fn get_draw<F>(&mut self, cx: &mut Cx, index: ID, mut insert_callback: F) -> &mut T
200 where F: FnMut(&mut Cx, &TEMPL) -> T {
201 if !cx.is_in_redraw_cycle {
202 panic!("Cannot call get_draw outside of redraw cycle!")
203 }
204 self.mark(cx);
205 let template = &self.template;
206 let element_list = &mut self.element_list;
207 let redraw_id = self.redraw_id;
208 let redraw = self.element_map.entry(index.clone()).or_insert_with( || {
209 element_list.push(index);
210 let elem = insert_callback(cx, &template);
211 ElementsRedraw {
212 redraw_id: redraw_id,
213 item: elem
214 }
215 });
216 redraw.redraw_id = redraw_id;
217 &mut redraw.item
218 }
219}
220
221
222#[derive(Clone, Default)]
224pub struct ElementsCounted<T>
225where T: Clone {
226 pub counter: u64,
227 pub elements: Elements<u64, T, T>
228}
229
230impl<T> ElementsCounted<T>
231where T:Clone{
232 pub fn new(template: T) -> ElementsCounted<T>
233 where T: Clone {
234 ElementsCounted::<T> {
235 counter: 0,
236 elements: Elements::new(template)
237 }
238 }
239
240 pub fn iter<'a>(&'a mut self) -> ElementsIterator<'a, u64, T, T>
241 where T: Clone {
242 return ElementsIterator::new(&mut self.elements)
243 }
244
245 pub fn enumerate<'a>(&'a mut self) -> ElementsIteratorNamed<'a, u64, T, T>
247 where T: Clone {
248 return ElementsIteratorNamed::new(&mut self.elements)
249 }
250
251 pub fn get<'a>(&'a mut self, index: u64) -> Option<&mut T>
253 where T: Clone {
254 return self.elements.get(index)
255 }
256
257 pub fn template(&mut self)->&mut T{
258 &mut self.elements.template
259 }
260
261 pub fn get_draw(&mut self, cx: &mut Cx) -> &mut T
262 where T:Clone{
263 if !cx.is_in_redraw_cycle {
264 panic!("Cannot call get_draw outside of redraw cycle!")
265 }
266 if self.elements.redraw_id != cx.redraw_id {
267 self.counter = 0;
268 }
269 else {
270 self.counter += 1;
271 }
272 self.elements.get_draw(cx, self.counter, | _cx, tmpl | tmpl.clone())
273 }
274}