despero_hecs_schedule/lib.rs
1//! # Hecs-schedule
2//!
3//! hecs-schedule is a framework for [hecs](https://crates.io/crates/hecs) that
4//! provides system abstractions for paralell execution.
5//!
6//! ## SubWorld
7//!
8//! [SubWorld]( crate::SubWorld ) provides the ability to split the world into smaller parts
9//! which can only access a subset of components. This allows
10//!
11//! ## Commandbuffer
12//!
13//! [CommandBuffer]( crate::CommandBuffer ) provides deferred world modification by
14//! means of component insertion, removal, entity spawning and despawning, as well
15//! as arbitrary world modification by closures, which will be executed at a later
16//! time.
17//!
18//! The commandbuffer extends the already existing hecs::CommandBuffer and provides
19//! more functionality.
20//!
21//! ## System and Schedule
22//!
23//! A system represents a unit of work which can access any resource. Systems are
24//! implemented for any function and closure with any number of arguments (well, up
25//! to a sane limit due to tuple size and compile time).
26//!
27//! A system may access a subworld and safely access the declared components. It can
28//! also access any other value by type with [Read](crate::Read) and [Write](crate::Write) wrappers.
29//!
30//! This value will be pulled from the provided [Context](crate::Context) which is
31//! provided to [Schedule::execute] as a mutable reference. This means that systems
32//! can access local variable and struct members from outside the ECS. If a value of
33//! the type was not provided, the system will exit cleanly with an error.
34//!
35//! Systems can either return nothing or an empty result, which will be properly
36//! boxed and propogated
37//!
38//! The schedule is a collection of ordered system executions.
39//!
40//! When a schedule is executed, a tuple of references for the contained systems
41//! will be provided.
42//!
43//! ## Usage
44//!
45//! ```rust
46//! use hecs_schedule::*;
47//! use hecs::*;
48//!
49//! let mut world = World::default();
50//!
51//! #[derive(Debug)]
52//! struct App {
53//! name: &'static str,
54//! }
55//!
56//! let mut app = App {
57//! name: "hecs-schedule"
58//! };
59//!
60//! // Spawn some entities
61//! let a = world.spawn(("a", 42));
62//! world.spawn(("b", 0));
63//! world.spawn(("c", 7));
64//!
65//! // Create a simple system to print the entities
66//! let print_system = | w: SubWorld<(& &'static str, &i32)> | {
67//! w.query::<(&&'static str, &i32)>().iter().for_each(|(e, val)| {
68//! println!("Entity {:?}: {:?}", e, val);
69//! })
70//! };
71//!
72//! // Get a component from a specific entity, failing gracefully if the entity
73//! // didn't exist or the subworld did not support the component. The result
74//! // will propogate to the schedule execution.
75//! let get_system = move | w: SubWorld<&i32> | -> anyhow::Result<()> {
76//! let val = w.get::<i32>(a)?;
77//!
78//! // Prints the answer to life, the universe, and everything.
79//! // Welp, maybe not how to please the borrow checker, but almost
80//! // everything.
81//! println!("Got: {}", *val);
82//!
83//! Ok(())
84//! };
85//!
86//! // Declare a system which borrows the app and prints it.
87//! // This requires that a reference to app was provided to execute.
88//! // Otherwise, the system fails and returns an error, which propogates to the
89//! // schedule and stops execution.
90//!
91//! // It is also possible to modify the app via `mut Write<App>`
92//! let print_app = |app: Read<App>| {
93//! println!("App: {:?}", app);
94//! };
95//!
96//! // Note: the `hecs_schedule::CommandBuffer` is a superset of `hecs::CommandBuffer` and is
97//! // accesible as a shared resource from systems.
98//! let spawn_system = |mut cmd: Write<hecs_schedule::CommandBuffer>| {
99//! cmd.spawn(("c", 5));
100//! };
101//!
102//! // Construct a schedule
103//! let mut schedule = Schedule::builder()
104//! .add_system(spawn_system)
105//! .add_system(print_system)
106//! .add_system(print_app)
107//! .add_system(get_system)
108//! .build();
109//!
110//! // Execute the schedule's systems and provide the world and app. This will parallelize as much
111//! // as possible.
112//! schedule.execute((&mut world, &mut app)).expect("Failed to execute schedule");
113//!
114//! ```
115
116#![warn(missing_docs)]
117#[macro_use]
118mod macros;
119mod access;
120#[macro_use]
121pub mod borrow;
122mod commandbuffer;
123pub mod context;
124pub mod error;
125mod query;
126mod schedule;
127mod subworld;
128mod subworld_impls;
129pub mod system;
130pub mod traits;
131
132pub use access::*;
133pub use borrow::{Read, Write};
134pub use commandbuffer::*;
135pub use context::*;
136pub use error::Error;
137pub use query::*;
138pub use subworld_impls::*;
139// Don't export result so that hecs-schedule can be glob imported without
140// conflict
141pub(crate) use error::Result;
142pub use schedule::*;
143pub use subworld::*;
144pub use system::*;