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

260 рядки
6.4 KiB

  1. use std::ops::{Deref, DerefMut};
  2. use hibitset::{BitIter, BitSetAll, BitSetLike};
  3. use log::warn;
  4. use crate::{
  5. entity::{Entities, Entity, Index},
  6. misc::BitAnd,
  7. resource::{Ref, RefMut, Resource},
  8. };
  9. use super::{read::Read, write::Write, ParJoin};
  10. pub trait Join {
  11. type Type;
  12. type Value;
  13. type Mask: BitSetLike;
  14. fn open(self) -> (Self::Mask, Self::Value);
  15. fn get(value: &mut Self::Value, index: Index) -> Self::Type;
  16. fn join(self) -> JoinIter<Self>
  17. where
  18. Self: Sized,
  19. {
  20. JoinIter::new(self)
  21. }
  22. fn maybe(self) -> MaybeJoin<Self>
  23. where
  24. Self: Sized,
  25. {
  26. MaybeJoin(self)
  27. }
  28. #[inline]
  29. fn is_unconstrained() -> bool {
  30. false
  31. }
  32. }
  33. pub struct MaybeJoin<J: Join>(pub J);
  34. impl<T> Join for MaybeJoin<T>
  35. where
  36. T: Join,
  37. {
  38. type Mask = BitSetAll;
  39. type Type = Option<<T as Join>::Type>;
  40. type Value = (<T as Join>::Mask, <T as Join>::Value);
  41. fn open(self) -> (Self::Mask, Self::Value) {
  42. let (mask, value) = self.0.open();
  43. (BitSetAll, (mask, value))
  44. }
  45. fn get((mask, value): &mut Self::Value, index: Index) -> Self::Type {
  46. if mask.contains(index) {
  47. Some(<T as Join>::get(value, index))
  48. } else {
  49. None
  50. }
  51. }
  52. fn is_unconstrained() -> bool {
  53. true
  54. }
  55. }
  56. impl<T> ParJoin for MaybeJoin<T> where T: ParJoin {}
  57. pub struct JoinIter<J: Join> {
  58. keys: BitIter<J::Mask>,
  59. values: J::Value,
  60. }
  61. impl<J: Join> JoinIter<J> {
  62. pub fn new(j: J) -> Self {
  63. if <J as Join>::is_unconstrained() {
  64. warn!(
  65. "`Join` possibly iterating through all indices, you might've made a join with all `MaybeJoin`s, which is unbounded in length."
  66. );
  67. }
  68. let (keys, values) = j.open();
  69. JoinIter {
  70. keys: keys.iter(),
  71. values,
  72. }
  73. }
  74. pub fn get(&mut self, entity: Entity, entities: &Entities) -> Option<J::Type> {
  75. if self.keys.contains(entity.index()) && entities.is_alive(entity) {
  76. Some(J::get(&mut self.values, entity.index()))
  77. } else {
  78. None
  79. }
  80. }
  81. }
  82. impl<J: Join> std::iter::Iterator for JoinIter<J> {
  83. type Item = J::Type;
  84. fn next(&mut self) -> Option<J::Type> {
  85. self.keys.next().map(|idx| J::get(&mut self.values, idx))
  86. }
  87. }
  88. impl<J: Join> Clone for JoinIter<J>
  89. where
  90. J::Mask: Clone,
  91. J::Value: Clone,
  92. {
  93. fn clone(&self) -> Self {
  94. Self {
  95. keys: self.keys.clone(),
  96. values: self.values.clone(),
  97. }
  98. }
  99. }
  100. macro_rules! define_tuple_join {
  101. ($($from:ident),*) => {
  102. impl<$($from,)*> Join for ($($from),*,)
  103. where $($from: Join),*,
  104. ($(<$from as Join>::Mask,)*): BitAnd,
  105. {
  106. type Type = ($($from::Type),*,);
  107. type Value = ($($from::Value),*,);
  108. type Mask = <($($from::Mask,)*) as BitAnd>::Value;
  109. #[allow(non_snake_case)]
  110. fn open(self) -> (Self::Mask, Self::Value) {
  111. let ($($from,)*) = self;
  112. let ($($from,)*) = ($($from.open(),)*);
  113. (
  114. ($($from.0),*,).and(),
  115. ($($from.1),*,)
  116. )
  117. }
  118. #[allow(non_snake_case)]
  119. fn get(v: &mut Self::Value, i: Index) -> Self::Type {
  120. let &mut ($(ref mut $from,)*) = v;
  121. ($($from::get($from, i),)*)
  122. }
  123. #[inline]
  124. fn is_unconstrained() -> bool {
  125. let mut unconstrained = true;
  126. $( unconstrained = unconstrained && $from::is_unconstrained(); )*
  127. unconstrained
  128. }
  129. }
  130. impl<$($from,)*> ParJoin for ($($from),*,)
  131. where $($from: ParJoin),*,
  132. ($(<$from as Join>::Mask,)*): BitAnd,
  133. {}
  134. }
  135. }
  136. define_tuple_join! { A }
  137. define_tuple_join! { A, B }
  138. define_tuple_join! { A, B, C }
  139. define_tuple_join! { A, B, C, D }
  140. define_tuple_join! { A, B, C, D, E }
  141. define_tuple_join! { A, B, C, D, E, F }
  142. define_tuple_join! { A, B, C, D, E, F, G }
  143. define_tuple_join! { A, B, C, D, E, F, G, H }
  144. define_tuple_join! { A, B, C, D, E, F, G, H, I }
  145. define_tuple_join! { A, B, C, D, E, F, G, H, I, J }
  146. define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K }
  147. define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L }
  148. define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M }
  149. define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M, N }
  150. define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O }
  151. define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P }
  152. macro_rules! define_mutable_join {
  153. ($ty:ty) => {
  154. impl<'a, 'b, T> Join for &'a mut $ty
  155. where
  156. &'a mut T: Join,
  157. T: Resource,
  158. {
  159. type Type = <&'a mut T as Join>::Type;
  160. type Value = <&'a mut T as Join>::Value;
  161. type Mask = <&'a mut T as Join>::Mask;
  162. fn open(self) -> (Self::Mask, Self::Value) {
  163. self.deref_mut().open()
  164. }
  165. fn get(v: &mut Self::Value, i: Index) -> Self::Type {
  166. <&'a mut T as Join>::get(v, i)
  167. }
  168. #[inline]
  169. fn is_unconstrained() -> bool {
  170. <&'a mut T as Join>::is_unconstrained()
  171. }
  172. }
  173. impl<'a, 'b, T> ParJoin for &'a mut $ty
  174. where
  175. &'a mut T: ParJoin,
  176. T: Resource,
  177. {
  178. }
  179. };
  180. }
  181. define_mutable_join!(Write<'b, T>);
  182. define_mutable_join!(RefMut<'b, T>);
  183. macro_rules! define_immutable_join {
  184. ($ty:ty) => {
  185. impl<'a, 'b, T> Join for &'a $ty
  186. where
  187. &'a T: Join,
  188. T: Resource,
  189. {
  190. type Type = <&'a T as Join>::Type;
  191. type Value = <&'a T as Join>::Value;
  192. type Mask = <&'a T as Join>::Mask;
  193. fn open(self) -> (Self::Mask, Self::Value) {
  194. self.deref().open()
  195. }
  196. fn get(v: &mut Self::Value, i: Index) -> Self::Type {
  197. <&'a T as Join>::get(v, i)
  198. }
  199. #[inline]
  200. fn is_unconstrained() -> bool {
  201. <&'a T as Join>::is_unconstrained()
  202. }
  203. }
  204. impl<'a, 'b, T> ParJoin for &'a $ty
  205. where
  206. &'a T: ParJoin,
  207. T: Resource,
  208. {
  209. }
  210. };
  211. }
  212. define_immutable_join!(Read<'b, T>);
  213. define_immutable_join!(Ref<'b, T>);