Async Entity Component System based on the ideas of specs (https://github.com/amethyst/specs)
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

295 rader
6.2 KiB

  1. use crate::{
  2. Consumer, Executor, Folder, IndexedParallelIterator, IndexedProducer, IndexedProducerCallback,
  3. ParallelIterator, Producer, ProducerCallback, Reducer, Setup, WithIndexedProducer,
  4. WithProducer, WithSetup,
  5. };
  6. /* Copied */
  7. pub struct Copied<X> {
  8. base: X,
  9. }
  10. impl<X> Copied<X> {
  11. pub fn new(base: X) -> Self {
  12. Self { base }
  13. }
  14. }
  15. impl<'a, X, T> ParallelIterator<'a> for Copied<X>
  16. where
  17. X: ParallelIterator<'a, Item = &'a T>,
  18. T: Copy + Send + Sync + 'a,
  19. {
  20. type Item = T;
  21. fn drive<E, C, D, R>(self, executor: E, consumer: C) -> E::Result
  22. where
  23. E: Executor<'a, D>,
  24. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  25. D: Send + 'a,
  26. R: Reducer<D> + Send + 'a,
  27. {
  28. self.base.drive(executor, CopiedConsumer { base: consumer })
  29. }
  30. fn len_hint_opt(&self) -> Option<usize> {
  31. self.base.len_hint_opt()
  32. }
  33. }
  34. impl<'a, X, T> IndexedParallelIterator<'a> for Copied<X>
  35. where
  36. X: IndexedParallelIterator<'a, Item = &'a T>,
  37. T: Copy + Send + Sync + 'a,
  38. {
  39. fn drive_indexed<E, C, D, R>(self, executor: E, consumer: C) -> E::Result
  40. where
  41. E: Executor<'a, D>,
  42. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  43. D: Send + 'a,
  44. R: Reducer<D> + Send + 'a,
  45. {
  46. self.base
  47. .drive_indexed(executor, CopiedConsumer { base: consumer })
  48. }
  49. fn len_hint(&self) -> usize {
  50. self.base.len_hint()
  51. }
  52. }
  53. impl<'a, X, T> WithProducer<'a> for Copied<X>
  54. where
  55. X: WithProducer<'a, Item = &'a T>,
  56. T: Copy + Send + Sync + 'a,
  57. {
  58. type Item = T;
  59. fn with_producer<CB>(self, callback: CB) -> CB::Output
  60. where
  61. CB: ProducerCallback<'a, Self::Item>,
  62. {
  63. self.base.with_producer(CopiedCallback { base: callback })
  64. }
  65. }
  66. impl<'a, X, T> WithIndexedProducer<'a> for Copied<X>
  67. where
  68. X: WithIndexedProducer<'a, Item = &'a T>,
  69. T: Copy + Send + Sync + 'a,
  70. {
  71. type Item = T;
  72. fn with_indexed_producer<CB>(self, callback: CB) -> CB::Output
  73. where
  74. CB: IndexedProducerCallback<'a, Self::Item>,
  75. {
  76. self.base
  77. .with_indexed_producer(CopiedCallback { base: callback })
  78. }
  79. }
  80. /* CopiedConsumer */
  81. struct CopiedConsumer<C> {
  82. base: C,
  83. }
  84. impl<C> WithSetup for CopiedConsumer<C>
  85. where
  86. C: WithSetup,
  87. {
  88. fn setup(&self) -> Setup {
  89. self.base.setup()
  90. }
  91. }
  92. impl<'a, T, C> Consumer<&'a T> for CopiedConsumer<C>
  93. where
  94. T: Copy,
  95. C: Consumer<T>,
  96. {
  97. type Folder = CopiedFolder<C::Folder>;
  98. type Reducer = C::Reducer;
  99. type Result = C::Result;
  100. fn split(self) -> (Self, Self, Self::Reducer) {
  101. let (left, right, reducer) = self.base.split();
  102. let left = CopiedConsumer { base: left };
  103. let right = CopiedConsumer { base: right };
  104. (left, right, reducer)
  105. }
  106. fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
  107. let (left, right, reducer) = self.base.split_at(index);
  108. let left = CopiedConsumer { base: left };
  109. let right = CopiedConsumer { base: right };
  110. (left, right, reducer)
  111. }
  112. fn into_folder(self) -> Self::Folder {
  113. CopiedFolder {
  114. base: self.base.into_folder(),
  115. }
  116. }
  117. fn is_full(&self) -> bool {
  118. self.base.is_full()
  119. }
  120. }
  121. /* CopiedFolder */
  122. struct CopiedFolder<F> {
  123. base: F,
  124. }
  125. impl<'a, T, F> Folder<&'a T> for CopiedFolder<F>
  126. where
  127. T: Copy + 'a,
  128. F: Folder<T>,
  129. {
  130. type Result = F::Result;
  131. fn consume(mut self, item: &'a T) -> Self {
  132. self.base = self.base.consume(*item);
  133. self
  134. }
  135. fn consume_iter<X>(mut self, iter: X) -> Self
  136. where
  137. X: IntoIterator<Item = &'a T>,
  138. {
  139. self.base = self.base.consume_iter(iter.into_iter().copied());
  140. self
  141. }
  142. fn complete(self) -> Self::Result {
  143. self.base.complete()
  144. }
  145. fn is_full(&self) -> bool {
  146. self.base.is_full()
  147. }
  148. }
  149. /* CopiedCallback */
  150. struct CopiedCallback<CB> {
  151. base: CB,
  152. }
  153. impl<'a, T, CB> ProducerCallback<'a, &'a T> for CopiedCallback<CB>
  154. where
  155. T: Copy + 'a,
  156. CB: ProducerCallback<'a, T>,
  157. {
  158. type Output = CB::Output;
  159. fn callback<P>(self, producer: P) -> Self::Output
  160. where
  161. P: Producer<Item = &'a T> + 'a,
  162. {
  163. self.base.callback(CopiedProducer { base: producer })
  164. }
  165. }
  166. impl<'a, T, CB> IndexedProducerCallback<'a, &'a T> for CopiedCallback<CB>
  167. where
  168. T: Copy + 'a,
  169. CB: IndexedProducerCallback<'a, T>,
  170. {
  171. type Output = CB::Output;
  172. fn callback<P>(self, producer: P) -> Self::Output
  173. where
  174. P: IndexedProducer<Item = &'a T> + 'a,
  175. {
  176. self.base.callback(CopiedProducer { base: producer })
  177. }
  178. }
  179. /* CopiedProducer */
  180. struct CopiedProducer<P> {
  181. base: P,
  182. }
  183. impl<P> WithSetup for CopiedProducer<P>
  184. where
  185. P: WithSetup,
  186. {
  187. fn setup(&self) -> Setup {
  188. self.base.setup()
  189. }
  190. }
  191. impl<'a, T, P> Producer for CopiedProducer<P>
  192. where
  193. T: Copy + 'a,
  194. P: Producer<Item = &'a T>,
  195. {
  196. type Item = T;
  197. type IntoIter = std::iter::Copied<P::IntoIter>;
  198. fn into_iter(self) -> Self::IntoIter {
  199. self.base.into_iter().copied()
  200. }
  201. fn split(self) -> (Self, Option<Self>) {
  202. let (left, right) = self.base.split();
  203. let left = CopiedProducer { base: left };
  204. let right = right.map(|right| CopiedProducer { base: right });
  205. (left, right)
  206. }
  207. fn fold_with<F>(self, folder: F) -> F
  208. where
  209. F: Folder<Self::Item>,
  210. {
  211. self.base.fold_with(CopiedFolder { base: folder }).base
  212. }
  213. }
  214. impl<'a, T, P> IndexedProducer for CopiedProducer<P>
  215. where
  216. T: Copy + 'a,
  217. P: IndexedProducer<Item = &'a T>,
  218. {
  219. type Item = T;
  220. type IntoIter = std::iter::Copied<P::IntoIter>;
  221. fn into_iter(self) -> Self::IntoIter {
  222. self.base.into_iter().copied()
  223. }
  224. fn len(&self) -> usize {
  225. self.base.len()
  226. }
  227. fn split_at(self, index: usize) -> (Self, Self) {
  228. let (left, right) = self.base.split_at(index);
  229. let left = CopiedProducer { base: left };
  230. let right = CopiedProducer { base: right };
  231. (left, right)
  232. }
  233. fn fold_with<F>(self, folder: F) -> F
  234. where
  235. F: Folder<Self::Item>,
  236. {
  237. self.base.fold_with(CopiedFolder { base: folder }).base
  238. }
  239. }