Repository: Ralith/hecs
Pull request #281 (2022-08-14 18:42:18)

Implement into_iter_batched for QueryMut
Skips the borrow checking

Uriopass: The CI test failing talked about an error message unrelated to the PR that looked like it changed in the latest Rust, fixed it in [another commit](https://github.com/Ralith/hecs/pull/281/commits/11dbef93655c345cf8759d528372dc195b5cecc9).

Patch:
diff --git a/src/query.rs b/src/query.rs
index 9e7ba4e..bbf5e75 100644
--- a/src/query.rs
+++ b/src/query.rs
@@ -824,6 +824,13 @@ impl<'q, Q: Query> QueryMut<'q, Q> {
             iter: unsafe { QueryIter::new(self.iter.meta, self.iter.archetypes) },
         }
     }
+
+    /// Like `into_iter`, but returns child iterators of at most `batch_size` elements
+    ///
+    /// Useful for distributing work over a threadpool.
+    pub fn into_iter_batched(self, batch_size: u32) -> BatchedIter<'q, Q> {
+        unsafe { BatchedIter::new(self.iter.meta, self.iter.archetypes, batch_size) }
+    }
 }
 
 impl<'q, Q: Query> IntoIterator for QueryMut<'q, Q> {


Test patch:
diff --git a/tests/derive/wrong_lifetime.stderr b/tests/derive/wrong_lifetime.stderr
index f462edb..f01264b 100644
--- a/tests/derive/wrong_lifetime.stderr
+++ b/tests/derive/wrong_lifetime.stderr
@@ -1,25 +1,10 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
- --> $DIR/wrong_lifetime.rs:3:10
+error: lifetime may not live long enough
+ --> tests/derive/wrong_lifetime.rs:3:10
   |
 3 | #[derive(Query)]
   |          ^^^^^
+  |          |
+  |          lifetime `'a` defined here
+  |          this usage requires that `'a` must outlive `'static`
   |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
- --> $DIR/wrong_lifetime.rs:3:10
-  |
-3 | #[derive(Query)]
-  |          ^^^^^
-note: ...so that the types are compatible
- --> $DIR/wrong_lifetime.rs:3:10
-  |
-3 | #[derive(Query)]
-  |          ^^^^^
-  = note: expected `Fetch<'a>`
-             found `Fetch<'_>`
-  = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that reference does not outlive borrowed content
- --> $DIR/wrong_lifetime.rs:3:10
-  |
-3 | #[derive(Query)]
-  |          ^^^^^
   = note: this error originates in the derive macro `Query` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/tests.rs b/tests/tests.rs
index 74ed7a6..170fa57 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -680,6 +680,46 @@ fn query_batched() {
     assert!(entities.contains(&c));
 }
 
+#[test]
+fn query_mut_batched() {
+    let mut world = World::new();
+    let a = world.spawn(());
+    let b = world.spawn(());
+    let c = world.spawn((42,));
+    assert_eq!(world.query_mut::<()>().into_iter_batched(1).count(), 3);
+    assert_eq!(world.query_mut::<()>().into_iter_batched(2).count(), 2);
+    assert_eq!(
+        world
+            .query_mut::<()>()
+            .into_iter_batched(2)
+            .flatten()
+            .count(),
+        3
+    );
+    // different archetypes are always in different batches
+    assert_eq!(world.query_mut::<()>().into_iter_batched(3).count(), 2);
+    assert_eq!(
+        world
+            .query_mut::<()>()
+            .into_iter_batched(3)
+            .flatten()
+            .count(),
+        3
+    );
+    assert_eq!(world.query_mut::<()>().into_iter_batched(4).count(), 2);
+    let entities = world
+        .query_mut::<()>()
+        .into_iter_batched(1)
+        .flatten()
+        .map(|(e, ())| e)
+        .collect::<Vec<_>>();
+    dbg!(&entities);
+    assert_eq!(entities.len(), 3);
+    assert!(entities.contains(&a));
+    assert!(entities.contains(&b));
+    assert!(entities.contains(&c));
+}
+
 #[test]
 fn spawn_batch() {
     let mut world = World::new();