async_ecs/system/
mod.rs

1mod system_data;
2
3pub use system_data::{DynamicSystemData, SystemData};
4
5use futures::future::BoxFuture;
6
7use crate::{
8    access::{Accessor, AccessorCow, AccessorType},
9    world::World,
10};
11
12/// A `System`, executed with a set of required [`Resource`]s.
13///
14/// [`Resource`]: trait.Resource.html
15pub trait System<'a>: Sized {
16    /// The resource bundle required to execute a system.
17    ///
18    /// You will mostly use a tuple of system data (which also implements
19    /// `SystemData`). You can also create such a resource bundle by simply
20    /// deriving `SystemData` for a struct.
21    ///
22    /// Every `SystemData` is also a `DynamicSystemData`.
23    type SystemData: DynamicSystemData<'a>;
24
25    /// Initialize the systems.
26    fn init(&mut self) {}
27
28    /// Executes the system with the required system data.
29    fn run(&mut self, data: Self::SystemData);
30
31    /// Return the accessor from the [`SystemData`].
32    fn accessor<'b>(&'b self) -> AccessorCow<'a, 'b, Self::SystemData> {
33        AccessorCow::Owned(
34            AccessorType::<'a, Self::SystemData>::try_new()
35                .expect("Missing implementation for `accessor`"),
36        )
37    }
38
39    /// Sets up the `World` using `Self::SystemData::setup`.
40    fn setup(&mut self, world: &mut World) {
41        self.init();
42
43        <Self::SystemData as DynamicSystemData>::setup(&self.accessor(), world)
44    }
45
46    /// Performs clean up that requires resources from the `World`.
47    /// This commonly removes components from `world` which depend on external
48    /// resources.
49    fn dispose(self, world: &mut World)
50    where
51        Self: Sized,
52    {
53        let _ = world;
54    }
55}
56
57/// A `System`, executed with a set of required [`Resource`]s asynchronous.
58///
59/// [`Resource`]: trait.Resource.html
60pub trait AsyncSystem<'a>: Sized {
61    /// The resource bundle required to execute a system.
62    ///
63    /// You will mostly use a tuple of system data (which also implements
64    /// `SystemData`). You can also create such a resource bundle by simply
65    /// deriving `SystemData` for a struct.
66    ///
67    /// Every `SystemData` is also a `DynamicSystemData`.
68    type SystemData: DynamicSystemData<'a>;
69
70    /// Initialize the systems.
71    fn init(&mut self) {}
72
73    /// Executes the system with the required system data asynchronous.
74    fn run_async(&mut self, data: Self::SystemData) -> BoxFuture<'a, ()>;
75
76    /// Return the accessor from the [`SystemData`].
77    fn accessor<'b>(&'b self) -> AccessorCow<'a, 'b, Self::SystemData> {
78        AccessorCow::Owned(
79            AccessorType::<'a, Self::SystemData>::try_new()
80                .expect("Missing implementation for `accessor`"),
81        )
82    }
83
84    /// Sets up the `World` using `Self::SystemData::setup`.
85    fn setup(&mut self, world: &mut World) {
86        self.init();
87
88        <Self::SystemData as DynamicSystemData>::setup(&self.accessor(), world)
89    }
90
91    /// Performs clean up that requires resources from the `World`.
92    /// This commonly removes components from `world` which depend on external
93    /// resources.
94    fn dispose(self, world: &mut World)
95    where
96        Self: Sized,
97    {
98        let _ = world;
99    }
100}