Async Entity Component System based on the ideas of specs (https://github.com/amethyst/specs)
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

281 рядки
5.8 KiB

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