Async Entity Component System based on the ideas of specs (https://github.com/amethyst/specs)
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

175 řádky
3.8 KiB

  1. use std::iter::Zip;
  2. use std::ops::Range;
  3. use crate::{
  4. Consumer, Executor, ExecutorCallback, IndexedParallelIterator, IndexedProducer,
  5. IndexedProducerCallback, ParallelIterator, Producer, Reducer, Setup, WithIndexedProducer,
  6. WithSetup,
  7. };
  8. /* Enumerate */
  9. pub struct Enumerate<X> {
  10. base: X,
  11. }
  12. impl<X> Enumerate<X> {
  13. pub fn new(base: X) -> Self {
  14. Self { base }
  15. }
  16. }
  17. impl<'a, X, I> ParallelIterator<'a> for Enumerate<X>
  18. where
  19. X: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
  20. I: Send + 'a,
  21. {
  22. type Item = (usize, I);
  23. fn drive<E, C, D, R>(self, executor: E, consumer: C) -> E::Result
  24. where
  25. E: Executor<'a, D>,
  26. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  27. D: Send + 'a,
  28. R: Reducer<D> + Send + 'a,
  29. {
  30. self.with_indexed_producer(ExecutorCallback::new(executor, consumer))
  31. }
  32. fn len_hint_opt(&self) -> Option<usize> {
  33. self.base.len_hint_opt()
  34. }
  35. }
  36. impl<'a, X, I> IndexedParallelIterator<'a> for Enumerate<X>
  37. where
  38. X: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
  39. I: Send + 'a,
  40. {
  41. fn drive_indexed<E, C, D, R>(self, executor: E, consumer: C) -> E::Result
  42. where
  43. E: Executor<'a, D>,
  44. C: Consumer<Self::Item, Result = D, Reducer = R> + 'a,
  45. D: Send + 'a,
  46. R: Reducer<D> + Send + 'a,
  47. {
  48. self.with_indexed_producer(ExecutorCallback::new(executor, consumer))
  49. }
  50. fn len_hint(&self) -> usize {
  51. self.base.len_hint()
  52. }
  53. }
  54. impl<'a, X> WithIndexedProducer<'a> for Enumerate<X>
  55. where
  56. X: WithIndexedProducer<'a>,
  57. {
  58. type Item = (usize, X::Item);
  59. fn with_indexed_producer<CB>(self, base: CB) -> CB::Output
  60. where
  61. CB: IndexedProducerCallback<'a, Self::Item>,
  62. {
  63. self.base.with_indexed_producer(EnumerateCallback { base })
  64. }
  65. }
  66. /* EnumerateCallback */
  67. struct EnumerateCallback<CB> {
  68. base: CB,
  69. }
  70. impl<'a, CB, I> IndexedProducerCallback<'a, I> for EnumerateCallback<CB>
  71. where
  72. CB: IndexedProducerCallback<'a, (usize, I)>,
  73. {
  74. type Output = CB::Output;
  75. fn callback<P>(self, base: P) -> Self::Output
  76. where
  77. P: IndexedProducer<Item = I> + 'a,
  78. {
  79. self.base.callback(EnumerateProducer { base, offset: 0 })
  80. }
  81. }
  82. /* EnumerateProducer */
  83. struct EnumerateProducer<P> {
  84. base: P,
  85. offset: usize,
  86. }
  87. impl<P> WithSetup for EnumerateProducer<P>
  88. where
  89. P: WithSetup,
  90. {
  91. fn setup(&self) -> Setup {
  92. self.base.setup()
  93. }
  94. }
  95. impl<P> Producer for EnumerateProducer<P>
  96. where
  97. P: IndexedProducer,
  98. {
  99. type Item = (usize, P::Item);
  100. type IntoIter = Zip<Range<usize>, P::IntoIter>;
  101. fn into_iter(self) -> Self::IntoIter {
  102. let base = self.base.into_iter();
  103. let start = self.offset;
  104. let end = start + base.len();
  105. (start..end).zip(base)
  106. }
  107. fn split(self) -> (Self, Option<Self>) {
  108. let len = self.base.len();
  109. if len < 2 {
  110. return (self, None);
  111. }
  112. let (left, right) = self.split_at(len / 2);
  113. (left, Some(right))
  114. }
  115. }
  116. impl<P> IndexedProducer for EnumerateProducer<P>
  117. where
  118. P: IndexedProducer,
  119. {
  120. type Item = (usize, P::Item);
  121. type IntoIter = Zip<Range<usize>, P::IntoIter>;
  122. fn into_iter(self) -> Self::IntoIter {
  123. let base = self.base.into_iter();
  124. let start = self.offset;
  125. let end = start + base.len();
  126. (start..end).zip(base)
  127. }
  128. fn len(&self) -> usize {
  129. self.base.len()
  130. }
  131. fn split_at(self, index: usize) -> (Self, Self) {
  132. let (left, right) = self.base.split_at(index);
  133. let left = Self {
  134. base: left,
  135. offset: self.offset,
  136. };
  137. let right = Self {
  138. base: right,
  139. offset: self.offset + index,
  140. };
  141. (left, right)
  142. }
  143. }