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}