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

#![warn(missing_docs)]
#[macro_use]
mod macros;
mod access;
#[macro_use]
pub mod borrow;
mod commandbuffer;
pub mod context;
pub mod error;
mod query;
mod schedule;
mod subworld;
mod subworld_impls;
pub mod system;
pub mod traits;

pub use access::*;
pub use borrow::{Read, Write};
pub use commandbuffer::*;
pub use context::*;
pub use error::Error;
pub use query::*;
pub use subworld_impls::*;
// Don't export result so that hecs-schedule can be glob imported without
// conflict
pub(crate) use error::Result;
pub use schedule::*;
pub use subworld::*;
pub use system::*;