Skip to main content

windows_collections/
vector.rs

1use super::*;
2use windows_core::*;
3
4struct StockVector<T>
5where
6    T: RuntimeType + 'static,
7    T::Default: Clone + PartialEq,
8{
9    values: std::sync::RwLock<Vec<T::Default>>,
10}
11
12implement_decl! {
13    impl<T> StockVector as StockVector_Impl: [
14        IVector<T>,
15        IIterable<T>,
16    ]
17    where T: RuntimeType + 'static, T::Default: Clone + PartialEq
18}
19
20impl<T> IIterable_Impl<T> for StockVector_Impl<T>
21where
22    T: RuntimeType,
23    T::Default: Clone + PartialEq,
24{
25    fn First(&self) -> Result<IIterator<T>> {
26        Ok(ComObject::new(StockVectorIterator {
27            owner: self.to_object(),
28            current: 0.into(),
29        })
30        .into_interface())
31    }
32}
33
34impl<T> IVector_Impl<T> for StockVector_Impl<T>
35where
36    T: RuntimeType,
37    T::Default: Clone + PartialEq,
38{
39    fn GetAt(&self, index: u32) -> Result<T> {
40        let values = self.values.read().unwrap();
41        let item = values
42            .get(index as usize)
43            .ok_or_else(|| Error::from(E_BOUNDS))?;
44        T::from_default(item)
45    }
46
47    fn Size(&self) -> Result<u32> {
48        Ok(self.values.read().unwrap().len().try_into()?)
49    }
50
51    fn GetView(&self) -> Result<IVectorView<T>> {
52        let snapshot = self.values.read().unwrap().clone();
53        Ok(IVectorView::<T>::from(snapshot))
54    }
55
56    fn IndexOf(&self, value: Ref<T>, result: &mut u32) -> Result<bool> {
57        let values = self.values.read().unwrap();
58        if let Some(index) = values
59            .iter()
60            .position(|element| element == ref_as_default::<T>(&value))
61        {
62            *result = index as u32;
63            Ok(true)
64        } else {
65            *result = 0;
66            Ok(false)
67        }
68    }
69
70    fn SetAt(&self, index: u32, value: Ref<T>) -> Result<()> {
71        let mut values = self.values.write().unwrap();
72        let item = values
73            .get_mut(index as usize)
74            .ok_or_else(|| Error::from(E_BOUNDS))?;
75        *item = ref_as_default::<T>(&value).clone();
76        Ok(())
77    }
78
79    fn InsertAt(&self, index: u32, value: Ref<T>) -> Result<()> {
80        let mut values = self.values.write().unwrap();
81        let index = index as usize;
82        if index > values.len() {
83            return Err(Error::from(E_BOUNDS));
84        }
85        values.insert(index, ref_as_default::<T>(&value).clone());
86        Ok(())
87    }
88
89    fn RemoveAt(&self, index: u32) -> Result<()> {
90        let mut values = self.values.write().unwrap();
91        if index as usize >= values.len() {
92            return Err(Error::from(E_BOUNDS));
93        }
94        values.remove(index as usize);
95        Ok(())
96    }
97
98    fn Append(&self, value: Ref<T>) -> Result<()> {
99        self.values
100            .write()
101            .unwrap()
102            .push(ref_as_default::<T>(&value).clone());
103        Ok(())
104    }
105
106    fn RemoveAtEnd(&self) -> Result<()> {
107        let mut values = self.values.write().unwrap();
108        if values.is_empty() {
109            return Err(Error::from(E_BOUNDS));
110        }
111        values.pop();
112        Ok(())
113    }
114
115    fn Clear(&self) -> Result<()> {
116        self.values.write().unwrap().clear();
117        Ok(())
118    }
119
120    fn GetMany(&self, start_index: u32, items: &mut [T::Default]) -> Result<u32> {
121        let values = self.values.read().unwrap();
122        let current = start_index as usize;
123
124        if current >= values.len() {
125            return Ok(0);
126        }
127
128        let actual = std::cmp::min(values.len() - current, items.len());
129        let (items, _) = items.split_at_mut(actual);
130        items.clone_from_slice(&values[current..current + actual]);
131        Ok(actual as u32)
132    }
133
134    fn ReplaceAll(&self, items: &[T::Default]) -> Result<()> {
135        let mut values = self.values.write().unwrap();
136        values.clear();
137        values.extend_from_slice(items);
138        Ok(())
139    }
140}
141
142struct StockVectorIterator<T>
143where
144    T: RuntimeType + 'static,
145    T::Default: Clone + PartialEq,
146{
147    owner: ComObject<StockVector<T>>,
148    current: std::sync::atomic::AtomicUsize,
149}
150
151implement_decl! {
152    impl<T> StockVectorIterator as StockVectorIterator_Impl: [
153        IIterator<T>,
154    ]
155    where T: RuntimeType + 'static, T::Default: Clone + PartialEq
156}
157
158impl<T> IIterator_Impl<T> for StockVectorIterator_Impl<T>
159where
160    T: RuntimeType,
161    T::Default: Clone + PartialEq,
162{
163    fn Current(&self) -> Result<T> {
164        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
165        let values = self.owner.values.read().unwrap();
166
167        if let Some(item) = values.get(current) {
168            T::from_default(item)
169        } else {
170            Err(Error::from(E_BOUNDS))
171        }
172    }
173
174    fn HasCurrent(&self) -> Result<bool> {
175        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
176        let values = self.owner.values.read().unwrap();
177        Ok(values.len() > current)
178    }
179
180    fn MoveNext(&self) -> Result<bool> {
181        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
182        let values = self.owner.values.read().unwrap();
183        let len = values.len();
184        drop(values);
185
186        if current < len {
187            self.current
188                .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
189        }
190
191        Ok(len > current + 1)
192    }
193
194    fn GetMany(&self, items: &mut [T::Default]) -> Result<u32> {
195        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
196        let values = self.owner.values.read().unwrap();
197
198        if current >= values.len() {
199            return Ok(0);
200        }
201
202        let actual = std::cmp::min(values.len() - current, items.len());
203        let (items, _) = items.split_at_mut(actual);
204        items.clone_from_slice(&values[current..current + actual]);
205
206        self.current
207            .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
208
209        Ok(actual as u32)
210    }
211}
212
213impl<T> From<Vec<T::Default>> for IVector<T>
214where
215    T: RuntimeType,
216    T::Default: Clone + PartialEq,
217{
218    /// Creates a mutable `IVector<T>` containing the given values.
219    fn from(values: Vec<T::Default>) -> Self {
220        ComObject::new(StockVector {
221            values: std::sync::RwLock::new(values),
222        })
223        .into_interface()
224    }
225}