[−][src]Struct yaks::ExecutorBuilder
A factory for Executor
(and the only way of creating one).
Implementations
impl<'closures, Resources, Handle> ExecutorBuilder<'closures, Resources, Handle> where
Resources: ResourceTuple,
Handle: Eq + Hash,
[src]
Resources: ResourceTuple,
Handle: Eq + Hash,
pub fn system<'a, Closure, ResourceRefs, Queries, Markers>(
self,
closure: Closure
) -> Self where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
[src]
self,
closure: Closure
) -> Self where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
Creates a new system from a closure or a function, and inserts it into the builder.
The system-to-be must return nothing and have these 3 arguments:
SystemContext
,- any tuple (up to 16) or a single one of "resources": references or mutable references
to
Send + Sync
values not contained in ahecs::World
that the system will be accessing, - any tuple (up to 16) or a single one of
QueryMarker
that represent the queries the system will be making.
Additionally, closures may mutably borrow from their environment for the lifetime
of the executor, but must be Send + Sync
.
All resources the system requires must correspond to a type in the executor's
signature; e.g., if any number of systems require a &f32
or a &mut f32
,
executor's generic parameter must contain f32
.
Example
fn system_0( context: SystemContext, res_a: &A, (query_0, query_1): ( QueryMarker<(&B, &mut C)>, QueryMarker<hecs::Without<B, &C>> ), ) { // This system may read resource of type `A`, and may prepare & execute queries // of `(&B, &mut C)` and `hecs::Without<B, &C>`. } fn system_1( context: SystemContext, (res_a, res_b): (&mut A, &B), query_0: QueryMarker<(&mut B, &mut C)>, ) { // This system may read or write resource of type `A`, may read resource of type `B`, // and may prepare & execute queries of `(&mut B, &mut C)`. } let mut increment = 0; // All together, systems require resources of types `A`, `B`, and `C`. let mut executor = Executor::<(A, B, C)>::builder() .system(system_0) .system(system_1) .system(|context, res_c: &C, _queries: ()| { // This system may read resource of type `C` and will not perform any queries. increment += 1; // `increment` will be borrowed by the executor. }) .build(); let (mut a, mut b, mut c) = (A, B, C); executor.run(&world, (&mut a, &mut b, &mut c)); executor.run(&world, (&mut a, &mut b, &mut c)); executor.run(&world, (&mut a, &mut b, &mut c)); drop(executor); // This releases the borrow of `increment`. assert_eq!(increment, 3);
pub fn system_with_handle<'a, Closure, ResourceRefs, Queries, Markers, NewHandle>(
self,
closure: Closure,
handle: NewHandle
) -> ExecutorBuilder<'closures, Resources, NewHandle> where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
NewHandle: HandleConversion<Handle> + Debug,
[src]
self,
closure: Closure,
handle: NewHandle
) -> ExecutorBuilder<'closures, Resources, NewHandle> where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
NewHandle: HandleConversion<Handle> + Debug,
Creates a new system from a closure or a function, and inserts it into
the builder with given handle; see ::system()
.
Handles allow defining relative order of execution between systems,
and using them is optional. They can be of any type that is Sized + Eq + Hash + Debug
and do not persist after ::build()
- the
resulting executor relies on lightweight opaque IDs;
see SystemContext::id()
.
Handles must be unique, and systems with dependencies must be inserted
into the builder after said dependencies.
If the default parallel
feature is disabled the systems will be executed in insertion
order, which these rules guarantee to be a valid order.
Since specifying a dependency between systems forbids them to run concurrently, this
functionality should be used only when necessary. In fact, for executors where systems
form a single chain of execution it is more performant to call them as functions,
in a sequence, inside a single rayon::scope()
or
rayon::ThreadPool::install()
block.
Examples
These two executors are identical.
let _ = Executor::<()>::builder() .system_with_handle(system_0, 0) .system_with_handle(system_1, 1) .system_with_handle_and_deps(system_2, 2, vec![0, 1]) .system_with_deps(system_3, vec![2]) .system_with_deps(system_4, vec![0]) .build(); let _ = Executor::<()>::builder() .system_with_handle(system_0, "system_0") .system_with_handle(system_1, "system_1") .system_with_handle_and_deps(system_2, "system_2", vec!["system_1", "system_0"]) .system_with_deps(system_3, vec!["system_2"]) .system_with_deps(system_4, vec!["system_0"]) .build();
The order of execution (with the default parallel
feature enabled) is:
- systems 0 and 1,
- system 4 as soon as 0 is finished and system 2 as soon as both 0 and 1 is finished,
- system 3 as soon as 2 is finished.
This executor will behave identically to the two above if the default parallel
feature is enabled; otherwise, the execution order will be different, but
that doesn't matter as long as the given dependencies truthfully reflect any
relationships the systems may have.
let _ = Executor::<()>::builder() .system_with_handle(system_1, 1) .system_with_handle(system_0, 0) .system_with_deps(system_4, vec![0]) .system_with_handle_and_deps(system_2, 2, vec![0, 1]) .system_with_deps(system_3, vec![2]) .build();
Panics
This function will panic if:
- a system with given handle is already present in the builder.
pub fn system_with_deps<'a, Closure, ResourceRefs, Queries, Markers>(
self,
closure: Closure,
dependencies: Vec<Handle>
) -> Self where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
Handle: Eq + Hash + Debug,
[src]
self,
closure: Closure,
dependencies: Vec<Handle>
) -> Self where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
Handle: Eq + Hash + Debug,
Creates a new system from a closure or a function, and inserts it into
the builder with given dependencies; see ::system()
.
Given system will start running only after all systems in given list of dependencies have finished running.
This function cannot be used unless the builder already has
at least one system with a handle;
see ::system_with_handle()
.
Panics
This function will panic if:
- given list of dependencies contains a handle that doesn't correspond to any system in the builder.
pub fn system_with_handle_and_deps<'a, Closure, ResourceRefs, Queries, Markers>(
self,
closure: Closure,
handle: Handle,
dependencies: Vec<Handle>
) -> Self where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
Handle: Eq + Hash + Debug,
[src]
self,
closure: Closure,
handle: Handle,
dependencies: Vec<Handle>
) -> Self where
Resources::Cells: 'a,
Closure: FnMut(SystemContext<'a>, ResourceRefs, Queries) + Send + Sync + 'closures,
ResourceRefs: Fetch<'a, WrappedResources<'a, Resources::Cells>, Markers> + 'a,
Queries: QueryBundle,
Handle: Eq + Hash + Debug,
Creates a new system from a closure or a function, and inserts it into
the builder with given handle and dependencies; see ::system()
.
Given system will start running only after all systems in given list of dependencies have finished running.
This function cannot be used unless the builder already has
at least one system with a handle;
see ::system_with_handle()
.
Panics
This function will panic if:
- a system with given handle is already present in the builder,
- given list of dependencies contains a handle that doesn't correspond to any system in the builder,
- given handle appears in given list of dependencies.
pub fn build(self) -> Executor<'closures, Resources>
[src]
Consumes the builder and returns the finalized executor.
Auto Trait Implementations
impl<'closures, Resources, Handle = DummyHandle> !RefUnwindSafe for ExecutorBuilder<'closures, Resources, Handle>
impl<'closures, Resources, Handle> Send for ExecutorBuilder<'closures, Resources, Handle> where
Handle: Send,
Handle: Send,
impl<'closures, Resources, Handle = DummyHandle> !Sync for ExecutorBuilder<'closures, Resources, Handle>
impl<'closures, Resources, Handle> Unpin for ExecutorBuilder<'closures, Resources, Handle> where
Handle: Unpin,
Handle: Unpin,
impl<'closures, Resources, Handle = DummyHandle> !UnwindSafe for ExecutorBuilder<'closures, Resources, Handle>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,