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

244 рядки
5.7 KiB

  1. use std::cmp::min;
  2. use crate::{
  3. Consumer, Executor, ExecutorCallback, IndexedParallelIterator, IndexedProducer,
  4. IndexedProducerCallback, ParallelIterator, Producer, Reducer, Setup, WithIndexedProducer,
  5. WithSetup,
  6. };
  7. pub struct Zip<XA, XB> {
  8. iterator_a: XA,
  9. iterator_b: XB,
  10. }
  11. impl<XA, XB> Zip<XA, XB> {
  12. pub fn new(iterator_a: XA, iterator_b: XB) -> Self {
  13. Self {
  14. iterator_a,
  15. iterator_b,
  16. }
  17. }
  18. }
  19. impl<'a, XA, XB, A, B> ParallelIterator<'a> for Zip<XA, XB>
  20. where
  21. XA: IndexedParallelIterator<'a, Item = A> + WithIndexedProducer<'a, Item = A>,
  22. XB: IndexedParallelIterator<'a, Item = B> + WithIndexedProducer<'a, Item = B>,
  23. A: Send + 'a,
  24. B: Send + 'a,
  25. {
  26. type Item = (A, B);
  27. fn drive<E, C, D, R>(self, executor: E, consumer: C) -> E::Result
  28. where
  29. E: Executor<'a, D>,
  30. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  31. D: Send + 'a,
  32. R: Reducer<D> + Send + 'a,
  33. {
  34. self.with_indexed_producer(ExecutorCallback::new(executor, consumer))
  35. }
  36. fn len_hint_opt(&self) -> Option<usize> {
  37. match (
  38. self.iterator_a.len_hint_opt(),
  39. self.iterator_b.len_hint_opt(),
  40. ) {
  41. (Some(a), Some(b)) => Some(min(a, b)),
  42. (_, _) => None,
  43. }
  44. }
  45. }
  46. impl<'a, XA, XB, A, B> IndexedParallelIterator<'a> for Zip<XA, XB>
  47. where
  48. XA: IndexedParallelIterator<'a, Item = A> + WithIndexedProducer<'a, Item = A>,
  49. XB: IndexedParallelIterator<'a, Item = B> + WithIndexedProducer<'a, Item = B>,
  50. A: Send + 'a,
  51. B: Send + 'a,
  52. {
  53. fn drive_indexed<E, C, D, R>(self, executor: E, consumer: C) -> E::Result
  54. where
  55. E: Executor<'a, D>,
  56. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  57. D: Send + 'a,
  58. R: Reducer<D> + Send + 'a,
  59. {
  60. self.with_indexed_producer(ExecutorCallback::new(executor, consumer))
  61. }
  62. fn len_hint(&self) -> usize {
  63. min(self.iterator_a.len_hint(), self.iterator_b.len_hint())
  64. }
  65. }
  66. impl<'a, XA, XB> WithIndexedProducer<'a> for Zip<XA, XB>
  67. where
  68. XA: WithIndexedProducer<'a>,
  69. XB: WithIndexedProducer<'a>,
  70. {
  71. type Item = (XA::Item, XB::Item);
  72. fn with_indexed_producer<CB>(self, base: CB) -> CB::Output
  73. where
  74. CB: IndexedProducerCallback<'a, Self::Item>,
  75. {
  76. let iterator_a = self.iterator_a;
  77. let iterator_b = self.iterator_b;
  78. iterator_a.with_indexed_producer(CallbackA { base, iterator_b })
  79. }
  80. }
  81. /* CallbackA */
  82. struct CallbackA<CB, XB> {
  83. base: CB,
  84. iterator_b: XB,
  85. }
  86. impl<'a, CB, XB, A, B> IndexedProducerCallback<'a, A> for CallbackA<CB, XB>
  87. where
  88. CB: IndexedProducerCallback<'a, (A, B)>,
  89. XB: WithIndexedProducer<'a, Item = B>,
  90. A: Send + 'a,
  91. B: Send + 'a,
  92. {
  93. type Output = CB::Output;
  94. fn callback<P>(self, producer_a: P) -> Self::Output
  95. where
  96. P: IndexedProducer<Item = A> + 'a,
  97. {
  98. let CallbackA { base, iterator_b } = self;
  99. iterator_b.with_indexed_producer(CallbackB { base, producer_a })
  100. }
  101. }
  102. /* CallbackB */
  103. struct CallbackB<CB, PA> {
  104. base: CB,
  105. producer_a: PA,
  106. }
  107. impl<'a, CB, PA, A, B> IndexedProducerCallback<'a, B> for CallbackB<CB, PA>
  108. where
  109. CB: IndexedProducerCallback<'a, (A, B)>,
  110. PA: IndexedProducer<Item = A> + 'a,
  111. A: Send + 'a,
  112. B: Send + 'a,
  113. {
  114. type Output = CB::Output;
  115. fn callback<P>(self, producer_b: P) -> Self::Output
  116. where
  117. P: IndexedProducer<Item = B> + 'a,
  118. {
  119. let CallbackB { base, producer_a } = self;
  120. let producer = ZipProducer {
  121. producer_a,
  122. producer_b,
  123. };
  124. base.callback(producer)
  125. }
  126. }
  127. /* ZipProducer */
  128. struct ZipProducer<PA, PB> {
  129. producer_a: PA,
  130. producer_b: PB,
  131. }
  132. impl<PA, PB> WithSetup for ZipProducer<PA, PB>
  133. where
  134. PA: WithSetup,
  135. PB: WithSetup,
  136. {
  137. fn setup(&self) -> Setup {
  138. let a = self.producer_a.setup();
  139. let b = self.producer_b.setup();
  140. a.merge(b)
  141. }
  142. }
  143. impl<PA, PB> Producer for ZipProducer<PA, PB>
  144. where
  145. PA: IndexedProducer,
  146. PB: IndexedProducer,
  147. {
  148. type Item = (PA::Item, PB::Item);
  149. type IntoIter = std::iter::Zip<PA::IntoIter, PB::IntoIter>;
  150. fn into_iter(self) -> Self::IntoIter {
  151. let a = self.producer_a.into_iter();
  152. let b = self.producer_b.into_iter();
  153. a.zip(b)
  154. }
  155. fn split(self) -> (Self, Option<Self>) {
  156. let len = self.len();
  157. if len < 2 {
  158. return (self, None);
  159. }
  160. let index = len / 2;
  161. let (left_a, right_a) = self.producer_a.split_at(index);
  162. let (left_b, right_b) = self.producer_b.split_at(index);
  163. let left = Self {
  164. producer_a: left_a,
  165. producer_b: left_b,
  166. };
  167. let right = Self {
  168. producer_a: right_a,
  169. producer_b: right_b,
  170. };
  171. (left, Some(right))
  172. }
  173. }
  174. impl<PA, PB> IndexedProducer for ZipProducer<PA, PB>
  175. where
  176. PA: IndexedProducer,
  177. PB: IndexedProducer,
  178. {
  179. type Item = (PA::Item, PB::Item);
  180. type IntoIter = std::iter::Zip<PA::IntoIter, PB::IntoIter>;
  181. fn into_iter(self) -> Self::IntoIter {
  182. let a = self.producer_a.into_iter();
  183. let b = self.producer_b.into_iter();
  184. a.zip(b)
  185. }
  186. fn len(&self) -> usize {
  187. min(self.producer_a.len(), self.producer_b.len())
  188. }
  189. fn split_at(self, index: usize) -> (Self, Self) {
  190. let (left_a, right_a) = self.producer_a.split_at(index);
  191. let (left_b, right_b) = self.producer_b.split_at(index);
  192. let left = Self {
  193. producer_a: left_a,
  194. producer_b: left_b,
  195. };
  196. let right = Self {
  197. producer_a: right_a,
  198. producer_b: right_b,
  199. };
  200. (left, right)
  201. }
  202. }