11use smallvec:: SmallVec ;
22
3- use crate :: { dispatch:: stage:: Stage , system:: RunNow , world:: World } ;
3+ use crate :: {
4+ dispatch:: { stage:: Stage , SendDispatcher } ,
5+ system:: RunNow ,
6+ world:: World ,
7+ } ;
48
59/// This wrapper is used to share a replaceable ThreadPool with other
610/// dispatchers. Useful with batch dispatchers.
@@ -10,19 +14,15 @@ pub type ThreadPoolWrapper = Option<::std::sync::Arc<::rayon::ThreadPool>>;
1014/// The dispatcher struct, allowing
1115/// systems to be executed in parallel.
1216pub struct Dispatcher < ' a , ' b > {
13- stages : Vec < Stage < ' a > > ,
17+ inner : SendDispatcher < ' a > ,
1418 thread_local : ThreadLocal < ' b > ,
15- #[ cfg( feature = "parallel" ) ]
16- thread_pool : :: std:: sync:: Arc < :: std:: sync:: RwLock < ThreadPoolWrapper > > ,
1719}
1820
1921impl < ' a , ' b > Dispatcher < ' a , ' b > {
2022 /// Sets up all the systems which means they are gonna add default values
2123 /// for the resources they need.
2224 pub fn setup ( & mut self , world : & mut World ) {
23- for stage in & mut self . stages {
24- stage. setup ( world) ;
25- }
25+ self . inner . setup ( world) ;
2626
2727 for sys in & mut self . thread_local {
2828 sys. setup ( world) ;
@@ -34,9 +34,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> {
3434 /// / or resources from the `World` which are associated with external
3535 /// resources.
3636 pub fn dispose ( self , world : & mut World ) {
37- for stage in self . stages {
38- stage. dispose ( world) ;
39- }
37+ self . inner . dispose ( world) ;
4038
4139 for sys in self . thread_local {
4240 sys. dispose ( world) ;
@@ -56,12 +54,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> {
5654 /// Please note that this method assumes that no resource
5755 /// is currently borrowed. If that's the case, it panics.
5856 pub fn dispatch ( & mut self , world : & World ) {
59- #[ cfg( feature = "parallel" ) ]
60- self . dispatch_par ( world) ;
61-
62- #[ cfg( not( feature = "parallel" ) ) ]
63- self . dispatch_seq ( world) ;
64-
57+ self . inner . dispatch ( world) ;
6558 self . dispatch_thread_local ( world) ;
6659 }
6760
@@ -77,18 +70,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> {
7770 /// is currently borrowed. If that's the case, it panics.
7871 #[ cfg( feature = "parallel" ) ]
7972 pub fn dispatch_par ( & mut self , world : & World ) {
80- let stages = & mut self . stages ;
81-
82- self . thread_pool
83- . read ( )
84- . unwrap ( )
85- . as_ref ( )
86- . unwrap ( )
87- . install ( move || {
88- for stage in stages {
89- stage. execute ( world) ;
90- }
91- } ) ;
73+ self . inner . dispatch_par ( world) ;
9274 }
9375
9476 /// Dispatches the systems (except thread local systems) sequentially.
@@ -99,9 +81,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> {
9981 /// Please note that this method assumes that no resource
10082 /// is currently borrowed. If that's the case, it panics.
10183 pub fn dispatch_seq ( & mut self , world : & World ) {
102- for stage in & mut self . stages {
103- stage. execute_seq ( world) ;
104- }
84+ self . inner . dispatch_seq ( world) ;
10585 }
10686
10787 /// Dispatch only thread local systems sequentially.
@@ -114,16 +94,28 @@ impl<'a, 'b> Dispatcher<'a, 'b> {
11494 }
11595 }
11696
97+ /// Converts this to a [`SendDispatcher`].
98+ ///
99+ /// Fails and returns the original distpatcher if it contains thread local systems.
100+ pub fn try_into_sendable ( self ) -> Result < SendDispatcher < ' a > , Self > {
101+ let Dispatcher {
102+ inner : _,
103+ thread_local,
104+ } = & self ;
105+
106+ if thread_local. is_empty ( ) {
107+ Ok ( self . inner )
108+ } else {
109+ Err ( self )
110+ }
111+ }
112+
117113 /// This method returns the largest amount of threads this dispatcher
118114 /// can make use of. This is mainly for debugging purposes so you can see
119115 /// how well your systems can make use of multi-threading.
120116 #[ cfg( feature = "parallel" ) ]
121117 pub fn max_threads ( & self ) -> usize {
122- self . stages
123- . iter ( )
124- . map ( Stage :: max_threads)
125- . max ( )
126- . unwrap_or ( 0 )
118+ self . inner . max_threads ( )
127119 }
128120}
129121
@@ -154,9 +146,11 @@ pub fn new_dispatcher<'a, 'b>(
154146 thread_pool : :: std:: sync:: Arc < :: std:: sync:: RwLock < ThreadPoolWrapper > > ,
155147) -> Dispatcher < ' a , ' b > {
156148 Dispatcher {
157- stages,
149+ inner : SendDispatcher {
150+ stages,
151+ thread_pool,
152+ } ,
158153 thread_local,
159- thread_pool,
160154 }
161155}
162156
@@ -166,7 +160,7 @@ pub fn new_dispatcher<'a, 'b>(
166160 thread_local : ThreadLocal < ' b > ,
167161) -> Dispatcher < ' a , ' b > {
168162 Dispatcher {
169- stages,
163+ inner : SendDispatcher { stages } ,
170164 thread_local,
171165 }
172166}
0 commit comments