From ef76b0ca228f0cc367b10549476656912f3489a8 Mon Sep 17 00:00:00 2001 From: Anders429 Date: Fri, 18 Aug 2023 15:10:40 -0700 Subject: [PATCH] Implement dynamic scheduling. --- src/hlist/mod.rs | 2 +- src/registry/mod.rs | 1 + src/registry/sealed/claim.rs | 10 + src/resource/claim.rs | 10 + src/resource/contains/mod.rs | 3 +- src/system/mod.rs | 60 +- src/system/schedule/claim/decision.rs | 2 - src/system/schedule/claim/inverse.rs | 59 - src/system/schedule/claim/merger.rs | 25 - src/system/schedule/claim/mod.rs | 62 - src/system/schedule/claim/verifier.rs | 236 --- src/system/schedule/mod.rs | 1340 +++-------------- src/system/schedule/scheduler.rs | 261 ---- src/system/schedule/sealed.rs | 119 -- src/system/schedule/sendable.rs | 46 - src/system/schedule/stage.rs | 513 ++----- src/system/schedule/stager.rs | 835 ---------- src/system/schedule/stages.rs | 174 --- src/system/schedule/task.rs | 277 ++++ src/system/schedule/task/mod.rs | 17 - src/system/schedule/task/sealed.rs | 103 -- src/world/mod.rs | 47 +- tests/trybuild/schedule/comma_alone.rs | 5 - tests/trybuild/schedule/comma_alone.stderr | 5 - .../trybuild/schedule/non_send_entry_views.rs | 9 +- .../schedule/non_send_entry_views.stderr | 15 +- .../schedule/non_send_resource_views.rs | 9 +- .../schedule/non_send_resource_views.stderr | 15 +- tests/trybuild/schedule/non_send_views.rs | 11 +- tests/trybuild/schedule/non_send_views.stderr | 15 +- tests/trybuild/schedule/type_comma_alone.rs | 5 - .../trybuild/schedule/type_comma_alone.stderr | 5 - .../schedule/type_unexpected_token.rs | 41 - .../schedule/type_unexpected_token.stderr | 5 - tests/trybuild/schedule/unexpected_token.rs | 41 - .../trybuild/schedule/unexpected_token.stderr | 5 - 36 files changed, 751 insertions(+), 3637 deletions(-) delete mode 100644 src/system/schedule/claim/decision.rs delete mode 100644 src/system/schedule/claim/inverse.rs delete mode 100644 src/system/schedule/claim/merger.rs delete mode 100644 src/system/schedule/claim/mod.rs delete mode 100644 src/system/schedule/claim/verifier.rs delete mode 100644 src/system/schedule/scheduler.rs delete mode 100644 src/system/schedule/sealed.rs delete mode 100644 src/system/schedule/sendable.rs delete mode 100644 src/system/schedule/stager.rs delete mode 100644 src/system/schedule/stages.rs create mode 100644 src/system/schedule/task.rs delete mode 100644 src/system/schedule/task/mod.rs delete mode 100644 src/system/schedule/task/sealed.rs delete mode 100644 tests/trybuild/schedule/comma_alone.rs delete mode 100644 tests/trybuild/schedule/comma_alone.stderr delete mode 100644 tests/trybuild/schedule/type_comma_alone.rs delete mode 100644 tests/trybuild/schedule/type_comma_alone.stderr delete mode 100644 tests/trybuild/schedule/type_unexpected_token.rs delete mode 100644 tests/trybuild/schedule/type_unexpected_token.stderr delete mode 100644 tests/trybuild/schedule/unexpected_token.rs delete mode 100644 tests/trybuild/schedule/unexpected_token.stderr diff --git a/src/hlist/mod.rs b/src/hlist/mod.rs index e7f6abb1..fcd9a31c 100644 --- a/src/hlist/mod.rs +++ b/src/hlist/mod.rs @@ -93,7 +93,7 @@ macro_rules! define_null_uninstantiable { }; } -define_null_uninstantiable!(); +define_null!(); pub(crate) use define_null; pub(crate) use define_null_uninstantiable; diff --git a/src/registry/mod.rs b/src/registry/mod.rs index acbff4ac..6e62026c 100644 --- a/src/registry/mod.rs +++ b/src/registry/mod.rs @@ -67,6 +67,7 @@ pub(crate) use sealed::CanonicalParViews; pub(crate) use sealed::{ Canonical, CanonicalViews, + Claims, Length, }; diff --git a/src/registry/sealed/claim.rs b/src/registry/sealed/claim.rs index 8c6ad67c..30165aaf 100644 --- a/src/registry/sealed/claim.rs +++ b/src/registry/sealed/claim.rs @@ -16,10 +16,16 @@ use core::{ pub trait Claims { type Claims: view::Claims + Clone + Debug + Eq + Hash + Send; + + fn empty_claims() -> Self::Claims; } impl Claims for Null { type Claims = claim::Null; + + fn empty_claims() -> Self::Claims { + claim::Null + } } impl Claims for (C, R) @@ -28,4 +34,8 @@ where R: Claims, { type Claims = (Claim, R::Claims); + + fn empty_claims() -> Self::Claims { + (Claim::None, R::empty_claims()) + } } diff --git a/src/resource/claim.rs b/src/resource/claim.rs index 71cda9f1..665050db 100644 --- a/src/resource/claim.rs +++ b/src/resource/claim.rs @@ -15,10 +15,16 @@ use core::{ pub trait Claims { type Claims: view::Claims + Clone + Debug + Eq + Hash + Send + Default; + + fn empty_claims() -> Self::Claims; } impl Claims for Null { type Claims = claim::Null; + + fn empty_claims() -> Self::Claims { + claim::Null + } } impl Claims for (Resource, Resources) @@ -26,4 +32,8 @@ where Resources: Claims, { type Claims = (Claim, Resources::Claims); + + fn empty_claims() -> Self::Claims { + (Claim::None, Resources::empty_claims()) + } } diff --git a/src/resource/contains/mod.rs b/src/resource/contains/mod.rs index b788487d..25537947 100644 --- a/src/resource/contains/mod.rs +++ b/src/resource/contains/mod.rs @@ -1,5 +1,6 @@ +pub(crate) mod views; + mod resource; -mod views; pub use resource::ContainsResource; pub use views::ContainsViews; diff --git a/src/system/mod.rs b/src/system/mod.rs index 6dc11337..13ac3fc1 100644 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -49,7 +49,7 @@ //! Defining `System`s allows for reuse of querying logic in multiple places, as well as combining //! `System`s together within a `Schedule` to allow them to be run in parallel. //! -//! [`Schedule`]: trait@crate::system::schedule::Schedule +//! [`Schedule`]: crate::system::schedule::Schedule //! [`System`]: crate::system::System //! [`World`]: crate::world::World @@ -64,15 +64,14 @@ mod par; pub use par::ParSystem; #[cfg(feature = "rayon")] #[doc(inline)] -pub use schedule::{ - inner::Schedule, - schedule, -}; +pub use schedule::Schedule; use crate::{ query::{ - view::Views, + filter, + view, Result, + Views, }, registry::ContainsViews, }; @@ -136,7 +135,7 @@ pub trait System { /// The filter to apply to queries run by this system. type Filter; /// The views on components this system should operate on. - type Views<'a>: Views<'a>; + type Views<'a>: view::Views<'a>; /// Views on resources. /// /// The system will have access to the resources requested here when run. @@ -148,7 +147,7 @@ pub trait System { /// The views here must be [`Disjoint`] with `Self::Views` /// /// [`Disjoint`]: crate::query::view::Disjoint - type EntryViews<'a>: Views<'a>; + type EntryViews<'a>: view::Views<'a>; /// Logic to be run over the query result. /// @@ -207,3 +206,48 @@ pub trait System { R: ContainsViews<'a, Self::EntryViews<'a>, E>, I: Iterator>; } + +#[cfg(feature = "rayon")] +mod private { + use super::*; + use rayon::iter::ParallelIterator; + + pub struct Null; + + impl System for Null { + type Filter = filter::None; + type Views<'a> = Views!(); + type EntryViews<'a> = Views!(); + type ResourceViews<'a> = Views!(); + + fn run<'a, R, S, I, E>( + &mut self, + _query_result: Result<'a, R, S, I, Self::ResourceViews<'a>, Self::EntryViews<'a>, E>, + ) where + R: ContainsViews<'a, Self::EntryViews<'a>, E>, + I: Iterator>, + { + unreachable!() + } + } + + impl ParSystem for Null { + type Filter = filter::None; + type Views<'a> = Views!(); + type EntryViews<'a> = Views!(); + type ResourceViews<'a> = Views!(); + + fn run<'a, R, S, I, E>( + &mut self, + _query_result: Result<'a, R, S, I, Self::ResourceViews<'a>, Self::EntryViews<'a>, E>, + ) where + R: ContainsViews<'a, Self::EntryViews<'a>, E>, + I: ParallelIterator>, + { + unreachable!() + } + } +} + +#[cfg(feature = "rayon")] +pub(crate) use private::Null; diff --git a/src/system/schedule/claim/decision.rs b/src/system/schedule/claim/decision.rs deleted file mode 100644 index 0cd2a690..00000000 --- a/src/system/schedule/claim/decision.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub struct Append; -pub struct Cut; diff --git a/src/system/schedule/claim/inverse.rs b/src/system/schedule/claim/inverse.rs deleted file mode 100644 index c1a6810b..00000000 --- a/src/system/schedule/claim/inverse.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::{ - entity, - hlist::{ - define_null, - Get, - }, - query::view, -}; - -define_null!(); - -/// Finds the inverse of a list of views, with respect to a registry `R`. -pub trait Inverse { - /// The inverse of the given views. - type Result; -} - -impl Inverse for view::Null { - type Result = R; -} - -impl Inverse for (&T, U) -where - R: Get, - U: Inverse<>::Remainder, IS>, -{ - type Result = >::Remainder, IS>>::Result; -} - -impl Inverse for (&mut T, U) -where - R: Get, - U: Inverse<>::Remainder, IS>, -{ - type Result = >::Remainder, IS>>::Result; -} - -impl Inverse for (Option<&T>, U) -where - R: Get, - U: Inverse<>::Remainder, IS>, -{ - type Result = >::Remainder, IS>>::Result; -} - -impl Inverse for (Option<&mut T>, U) -where - R: Get, - U: Inverse<>::Remainder, IS>, -{ - type Result = >::Remainder, IS>>::Result; -} - -impl Inverse for (entity::Identifier, U) -where - U: Inverse, -{ - type Result = >::Result; -} diff --git a/src/system/schedule/claim/merger.rs b/src/system/schedule/claim/merger.rs deleted file mode 100644 index 89fddd5b..00000000 --- a/src/system/schedule/claim/merger.rs +++ /dev/null @@ -1,25 +0,0 @@ -/// Merges two decisions into a single decision. -use crate::system::schedule::claim::decision::{ - Append, - Cut, -}; - -pub trait Merger { - type Decision; -} - -impl Merger for (Cut, Cut) { - type Decision = Cut; -} - -impl Merger for (Cut, Append) { - type Decision = Cut; -} - -impl Merger for (Append, Cut) { - type Decision = Cut; -} - -impl Merger for (Append, Append) { - type Decision = Append; -} diff --git a/src/system/schedule/claim/mod.rs b/src/system/schedule/claim/mod.rs deleted file mode 100644 index cb64b55b..00000000 --- a/src/system/schedule/claim/mod.rs +++ /dev/null @@ -1,62 +0,0 @@ -pub(crate) mod decision; - -mod inverse; -mod merger; -mod verifier; - -pub(crate) use merger::Merger; -pub(crate) use verifier::Verifier; - -use crate::hlist::define_null; -use inverse::Inverse; - -define_null!(); - -pub trait Claims<'a, V, I, P, R, RI> { - type Decision; -} - -impl Claims<'_, V, Null, Null, R, Null> for Null { - type Decision = decision::Append; -} - -impl<'a, V, I, IS, P, PS, C, R, T, RI, RIS> Claims<'a, V, (I, IS), (P, PS), R, (RI, RIS)> for (C, T) -where - C: Inverse, - V: Verifier<'a, >::Result, C, I, P>, - (C, T): Check< - 'a, - >::Result, C, I, P>>::Decision, - V, - IS, - PS, - R, - RIS, - >, -{ - type Decision = <(C, T) as Check< - 'a, - >::Result, C, I, P>>::Decision, - V, - IS, - PS, - R, - RIS, - >>::Decision; -} - -/// Intermediate step. -pub trait Check<'a, D, V, I, P, R, RI> { - type Decision; -} - -impl Check<'_, decision::Cut, V, Null, Null, R, Null> for T { - type Decision = decision::Cut; -} - -impl<'a, V, I, P, R, C, T, RI> Check<'a, decision::Append, V, I, P, R, RI> for (C, T) -where - T: Claims<'a, V, I, P, R, RI>, -{ - type Decision = >::Decision; -} diff --git a/src/system/schedule/claim/verifier.rs b/src/system/schedule/claim/verifier.rs deleted file mode 100644 index 633fbc77..00000000 --- a/src/system/schedule/claim/verifier.rs +++ /dev/null @@ -1,236 +0,0 @@ -use crate::{ - entity, - hlist::{ - define_null, - Get, - }, - query::view, - system::schedule::claim::decision, -}; - -define_null!(); - -// All of the possible cases of pairings between view and previous claims are enumerated below. -pub struct NotPresent; -pub struct ImmutImmut; -pub struct ImmutOptionImmut; -pub struct ImmutMut; -pub struct ImmutOptionMut; -pub struct MutImmut; -pub struct MutOptionImmut; -pub struct MutMut; -pub struct MutOptionMut; - -/// Verifies whether a set of views, when compared with a claim, should result in an -/// `Append` or a `Cut` for the task. -/// -/// Note that the `R` is not a proper `Registry`, but rather it is an inverse of the claimed views -/// `C` with respect to a `Registry` `R`. -pub trait Verifier<'a, R, C, I, P> { - type Decision; -} - -impl<'a, R, C> Verifier<'a, R, C, Null, Null> for view::Null { - type Decision = decision::Append; -} - -// ------------ -// "Pass" cases -// ------------ - -/// Not present in the claims. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (NotPresent, P)> for (&'a T, U) -where - R: Get, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Not present in the claims. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (NotPresent, P)> for (&'a mut T, U) -where - R: Get, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Not present in the claims. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (NotPresent, P)> for (Option<&'a T>, U) -where - R: Get, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Not present in the claims. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (NotPresent, P)> - for (Option<&'a mut T>, U) -where - R: Get, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Multiple immutable references are acceptable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutImmut, P)> for (&'a T, U) -where - C: Get<&'a T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Multiple immutable references are acceptable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutImmut, P)> for (Option<&'a T>, U) -where - C: Get<&'a T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Multiple immutable references are acceptable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutOptionImmut, P)> for (&'a T, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Multiple immutable references are acceptable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutOptionImmut, P)> - for (Option<&'a T>, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = >::Decision; -} - -/// Skip entity identifiers. -impl<'a, R, C, I, U, P> Verifier<'a, R, C, I, P> for (entity::Identifier, U) -where - U: Verifier<'a, R, C, I, P>, -{ - type Decision = >::Decision; -} - -// ------------ -// "Fail" cases -// ------------ - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutMut, P)> for (&'a T, U) -where - C: Get<&'a mut T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutOptionMut, P)> for (&'a T, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutMut, P)> for (Option<&'a T>, U) -where - C: Get<&'a mut T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (ImmutOptionMut, P)> - for (Option<&'a T>, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutMut, P)> for (&'a mut T, U) -where - C: Get<&'a mut T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutOptionMut, P)> for (&'a mut T, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutMut, P)> for (Option<&'a mut T>, U) -where - C: Get<&'a mut T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as mutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutOptionMut, P)> - for (Option<&'a mut T>, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as immutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutImmut, P)> for (&'a mut T, U) -where - C: Get<&'a T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as immutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutOptionImmut, P)> for (&'a mut T, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as immutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutImmut, P)> for (Option<&'a mut T>, U) -where - C: Get<&'a T, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} - -/// Previously borrowed as immutable. -impl<'a, R, C, I, IS, T, U, P> Verifier<'a, R, C, (I, IS), (MutOptionImmut, P)> - for (Option<&'a mut T>, U) -where - C: Get, I>, - U: Verifier<'a, R, C, IS, P>, -{ - type Decision = decision::Cut; -} diff --git a/src/system/schedule/mod.rs b/src/system/schedule/mod.rs index f9808dea..84f43513 100644 --- a/src/system/schedule/mod.rs +++ b/src/system/schedule/mod.rs @@ -8,7 +8,7 @@ //! The below example will define a schedule that will execute both `SystemA` and `SystemB` in //! parallel, since their views can be borrowed simultaneously. //! -//! ``` rust +//! ``` //! use brood::{ //! query::{ //! filter, @@ -19,8 +19,7 @@ //! }, //! registry, //! system::{ -//! schedule, -//! schedule::task, +//! Schedule, //! System, //! }, //! }; @@ -72,1148 +71,265 @@ //! } //! } //! -//! let schedule = schedule!(task::System(SystemA), task::System(SystemB)); +//! let schedule = Schedule::builder().system(SystemA).system(SystemB).build(); //! ``` //! //! [`ParSystem`]: crate::system::ParSystem -//! [`Schedule`]: trait@crate::system::schedule::Schedule //! [`System`]: crate::system::System //! [`Views`]: trait@crate::query::view::Views -pub mod task; - -mod claim; -mod scheduler; -mod sealed; -mod sendable; mod stage; -mod stager; -mod stages; +mod task; -pub(crate) use stages::Stages; +pub use stage::Stages; +pub use task::Tasks; use crate::{ - doc, - registry, - resource, + hlist::Null, + registry::Registry, + resource::Resources, + system, + world::World, }; -use scheduler::Scheduler; -use sealed::Sealed; +use core::marker::PhantomData; use stage::Stage; -use stager::Stager; use task::Task; /// A list of tasks, scheduled to run in stages. /// -/// This is a heterogeneous list of [`System`]s and [`ParSystem`]s. Stages are created at compile -/// time based on the [`Views`] of each system, ensuring the borrows will follow Rust's borrowing -/// rules. +/// A `Schedule` is created using the [builder +/// pattern](https://doc.rust-lang.org/1.0.0/style/ownership/builders.html). Systems are scheduled +/// in the order they are provided to the builder. /// -/// The easiest way to create a `Schedule` is by using the [`schedule!`] macro. +/// To execute a `Schedule` on a [`World`], use the [`World::run_schedule()`] method. /// -/// [`ParSystem`]: crate::system::ParSystem -/// [`schedule!`]: crate::system::schedule! -/// [`System`]: crate::system::System -/// [`Views`]: trait@crate::query::view::Views -pub trait Schedule<'a, Registry, Resources, Indices>: - Sealed<'a, Registry, Resources, Indices> -where - Registry: registry::Registry, - Resources: resource::Resources, -{ -} - -impl<'a, T, Registry, Resources, Indices> Schedule<'a, Registry, Resources, Indices> for T -where - Registry: registry::Registry, - Resources: resource::Resources, - T: Sealed<'a, Registry, Resources, Indices>, -{ -} - -doc::non_root_macro! { - /// Macro for defining a heterogeneous list of tasks. - /// - /// Note that this is a list of tasks, not systems. Specifically, this is a list of - /// [`task::System`]s and [`task::ParSystem`]s. +/// # Example +/// ``` +/// use brood::{ +/// query::{ +/// filter, +/// filter::Filter, +/// result, +/// Result, +/// Views, +/// }, +/// registry, +/// system::{ +/// Schedule, +/// System, +/// }, +/// }; +/// +/// // Define components. +/// struct Foo(usize); +/// struct Bar(bool); +/// struct Baz(f64); +/// +/// struct SystemA; +/// +/// impl System for SystemA { +/// type Views<'a> = Views!(&'a mut Foo, &'a Bar); +/// type Filter = filter::None; +/// type ResourceViews<'a> = Views!(); +/// type EntryViews<'a> = Views!(); +/// +/// fn run<'a, R, S, I, E>( +/// &mut self, +/// query_results: Result, Self::EntryViews<'a>, E>, +/// ) where +/// R: registry::Registry, +/// I: Iterator>, +/// { +/// for result!(foo, bar) in query_results.iter { +/// // Do something... +/// } +/// } +/// } +/// +/// struct SystemB; +/// +/// impl System for SystemB { +/// type Views<'a> = Views!(&'a mut Baz, &'a Bar); +/// type Filter = filter::None; +/// type ResourceViews<'a> = Views!(); +/// type EntryViews<'a> = Views!(); +/// +/// fn run<'a, R, S, I, E>( +/// &mut self, +/// query_results: Result, Self::EntryViews<'a>, E>, +/// ) where +/// R: registry::Registry, +/// I: Iterator>, +/// { +/// for result!(baz, bar) in query_results.iter { +/// // Do something... +/// } +/// } +/// } +/// +/// let schedule = Schedule::builder().system(SystemA).system(SystemB).build(); +/// ``` +pub struct Schedule( + Stages, + PhantomData, + PhantomData, +); + +impl Schedule { + /// Creates an empty [`Builder`]. /// /// # Example - /// ``` rust - /// use brood::{ - /// query::{ - /// filter, - /// filter::Filter, - /// result, - /// Result, - /// Views, - /// }, - /// registry, - /// system::{ - /// schedule, - /// schedule::task, - /// ParSystem, - /// System, - /// }, - /// }; - /// use rayon::iter::ParallelIterator; - /// - /// // Define components. - /// struct Foo(usize); - /// struct Bar(bool); - /// struct Baz(f64); - /// - /// struct SystemA; - /// - /// impl System for SystemA { - /// type Views<'a> = Views!(&'a mut Foo, &'a Bar); - /// type Filter = filter::None; - /// type ResourceViews<'a> = Views!(); - /// type EntryViews<'a> = Views!(); - /// - /// fn run<'a, R, S, I, E>( - /// &mut self, - /// query_results: Result, Self::EntryViews<'a>, E>, - /// ) where - /// R: registry::Registry, - /// I: Iterator>, - /// { - /// // Do something.. - /// } - /// } - /// - /// struct SystemB; - /// - /// impl ParSystem for SystemB { - /// type Views<'a> = Views!(&'a mut Baz, &'a Bar); - /// type Filter = filter::None; - /// type ResourceViews<'a> = Views!(); - /// type EntryViews<'a> = Views!(); - /// - /// fn run<'a, R, S, I, E>( - /// &mut self, - /// query_results: Result, Self::EntryViews<'a>, E>, - /// ) where - /// R: registry::Registry, - /// I: ParallelIterator>, - /// { - /// // Do something.. - /// } - /// } - /// - /// let schedule = schedule!(task::System(SystemA), task::System(SystemB)); /// ``` + /// use brood::system::Schedule; /// - /// [`task::ParSystem`]: crate::system::schedule::task::ParSystem - /// [`task::System`]: crate::system::schedule::task::System - macro_rules! schedule { - ($task:expr $(,$tasks:expr)* $(,)?) => ( - ($task, $crate::system::schedule::schedule!($($tasks,)*)) - ); - () => ( - $crate::system::schedule::task::Null - ); + /// let builder = Schedule::builder(); + /// ``` + pub fn builder() -> Builder { + Builder::new() } } -/// Nesting this macro definition in a module is necessary to unambiguate the import of the macro. -pub(crate) mod inner { - use crate::doc; - - doc::non_root_macro! { - /// Macro for defining the type of a schedule. - /// - /// This macro is used to define the type of a schedule made up of a list of tasks. - /// - /// # Example - /// ``` rust - /// use brood::{ - /// query::{ - /// filter, - /// filter::Filter, - /// result, - /// Result, - /// Views, - /// }, - /// registry, - /// system::{ - /// schedule::task, - /// ParSystem, - /// Schedule, - /// System, - /// }, - /// }; - /// use rayon::iter::ParallelIterator; - /// - /// // Define components. - /// struct Foo(usize); - /// struct Bar(bool); - /// struct Baz(f64); - /// - /// struct SystemA; - /// - /// impl System for SystemA { - /// type Views<'a> = Views!(&'a mut Foo, &'a Bar); - /// type Filter = filter::None; - /// type ResourceViews<'a> = Views!(); - /// type EntryViews<'a> = Views!(); - /// - /// fn run<'a, R, S, I, E>( - /// &mut self, - /// query_results: Result, Self::EntryViews<'a>, E>, - /// ) where - /// R: registry::Registry, - /// I: Iterator>, - /// { - /// // Do something.. - /// } - /// } - /// - /// struct SystemB; - /// - /// impl ParSystem for SystemB { - /// type Views<'a> = Views!(&'a mut Baz, &'a Bar); - /// type Filter = filter::None; - /// type ResourceViews<'a> = Views!(); - /// type EntryViews<'a> = Views!(); - /// - /// fn run<'a, R, S, I, E>( - /// &mut self, - /// query_results: Result, Self::EntryViews<'a>, E>, - /// ) where - /// R: registry::Registry, - /// I: ParallelIterator>, - /// { - /// // Do something.. - /// } - /// } - /// - /// type Schedule = Schedule!(task::System, task::System); - /// ``` - macro_rules! Schedule { - ($task:ty $(,$tasks:ty)* $(,)?) => ( - ($task, $crate::system::schedule::Schedule!($($tasks,)*)) - ); - () => ( - $crate::system::schedule::task::Null - ); - } +impl Schedule { + pub(crate) fn run<'a, Indices>(&mut self, world: &mut World) + where + Registry: self::Registry, + Stages: self::Stages<'a, Registry, Resources, Indices>, + { + self.0.run(stage::SendPtr(world)); } } -pub use inner::Schedule; - -#[cfg(test)] -mod tests { - use super::Sealed as Schedule; - use crate::{ - entity, - query::{ - filter, - Result, - Views, - }, - registry, - system::{ - schedule::{ - stage, - stages, - task, - }, - ParSystem, - System, - }, - Registry, - Resources, - }; - use core::any::TypeId; - use rayon::iter::ParallelIterator; - - struct A; - struct B; - struct C; - struct D; - struct E; - - type Registry = Registry!(A, B, C, D, E); - - #[test] - fn null() { - assert_eq!( - TypeId::of::<>::Stages>(), - TypeId::of::() - ); - } - - #[test] - fn null_resources() { - assert_eq!( - TypeId::of::< - >::Stages, - >(), - TypeId::of::() - ); - } - - #[test] - fn null_components_and_resources() { - assert_eq!( - TypeId::of::< - >::Stages, - >(), - TypeId::of::() - ); - } - - #[test] - fn single_system_immut_a() { - struct ImmutA; - - impl System for ImmutA { - type Views<'a> = Views!(&'a A); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _ - >>::Stages, - >(), - TypeId::of::<((&mut task::System, stage::Null), stages::Null)>() - ); - } - - #[test] - fn single_system_mut_a() { - struct MutA; - - impl System for MutA { - type Views<'a> = Views!(&'a mut A); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _ - >>::Stages, - >(), - TypeId::of::<((&mut task::System, stage::Null), stages::Null)>() - ); - } - - #[test] - fn single_system_option_immut_a() { - struct OptionImmutA; - - impl System for OptionImmutA { - type Views<'a> = Views!(Option<&'a A>); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<((&mut task::System, stage::Null), stages::Null)>() - ); - } - - #[test] - fn single_system_option_mut_a() { - struct OptionMutA; - - impl System for OptionMutA { - type Views<'a> = Views!(Option<&'a mut A>); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<((&mut task::System, stage::Null), stages::Null)>() - ); - } - - #[test] - fn single_system_entity_identifier() { - struct EntityIdentifier; - - impl System for EntityIdentifier { - type Views<'a> = Views!(entity::Identifier); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - (&mut task::System, stage::Null), - stages::Null - )>() - ); - } - - #[test] - fn single_par_system_immut_a() { - struct ImmutA; - - impl ParSystem for ImmutA { - type Views<'a> = Views!(&'a A); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::ParSystem, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<((&mut task::ParSystem, stage::Null), stages::Null)>() - ); - } - - #[test] - fn single_par_system_mut_a() { - struct MutA; - - impl ParSystem for MutA { - type Views<'a> = Views!(&'a mut A); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::ParSystem, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _ - >>::Stages, - >(), - TypeId::of::<((&mut task::ParSystem, stage::Null), stages::Null)>() - ); - } - - #[test] - fn single_par_system_option_immut_a() { - struct OptionImmutA; - - impl ParSystem for OptionImmutA { - type Views<'a> = Views!(Option<&'a A>); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::ParSystem, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - (&mut task::ParSystem, stage::Null), - stages::Null - )>() - ); - } - - #[test] - fn single_par_system_option_mut_a() { - struct OptionMutA; - - impl ParSystem for OptionMutA { - type Views<'a> = Views!(Option<&'a mut A>); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::ParSystem, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - (&mut task::ParSystem, stage::Null), - stages::Null - )>() - ); - } - - #[test] - fn single_par_system_entity_identifier() { - struct EntityIdentifier; - - impl ParSystem for EntityIdentifier { - type Views<'a> = Views!(entity::Identifier); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::ParSystem, task::Null) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - (&mut task::ParSystem, stage::Null), - stages::Null - )>() - ); - } - - #[test] - fn multiple_stages() { - struct AB; - - impl System for AB { - type Views<'a> = Views!(&'a mut A, &'a mut B); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct CD; - - impl System for CD { - type Views<'a> = Views!(&'a mut C, &'a mut D); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct CE; - - impl System for CE { - type Views<'a> = Views!(&'a mut C, &'a mut E); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <( - task::System, - (task::System, (task::System, task::Null)) - ) as Schedule<'_, Registry, Resources!(), _>>::Stages, - >(), - TypeId::of::<( - (&mut task::System, (&mut task::System, stage::Null)), - ((&mut task::System, stage::Null), stages::Null) - )>() - ); - } - - #[test] - fn resources_single_stage() { - struct Foo; - - impl System for Foo { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(&'a A); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct Bar; - - impl ParSystem for Bar { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(&'a A, &'a B); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, (task::ParSystem, task::Null)) as Schedule< - '_, - Registry!(), - Resources!(A, B), - _, - >>::Stages, - >(), - TypeId::of::<( - ( - &mut task::System, - (&mut task::ParSystem, stage::Null) - ), - stages::Null - )>() - ); - } - - #[test] - fn resources_multiple_stage() { - struct Foo; - - impl System for Foo { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(&'a mut A); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct Bar; - - impl ParSystem for Bar { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(&'a mut A, &'a B); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - struct Baz; - - impl System for Baz { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(&'a mut B, &'a C); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <( - task::System, - (task::ParSystem, (task::System, task::Null)) - ) as Schedule<'_, Registry!(), Resources!(A, B, C), _>>::Stages, - >(), - TypeId::of::<( - (&mut task::System, stage::Null), - ( - (&mut task::ParSystem, stage::Null), - ((&mut task::System, stage::Null), stages::Null) - ) - )>() - ); - } - - #[test] - fn entry_views_single_stage() { - struct Foo; - - impl System for Foo { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a A); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct Bar; - - impl ParSystem for Bar { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a A, &'a B); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, (task::ParSystem, task::Null)) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - ( - &mut task::System, - (&mut task::ParSystem, stage::Null) - ), - stages::Null - )>() - ); - } - - #[test] - fn entry_views_multiple_stages() { - struct Foo; - - impl System for Foo { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a A); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct Bar; - - impl ParSystem for Bar { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a mut A, &'a B); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, (task::ParSystem, task::Null)) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - (&mut task::System, stage::Null), - ((&mut task::ParSystem, stage::Null), stages::Null) - )>() - ); +/// A [`Schedule`] builder. +/// +/// A `Builder` is used to consruct a `Schedule` of [`System`]s and [`ParSystem`]s to be run in +/// order. Systems that can be run in parallel are combined into a single stage. +/// +/// # Example +/// The below example will schedule both `SystemA` and `SystemB` in parallel, since their [`Views`] +/// can be borrowed simultaneously. +/// +/// ``` +/// use brood::{ +/// query::{ +/// filter, +/// filter::Filter, +/// result, +/// Result, +/// Views, +/// }, +/// registry, +/// system::{ +/// Schedule, +/// System, +/// }, +/// }; +/// +/// // Define components. +/// struct Foo(usize); +/// struct Bar(bool); +/// struct Baz(f64); +/// +/// struct SystemA; +/// +/// impl System for SystemA { +/// type Views<'a> = Views!(&'a mut Foo, &'a Bar); +/// type Filter = filter::None; +/// type ResourceViews<'a> = Views!(); +/// type EntryViews<'a> = Views!(); +/// +/// fn run<'a, R, S, I, E>( +/// &mut self, +/// query_results: Result, Self::EntryViews<'a>, E>, +/// ) where +/// R: registry::Registry, +/// I: Iterator>, +/// { +/// for result!(foo, bar) in query_results.iter { +/// // Do something... +/// } +/// } +/// } +/// +/// struct SystemB; +/// +/// impl System for SystemB { +/// type Views<'a> = Views!(&'a mut Baz, &'a Bar); +/// type Filter = filter::None; +/// type ResourceViews<'a> = Views!(); +/// type EntryViews<'a> = Views!(); +/// +/// fn run<'a, R, S, I, E>( +/// &mut self, +/// query_results: Result, Self::EntryViews<'a>, E>, +/// ) where +/// R: registry::Registry, +/// I: Iterator>, +/// { +/// for result!(baz, bar) in query_results.iter { +/// // Do something... +/// } +/// } +/// } +/// +/// let schedule = Schedule::builder().system(SystemA).system(SystemB).build(); +/// ``` +/// +/// [`ParSystem`]: crate::system::ParSystem +/// [`System`]: crate::system::System +/// [`Views`]: trait@crate::query::view::Views +pub struct Builder( + Tasks, + PhantomData, + PhantomData, +); + +impl Builder { + fn new() -> Self { + Builder(Null, PhantomData, PhantomData) } +} - #[test] - fn entry_views_single_stage_with_component_views() { - struct Foo; - - impl System for Foo { - type Views<'a> = Views!(&'a A, &'a mut B); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a A); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct Bar; - - impl ParSystem for Bar { - type Views<'a> = Views!(&'a C, &'a mut D); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a A, &'a C); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, (task::ParSystem, task::Null)) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - ( - &mut task::System, - (&mut task::ParSystem, stage::Null) - ), - stages::Null - )>() - ); +impl Builder { + /// Inserts a [`System`] into the [`Schedule`]. + /// + /// [`System`]: crate::system::System + pub fn system( + self, + system: System, + ) -> Builder<(Task, Tasks), Registry, Resources> { + Builder((Task::System(system), self.0), PhantomData, PhantomData) } - #[test] - fn entry_views_multiple_stages_with_component_views() { - struct Foo; - - impl System for Foo { - type Views<'a> = Views!(&'a A, &'a mut B); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a A); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - struct Bar; - - impl ParSystem for Bar { - type Views<'a> = Views!(&'a C, &'a mut D); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(&'a A, &'a B); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: ParallelIterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, (task::ParSystem, task::Null)) as Schedule< - '_, - Registry, - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<( - (&mut task::System, stage::Null), - ((&mut task::ParSystem, stage::Null), stages::Null) - )>() - ); + /// Inserts a [`ParSystem`] into the [`Schedule`]. + /// + /// [`ParSystem`]: crate::system::ParSystem + pub fn par_system( + self, + par_system: ParSystem, + ) -> Builder<(Task, Tasks), Registry, Resources> { + Builder( + (Task::ParSystem(par_system), self.0), + PhantomData, + PhantomData, + ) } +} - /// This test verifies that the schedule compiles just fine even when the registry contains a - /// non-`Sync` component, so long as the schedule itself doesn't borrow said component. - #[test] - fn registry_contains_non_sync_component() { - struct Foo; - - impl System for Foo { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - #[cfg_attr(coverage_nightly, no_coverage)] - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, - I: Iterator>, - { - unimplemented!() - } - } - - assert_eq!( - TypeId::of::< - <(task::System, task::Null) as Schedule< - '_, - (alloc::rc::Rc, Registry), - Resources!(), - _, - >>::Stages, - >(), - TypeId::of::<((&mut task::System, stage::Null), stages::Null)>() - ); +impl Builder +where + Registry: self::Registry, + Resources: self::Resources, +{ + /// Creates a [`Schedule`] from the provided [`System`]s and [`ParSystem`]s. + /// + /// This causes the provided systems to be scheduled into stages to be run in parallel. + /// + /// [`System`]: crate::system::System + /// [`ParSystem`]: crate::system::ParSystem + pub fn build<'a, Indices>(self) -> Schedule + where + Tasks: self::Tasks<'a, Registry, Resources, Indices>, + { + Schedule(self.0.into_stages(), PhantomData, PhantomData) } } diff --git a/src/system/schedule/scheduler.rs b/src/system/schedule/scheduler.rs deleted file mode 100644 index 2773fc47..00000000 --- a/src/system/schedule/scheduler.rs +++ /dev/null @@ -1,261 +0,0 @@ -use crate::{ - hlist::define_null, - registry::Registry, - resource, - system::schedule::{ - claim, - stages, - task, - Stager, - Stages, - }, -}; - -define_null!(); - -pub trait Scheduler< - 'a, - R, - Resources, - I, - P, - RI, - MergeParamtersList, - ResourcesIndicesLists, - ResourcesContainmentsLists, - ResourcesInverseIndicesLists, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, -> where - R: Registry, - Resources: resource::Resources, -{ - type Stages: Stages< - 'a, - R, - Resources, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, - >; - - fn as_stages(&'a mut self) -> Self::Stages; -} - -impl<'a, R, Resources> - Scheduler< - 'a, - R, - Resources, - Null, - Null, - Null, - stages::Null, - stages::Null, - stages::Null, - stages::Null, - stages::Null, - stages::Null, - stages::Null, - stages::Null, - stages::Null, - > for task::Null -where - R: Registry, - Resources: resource::Resources, -{ - type Stages = stages::Null; - - #[inline] - fn as_stages(&'a mut self) -> Self::Stages { - stages::Null - } -} - -impl< - 'a, - R, - Resources, - T, - U, - I, - IS, - P, - PS, - RI, - RIS, - MergeParameters, - MergeParametersList, - ResourcesIndicesList, - ResourcesIndicesLists, - ResourcesContainmentsList, - ResourcesContainmentsLists, - ResourcesInverseIndicesList, - ResourcesInverseIndicesLists, - QueryIndicesList, - QueryIndicesLists, - ResourceViewsIndicesList, - ResourceViewsIndicesLists, - DisjointIndicesList, - DisjointIndicesLists, - EntryIndicesList, - EntryIndicesLists, - EntryViewsFilterIndicesList, - EntryViewsFilterIndicesLists, - > - Scheduler< - 'a, - R, - Resources, - (I, IS), - (P, PS), - (RI, RIS), - (MergeParameters, MergeParametersList), - (ResourcesIndicesList, ResourcesIndicesLists), - (ResourcesContainmentsList, ResourcesContainmentsLists), - (ResourcesInverseIndicesList, ResourcesInverseIndicesLists), - (QueryIndicesList, QueryIndicesLists), - (ResourceViewsIndicesList, ResourceViewsIndicesLists), - (DisjointIndicesList, DisjointIndicesLists), - (EntryIndicesList, EntryIndicesLists), - (EntryViewsFilterIndicesList, EntryViewsFilterIndicesLists), - > for (T, U) -where - (T, U): Stager< - 'a, - R, - Resources, - claim::Null, - I, - P, - RI, - MergeParameters, - claim::Null, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >, - <(T, U) as Stager< - 'a, - R, - Resources, - claim::Null, - I, - P, - RI, - MergeParameters, - claim::Null, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >>::Remainder: Scheduler< - 'a, - R, - Resources, - IS, - PS, - RIS, - MergeParametersList, - ResourcesIndicesLists, - ResourcesContainmentsLists, - ResourcesInverseIndicesLists, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, - >, - R: Registry + 'a, - Resources: resource::Resources, - Resources: 'a, - I: 'a, - P: 'a, - RI: 'a, - MergeParameters: 'a, - ResourcesIndicesList: 'a, - ResourcesContainmentsList: 'a, - ResourcesInverseIndicesList: 'a, - QueryIndicesList: 'a, - ResourceViewsIndicesList: 'a, - DisjointIndicesList: 'a, - EntryIndicesList: 'a, - EntryViewsFilterIndicesList: 'a, -{ - type Stages = ( - <(T, U) as Stager< - 'a, - R, - Resources, - claim::Null, - I, - P, - RI, - MergeParameters, - claim::Null, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >>::Stage, - <<(T, U) as Stager< - 'a, - R, - Resources, - claim::Null, - I, - P, - RI, - MergeParameters, - claim::Null, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >>::Remainder as Scheduler< - 'a, - R, - Resources, - IS, - PS, - RIS, - MergeParametersList, - ResourcesIndicesLists, - ResourcesContainmentsLists, - ResourcesInverseIndicesLists, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, - >>::Stages, - ); - - #[inline] - fn as_stages(&'a mut self) -> Self::Stages { - let (stage, remainder) = self.extract_stage(); - (stage, remainder.as_stages()) - } -} diff --git a/src/system/schedule/sealed.rs b/src/system/schedule/sealed.rs deleted file mode 100644 index d97b1efa..00000000 --- a/src/system/schedule/sealed.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::{ - registry::Registry, - resource, - system::schedule::{ - Scheduler, - Stages, - }, -}; - -pub trait Sealed<'a, R, Resources, Indices> -where - R: Registry, - Resources: resource::Resources, -{ - type QueryIndicesLists; - type ResourceViewsIndicesLists; - type DisjointIndicesLists; - type EntryIndicesLists; - type EntryViewsFilterIndicesLists; - type Stages: Stages< - 'a, - R, - Resources, - Self::QueryIndicesLists, - Self::ResourceViewsIndicesLists, - Self::DisjointIndicesLists, - Self::EntryIndicesLists, - Self::EntryViewsFilterIndicesLists, - >; - - fn as_stages(&'a mut self) -> Self::Stages; -} - -impl< - 'a, - R, - Resources, - T, - I, - P, - RI, - MergeParametersList, - ResourcesIndicesLists, - ResourcesContainmentsLists, - ResourcesInverseIndicesLists, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, - > - Sealed< - 'a, - R, - Resources, - ( - I, - P, - RI, - MergeParametersList, - ResourcesIndicesLists, - ResourcesContainmentsLists, - ResourcesInverseIndicesLists, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, - ), - > for T -where - R: Registry, - Resources: resource::Resources, - T: Scheduler< - 'a, - R, - Resources, - I, - P, - RI, - MergeParametersList, - ResourcesIndicesLists, - ResourcesContainmentsLists, - ResourcesInverseIndicesLists, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, - >, -{ - type QueryIndicesLists = QueryIndicesLists; - type ResourceViewsIndicesLists = ResourceViewsIndicesLists; - type DisjointIndicesLists = DisjointIndicesLists; - type EntryIndicesLists = EntryIndicesLists; - type EntryViewsFilterIndicesLists = EntryViewsFilterIndicesLists; - type Stages = >::Stages; - - #[inline] - fn as_stages(&'a mut self) -> Self::Stages { - self.as_stages() - } -} diff --git a/src/system/schedule/sendable.rs b/src/system/schedule/sendable.rs deleted file mode 100644 index b7c1c1a1..00000000 --- a/src/system/schedule/sendable.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::{ - registry::Registry, - world::World, -}; - -pub struct SendableWorld(*mut World) -where - R: Registry; - -impl SendableWorld -where - R: Registry, -{ - /// # Safety - /// The `world` pointer passed here must be exclusively. - pub(crate) unsafe fn new(world: *mut World) -> Self { - Self(world) - } - - /// # Safety - /// The pointer returned here must only be used for access to components that follow Rust's - /// borrowing rules. - pub(crate) unsafe fn get(self) -> *mut World { - self.0 - } -} - -impl Clone for SendableWorld -where - R: Registry, -{ - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SendableWorld where R: Registry {} - -// SAFETY: This type can be safely sent between threads as long as the safety contracts of its -// methods are upheld, because the data accessed will be accessed uniquely. -unsafe impl Send for SendableWorld where R: Registry {} - -// SAFETY: This type can be safely shared between threads as long as the safety contracts of its -// methods are upheld, because the data accessed will be accessed uniquely, including mutable -// reference access. -unsafe impl Sync for SendableWorld where R: Registry {} diff --git a/src/system/schedule/stage.rs b/src/system/schedule/stage.rs index 8740aec1..f0ad0b3b 100644 --- a/src/system/schedule/stage.rs +++ b/src/system/schedule/stage.rs @@ -1,439 +1,168 @@ use crate::{ - archetype, - hlist::define_null, - query::{ - filter::{ - And, - Or, - }, - view::Claims, - }, - registry::{ - ContainsFilter, - ContainsQuery, - ContainsViews, - Registry, - }, + hlist::Null, + query::view, + registry, + registry::Registry, resource, - system::schedule::{ - sendable::SendableWorld, - Task, + system::{ + schedule::Task, + ParSystem, + System, }, -}; -use fnv::FnvBuildHasher; -use hashbrown::{ - hash_map, - HashMap, + world::World, }; -use super::Stages; - -define_null!(); +pub enum Stage { + Start(Task), + Continue(Task), +} -/// A stage within a schedule. +/// A heterogeneous list of stages. /// -/// A single stage contains only tasks that can always be run in parallel. -pub trait Stage< - 'a, - R, - Resources, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, ->: Send where - R: Registry, - Resources: resource::Resources, +/// A list of stages is a list of tasks that has been annotated with stage boundary information. It +/// is created when building a schedule. +pub trait Stages<'a, Registry, Resources, Indices>: + Sealed<'a, Registry, Resources, Indices> { - /// A list of booleans indicating whether each task within the stage has already been run. - type HasRun: Send; - - /// Run all of the tasks within this stage in parallel. - /// - /// After the tasks have been scheduled to run, tasks within the following stage will also - /// be attempted to be scheduled. Any tasks that are dynamically found to be able to run in - /// parallel with the current tasks will be executed as well. - fn run< - 'b, - N, - NextQueryIndicesLists, - NextResourceViewsIndicesLists, - NextDisjointIndicesList, - NextEntryIndicesList, - NextEntryViewsFilterIndicesList, - >( - &mut self, - world: SendableWorld, - borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - resource_claims: Resources::Claims, - has_run: Self::HasRun, - next_stage: &mut N, - ) -> N::HasRun - where - N: Stages< - 'b, - R, - Resources, - NextQueryIndicesLists, - NextResourceViewsIndicesLists, - NextDisjointIndicesList, - NextEntryIndicesList, - NextEntryViewsFilterIndicesList, - >; - - /// Attempt to run as many tasks within this stage as possible as add-ons to the previous - /// stage. - /// - /// `borrowed_archetypes` contains a set of dynamic claims that are already borrowed by the - /// previous stage. This method respects those claims when evaluating whether new tasks can be - /// executed. - /// - /// # Safety - /// `borrowed_archetypes` must accurately represent the dynamic claims already made on the - /// component columns within `world`. - unsafe fn run_add_ons( - &mut self, - world: SendableWorld, - borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - resource_claims: Resources::Claims, - ) -> Self::HasRun; - - /// Creates a new default set of booleans to indicate that each task within the stage has not - /// been run. - fn new_has_run() -> Self::HasRun; } -impl Stage<'_, R, Resources, Null, Null, Null, Null, Null> for Null +impl<'a, Stages, Registry, Resources, Indices> self::Stages<'a, Registry, Resources, Indices> + for Stages where - R: Registry, - Resources: resource::Resources, + Stages: Sealed<'a, Registry, Resources, Indices>, { - type HasRun = Null; +} - fn run< - 'b, - N, - NextQueryIndicesLists, - NextResourceViewsIndicesLists, - NextDisjointIndicesList, - NextEntryIndicesList, - NextEntryViewsFilterIndicesList, - >( - &mut self, - world: SendableWorld, - borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - resource_claims: Resources::Claims, - _has_run: Self::HasRun, - next_stage: &mut N, - ) -> N::HasRun - where - N: Stages< - 'b, - R, - Resources, - NextQueryIndicesLists, - NextResourceViewsIndicesLists, - NextDisjointIndicesList, - NextEntryIndicesList, - NextEntryViewsFilterIndicesList, - >, - { - // Check if borrowed_archetypes is empty. - // If so, it is better to just run the next stage directly. - if borrowed_archetypes.is_empty() { - N::new_has_run() - } else { - // Run tasks from next stage that can be parallelized dynamically. - // SAFETY: The safety contract of this method call is upheld by the safety contract of - // this method. - unsafe { next_stage.run_add_ons(world, borrowed_archetypes, resource_claims) } - } - } +pub struct SendPtr(pub(crate) *mut T); - unsafe fn run_add_ons( - &mut self, - _world: SendableWorld, - _borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - _resource_claims: Resources::Claims, - ) -> Self::HasRun { - Null - } +unsafe impl Send for SendPtr {} - fn new_has_run() -> Self::HasRun { - Null +unsafe impl Sync for SendPtr {} + +impl Clone for SendPtr { + fn clone(&self) -> Self { + *self } } -fn query_archetype_identifiers< - 'a, - R, - Resources, - T, - QueryIndices, - ResourceViewsIndices, - DisjointIndices, - EntryIndices, - EntryViewsFilterIndices, ->( - world: SendableWorld, - borrowed_archetypes: &mut HashMap, R::Claims, FnvBuildHasher>, -) -> bool -where - R: ContainsFilter< - Or, T::EntryViewsFilter>, - Or, EntryViewsFilterIndices>, - > + ContainsQuery<'a, T::Filter, T::Views, QueryIndices> - + ContainsViews<'a, T::EntryViews, EntryIndices>, - Resources: 'a, - T: Task<'a, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices>, -{ - let mut merged_borrowed_archetypes = borrowed_archetypes.clone(); - - for (identifier, claims) in - // SAFETY: The access to the world's archetype identifiers follows Rust's borrowing - // rules. Additionally, the views within the task are guaranteed to be valid and - // compatible. - unsafe { - (*world.get()).query_archetype_claims::, T::EntryViewsFilter>, T::EntryViews, QueryIndices, Or, EntryViewsFilterIndices>, EntryIndices>() - } - { - match merged_borrowed_archetypes.entry(identifier) { - hash_map::Entry::Occupied(mut entry) => { - if let Some(merged_claims) = claims.try_merge(entry.get()) { - entry.insert(merged_claims); - } else { - return false; - } - } - hash_map::Entry::Vacant(entry) => { - entry.insert(claims); - } - } - } +impl Copy for SendPtr {} - *borrowed_archetypes = merged_borrowed_archetypes; - true +pub trait Sealed<'a, Registry, Resources, Indices>: Send { + fn run(&mut self, world: SendPtr>) + where + Registry: self::Registry; + fn defer(&mut self, world: SendPtr>) + where + Registry: self::Registry; + fn run_current(&mut self, world: SendPtr>) + where + Registry: self::Registry; } -fn query_archetype_identifiers_unchecked< - 'a, - R, - Resources, - T, - QueryIndices, - ResourceViewsIndices, - DisjointIndices, - EntryIndices, - EntryViewsFilterIndices, ->( - world: SendableWorld, - borrowed_archetypes: &mut HashMap, R::Claims, FnvBuildHasher>, -) where - R: ContainsFilter< - Or, T::EntryViewsFilter>, - Or, EntryViewsFilterIndices>, - > + ContainsQuery<'a, T::Filter, T::Views, QueryIndices> - + ContainsViews<'a, T::EntryViews, EntryIndices>, - Resources: 'a, - T: Task<'a, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices>, -{ - for (identifier, claims) in - // SAFETY: The access to the world's archetype identifiers follows Rust's borrowing - // rules. Additionally, the views within the task are guaranteed to be valid and - // compatible. - unsafe { - (*world.get()).query_archetype_claims::, T::EntryViewsFilter>, T::EntryViews, QueryIndices, Or, EntryViewsFilterIndices>, EntryIndices>() - } +impl Sealed<'_, Registry, Resources, Null> for Null { + fn run(&mut self, _world: SendPtr>) + where + Registry: self::Registry, + { + } + fn defer(&mut self, _world: SendPtr>) + where + Registry: self::Registry, + { + } + fn run_current(&mut self, _world: SendPtr>) + where + Registry: self::Registry, { - borrowed_archetypes.insert_unique_unchecked(identifier, claims); } } impl< 'a, - R, + Stages, + System, + ParSystem, + Registry, Resources, - T, - U, QueryIndices, - QueryIndicesList, - ResourceViewsIndices, - ResourceViewsIndicesList, + ResourceViewIndices, DisjointIndices, - DisjointIndicesList, EntryIndices, - EntryIndicesList, - EntryViewsFilterIndices, - EntryViewsFilterIndicesList, + ParQueryIndices, + ParResourceViewIndices, + ParDisjointIndices, + ParEntryIndices, + Indices, > - Stage< + Sealed< 'a, - R, + Registry, Resources, - (QueryIndices, QueryIndicesList), - (ResourceViewsIndices, ResourceViewsIndicesList), - (DisjointIndices, DisjointIndicesList), - (EntryIndices, EntryIndicesList), - (EntryViewsFilterIndices, EntryViewsFilterIndicesList), - > for (&mut T, U) + ( + QueryIndices, + ResourceViewIndices, + DisjointIndices, + EntryIndices, + ParQueryIndices, + ParResourceViewIndices, + ParDisjointIndices, + ParEntryIndices, + Indices, + ), + > for (Stage, Stages) where - R: ContainsFilter< - Or, T::EntryViewsFilter>, - Or, EntryViewsFilterIndices>, - > + ContainsQuery<'a, T::Filter, T::Views, QueryIndices> - + ContainsViews<'a, T::EntryViews, EntryIndices>, - Resources: resource::Resources - + resource::ContainsViews<'a, T::ResourceViews, ResourceViewsIndices> + Stages: Sealed<'a, Registry, Resources, Indices>, + Registry: registry::ContainsQuery<'a, System::Filter, System::Views<'a>, QueryIndices> + + registry::ContainsViews<'a, System::EntryViews<'a>, EntryIndices> + + registry::ContainsParQuery<'a, ParSystem::Filter, ParSystem::Views<'a>, ParQueryIndices> + + registry::ContainsViews<'a, ParSystem::EntryViews<'a>, ParEntryIndices> + 'a, - T: Task<'a, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices> - + Send, - U: Stage< - 'a, - R, - Resources, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >, + Resources: resource::ContainsViews<'a, System::ResourceViews<'a>, ResourceViewIndices> + + resource::ContainsViews<'a, ParSystem::ResourceViews<'a>, ParResourceViewIndices> + + 'a, + System: self::System + Send, + System::Views<'a>: Send, + System::ResourceViews<'a>: Send, + System::EntryViews<'a>: view::Disjoint, Registry, DisjointIndices> + Send, + ParSystem: self::ParSystem + Send, + ParSystem::Views<'a>: Send, + ParSystem::ResourceViews<'a>: Send, + ParSystem::EntryViews<'a>: + view::Disjoint, Registry, ParDisjointIndices> + Send, { - type HasRun = (bool, U::HasRun); - - fn run< - 'b, - N, - NextQueryIndicesLists, - NextResourceViewsIndicesLists, - NextDisjointIndicesList, - NextEntryIndices, - NextEntryViewsFilterIndicesList, - >( - &mut self, - world: SendableWorld, - mut borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - resource_claims: Resources::Claims, - has_run: Self::HasRun, - next_stage: &mut N, - ) -> N::HasRun + fn run(&mut self, world: SendPtr>) where - N: Stages< - 'b, - R, - Resources, - NextQueryIndicesLists, - NextResourceViewsIndicesLists, - NextDisjointIndicesList, - NextEntryIndices, - NextEntryViewsFilterIndicesList, - >, + Registry: self::Registry, { - // Determine whether this task still needs to run, or if it has been run as part of a - // previous stage. - if has_run.0 { - self.1.run( - world, - borrowed_archetypes, - resource_claims, - has_run.1, - next_stage, - ) - } else { - rayon::join( - // Continue scheduling tasks. Note that the first task is executed on the - // current thread. - || { - // Track all archetypes that are being directly borrowed by this task. - query_archetype_identifiers_unchecked::< - R, - Resources, - T, - QueryIndices, - ResourceViewsIndices, - DisjointIndices, - EntryIndices, - EntryViewsFilterIndices, - >(world, &mut borrowed_archetypes); - - let resource_claims = - // SAFETY: The resource claims are compatible because they are in the same - // stage. - unsafe { resource_claims.merge_unchecked(&Resources::claims()) }; - - self.1.run( - world, - borrowed_archetypes, - resource_claims, - has_run.1, - next_stage, - ) - }, - // Execute the current task. - || self.0.run(world), - ) - .0 - } + self.defer(world); + self.run_current(world); } - unsafe fn run_add_ons( - &mut self, - world: SendableWorld, - mut borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - resource_claims: Resources::Claims, - ) -> Self::HasRun { - if let Some(resource_claims) = Resources::claims().try_merge(&resource_claims) { - if query_archetype_identifiers::< - R, - Resources, - T, - QueryIndices, - ResourceViewsIndices, - DisjointIndices, - EntryIndices, - EntryViewsFilterIndices, - >(world, &mut borrowed_archetypes) - { - rayon::join( - || { - ( - true, - // SAFETY: The safety contract of this method call is upheld by the - // safety contract of this method. - unsafe { - self.1 - .run_add_ons(world, borrowed_archetypes, resource_claims) - }, - ) - }, - || self.0.run(world), - ) - .0 - } else { - ( - false, - // SAFETY: The safety contract of this method call is upheld by the safety - // contract of this method. - unsafe { - self.1 - .run_add_ons(world, borrowed_archetypes, resource_claims) - }, - ) + fn defer(&mut self, world: SendPtr>) + where + Registry: self::Registry, + { + match self.0 { + Stage::Start(_) => { + self.1.run(world); + } + Stage::Continue(_) => { + self.1.defer(world); } - } else { - ( - false, - // SAFETY: The safety contract of this method call is upheld by the safety contract - // of this method. - unsafe { - self.1 - .run_add_ons(world, borrowed_archetypes, resource_claims) - }, - ) } } - fn new_has_run() -> Self::HasRun { - (false, U::new_has_run()) + fn run_current(&mut self, world: SendPtr>) + where + Registry: self::Registry, + { + match &mut self.0 { + Stage::Start(task) => { + task.run(world); + } + Stage::Continue(task) => { + rayon::join(|| self.1.run_current(world), || task.run(world)); + } + } } } diff --git a/src/system/schedule/stager.rs b/src/system/schedule/stager.rs deleted file mode 100644 index d7a4ddbf..00000000 --- a/src/system/schedule/stager.rs +++ /dev/null @@ -1,835 +0,0 @@ -use crate::{ - hlist::define_null, - query::{ - filter::{ - And, - Or, - }, - view, - }, - registry::{ - contains::views::{ - ContainsViewsOuter, - Sealed as ContainsViewsSealed, - }, - ContainsFilter, - ContainsQuery, - ContainsViews, - Registry, - }, - resource, - system::{ - schedule::{ - claim::{ - decision, - Claims, - Merger, - }, - stage, - task, - Stage, - Task, - }, - ParSystem, - System, - }, -}; - -define_null!(); - -pub trait Stager< - 'a, - R, - Resources, - C, - I, - P, - RI, - MergeParameters, - ResourcesClaims, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, -> where - R: Registry, - Resources: resource::Resources, -{ - type Stage: Stage< - 'a, - R, - Resources, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >; - type Remainder; - - fn extract_stage(&'a mut self) -> (Self::Stage, &'a mut Self::Remainder); -} - -impl<'a, R, Resources, C, ResourcesClaims> - Stager< - 'a, - R, - Resources, - C, - Null, - Null, - Null, - Null, - ResourcesClaims, - Null, - Null, - Null, - stage::Null, - stage::Null, - stage::Null, - stage::Null, - stage::Null, - > for task::Null -where - R: Registry, - Resources: resource::Resources, -{ - type Stage = stage::Null; - type Remainder = task::Null; - - #[inline] - fn extract_stage(&'a mut self) -> (Self::Stage, &'a mut Self::Remainder) { - (stage::Null, self) - } -} - -impl< - 'a, - R, - Resources, - T, - U, - C, - I, - IS, - P, - PS, - RI, - RIS, - LeftMergeIndices, RightMergeIndices, MergeContainments, MergeParameters, - ResourcesClaims, - ResourcesIndices, - ResourcesIndicesList, - ResourcesContainments, - ResourcesContainmentsList, - ResourcesInverseIndices, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - > - Stager< - 'a, - R, - Resources, - C, - (I, IS), - (P, PS), - (RI, RIS), - ((LeftMergeIndices, RightMergeIndices, MergeContainments), MergeParameters), - ResourcesClaims, - (ResourcesIndices, ResourcesIndicesList), - (ResourcesContainments, ResourcesContainmentsList), - (ResourcesInverseIndices, ResourcesInverseIndicesList), - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - > for (task::System, U) -where - T::EntryViews<'a>: view::Views<'a>, - R: ContainsViewsSealed< - 'a, - T::Views<'a>, - LeftMergeIndices - > + ContainsViewsSealed< - 'a, - T::EntryViews<'a>, - RightMergeIndices - >, - Resources: resource::Resources, - , LeftMergeIndices>>::Viewable: view::Merge< - <, - LeftMergeIndices - >>::Viewable as ContainsViewsOuter< - 'a, - T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices, - >>::Canonical, - <, - RightMergeIndices - >>::Viewable as ContainsViewsOuter< - 'a, - T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices, - >>::Canonical, - MergeContainments - >, - , - LeftMergeIndices - >>::Viewable: ContainsViewsOuter< - 'a, - T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices, - >, - , - RightMergeIndices - >>::Viewable: ContainsViewsOuter< - 'a, - T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices, - >, - T: System + Send, - C: Claims< - 'a, - <, - LeftMergeIndices - >>::Viewable as view::Merge< - <, - LeftMergeIndices - >>::Viewable as ContainsViewsOuter< - 'a, - T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices, - >>::Canonical, - <, - RightMergeIndices, - >>::Viewable as ContainsViewsOuter< - 'a, - T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices, - >>::Canonical, - MergeContainments, - >>::Merged, - I, - P, - R, - RI, - >, - ResourcesClaims: Claims< - 'a, - T::ResourceViews<'a>, - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >, - ( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, , LeftMergeIndices>>::Containments, , LeftMergeIndices>>::Indices, , LeftMergeIndices>>::ReshapeIndices>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, , RightMergeIndices>>::Containments, , RightMergeIndices>>::Indices, , RightMergeIndices>>::ReshapeIndices>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ): Merger, - (task::System, U): Cutoff< - 'a, - R, - Resources, - <( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ) as Merger>::Decision, - (<, LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, C), - IS, - PS, - RIS, - MergeParameters, - (T::ResourceViews<'a>, ResourcesClaims), - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >, -{ - type Stage = <(task::System, U) as Cutoff< - 'a, - R, - Resources, - <( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ) as Merger>::Decision, - (<, LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, C), - IS, - PS, - RIS, - MergeParameters, - (T::ResourceViews<'a>, ResourcesClaims), - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >>::Stage; - type Remainder = <(task::System, U) as Cutoff< - 'a, - R, - Resources, - <( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ) as Merger>::Decision, - (<, LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, C), - IS, - PS, - RIS, - MergeParameters, - (T::ResourceViews<'a>, ResourcesClaims), - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >>::Remainder; - - #[inline] - fn extract_stage(&'a mut self) -> (Self::Stage, &'a mut Self::Remainder) { - self.cutoff_stage() - } -} - -impl< - 'a, - R, - Resources, - T, - U, - C, - I, - IS, - P, - PS, - RI, - RIS, - LeftMergeIndices, RightMergeIndices, MergeContainments, MergeParameters, - ResourcesClaims, - ResourcesIndices, - ResourcesIndicesList, - ResourcesContainments, - ResourcesContainmentsList, - ResourcesInverseIndices, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - > - Stager< - 'a, - R, - Resources, - C, - (I, IS), - (P, PS), - (RI, RIS), - ((LeftMergeIndices, RightMergeIndices, MergeContainments), MergeParameters), - ResourcesClaims, - (ResourcesIndices, ResourcesIndicesList), - (ResourcesContainments, ResourcesContainmentsList), - (ResourcesInverseIndices, ResourcesInverseIndicesList), - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - > for (task::ParSystem, U) -where - T::EntryViews<'a>: view::Views<'a>, - R: ContainsViewsSealed<'a, T::Views<'a>, LeftMergeIndices> + ContainsViewsSealed<'a, T::EntryViews<'a>, RightMergeIndices>, - Resources: resource::Resources, - , LeftMergeIndices>>::Viewable: view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>, - , LeftMergeIndices>>::Viewable: ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>, - , RightMergeIndices>>::Viewable: ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>, - T: ParSystem + Send, - C: Claims<'a, <, LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>, - ResourcesClaims: Claims< - 'a, - T::ResourceViews<'a>, - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >, - ( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ): Merger, - (task::ParSystem, U): Cutoff< - 'a, - R, - Resources, - <( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ) as Merger>::Decision, - (<, LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, C), - IS, - PS, - RIS, - MergeParameters, - (T::ResourceViews<'a>, ResourcesClaims), - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >, -{ - type Stage = <(task::ParSystem, U) as Cutoff< - 'a, - R, - Resources, - <( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ) as Merger>::Decision, - (<, LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, C), - IS, - PS, - RIS, - MergeParameters, - (T::ResourceViews<'a>, ResourcesClaims), - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >>::Stage; - type Remainder = <(task::ParSystem, U) as Cutoff< - 'a, - R, - Resources, - <( - , LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, I, P, R, RI>>::Decision, - , - ResourcesIndices, - ResourcesContainments, - Resources, - ResourcesInverseIndices, - >>::Decision, - ) as Merger>::Decision, - (<, LeftMergeIndices>>::Viewable as view::Merge<<, LeftMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::Views<'a>, - , LeftMergeIndices>>::Containments, - , LeftMergeIndices>>::Indices, - , LeftMergeIndices>>::ReshapeIndices,>>::Canonical, <, RightMergeIndices>>::Viewable as ContainsViewsOuter<'a, T::EntryViews<'a>, - , RightMergeIndices>>::Containments, - , RightMergeIndices>>::Indices, - , RightMergeIndices>>::ReshapeIndices,>>::Canonical, MergeContainments>>::Merged, C), - IS, - PS, - RIS, - MergeParameters, - (T::ResourceViews<'a>, ResourcesClaims), - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >>::Remainder; - - #[inline] - fn extract_stage(&'a mut self) -> (Self::Stage, &'a mut Self::Remainder) { - self.cutoff_stage() - } -} - -pub trait Cutoff< - 'a, - R, - Resources, - D, - C, - I, - P, - RI, - MergeParameters, - ResourcesClaims, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, -> where - R: Registry, - Resources: resource::Resources, -{ - type Stage: Stage< - 'a, - R, - Resources, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >; - type Remainder; - - fn cutoff_stage(&'a mut self) -> (Self::Stage, &'a mut Self::Remainder); -} - -impl<'a, R, Resources, T, C, ResourcesClaims> - Cutoff< - 'a, - R, - Resources, - decision::Cut, - C, - Null, - Null, - Null, - Null, - ResourcesClaims, - Null, - Null, - Null, - stage::Null, - stage::Null, - stage::Null, - stage::Null, - stage::Null, - > for T -where - R: Registry, - Resources: resource::Resources, - T: 'a, -{ - type Stage = stage::Null; - type Remainder = T; - - #[inline] - fn cutoff_stage(&'a mut self) -> (Self::Stage, &'a mut Self::Remainder) { - (stage::Null, self) - } -} - -impl< - 'a, - R, - Resources, - T, - U, - C, - I, - P, - RI, - MergeParameters, - ResourcesClaims, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndices, - QueryIndicesList, - ResourceViewsIndices, - ResourceViewsIndicesList, - DisjointIndices, - DisjointIndicesList, - EntryIndices, - EntryIndicesList, - EntryViewsFilterIndices, - EntryViewsFilterIndicesList, - > - Cutoff< - 'a, - R, - Resources, - decision::Append, - C, - I, - P, - RI, - MergeParameters, - ResourcesClaims, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - (QueryIndices, QueryIndicesList), - (ResourceViewsIndices, ResourceViewsIndicesList), - (DisjointIndices, DisjointIndicesList), - (EntryIndices, EntryIndicesList), - (EntryViewsFilterIndices, EntryViewsFilterIndicesList), - > for (T, U) -where - R: ContainsFilter< - Or, T::EntryViewsFilter>, - Or, EntryViewsFilterIndices>, - > + ContainsQuery<'a, T::Filter, T::Views, QueryIndices> - + ContainsViews<'a, T::EntryViews, EntryIndices>, - Resources: 'a, - Resources: - resource::Resources + resource::ContainsViews<'a, T::ResourceViews, ResourceViewsIndices>, - T: Task<'a, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices> - + Send - + 'a, - U: Stager< - 'a, - R, - Resources, - C, - I, - P, - RI, - MergeParameters, - ResourcesClaims, - ResourcesIndicesList, - ResourcesContainmentsList, - ResourcesInverseIndicesList, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >, -{ - type Stage = ( - &'a mut T, - >::Stage, - ); - type Remainder = >::Remainder; - - #[inline] - fn cutoff_stage(&'a mut self) -> (Self::Stage, &'a mut Self::Remainder) { - let (stage, remainder) = self.1.extract_stage(); - ((&mut self.0, stage), remainder) - } -} diff --git a/src/system/schedule/stages.rs b/src/system/schedule/stages.rs deleted file mode 100644 index 98f38f22..00000000 --- a/src/system/schedule/stages.rs +++ /dev/null @@ -1,174 +0,0 @@ -use crate::{ - archetype, - hlist::define_null, - registry::Registry, - resource, - system::schedule::{ - sendable::SendableWorld, - Stage, - }, - World, -}; -use fnv::FnvBuildHasher; -use hashbrown::HashMap; - -define_null!(); - -/// The stages within a schedule. -pub trait Stages< - 'a, - R, - Resources, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, ->: Send where - R: Registry, - Resources: resource::Resources, -{ - /// A list of booleans indicating whether each task within the first stage has already been run. - type HasRun: Send; - - /// Run all of the stages, parallelizing as much work as possible. - /// - /// The parallelization strategy involves two parts: - /// - /// 1. Compile-time scheduling: at compile time, tasks are split into stages, where all tasks - /// in a stage can always be run in parallel with each other, no matter the `World`. - /// 2. Run-time optimization: at run-time, component claims on archetype tables within the - /// `World` are tracked when scheduling a single stage. Then, any tasks within the next stage - /// whose borrowed components do not interfere with the tasks in the current stage's dynamic - /// claims are run as well. - fn run(&mut self, world: &mut World, has_run: Self::HasRun); - - /// Attempt to run as many tasks within the first stage in the list as possible as add-ons to - /// the previous stage. - /// - /// `borrowed_archetypes` contains a set of dynamic claims that are already borrowed by the - /// previous stage. This method respects those claims when evaluating whether new tasks can be - /// executed. - /// - /// # Safety - /// `borrowed_archetypes` must accurately represent the dynamic claims already made on the - /// component columns within `world`. - unsafe fn run_add_ons( - &mut self, - world: SendableWorld, - borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - resource_claims: Resources::Claims, - ) -> Self::HasRun; - - /// Creates a new default set of booleans to indicate that each task within the first stage has - /// not been run. - fn new_has_run() -> Self::HasRun; -} - -impl Stages<'_, R, Resources, Null, Null, Null, Null, Null> for Null -where - R: Registry, - Resources: resource::Resources, -{ - type HasRun = Null; - - fn run(&mut self, _world: &mut World, _has_run: Self::HasRun) {} - - unsafe fn run_add_ons( - &mut self, - _world: SendableWorld, - _borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - _resource_claims: Resources::Claims, - ) -> Self::HasRun { - Null - } - - fn new_has_run() -> Self::HasRun { - Null - } -} - -impl< - 'a, - R, - Resources, - T, - U, - QueryIndicesList, - QueryIndicesLists, - ResourceViewsIndicesList, - ResourceViewsIndicesLists, - DisjointIndicesList, - DisjointIndicesLists, - EntryIndicesList, - EntryIndicesLists, - EntryViewsFilterIndicesList, - EntryViewsFilterIndicesLists, - > - Stages< - 'a, - R, - Resources, - (QueryIndicesList, QueryIndicesLists), - (ResourceViewsIndicesList, ResourceViewsIndicesLists), - (DisjointIndicesList, DisjointIndicesLists), - (EntryIndicesList, EntryIndicesLists), - (EntryViewsFilterIndicesList, EntryViewsFilterIndicesLists), - > for (T, U) -where - R: Registry, - Resources: resource::Resources, - T: Stage< - 'a, - R, - Resources, - QueryIndicesList, - ResourceViewsIndicesList, - DisjointIndicesList, - EntryIndicesList, - EntryViewsFilterIndicesList, - >, - U: Stages< - 'a, - R, - Resources, - QueryIndicesLists, - ResourceViewsIndicesLists, - DisjointIndicesLists, - EntryIndicesLists, - EntryViewsFilterIndicesLists, - >, -{ - type HasRun = T::HasRun; - - fn run(&mut self, world: &mut World, has_run: Self::HasRun) { - // Each stage is run sequentially. The tasks within a stage are parallelized. - let next_has_run = self.0.run( - // SAFETY: The pointer provided here is unique, being created from a mutable reference. - unsafe { SendableWorld::new(world) }, - HashMap::default(), - Resources::Claims::default(), - has_run, - &mut self.1, - ); - self.1.run(world, next_has_run); - } - - unsafe fn run_add_ons( - &mut self, - world: SendableWorld, - borrowed_archetypes: HashMap, R::Claims, FnvBuildHasher>, - resource_claims: Resources::Claims, - ) -> Self::HasRun { - // SAFETY: The safety contract of this method call is upheld by the safety contract of this - // method. - unsafe { - self.0 - .run_add_ons(world, borrowed_archetypes, resource_claims) - } - } - - fn new_has_run() -> Self::HasRun { - T::new_has_run() - } -} diff --git a/src/system/schedule/task.rs b/src/system/schedule/task.rs new file mode 100644 index 00000000..54cf688c --- /dev/null +++ b/src/system/schedule/task.rs @@ -0,0 +1,277 @@ +use crate::{ + hlist::Null, + query::{ + view::{ + self, + Claims, + }, + Query, + }, + registry, + resource, + system::{ + schedule::{ + stage::SendPtr, + Stage, + }, + ParSystem, + System, + }, + world::World, +}; + +pub enum Task { + System(System), + ParSystem(ParSystem), +} + +impl Task { + pub(crate) fn run< + 'a, + Registry, + Resources, + QueryIndices, + ResourceViewIndices, + DisjointIndices, + EntryIndices, + ParQueryIndices, + ParResourceViewIndices, + ParDisjointIndices, + ParEntryIndices, + >( + &mut self, + world: SendPtr>, + ) where + Registry: registry::ContainsQuery<'a, System::Filter, System::Views<'a>, QueryIndices> + + registry::ContainsViews<'a, System::EntryViews<'a>, EntryIndices> + + registry::ContainsParQuery<'a, ParSystem::Filter, ParSystem::Views<'a>, ParQueryIndices> + + registry::ContainsViews<'a, ParSystem::EntryViews<'a>, ParEntryIndices> + + 'a, + Resources: resource::ContainsViews<'a, System::ResourceViews<'a>, ResourceViewIndices> + + resource::ContainsViews<'a, ParSystem::ResourceViews<'a>, ParResourceViewIndices> + + 'a, + System: self::System, + System::Views<'a>: Send, + System::ResourceViews<'a>: Send, + System::EntryViews<'a>: view::Disjoint, Registry, DisjointIndices> + Send, + ParSystem: self::ParSystem, + ParSystem::Views<'a>: Send, + ParSystem::ResourceViews<'a>: Send, + ParSystem::EntryViews<'a>: + view::Disjoint, Registry, ParDisjointIndices> + Send, + { + match self { + Self::System(system) => { + let result = unsafe { + (*world.0).query(Query::< + System::Views<'a>, + System::Filter, + System::ResourceViews<'a>, + System::EntryViews<'a>, + >::new()) + }; + system.run(result); + } + Self::ParSystem(par_system) => { + let result = unsafe { + (*world.0).par_query(Query::< + ParSystem::Views<'a>, + ParSystem::Filter, + ParSystem::ResourceViews<'a>, + ParSystem::EntryViews<'a>, + >::new()) + }; + par_system.run(result); + } + } + } + + fn claims< + 'a, + Registry, + Resources, + ViewsIndices, + EntryViewsIndices, + ResourceViewsIndices, + ParViewsIndices, + ParEntryViewsIndices, + ParResourceViewsIndices, + >( + &self, + ) -> (Registry::Claims, Resources::Claims) + where + System: self::System, + ParSystem: self::ParSystem, + Registry: registry::ContainsViews<'a, System::Views<'a>, ViewsIndices> + + registry::ContainsViews<'a, System::EntryViews<'a>, EntryViewsIndices> + + registry::ContainsViews<'a, ParSystem::Views<'a>, ParViewsIndices> + + registry::ContainsViews<'a, ParSystem::EntryViews<'a>, ParEntryViewsIndices>, + Resources: resource::ContainsViews<'a, System::ResourceViews<'a>, ResourceViewsIndices> + + resource::ContainsViews<'a, ParSystem::ResourceViews<'a>, ParResourceViewsIndices>, + { + match self { + Self::System(_) => ( + unsafe { + , + ViewsIndices, + >>::claims() + .merge_unchecked(&, + EntryViewsIndices, + >>::claims()) + }, + , + ResourceViewsIndices, + >>::claims(), + ), + Self::ParSystem(_) => ( + unsafe { + , + ParViewsIndices, + >>::claims() + .merge_unchecked(&, + ParEntryViewsIndices, + >>::claims()) + }, + , + ParResourceViewsIndices, + >>::claims(), + ), + } + } +} + +/// A heterogeneous list of tasks. +/// +/// A task is a system to be run on a [`World`]. A set of tasks implementing this trait can be +/// converted into a set of stages, dividing the tasks into parallelizable groups. +pub trait Tasks<'a, Registry, Resources, Indices>: + Sealed<'a, Registry, Resources, Indices> +{ +} + +impl<'a, Tasks, Registry, Resources, Indices> self::Tasks<'a, Registry, Resources, Indices> + for Tasks +where + Tasks: Sealed<'a, Registry, Resources, Indices>, +{ +} + +pub trait Sealed<'a, Registry, Resources, Indices> { + type Stages; + + fn into_stages(self) -> Self::Stages + where + Registry: registry::Claims, + Resources: resource::Claims; + fn into_stages_internal(self) -> (Registry::Claims, Resources::Claims, Self::Stages) + where + Registry: registry::Claims, + Resources: resource::Claims; +} + +impl Sealed<'_, Registry, Resources, Null> for Null { + type Stages = Null; + + fn into_stages(self) -> Self::Stages + where + Registry: registry::Claims, + Resources: resource::Claims, + { + Null + } + + fn into_stages_internal(self) -> (Registry::Claims, Resources::Claims, Self::Stages) + where + Registry: registry::Claims, + Resources: resource::Claims, + { + (Registry::empty_claims(), Resources::empty_claims(), Null) + } +} + +impl< + 'a, + Tasks, + System, + ParSystem, + Registry, + Resources, + ViewsIndices, + EntryViewsIndices, + ResourceViewsIndices, + ParViewsIndices, + ParEntryViewsIndices, + ParResourceViewsIndices, + Indices, + > + Sealed< + 'a, + Registry, + Resources, + ( + ViewsIndices, + EntryViewsIndices, + ResourceViewsIndices, + ParViewsIndices, + ParEntryViewsIndices, + ParResourceViewsIndices, + Indices, + ), + > for (Task, Tasks) +where + Tasks: Sealed<'a, Registry, Resources, Indices>, + System: self::System, + ParSystem: self::ParSystem, + Registry: registry::ContainsViews<'a, System::Views<'a>, ViewsIndices> + + registry::ContainsViews<'a, System::EntryViews<'a>, EntryViewsIndices> + + registry::ContainsViews<'a, ParSystem::Views<'a>, ParViewsIndices> + + registry::ContainsViews<'a, ParSystem::EntryViews<'a>, ParEntryViewsIndices>, + Resources: resource::ContainsViews<'a, System::ResourceViews<'a>, ResourceViewsIndices> + + resource::ContainsViews<'a, ParSystem::ResourceViews<'a>, ParResourceViewsIndices>, +{ + type Stages = (Stage, Tasks::Stages); + + fn into_stages(self) -> Self::Stages + where + Registry: registry::Claims, + Resources: resource::Claims, + { + self.into_stages_internal().2 + } + + fn into_stages_internal(self) -> (Registry::Claims, Resources::Claims, Self::Stages) + where + Registry: registry::Claims, + Resources: resource::Claims, + { + let (component_claims, resource_claims, stages) = self.1.into_stages_internal(); + let (new_component_claims, new_resource_claims) = self.0.claims::(); + match ( + component_claims.try_merge(&new_component_claims), + resource_claims.try_merge(&new_resource_claims), + ) { + (Some(component_claims), Some(resource_claims)) => ( + component_claims, + resource_claims, + (Stage::Continue(self.0), stages), + ), + _ => ( + Registry::empty_claims(), + Resources::empty_claims(), + (Stage::Start(self.0), stages), + ), + } + } +} diff --git a/src/system/schedule/task/mod.rs b/src/system/schedule/task/mod.rs deleted file mode 100644 index 931467ce..00000000 --- a/src/system/schedule/task/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! Tasks that are used to define a [`Schedule`]. -//! -//! [`Schedule`]: trait@crate::system::schedule::Schedule - -mod sealed; - -pub(crate) use sealed::Task; - -use crate::hlist::define_null; - -define_null!(); - -/// A task that implements [`System`]. -pub struct System(pub System); - -/// A task that implements [`ParSystem`]. -pub struct ParSystem(pub ParSystem); diff --git a/src/system/schedule/task/sealed.rs b/src/system/schedule/task/sealed.rs deleted file mode 100644 index dfef8c31..00000000 --- a/src/system/schedule/task/sealed.rs +++ /dev/null @@ -1,103 +0,0 @@ -//! Common interface for tasks. - -use super::{ - ParSystem, - System, -}; -use crate::{ - query::{ - view, - view::{ - Views, - ViewsSealed, - }, - Query, - }, - registry, - registry::{ - ContainsParQuery, - ContainsQuery, - Registry, - }, - resource::ContainsViews, - system, - system::schedule::sendable::SendableWorld, -}; - -/// A task that can be run in a schedule. -pub trait Task<'a, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices> -where - R: Registry, -{ - /// The components viewed by this task. - type Views: Views<'a> + Send; - /// A filter applied to the components viewed by this task. - type Filter; - /// The views on resources for this task. - type ResourceViews; - /// The entry views on components for this task. - type EntryViews: Views<'a>; - /// The entry views filter on components for this task. - type EntryViewsFilter; - - /// Executes the task over the given world. - fn run(&mut self, world: SendableWorld); -} - -impl<'a, R, Resources, S, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices> - Task<'a, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices> - for System -where - S: system::System + Send, - R: ContainsQuery<'a, S::Filter, S::Views<'a>, QueryIndices> - + registry::ContainsViews<'a, S::EntryViews<'a>, EntryIndices>, - Resources: 'a, - Resources: ContainsViews<'a, S::ResourceViews<'a>, ResourceViewsIndices>, - S::Views<'a>: Send, - S::ResourceViews<'a>: Send, - S::EntryViews<'a>: view::Disjoint, R, DisjointIndices> + Views<'a> + Send, -{ - type Views = S::Views<'a>; - type Filter = S::Filter; - type ResourceViews = S::ResourceViews<'a>; - type EntryViews = S::EntryViews<'a>; - type EntryViewsFilter = as ViewsSealed<'a>>::EntryFilter; - - fn run(&mut self, world: SendableWorld) { - // Query world using system. - let result = - // SAFETY: The access to the world's components follows Rust's borrowing rules. - unsafe { (*world.get()).query(Query::, S::Filter, S::ResourceViews<'a>, S::EntryViews<'a>>::new()) }; - // Run system using the query result. - self.0.run(result); - } -} - -impl<'a, P, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices> - Task<'a, R, Resources, QueryIndices, ResourceViewsIndices, DisjointIndices, EntryIndices> - for ParSystem

-where - P: system::ParSystem + Send, - R: ContainsParQuery<'a, P::Filter, P::Views<'a>, QueryIndices> - + registry::ContainsViews<'a, P::EntryViews<'a>, EntryIndices>, - Resources: 'a, - Resources: ContainsViews<'a, P::ResourceViews<'a>, ResourceViewsIndices>, - P::Views<'a>: Send, - P::ResourceViews<'a>: Send, - P::EntryViews<'a>: view::Disjoint, R, DisjointIndices> + Views<'a> + Send, -{ - type Views = P::Views<'a>; - type Filter = P::Filter; - type ResourceViews = P::ResourceViews<'a>; - type EntryViews = P::EntryViews<'a>; - type EntryViewsFilter = as ViewsSealed<'a>>::EntryFilter; - - fn run(&mut self, world: SendableWorld) { - // Query world using system. - let result = - // SAFETY: The access to the world's components follows Rust's borrowing rules. - unsafe { (*world.get()).par_query(Query::, P::Filter, P::ResourceViews<'a>, P::EntryViews<'a>>::new()) }; - // Run system using the query result. - self.0.run(result); - } -} diff --git a/src/world/mod.rs b/src/world/mod.rs index 37c04227..c2792388 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -50,8 +50,8 @@ use crate::{ ContainsParQuery, }, system::{ - schedule, schedule::Stages, + Schedule, }, }; use alloc::vec::Vec; @@ -673,8 +673,6 @@ where /// }, /// registry, /// system::{ - /// schedule, - /// schedule::task, /// Schedule, /// System, /// }, @@ -731,7 +729,7 @@ where /// } /// /// // Define schedule. - /// let mut schedule = schedule!(task::System(SystemA), task::System(SystemB)); + /// let mut schedule = Schedule::builder().system(SystemA).system(SystemB).build(); /// /// let mut world = World::::new(); /// world.insert(entity!(Foo(42), Bar(100))); @@ -739,17 +737,16 @@ where /// world.run_schedule(&mut schedule); /// ``` /// - /// [`Schedule`]: trait@crate::system::schedule::Schedule + /// [`Schedule`]: crate::system::schedule::Schedule #[cfg(feature = "rayon")] #[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] - pub fn run_schedule<'a, Schedule, Indices>(&mut self, schedule: &'a mut Schedule) - where - Resources: resource::Resources, - Schedule: schedule::Schedule<'a, Registry, Resources, Indices>, + pub fn run_schedule<'a, Stages, Indices>( + &mut self, + schedule: &mut Schedule, + ) where + Stages: self::Stages<'a, Registry, Resources, Indices>, { - schedule - .as_stages() - .run(self, Schedule::Stages::new_has_run()); + schedule.run(self); } /// Returns `true` if the world contains an entity identified by `entity_identifier`. @@ -1112,10 +1109,7 @@ mod tests { #[cfg(feature = "rayon")] use crate::system::ParSystem; #[cfg(feature = "rayon")] - use crate::system::{ - schedule, - schedule::task, - }; + use crate::system::Schedule; use crate::{ entities, entity, @@ -2407,7 +2401,10 @@ mod tests { world.insert(entity!(B('b'))); world.insert(entity!()); - let mut schedule = schedule!(task::System(TestSystem), task::ParSystem(TestParSystem)); + let mut schedule = Schedule::builder() + .system(TestSystem) + .par_system(TestParSystem) + .build(); world.run_schedule(&mut schedule); } @@ -2471,7 +2468,7 @@ mod tests { world.extend(entities!((A(0), B(0)); 1000)); world.extend(entities!((A(0), C(0)); 1000)); - let mut schedule = schedule!(task::System(Foo), task::System(Bar)); + let mut schedule = Schedule::builder().system(Foo).system(Bar).build(); world.run_schedule(&mut schedule); } @@ -2556,7 +2553,11 @@ mod tests { world.extend(entities!((A(0), B(0)); 1000)); world.extend(entities!((A(0), C(0)); 1000)); - let mut schedule = schedule!(task::System(Foo), task::System(Bar), task::System(Baz)); + let mut schedule = Schedule::builder() + .system(Foo) + .system(Bar) + .system(Baz) + .build(); world.run_schedule(&mut schedule); } @@ -2650,7 +2651,7 @@ mod tests { world.extend(entities!((B(0)); 1000)); world.extend(entities!((C(0)); 1000)); - let mut schedule = schedule!(task::System(Foo), task::System(Bar)); + let mut schedule = Schedule::builder().system(Foo).system(Bar).build(); world.run_schedule(&mut schedule); } @@ -2721,7 +2722,7 @@ mod tests { let mut world = World::::with_resources(resources!(A(0))); - let mut schedule = schedule!(task::System(Foo), task::System(Bar)); + let mut schedule = Schedule::builder().system(Foo).system(Bar).build(); world.run_schedule(&mut schedule); } @@ -2792,7 +2793,7 @@ mod tests { let mut world = World::::with_resources(resources!(A(0), B(0), C(0))); - let mut schedule = schedule!(task::System(Foo), task::System(Bar)); + let mut schedule = Schedule::builder().system(Foo).system(Bar).build(); world.run_schedule(&mut schedule); } @@ -2865,7 +2866,7 @@ mod tests { let mut world = World::::with_resources(resources!(A(0), B(0), C(0))); - let mut schedule = schedule!(task::System(Foo), task::System(Bar)); + let mut schedule = Schedule::builder().system(Foo).system(Bar).build(); world.run_schedule(&mut schedule); } diff --git a/tests/trybuild/schedule/comma_alone.rs b/tests/trybuild/schedule/comma_alone.rs deleted file mode 100644 index ef303e6c..00000000 --- a/tests/trybuild/schedule/comma_alone.rs +++ /dev/null @@ -1,5 +0,0 @@ -use brood::system::schedule; - -fn main() { - let schedule = schedule!(,); -} diff --git a/tests/trybuild/schedule/comma_alone.stderr b/tests/trybuild/schedule/comma_alone.stderr deleted file mode 100644 index 7753dd47..00000000 --- a/tests/trybuild/schedule/comma_alone.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `,` - --> tests/trybuild/schedule/comma_alone.rs:4:30 - | -4 | let schedule = schedule!(,); - | ^ no rules expected this token in macro call diff --git a/tests/trybuild/schedule/non_send_entry_views.rs b/tests/trybuild/schedule/non_send_entry_views.rs index 2680dae2..58cf5a59 100644 --- a/tests/trybuild/schedule/non_send_entry_views.rs +++ b/tests/trybuild/schedule/non_send_entry_views.rs @@ -1,9 +1,4 @@ -use brood::{query::{Views, filter, Result}, registry, World, Registry, system::{System, schedule}}; -// This import is technically unused, since the macro fails to compile before it would be consumed. -// I'm leaving it here, though, for completeness; user code would use this module, and these tests -// should do their best to simulate user code. -#[allow(unused_imports)] -use brood::system::schedule::task; +use brood::{query::{Views, filter, Result}, registry, World, Registry, system::{System, Schedule}}; use std::rc::Rc; struct A; @@ -30,7 +25,7 @@ impl System for Foo { fn main() { let mut world = World::)>::new(); - let schedule = schedule!(task::System(Foo)); + let mut schedule = Schedule::builder().system(Foo).build(); world.run_schedule(&mut schedule); } diff --git a/tests/trybuild/schedule/non_send_entry_views.stderr b/tests/trybuild/schedule/non_send_entry_views.stderr index 116f6401..ad23daa2 100644 --- a/tests/trybuild/schedule/non_send_entry_views.stderr +++ b/tests/trybuild/schedule/non_send_entry_views.stderr @@ -1,7 +1,7 @@ error[E0277]: `Rc` cannot be shared between threads safely - --> tests/trybuild/schedule/non_send_entry_views.rs:35:24 + --> tests/trybuild/schedule/non_send_entry_views.rs:30:24 | -35 | world.run_schedule(&mut schedule); +30 | world.run_schedule(&mut schedule); | ------------ ^^^^^^^^^^^^^ `Rc` cannot be shared between threads safely | | | required by a bound introduced by this call @@ -9,13 +9,10 @@ error[E0277]: `Rc` cannot be shared between threads safely = help: the trait `Sync` is not implemented for `Rc` = note: required for `&Rc` to implement `Send` = note: required because it appears within the type `(&Rc, brood::query::view::Null)` - = note: required for `brood::system::schedule::task::System` to implement `brood::system::schedule::task::sealed::Task<'_, (Rc, brood::registry::Null), brood::resource::Null, (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null))>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::stager::Cutoff<'_, (Rc, brood::registry::Null), brood::resource::Null, schedule::claim::decision::Append, ((&Rc, brood::query::view::Null), schedule::claim::Null), schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, (brood::query::view::Null, schedule::claim::Null), schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, ((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), ((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), ((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), (((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), (Or, registry::contains::Contained>, schedule::stage::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::scheduler::Scheduler<'_, (Rc, brood::registry::Null), brood::resource::Null, ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (view::merge::Neither, (view::merge::Right, view::merge::Null))), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), (((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), schedule::stages::Null), ((Or, registry::contains::Contained>, schedule::stage::Null), schedule::stages::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::sealed::Sealed<'_, (Rc, brood::registry::Null), brood::resource::Null, (((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (view::merge::Neither, (view::merge::Right, view::merge::Null))), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), (((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), schedule::stages::Null), ((Or, registry::contains::Contained>, schedule::stage::Null), schedule::stages::Null))>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `Schedule<'_, (Rc, brood::registry::Null), brood::resource::Null, (((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (view::merge::Neither, (view::merge::Right, view::merge::Null))), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), (((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), schedule::stages::Null), ((Or, registry::contains::Contained>, schedule::stage::Null), schedule::stages::Null))>` + = note: required for `(schedule::stage::Stage, brood::hlist::Null)` to implement `schedule::stage::Sealed<'_, (Rc, brood::registry::Null), brood::resource::Null, ((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), brood::hlist::Null)>` + = note: required for `(schedule::stage::Stage, brood::hlist::Null)` to implement `Stages<'_, (Rc, brood::registry::Null), brood::resource::Null, ((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), brood::hlist::Null)>` note: required by a bound in `World::::run_schedule` --> src/world/mod.rs | - | Schedule: schedule::Schedule<'a, Registry, Resources, Indices>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `World::::run_schedule` + | Stages: self::Stages<'a, Registry, Resources, Indices>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `World::::run_schedule` diff --git a/tests/trybuild/schedule/non_send_resource_views.rs b/tests/trybuild/schedule/non_send_resource_views.rs index e212153a..575306f0 100644 --- a/tests/trybuild/schedule/non_send_resource_views.rs +++ b/tests/trybuild/schedule/non_send_resource_views.rs @@ -1,9 +1,4 @@ -use brood::{query::{Views, filter, Result}, registry, World, Registry, resources, system::{System, schedule}}; -// This import is technically unused, since the macro fails to compile before it would be consumed. -// I'm leaving it here, though, for completeness; user code would use this module, and these tests -// should do their best to simulate user code. -#[allow(unused_imports)] -use brood::system::schedule::task; +use brood::{query::{Views, filter, Result}, registry, World, Registry, resources, system::{System, Schedule}}; use std::rc::Rc; struct A; @@ -30,7 +25,7 @@ impl System for Foo { fn main() { let mut world = World::::with_resources(resources!(Rc::new(A))); - let schedule = schedule!(task::System(Foo)); + let mut schedule = Schedule::builder().system(Foo).build(); world.run_schedule(&mut schedule); } diff --git a/tests/trybuild/schedule/non_send_resource_views.stderr b/tests/trybuild/schedule/non_send_resource_views.stderr index 2e280050..3dda00cd 100644 --- a/tests/trybuild/schedule/non_send_resource_views.stderr +++ b/tests/trybuild/schedule/non_send_resource_views.stderr @@ -1,7 +1,7 @@ error[E0277]: `Rc` cannot be shared between threads safely - --> tests/trybuild/schedule/non_send_resource_views.rs:35:24 + --> tests/trybuild/schedule/non_send_resource_views.rs:30:24 | -35 | world.run_schedule(&mut schedule); +30 | world.run_schedule(&mut schedule); | ------------ ^^^^^^^^^^^^^ `Rc` cannot be shared between threads safely | | | required by a bound introduced by this call @@ -9,13 +9,10 @@ error[E0277]: `Rc` cannot be shared between threads safely = help: the trait `Sync` is not implemented for `Rc` = note: required for `&Rc` to implement `Send` = note: required because it appears within the type `(&Rc, brood::query::view::Null)` - = note: required for `brood::system::schedule::task::System` to implement `brood::system::schedule::task::sealed::Task<'_, brood::registry::Null, (Rc, brood::resource::Null), (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null), (resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null)), (((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::stager::Cutoff<'_, brood::registry::Null, (Rc, brood::resource::Null), schedule::claim::decision::Append, (brood::query::view::Null, schedule::claim::Null), schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, ((&Rc, brood::query::view::Null), schedule::claim::Null), schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, ((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), (((resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null), (resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null)), schedule::stage::Null), ((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), (((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), (brood::query::filter::Not, schedule::stage::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::scheduler::Scheduler<'_, brood::registry::Null, (Rc, brood::resource::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), (view::merge::Neither, view::merge::Null)), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((((resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null), (resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null)), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((brood::query::filter::Not, schedule::stage::Null), schedule::stages::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::sealed::Sealed<'_, brood::registry::Null, (Rc, brood::resource::Null), (((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), (view::merge::Neither, view::merge::Null)), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((((resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null), (resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null)), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((brood::query::filter::Not, schedule::stage::Null), schedule::stages::Null))>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `Schedule<'_, brood::registry::Null, (Rc, brood::resource::Null), (((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), (view::merge::Neither, view::merge::Null)), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((((resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null), (resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null)), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((brood::query::filter::Not, schedule::stage::Null), schedule::stages::Null))>` + = note: required for `(schedule::stage::Stage, brood::hlist::Null)` to implement `schedule::stage::Sealed<'_, brood::registry::Null, (Rc, brood::resource::Null), ((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null), (resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null)), (((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((resource::contains::NotContained, resource::contains::Null), resource::contains::Null, (resource::contains::NotContained, resource::contains::Null), resource::contains::Null), (((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), brood::hlist::Null)>` + = note: required for `(schedule::stage::Stage, brood::hlist::Null)` to implement `Stages<'_, brood::registry::Null, (Rc, brood::resource::Null), ((registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null), (resource::contains::Contained, resource::contains::Null), (view::resource::get::index::Index, resource::contains::Null)), (((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), ((resource::contains::NotContained, resource::contains::Null), resource::contains::Null, (resource::contains::NotContained, resource::contains::Null), resource::contains::Null), (((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, registry::contains::Null), registry::contains::Null, brood::hlist::Null), brood::hlist::Null)>` note: required by a bound in `World::::run_schedule` --> src/world/mod.rs | - | Schedule: schedule::Schedule<'a, Registry, Resources, Indices>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `World::::run_schedule` + | Stages: self::Stages<'a, Registry, Resources, Indices>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `World::::run_schedule` diff --git a/tests/trybuild/schedule/non_send_views.rs b/tests/trybuild/schedule/non_send_views.rs index ee145b37..bad2599b 100644 --- a/tests/trybuild/schedule/non_send_views.rs +++ b/tests/trybuild/schedule/non_send_views.rs @@ -1,9 +1,4 @@ -use brood::{query::{Views, filter, Result}, registry, World, Registry, system::{System, schedule}}; -// This import is technically unused, since the macro fails to compile before it would be consumed. -// I'm leaving it here, though, for completeness; user code would use this module, and these tests -// should do their best to simulate user code. -#[allow(unused_imports)] -use brood::system::schedule::task; +use brood::{query::{Views, filter, Result}, registry, World, Registry, system::{System, Schedule}}; use std::rc::Rc; struct A; @@ -30,7 +25,7 @@ impl System for Foo { fn main() { let mut world = World::)>::new(); - let schedule = schedule!(task::System(Foo)); - + let mut schedule = Schedule::builder().system(Foo).build(); + world.run_schedule(&mut schedule); } diff --git a/tests/trybuild/schedule/non_send_views.stderr b/tests/trybuild/schedule/non_send_views.stderr index 1c5273bc..abf0be7e 100644 --- a/tests/trybuild/schedule/non_send_views.stderr +++ b/tests/trybuild/schedule/non_send_views.stderr @@ -1,7 +1,7 @@ error[E0277]: `Rc` cannot be shared between threads safely - --> tests/trybuild/schedule/non_send_views.rs:35:24 + --> tests/trybuild/schedule/non_send_views.rs:30:24 | -35 | world.run_schedule(&mut schedule); +30 | world.run_schedule(&mut schedule); | ------------ ^^^^^^^^^^^^^ `Rc` cannot be shared between threads safely | | | required by a bound introduced by this call @@ -9,13 +9,10 @@ error[E0277]: `Rc` cannot be shared between threads safely = help: the trait `Sync` is not implemented for `Rc` = note: required for `&Rc` to implement `Send` = note: required because it appears within the type `(&Rc, brood::query::view::Null)` - = note: required for `brood::system::schedule::task::System` to implement `brood::system::schedule::task::sealed::Task<'_, (Rc, brood::registry::Null), brood::resource::Null, (registry::contains::Null, (registry::contains::Contained, registry::contains::Null), (registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::stager::Cutoff<'_, (Rc, brood::registry::Null), brood::resource::Null, schedule::claim::decision::Append, ((&Rc, brood::query::view::Null), schedule::claim::Null), schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, (brood::query::view::Null, schedule::claim::Null), schedule::stager::Null, schedule::stager::Null, schedule::stager::Null, ((registry::contains::Null, (registry::contains::Contained, registry::contains::Null), (registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), ((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), ((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null), schedule::stage::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), (brood::query::filter::Not, schedule::stage::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::scheduler::Scheduler<'_, (Rc, brood::registry::Null), brood::resource::Null, ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (view::merge::Neither, (view::merge::Left, view::merge::Null))), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, (registry::contains::Contained, registry::contains::Null), (registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), schedule::stages::Null), (((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((brood::query::filter::Not, schedule::stage::Null), schedule::stages::Null)>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `schedule::sealed::Sealed<'_, (Rc, brood::registry::Null), brood::resource::Null, (((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (view::merge::Neither, (view::merge::Left, view::merge::Null))), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, (registry::contains::Contained, registry::contains::Null), (registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), schedule::stages::Null), (((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((brood::query::filter::Not, schedule::stage::Null), schedule::stages::Null))>` - = note: required for `(brood::system::schedule::task::System, brood::system::schedule::task::Null)` to implement `Schedule<'_, (Rc, brood::registry::Null), brood::resource::Null, (((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::scheduler::Null), (((((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (view::merge::Neither, (view::merge::Left, view::merge::Null))), schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), ((schedule::claim::Null, schedule::stager::Null), schedule::stages::Null), (((registry::contains::Null, (registry::contains::Contained, registry::contains::Null), (registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), schedule::stage::Null), schedule::stages::Null), (((resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), schedule::stage::Null), schedule::stages::Null), (((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null), schedule::stage::Null), schedule::stages::Null), ((((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), schedule::stage::Null), schedule::stages::Null), ((brood::query::filter::Not, schedule::stage::Null), schedule::stages::Null))>` + = note: required for `(schedule::stage::Stage, brood::hlist::Null)` to implement `schedule::stage::Sealed<'_, (Rc, brood::registry::Null), brood::resource::Null, ((registry::contains::Null, (registry::contains::Contained, registry::contains::Null), (registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), brood::hlist::Null)>` + = note: required for `(schedule::stage::Stage, brood::hlist::Null)` to implement `Stages<'_, (Rc, brood::registry::Null), brood::resource::Null, ((registry::contains::Null, (registry::contains::Contained, registry::contains::Null), (registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (®istry::contains::Contained, registry::contains::Null)), (brood::hlist::get::Index, registry::contains::Null), (brood::hlist::get::Index, brood::hlist::Null)), view::disjoint::Null), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (registry::contains::Null, registry::contains::Null, (registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), (resource::contains::Null, resource::contains::Null, resource::contains::Null, resource::contains::Null), (((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null, ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), view::disjoint::Null), ((registry::contains::NotContained, (registry::contains::NotContained, registry::contains::Null)), registry::contains::Null, brood::hlist::Null), brood::hlist::Null)>` note: required by a bound in `World::::run_schedule` --> src/world/mod.rs | - | Schedule: schedule::Schedule<'a, Registry, Resources, Indices>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `World::::run_schedule` + | Stages: self::Stages<'a, Registry, Resources, Indices>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `World::::run_schedule` diff --git a/tests/trybuild/schedule/type_comma_alone.rs b/tests/trybuild/schedule/type_comma_alone.rs deleted file mode 100644 index 3361ea8e..00000000 --- a/tests/trybuild/schedule/type_comma_alone.rs +++ /dev/null @@ -1,5 +0,0 @@ -use brood::system::Schedule; - -type Schedule = Schedule!(,); - -fn main() {} diff --git a/tests/trybuild/schedule/type_comma_alone.stderr b/tests/trybuild/schedule/type_comma_alone.stderr deleted file mode 100644 index 7bd11d0a..00000000 --- a/tests/trybuild/schedule/type_comma_alone.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `,` - --> tests/trybuild/schedule/type_comma_alone.rs:3:27 - | -3 | type Schedule = Schedule!(,); - | ^ no rules expected this token in macro call diff --git a/tests/trybuild/schedule/type_unexpected_token.rs b/tests/trybuild/schedule/type_unexpected_token.rs deleted file mode 100644 index 9c4e6aa7..00000000 --- a/tests/trybuild/schedule/type_unexpected_token.rs +++ /dev/null @@ -1,41 +0,0 @@ -use brood::{query::{Views, filter, Result}, registry, system::{System, Schedule}}; -// This import is technically unused, since the macro fails to compile before it would be consumed. -// I'm leaving it here, though, for completeness; user code would use this module, and these tests -// should do their best to simulate user code. -#[allow(unused_imports)] -use brood::system::schedule::task; - -// Define systems. -struct A; - -impl System for A { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, I: Iterator> {} -} - -struct B; - -impl System for B { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, I: Iterator> {} -} - -type Schedule = Schedule!(task::System, + task::System,); - -fn main() {} diff --git a/tests/trybuild/schedule/type_unexpected_token.stderr b/tests/trybuild/schedule/type_unexpected_token.stderr deleted file mode 100644 index aaacedb0..00000000 --- a/tests/trybuild/schedule/type_unexpected_token.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `+` - --> tests/trybuild/schedule/type_unexpected_token.rs:39:44 - | -39 | type Schedule = Schedule!(task::System, + task::System,); - | ^ no rules expected this token in macro call diff --git a/tests/trybuild/schedule/unexpected_token.rs b/tests/trybuild/schedule/unexpected_token.rs deleted file mode 100644 index 1bb8c59f..00000000 --- a/tests/trybuild/schedule/unexpected_token.rs +++ /dev/null @@ -1,41 +0,0 @@ -use brood::{query::{Views, filter, Result}, registry, system::{System, schedule}}; -// This import is technically unused, since the macro fails to compile before it would be consumed. -// I'm leaving it here, though, for completeness; user code would use this module, and these tests -// should do their best to simulate user code. -#[allow(unused_imports)] -use brood::system::schedule::task; - -// Define systems. -struct A; - -impl System for A { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, I: Iterator> {} -} - -struct B; - -impl System for B { - type Views<'a> = Views!(); - type Filter = filter::None; - type ResourceViews<'a> = Views!(); - type EntryViews<'a> = Views!(); - - fn run<'a, R, S, I, E>( - &mut self, - _query_results: Result, Self::EntryViews<'a>, E>, - ) where - R: registry::Registry, I: Iterator>, {} -} - -fn main() { - let schedule = schedule!(task::System(A), + task::System(B),); -} diff --git a/tests/trybuild/schedule/unexpected_token.stderr b/tests/trybuild/schedule/unexpected_token.stderr deleted file mode 100644 index d02d2b66..00000000 --- a/tests/trybuild/schedule/unexpected_token.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `+` - --> tests/trybuild/schedule/unexpected_token.rs:40:47 - | -40 | let schedule = schedule!(task::System(A), + task::System(B),); - | ^ no rules expected this token in macro call