windows_collections/
observable_vector.rs1use super::*;
2use windows_core::*;
3
4struct StockObservableVector<T>
5where
6 T: RuntimeType + 'static,
7 T::Default: Clone + PartialEq,
8{
9 values: std::sync::RwLock<Vec<T::Default>>,
10 handlers: Event<VectorChangedEventHandler<T>>,
11}
12
13implement_decl! {
14 impl<T> StockObservableVector as StockObservableVector_Impl: [
15 IObservableVector<T>,
16 IVector<T>,
17 IIterable<T>,
18 ]
19 where T: RuntimeType + 'static, T::Default: Clone + PartialEq
20}
21
22impl<T> IObservableVector_Impl<T> for StockObservableVector_Impl<T>
23where
24 T: RuntimeType,
25 T::Default: Clone + PartialEq,
26{
27 fn VectorChanged(&self, vhnd: Ref<VectorChangedEventHandler<T>>) -> Result<i64> {
28 self.handlers.add(vhnd.ok()?)
29 }
30
31 fn RemoveVectorChanged(&self, token: i64) -> Result<()> {
32 self.handlers.remove(token);
33 Ok(())
34 }
35}
36
37impl<T> IIterable_Impl<T> for StockObservableVector_Impl<T>
38where
39 T: RuntimeType,
40 T::Default: Clone + PartialEq,
41{
42 fn First(&self) -> Result<IIterator<T>> {
43 Ok(ComObject::new(StockObservableVectorIterator {
44 owner: self.to_object(),
45 current: 0.into(),
46 })
47 .into_interface())
48 }
49}
50
51impl<T> IVector_Impl<T> for StockObservableVector_Impl<T>
52where
53 T: RuntimeType,
54 T::Default: Clone + PartialEq,
55{
56 fn GetAt(&self, index: u32) -> Result<T> {
57 let values = self.values.read().unwrap();
58 let item = values
59 .get(index as usize)
60 .ok_or_else(|| Error::from(E_BOUNDS))?;
61 T::from_default(item)
62 }
63
64 fn Size(&self) -> Result<u32> {
65 Ok(self.values.read().unwrap().len().try_into()?)
66 }
67
68 fn GetView(&self) -> Result<IVectorView<T>> {
69 let snapshot = self.values.read().unwrap().clone();
70 Ok(IVectorView::<T>::from(snapshot))
71 }
72
73 fn IndexOf(&self, value: Ref<T>, result: &mut u32) -> Result<bool> {
74 let values = self.values.read().unwrap();
75 if let Some(index) = values
76 .iter()
77 .position(|element| element == ref_as_default::<T>(&value))
78 {
79 *result = index as u32;
80 Ok(true)
81 } else {
82 *result = 0;
83 Ok(false)
84 }
85 }
86
87 fn SetAt(&self, index: u32, value: Ref<T>) -> Result<()> {
88 {
89 let mut values = self.values.write().unwrap();
90 let item = values
91 .get_mut(index as usize)
92 .ok_or_else(|| Error::from(E_BOUNDS))?;
93 *item = ref_as_default::<T>(&value).clone();
94 }
95 self.fire_changed(CollectionChange::ItemChanged, index);
96 Ok(())
97 }
98
99 fn InsertAt(&self, index: u32, value: Ref<T>) -> Result<()> {
100 {
101 let mut values = self.values.write().unwrap();
102 let index = index as usize;
103 if index > values.len() {
104 return Err(Error::from(E_BOUNDS));
105 }
106 values.insert(index, ref_as_default::<T>(&value).clone());
107 }
108 self.fire_changed(CollectionChange::ItemInserted, index);
109 Ok(())
110 }
111
112 fn RemoveAt(&self, index: u32) -> Result<()> {
113 {
114 let mut values = self.values.write().unwrap();
115 if index as usize >= values.len() {
116 return Err(Error::from(E_BOUNDS));
117 }
118 values.remove(index as usize);
119 }
120 self.fire_changed(CollectionChange::ItemRemoved, index);
121 Ok(())
122 }
123
124 fn Append(&self, value: Ref<T>) -> Result<()> {
125 let index = {
126 let mut values = self.values.write().unwrap();
127 values.push(ref_as_default::<T>(&value).clone());
128 (values.len() - 1) as u32
129 };
130 self.fire_changed(CollectionChange::ItemInserted, index);
131 Ok(())
132 }
133
134 fn RemoveAtEnd(&self) -> Result<()> {
135 let index = {
136 let mut values = self.values.write().unwrap();
137 if values.is_empty() {
138 return Err(Error::from(E_BOUNDS));
139 }
140 let index = (values.len() - 1) as u32;
141 values.pop();
142 index
143 };
144 self.fire_changed(CollectionChange::ItemRemoved, index);
145 Ok(())
146 }
147
148 fn Clear(&self) -> Result<()> {
149 self.values.write().unwrap().clear();
150 self.fire_changed(CollectionChange::Reset, 0);
151 Ok(())
152 }
153
154 fn GetMany(&self, start_index: u32, items: &mut [T::Default]) -> Result<u32> {
155 let values = self.values.read().unwrap();
156 let current = start_index as usize;
157
158 if current >= values.len() {
159 return Ok(0);
160 }
161
162 let actual = std::cmp::min(values.len() - current, items.len());
163 let (items, _) = items.split_at_mut(actual);
164 items.clone_from_slice(&values[current..current + actual]);
165 Ok(actual as u32)
166 }
167
168 fn ReplaceAll(&self, items: &[T::Default]) -> Result<()> {
169 {
170 let mut values = self.values.write().unwrap();
171 values.clear();
172 values.extend_from_slice(items);
173 }
174 self.fire_changed(CollectionChange::Reset, 0);
175 Ok(())
176 }
177}
178
179impl<T> StockObservableVector_Impl<T>
180where
181 T: RuntimeType,
182 T::Default: Clone + PartialEq,
183{
184 fn fire_changed(&self, change: CollectionChange, index: u32) {
185 let observable: IObservableVector<T> = self.to_object().into_interface();
186 let args: IVectorChangedEventArgs =
187 ComObject::new(StockVectorChangedEventArgs { change, index }).into_interface();
188 self.handlers
189 .call(|handler: &VectorChangedEventHandler<T>| handler.Invoke(&observable, &args));
190 }
191}
192
193struct StockVectorChangedEventArgs {
194 change: CollectionChange,
195 index: u32,
196}
197
198implement_decl! {
199 impl StockVectorChangedEventArgs as StockVectorChangedEventArgs_Impl: [IVectorChangedEventArgs]
200}
201
202impl IVectorChangedEventArgs_Impl for StockVectorChangedEventArgs_Impl {
203 fn CollectionChange(&self) -> Result<CollectionChange> {
204 Ok(self.change)
205 }
206
207 fn Index(&self) -> Result<u32> {
208 Ok(self.index)
209 }
210}
211
212struct StockObservableVectorIterator<T>
213where
214 T: RuntimeType + 'static,
215 T::Default: Clone + PartialEq,
216{
217 owner: ComObject<StockObservableVector<T>>,
218 current: std::sync::atomic::AtomicUsize,
219}
220
221implement_decl! {
222 impl<T> StockObservableVectorIterator as StockObservableVectorIterator_Impl: [
223 IIterator<T>,
224 ]
225 where T: RuntimeType + 'static, T::Default: Clone + PartialEq
226}
227
228impl<T> IIterator_Impl<T> for StockObservableVectorIterator_Impl<T>
229where
230 T: RuntimeType,
231 T::Default: Clone + PartialEq,
232{
233 fn Current(&self) -> Result<T> {
234 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
235 let values = self.owner.values.read().unwrap();
236
237 if let Some(item) = values.get(current) {
238 T::from_default(item)
239 } else {
240 Err(Error::from(E_BOUNDS))
241 }
242 }
243
244 fn HasCurrent(&self) -> Result<bool> {
245 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
246 let values = self.owner.values.read().unwrap();
247 Ok(values.len() > current)
248 }
249
250 fn MoveNext(&self) -> Result<bool> {
251 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
252 let values = self.owner.values.read().unwrap();
253 let len = values.len();
254 drop(values);
255
256 if current < len {
257 self.current
258 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
259 }
260
261 Ok(len > current + 1)
262 }
263
264 fn GetMany(&self, items: &mut [T::Default]) -> Result<u32> {
265 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
266 let values = self.owner.values.read().unwrap();
267
268 if current >= values.len() {
269 return Ok(0);
270 }
271
272 let actual = std::cmp::min(values.len() - current, items.len());
273 let (items, _) = items.split_at_mut(actual);
274 items.clone_from_slice(&values[current..current + actual]);
275
276 self.current
277 .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
278
279 Ok(actual as u32)
280 }
281}
282
283impl<T> From<Vec<T::Default>> for IObservableVector<T>
284where
285 T: RuntimeType,
286 T::Default: Clone + PartialEq,
287{
288 fn from(values: Vec<T::Default>) -> Self {
290 ComObject::new(StockObservableVector {
291 values: std::sync::RwLock::new(values),
292 handlers: Event::new(),
293 })
294 .into_interface()
295 }
296}