From 3f15a49f94892dc7845bac4d7b8ab842b3f1db4c Mon Sep 17 00:00:00 2001 From: Imbris Date: Wed, 3 Jan 2024 17:34:30 -0500 Subject: [PATCH] Re-use SendDispatcher in Dispatcher to reduce code duplication --- src/dispatch/dispatcher.rs | 69 +++++++++----------------------------- 1 file changed, 16 insertions(+), 53 deletions(-) diff --git a/src/dispatch/dispatcher.rs b/src/dispatch/dispatcher.rs index 19b9d8b..e6f064c 100644 --- a/src/dispatch/dispatcher.rs +++ b/src/dispatch/dispatcher.rs @@ -14,19 +14,15 @@ pub type ThreadPoolWrapper = Option<::std::sync::Arc<::rayon::ThreadPool>>; /// The dispatcher struct, allowing /// systems to be executed in parallel. pub struct Dispatcher<'a, 'b> { - stages: Vec>, + inner: SendDispatcher<'a>, thread_local: ThreadLocal<'b>, - #[cfg(feature = "parallel")] - thread_pool: ::std::sync::Arc<::std::sync::RwLock>, } impl<'a, 'b> Dispatcher<'a, 'b> { /// Sets up all the systems which means they are gonna add default values /// for the resources they need. pub fn setup(&mut self, world: &mut World) { - for stage in &mut self.stages { - stage.setup(world); - } + self.inner.setup(world); for sys in &mut self.thread_local { sys.setup(world); @@ -38,9 +34,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> { /// / or resources from the `World` which are associated with external /// resources. pub fn dispose(self, world: &mut World) { - for stage in self.stages { - stage.dispose(world); - } + self.inner.dispose(world); for sys in self.thread_local { sys.dispose(world); @@ -60,12 +54,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> { /// Please note that this method assumes that no resource /// is currently borrowed. If that's the case, it panics. pub fn dispatch(&mut self, world: &World) { - #[cfg(feature = "parallel")] - self.dispatch_par(world); - - #[cfg(not(feature = "parallel"))] - self.dispatch_seq(world); - + self.inner.dispatch(world); self.dispatch_thread_local(world); } @@ -81,18 +70,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> { /// is currently borrowed. If that's the case, it panics. #[cfg(feature = "parallel")] pub fn dispatch_par(&mut self, world: &World) { - let stages = &mut self.stages; - - self.thread_pool - .read() - .unwrap() - .as_ref() - .unwrap() - .install(move || { - for stage in stages { - stage.execute(world); - } - }); + self.inner.dispatch_par(world); } /// Dispatches the systems (except thread local systems) sequentially. @@ -103,9 +81,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> { /// Please note that this method assumes that no resource /// is currently borrowed. If that's the case, it panics. pub fn dispatch_seq(&mut self, world: &World) { - for stage in &mut self.stages { - stage.execute_seq(world); - } + self.inner.dispatch_seq(world); } /// Dispatch only thread local systems sequentially. @@ -123,25 +99,14 @@ impl<'a, 'b> Dispatcher<'a, 'b> { /// Fails and returns the original distpatcher if it contains thread local systems. pub fn try_into_sendable(self) -> Result, Self> { let Dispatcher { - stages, + inner: _, thread_local, - #[cfg(feature = "parallel")] - thread_pool, - } = self; + } = &self; if thread_local.is_empty() { - Ok(SendDispatcher { - stages, - #[cfg(feature = "parallel")] - thread_pool, - }) + Ok(self.inner) } else { - Err(Dispatcher { - stages, - thread_local, - #[cfg(feature = "parallel")] - thread_pool, - }) + Err(self) } } @@ -150,11 +115,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> { /// how well your systems can make use of multi-threading. #[cfg(feature = "parallel")] pub fn max_threads(&self) -> usize { - self.stages - .iter() - .map(Stage::max_threads) - .max() - .unwrap_or(0) + self.inner.max_threads() } } @@ -185,9 +146,11 @@ pub fn new_dispatcher<'a, 'b>( thread_pool: ::std::sync::Arc<::std::sync::RwLock>, ) -> Dispatcher<'a, 'b> { Dispatcher { - stages, + inner: SendDispatcher { + stages, + thread_pool, + }, thread_local, - thread_pool, } } @@ -197,7 +160,7 @@ pub fn new_dispatcher<'a, 'b>( thread_local: ThreadLocal<'b>, ) -> Dispatcher<'a, 'b> { Dispatcher { - stages, + inner: SendDispatcher { stages }, thread_local, } }