Async Entity Component System based on the ideas of specs (https://github.com/amethyst/specs)
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

152 wiersze
3.2 KiB

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