Skip to main content

windows_collections/
observable_vector.rs

1use 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    /// Creates an `IObservableVector<T>` containing the given values.
289    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}