shred/
lib.rs

1#![cfg_attr(feature = "nightly", feature(ptr_metadata, strict_provenance))]
2//! **Sh**ared **re**source **d**ispatcher
3//!
4//! This library allows to dispatch
5//! systems, which can have interdependencies,
6//! shared and exclusive resource access, in parallel.
7//!
8//! # Examples
9//!
10//! ```rust
11//! extern crate shred;
12//!
13//! use shred::{DispatcherBuilder, Read, Resource, ResourceId, System, SystemData, World, Write};
14//!
15//! #[derive(Debug, Default)]
16//! struct ResA;
17//!
18//! #[derive(Debug, Default)]
19//! struct ResB;
20//!
21//! # #[cfg(feature = "shred-derive")]
22//! #[derive(SystemData)] // Provided with `shred-derive` feature
23//! struct Data<'a> {
24//!     a: Read<'a, ResA>,
25//!     b: Write<'a, ResB>,
26//! }
27//!
28//! struct EmptySystem;
29//!
30//! impl<'a> System<'a> for EmptySystem {
31//!     type SystemData = Data<'a>;
32//!
33//!     fn run(&mut self, bundle: Data<'a>) {
34//!         println!("{:?}", &*bundle.a);
35//!         println!("{:?}", &*bundle.b);
36//!     }
37//! }
38//!
39//! let mut world = World::empty();
40//! let mut dispatcher = DispatcherBuilder::new()
41//!     .with(EmptySystem, "empty", &[])
42//!     .build();
43//! world.insert(ResA);
44//! world.insert(ResB);
45//!
46//! dispatcher.dispatch(&mut world);
47//! #
48//! # // The following is required for the snippet to compile without the `shred-derive` feature.
49//! #
50//! # #[cfg(not(feature = "shred-derive"))]
51//! # struct Data<'a> {
52//! #     a: Read<'a, ResA>,
53//! #     b: Write<'a, ResB>,
54//! # }
55//! #
56//! # #[cfg(not(feature = "shred-derive"))]
57//! # impl<'a> SystemData<'a> for Data<'a> {
58//! #     fn setup(world: &mut World) {
59//! #         Read::<'_, ResA>::setup(world);
60//! #         Write::<'_, ResB>::setup(world);
61//! #     }
62//! #
63//! #     fn fetch(world: &'a World) -> Self {
64//! #         Self {
65//! #             a: Read::<'_, ResA>::fetch(world),
66//! #             b: Write::<'_, ResB>::fetch(world),
67//! #         }
68//! #     }
69//! #
70//! #     fn reads() -> Vec<ResourceId> {
71//! #         Read::<'_, ResA>::reads()
72//! #     }
73//! #
74//! #     fn writes() -> Vec<ResourceId> {
75//! #         Write::<'_, ResB>::writes()
76//! #     }
77//! # }
78//! ```
79//!
80//! Once you are more familiar with how system data and parallelization works,
81//! you can take look at a more flexible and performant way to dispatch:
82//! `ParSeq`. Using it is bit trickier, but it allows dispatching without any
83//! virtual function calls.
84
85#![deny(unused_must_use, clippy::disallowed_types)]
86#![deny(unsafe_op_in_unsafe_fn)]
87#![warn(missing_docs)]
88
89/// Re-exports from [`atomic_refcell`]
90///
91/// Mainly for internals, most users don't need to interact with this.
92pub mod cell {
93    pub use atomic_refcell::*;
94}
95
96mod dispatch;
97mod meta;
98mod system;
99mod world;
100
101/// A reexport of the `#[derive(SystemData]` macro provided by `shred-derive`.
102/// This requires that the `shred-derive` feature is enabled.
103#[cfg(feature = "shred-derive")]
104pub use shred_derive::SystemData;
105
106#[cfg(feature = "parallel")]
107pub use crate::dispatch::AsyncDispatcher;
108#[cfg(feature = "parallel")]
109pub use crate::dispatch::{Par, ParSeq, RunWithPool, Seq};
110pub use crate::{
111    dispatch::{
112        BatchAccessor, BatchController, BatchUncheckedWorld, Dispatcher, DispatcherBuilder,
113        MultiDispatchController, MultiDispatcher, SendDispatcher,
114    },
115    meta::{CastFrom, MetaIter, MetaIterMut, MetaTable},
116    system::{
117        Accessor, AccessorCow, DynamicSystemData, RunNow, RunningTime, StaticAccessor, System,
118        SystemData,
119    },
120    world::{
121        DefaultProvider, Entry, Fetch, FetchMut, PanicHandler, Read, ReadExpect, Resource,
122        ResourceId, SetupHandler, World, Write, WriteExpect,
123    },
124};
125
126/// Alias for `World` for easier migration to the new version. Will be removed
127/// in the future.
128#[deprecated(since = "0.8.0", note = "renamed to `World`")]
129pub type Resources = World;