diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index db18648..ae78735 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -17,7 +17,7 @@ pub use crate::type_map::{ }; pub use crate::unsafe_component_store::UnsafeComponentStore; pub use crate::updates::*; -pub use crate::world::{World, WorldBuilder}; +pub use crate::world::{AddSystem, World, WorldBuilder}; pub use commands::Commands; pub use get_disjoint_mut::GetDisjointMut; pub use update_macros::Resource; diff --git a/ecs/src/updates.rs b/ecs/src/updates.rs index b8a957e..2190d0a 100644 --- a/ecs/src/updates.rs +++ b/ecs/src/updates.rs @@ -292,4 +292,4 @@ impl_update_filter!(Nonuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], #[rustfmt::skip] impl_update_filter!(Decuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z], [A, a]); -implement_updates!(5, 5); +implement_updates!(5, 6); diff --git a/ecs/src/world.rs b/ecs/src/world.rs index dc2caad..20c819f 100644 --- a/ecs/src/world.rs +++ b/ecs/src/world.rs @@ -10,26 +10,20 @@ use utilities::prelude::{remove_life_time, remove_life_time_mut}; use crate::{entity_object_manager::EntityObjectManager, *}; +pub trait AddSystem { + fn add_system(&mut self, priority: u32, f: Func); +} + pub struct WorldBuilder { pub(crate) updates: Updates, pub events: Events, pub resources: Resources, - systems: Vec<( + pub(crate) systems: Vec<( u32, - Box Result + Send + Sync + 'static>, + Box Result + Send + Sync + 'static>, )>, } -impl WorldBuilder { - pub fn add_system(&mut self, priority: u32, f: F) - where - F: Fn(&mut World) -> Result + Send + Sync + 'static, - { - self.systems.push((priority, Box::new(f))); - self.systems.sort_by_key(|(priority, _)| *priority); - } -} - impl WorldBuilder { pub fn build(self) -> World { World { @@ -72,7 +66,7 @@ pub struct World { start_time: Instant, - systems: Vec Result + Send + Sync + 'static>>, + systems: Vec Result + Send + Sync + 'static>>, } impl World { @@ -433,12 +427,16 @@ impl World { self.commit_entity_changes()?; + let mut commands = Commands::new(self.now()); + for system in systems.iter() { - if !system(self)? { + if !system(self, &mut commands)? { return Ok(()); } } + commands.apply_deferred(self)?; + // reset flag self.had_entity_changes = false; } diff --git a/update_macros/src/update.rs b/update_macros/src/update.rs index fd8d3a3..e842024 100644 --- a/update_macros/src/update.rs +++ b/update_macros/src/update.rs @@ -309,7 +309,7 @@ impl Update { } } - pub fn resource_only_events(&self) -> TokenStream2 { + pub fn resource_only_events_and_systems(&self) -> TokenStream2 { let resource_types = self.resource_types(); let resource_type_impls = self.resource_type_impls(); @@ -329,7 +329,7 @@ impl Update { quote! { impl EventReader for Events where - Func: Fn(&P, &mut Commands, #resources ) -> Result<()> + Send + Sync + Clone + 'static, + Func: Fn(&P, &mut Commands, #resources ) -> Result<()> + Send + Sync + 'static, #reource_requirement P: std::any::Any + Send + Sync, { @@ -350,6 +350,22 @@ impl Update { } } } + + impl AddSystem<#resource_types, Func> for WorldBuilder + where + Func: Fn(&mut Commands, #resources ) -> Result + Send + Sync + 'static, + #reource_requirement + { + fn add_system(&mut self, priority: u32, func: Func) { + self.systems.push((priority, Box::new(move |world: &mut World, commands: &mut Commands| { + #resource_store + func(commands, #( #resource_idents, )*) + }))); + self.systems.sort_by_key(|(priority, _)| *priority); + } + } + + } } } @@ -495,7 +511,7 @@ impl ToTokens for Update { impl EventReader for Events where - Func: Fn(&P, &mut Commands, #( #queries, )* #resources ) -> Result<()> + Send + Sync + Clone + 'static, + Func: Fn(&P, &mut Commands, #( #queries, )* #resources ) -> Result<()> + Send + Sync + 'static, #filter_requirements #component_requirements #reource_requirement @@ -588,7 +604,8 @@ pub fn update(max_components: usize, max_resources: usize) -> TokenStream { let mut events = Vec::new(); for resource_count in resources.iter() { - let q = Update::new(vec![1].into_iter(), *resource_count).resource_only_events(); + let q = + Update::new(vec![1].into_iter(), *resource_count).resource_only_events_and_systems(); events.push(q); }