Async Entity Component System based on the ideas of specs (https://github.com/amethyst/specs)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 line
8.7 KiB

  1. use std::iter::{DoubleEndedIterator, ExactSizeIterator, Iterator};
  2. use std::sync::{
  3. atomic::{AtomicBool, Ordering},
  4. Arc,
  5. };
  6. use crate::{
  7. Consumer, Executor, Folder, IndexedParallelIterator, IndexedProducer, IndexedProducerCallback,
  8. ParallelIterator, Producer, ProducerCallback, Reducer, Setup, WithIndexedProducer,
  9. WithProducer, WithSetup,
  10. };
  11. /* WhileSome */
  12. pub struct WhileSome<X> {
  13. base: X,
  14. }
  15. impl<X> WhileSome<X> {
  16. pub fn new(base: X) -> Self {
  17. Self { base }
  18. }
  19. }
  20. impl<'a, X, T> ParallelIterator<'a> for WhileSome<X>
  21. where
  22. X: ParallelIterator<'a, Item = Option<T>>,
  23. T: Send + 'a,
  24. {
  25. type Item = T;
  26. fn drive<E, C, D, R>(self, executor: E, base: C) -> E::Result
  27. where
  28. E: Executor<'a, D>,
  29. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  30. D: Send + 'a,
  31. R: Reducer<D> + Send + 'a,
  32. {
  33. let consumer = WhileSomeConsumer {
  34. base,
  35. is_full: Arc::new(AtomicBool::new(false)),
  36. };
  37. self.base.drive(executor, consumer)
  38. }
  39. fn len_hint_opt(&self) -> Option<usize> {
  40. self.base.len_hint_opt()
  41. }
  42. }
  43. impl<'a, X, T> IndexedParallelIterator<'a> for WhileSome<X>
  44. where
  45. X: IndexedParallelIterator<'a, Item = Option<T>>,
  46. T: Send + 'a,
  47. {
  48. fn drive_indexed<E, C, D, R>(self, executor: E, base: C) -> E::Result
  49. where
  50. E: Executor<'a, D>,
  51. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  52. D: Send + 'a,
  53. R: Reducer<D> + Send + 'a,
  54. {
  55. let consumer = WhileSomeConsumer {
  56. base,
  57. is_full: Arc::new(AtomicBool::new(false)),
  58. };
  59. self.base.drive_indexed(executor, consumer)
  60. }
  61. fn len_hint(&self) -> usize {
  62. self.base.len_hint()
  63. }
  64. }
  65. impl<'a, X, T> WithProducer<'a> for WhileSome<X>
  66. where
  67. X: WithProducer<'a, Item = Option<T>>,
  68. T: Send + 'a,
  69. {
  70. type Item = T;
  71. fn with_producer<CB>(self, base: CB) -> CB::Output
  72. where
  73. CB: ProducerCallback<'a, Self::Item>,
  74. {
  75. self.base.with_producer(WhileSomeCallback { base })
  76. }
  77. }
  78. impl<'a, X, T> WithIndexedProducer<'a> for WhileSome<X>
  79. where
  80. X: WithIndexedProducer<'a, Item = Option<T>>,
  81. T: Send + 'a,
  82. {
  83. type Item = T;
  84. fn with_indexed_producer<CB>(self, base: CB) -> CB::Output
  85. where
  86. CB: IndexedProducerCallback<'a, Self::Item>,
  87. {
  88. self.base.with_indexed_producer(WhileSomeCallback { base })
  89. }
  90. }
  91. /* WhileSomeCallback */
  92. struct WhileSomeCallback<CB> {
  93. base: CB,
  94. }
  95. impl<'a, CB, T> ProducerCallback<'a, Option<T>> for WhileSomeCallback<CB>
  96. where
  97. CB: ProducerCallback<'a, T>,
  98. {
  99. type Output = CB::Output;
  100. fn callback<P>(self, base: P) -> Self::Output
  101. where
  102. P: Producer<Item = Option<T>> + 'a,
  103. {
  104. self.base.callback(WhileSomeProducer {
  105. base,
  106. is_full: Arc::new(AtomicBool::new(false)),
  107. })
  108. }
  109. }
  110. impl<'a, CB, T> IndexedProducerCallback<'a, Option<T>> for WhileSomeCallback<CB>
  111. where
  112. CB: IndexedProducerCallback<'a, T>,
  113. {
  114. type Output = CB::Output;
  115. fn callback<P>(self, base: P) -> Self::Output
  116. where
  117. P: IndexedProducer<Item = Option<T>> + 'a,
  118. {
  119. self.base.callback(WhileSomeProducer {
  120. base,
  121. is_full: Arc::new(AtomicBool::new(false)),
  122. })
  123. }
  124. }
  125. /* WhileSomeProducer */
  126. struct WhileSomeProducer<P> {
  127. base: P,
  128. is_full: Arc<AtomicBool>,
  129. }
  130. impl<P> WithSetup for WhileSomeProducer<P>
  131. where
  132. P: WithSetup,
  133. {
  134. fn setup(&self) -> Setup {
  135. self.base.setup()
  136. }
  137. }
  138. impl<P, T> Producer for WhileSomeProducer<P>
  139. where
  140. P: Producer<Item = Option<T>>,
  141. {
  142. type Item = T;
  143. type IntoIter = WhileSomeIter<P::IntoIter>;
  144. fn into_iter(self) -> Self::IntoIter {
  145. WhileSomeIter {
  146. base: self.base.into_iter(),
  147. is_full: self.is_full,
  148. }
  149. }
  150. fn split(self) -> (Self, Option<Self>) {
  151. let is_full = self.is_full;
  152. let (left, right) = self.base.split();
  153. let left = Self {
  154. base: left,
  155. is_full: is_full.clone(),
  156. };
  157. let right = right.map(|x| Self { base: x, is_full });
  158. (left, right)
  159. }
  160. }
  161. impl<P, T> IndexedProducer for WhileSomeProducer<P>
  162. where
  163. P: IndexedProducer<Item = Option<T>>,
  164. {
  165. type Item = T;
  166. type IntoIter = WhileSomeIter<P::IntoIter>;
  167. fn into_iter(self) -> Self::IntoIter {
  168. WhileSomeIter {
  169. base: self.base.into_iter(),
  170. is_full: self.is_full,
  171. }
  172. }
  173. fn len(&self) -> usize {
  174. self.base.len()
  175. }
  176. fn split_at(self, index: usize) -> (Self, Self) {
  177. let (left, right) = self.base.split_at(index);
  178. let left = Self {
  179. base: left,
  180. is_full: self.is_full.clone(),
  181. };
  182. let right = Self {
  183. base: right,
  184. is_full: self.is_full,
  185. };
  186. (left, right)
  187. }
  188. }
  189. /* WhileSomeIter */
  190. struct WhileSomeIter<I> {
  191. base: I,
  192. is_full: Arc<AtomicBool>,
  193. }
  194. impl<I, T> Iterator for WhileSomeIter<I>
  195. where
  196. I: Iterator<Item = Option<T>>,
  197. {
  198. type Item = T;
  199. fn next(&mut self) -> Option<Self::Item> {
  200. if self.is_full.load(Ordering::Relaxed) {
  201. return None;
  202. }
  203. match self.base.next()? {
  204. Some(next) => Some(next),
  205. None => {
  206. self.is_full.store(true, Ordering::Relaxed);
  207. None
  208. }
  209. }
  210. }
  211. fn size_hint(&self) -> (usize, Option<usize>) {
  212. if self.is_full.load(Ordering::Relaxed) {
  213. (0, Some(0))
  214. } else {
  215. let (_min, max) = self.base.size_hint();
  216. (0, max)
  217. }
  218. }
  219. }
  220. impl<I, T> DoubleEndedIterator for WhileSomeIter<I>
  221. where
  222. I: DoubleEndedIterator<Item = Option<T>>,
  223. {
  224. fn next_back(&mut self) -> Option<Self::Item> {
  225. if self.is_full.load(Ordering::Relaxed) {
  226. return None;
  227. }
  228. match self.base.next()? {
  229. Some(next) => Some(next),
  230. None => {
  231. self.is_full.store(true, Ordering::Relaxed);
  232. None
  233. }
  234. }
  235. }
  236. }
  237. impl<I, T> ExactSizeIterator for WhileSomeIter<I> where I: ExactSizeIterator<Item = Option<T>> {}
  238. /* WhileSomeConsumer */
  239. struct WhileSomeConsumer<C> {
  240. base: C,
  241. is_full: Arc<AtomicBool>,
  242. }
  243. impl<C> WithSetup for WhileSomeConsumer<C>
  244. where
  245. C: WithSetup,
  246. {
  247. fn setup(&self) -> Setup {
  248. self.base.setup()
  249. }
  250. }
  251. impl<C, T> Consumer<Option<T>> for WhileSomeConsumer<C>
  252. where
  253. C: Consumer<T>,
  254. T: Send,
  255. {
  256. type Folder = WhileSomeFolder<C::Folder>;
  257. type Reducer = C::Reducer;
  258. type Result = C::Result;
  259. fn split(self) -> (Self, Self, Self::Reducer) {
  260. let (left, right, reducer) = self.base.split();
  261. let left = Self {
  262. base: left,
  263. is_full: self.is_full.clone(),
  264. };
  265. let right = Self {
  266. base: right,
  267. is_full: self.is_full,
  268. };
  269. (left, right, reducer)
  270. }
  271. fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
  272. let (left, right, reducer) = self.base.split_at(index);
  273. let left = Self {
  274. base: left,
  275. is_full: self.is_full.clone(),
  276. };
  277. let right = Self {
  278. base: right,
  279. is_full: self.is_full,
  280. };
  281. (left, right, reducer)
  282. }
  283. fn into_folder(self) -> Self::Folder {
  284. let base = self.base.into_folder();
  285. WhileSomeFolder {
  286. base,
  287. is_full: self.is_full,
  288. }
  289. }
  290. fn is_full(&self) -> bool {
  291. self.is_full.load(Ordering::Relaxed) || self.base.is_full()
  292. }
  293. }
  294. /* WhileSomeFolder */
  295. struct WhileSomeFolder<F> {
  296. base: F,
  297. is_full: Arc<AtomicBool>,
  298. }
  299. impl<F, I> Folder<Option<I>> for WhileSomeFolder<F>
  300. where
  301. F: Folder<I>,
  302. {
  303. type Result = F::Result;
  304. fn consume(mut self, item: Option<I>) -> Self {
  305. match item {
  306. Some(item) => self.base = self.base.consume(item),
  307. None => self.is_full.store(true, Ordering::Relaxed),
  308. }
  309. self
  310. }
  311. fn consume_iter<X>(mut self, iter: X) -> Self
  312. where
  313. X: IntoIterator<Item = Option<I>>,
  314. {
  315. let is_full = self.is_full.clone();
  316. let iter = iter
  317. .into_iter()
  318. .take_while(|x| match *x {
  319. Some(_) => !is_full.load(Ordering::Relaxed),
  320. None => {
  321. is_full.store(true, Ordering::Relaxed);
  322. false
  323. }
  324. })
  325. .map(Option::unwrap);
  326. self.base = self.base.consume_iter(iter);
  327. self
  328. }
  329. fn complete(self) -> Self::Result {
  330. self.base.complete()
  331. }
  332. fn is_full(&self) -> bool {
  333. self.is_full.load(Ordering::Relaxed) || self.base.is_full()
  334. }
  335. }