From ebfcae645a90f2c0e3a4259397808920c2e6d362 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Sun, 2 Jul 2023 17:28:37 -0700 Subject: [PATCH] Require Fetch impls to be Clone --- macros/src/query.rs | 1 + src/query.rs | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/macros/src/query.rs b/macros/src/query.rs index 84830727..45e2bccb 100644 --- a/macros/src/query.rs +++ b/macros/src/query.rs @@ -115,6 +115,7 @@ pub fn derive(input: DeriveInput) -> Result { Ok(quote! { const _: () = { + #[derive(Clone)] #fetch impl<'a> ::hecs::Query for #ident<'a> { diff --git a/src/query.rs b/src/query.rs index 3e7c6124..48ee0c4f 100644 --- a/src/query.rs +++ b/src/query.rs @@ -45,7 +45,7 @@ pub unsafe trait QueryShared {} /// Streaming iterators over contiguous homogeneous ranges of components #[allow(clippy::missing_safety_doc)] -pub unsafe trait Fetch: Sized { +pub unsafe trait Fetch: Clone + Sized { /// The type of the data which can be cached to speed up retrieving /// the relevant type states from a matching [`Archetype`] type State: Copy; @@ -128,6 +128,13 @@ unsafe impl Fetch for FetchRead { } } +impl Clone for FetchRead { + #[inline] + fn clone(&self) -> Self { + Self(self.0) + } +} + impl<'a, T: Component> Query for &'a mut T { type Item<'q> = &'q mut T; @@ -175,6 +182,13 @@ unsafe impl Fetch for FetchWrite { } } +impl Clone for FetchWrite { + #[inline] + fn clone(&self) -> Self { + Self(self.0) + } +} + impl Query for Option { type Item<'q> = Option>; @@ -188,6 +202,7 @@ impl Query for Option { unsafe impl QueryShared for Option {} #[doc(hidden)] +#[derive(Clone)] pub struct TryFetch(Option); unsafe impl Fetch for TryFetch { @@ -328,6 +343,7 @@ impl Query for Or { unsafe impl QueryShared for Or {} #[doc(hidden)] +#[derive(Clone)] pub struct FetchOr(Or); unsafe impl Fetch for FetchOr { @@ -433,6 +449,13 @@ unsafe impl Fetch for FetchWithout { } } +impl Clone for FetchWithout { + #[inline] + fn clone(&self) -> Self { + Self(self.0.clone(), PhantomData) + } +} + /// Transforms query `Q` by skipping entities not satisfying query `R` /// /// See also `QueryBorrow::with`. @@ -503,6 +526,13 @@ unsafe impl Fetch for FetchWith { } } +impl Clone for FetchWith { + #[inline] + fn clone(&self) -> Self { + Self(self.0.clone(), PhantomData) + } +} + /// A query that matches all entities, yielding `bool`s indicating whether each satisfies query `Q` /// /// Does not borrow any components, making it faster and more concurrency-friendly than `Option`. @@ -563,6 +593,13 @@ unsafe impl Fetch for FetchSatisfies { fn for_each_borrow(_: impl FnMut(TypeId, bool)) {} } +impl Clone for FetchSatisfies { + #[inline] + fn clone(&self) -> Self { + Self(self.0, PhantomData) + } +} + /// A borrow of a [`World`](crate::World) sufficient to execute the query `Q` /// /// Note that borrows are not released until this object is dropped.