@@ -28,7 +28,7 @@ It defines simple and practical hehaviors of `Actor` model.
2828*/
2929pub trait Actor < Msg , ContextValue , HandleType , Functor > : UniqueId < String > {
3030 fn receive ( & mut self , message : Msg , context : & mut HashMap < String , ContextValue > ) ;
31- fn spawn_with_handle ( & self , name : impl Into < String > , func : Functor ) -> HandleType ;
31+ fn spawn_with_handle ( & self , func : Functor ) -> HandleType ;
3232
3333 fn get_handle ( & self ) -> HandleType ;
3434 fn get_handle_child ( & self , name : impl Into < String > ) -> Option < HandleType > ;
@@ -76,7 +76,14 @@ pub struct ActorAsync<Msg, ContextValue> {
7676
7777 context : Arc < Mutex < Box < HashMap < String , ContextValue > > > > ,
7878 queue : Arc < Mutex < BlockingQueue < Msg > > > ,
79- effect : Arc < Mutex < dyn FnMut ( Msg , & mut HashMap < String , ContextValue > ) + Send + Sync + ' static > > ,
79+ effect : Arc <
80+ Mutex <
81+ dyn FnMut ( & mut ActorAsync < Msg , ContextValue > , Msg , & mut HashMap < String , ContextValue > )
82+ + Send
83+ + Sync
84+ + ' static ,
85+ > ,
86+ > ,
8087
8188 join_handle : Arc < Mutex < Option < thread:: JoinHandle < ( ) > > > > ,
8289}
@@ -99,13 +106,19 @@ impl<Msg, ContextValue> Clone for ActorAsync<Msg, ContextValue> {
99106
100107impl < Msg , ContextValue > ActorAsync < Msg , ContextValue > {
101108 pub fn new (
102- effect : impl FnMut ( Msg , & mut HashMap < String , ContextValue > ) + Send + Sync + ' static ,
109+ effect : impl FnMut ( & mut ActorAsync < Msg , ContextValue > , Msg , & mut HashMap < String , ContextValue > )
110+ + Send
111+ + Sync
112+ + ' static ,
103113 ) -> Self {
104114 Self :: new_with_options ( effect, None , Arc :: new ( Mutex :: new ( BlockingQueue :: new ( ) ) ) )
105115 }
106116
107117 pub fn new_with_options (
108- effect : impl FnMut ( Msg , & mut HashMap < String , ContextValue > ) + Send + Sync + ' static ,
118+ effect : impl FnMut ( & mut ActorAsync < Msg , ContextValue > , Msg , & mut HashMap < String , ContextValue > )
119+ + Send
120+ + Sync
121+ + ' static ,
109122 parent_handle : Option < Arc < dyn Handle < Msg , ContextValue > + Send + Sync + ' static > > ,
110123 queue : Arc < Mutex < BlockingQueue < Msg > > > ,
111124 ) -> Self {
@@ -226,30 +239,41 @@ impl<Msg, ContextValue>
226239 Msg ,
227240 ContextValue ,
228241 Arc < dyn Handle < Msg , ContextValue > + Send + Sync + ' static > ,
229- Box < dyn FnMut ( Msg , & mut HashMap < String , ContextValue > ) + Send + Sync + ' static > ,
242+ Box <
243+ dyn FnMut ( & mut ActorAsync < Msg , ContextValue > , Msg , & mut HashMap < String , ContextValue > )
244+ + Send
245+ + Sync
246+ + ' static ,
247+ > ,
230248 > for ActorAsync < Msg , ContextValue >
231249where
232- Msg : Send + ' static ,
233- ContextValue : ' static ,
250+ Msg : Clone + Send + ' static ,
251+ ContextValue : Send + ' static ,
234252{
235253 fn receive ( & mut self , message : Msg , context : & mut HashMap < String , ContextValue > ) {
236254 {
237- self . effect . lock ( ) . unwrap ( ) ( message, context) ;
255+ let effect = self . effect . clone ( ) ;
256+ effect. lock ( ) . unwrap ( ) ( self , message, context) ;
238257 }
239258 }
240259 fn spawn_with_handle (
241260 & self ,
242- name : impl Into < String > ,
243- func : Box < dyn FnMut ( Msg , & mut HashMap < String , ContextValue > ) + Send + Sync + ' static > ,
261+ func : Box <
262+ dyn FnMut ( & mut ActorAsync < Msg , ContextValue > , Msg , & mut HashMap < String , ContextValue > )
263+ + Send
264+ + Sync
265+ + ' static ,
266+ > ,
244267 ) -> Arc < dyn Handle < Msg , ContextValue > + Send + Sync + ' static > {
245268 let mut new_one = Self :: new ( func) ;
246269 new_one. parent_handle = Some ( self . get_handle ( ) ) ;
247270 {
248271 self . children_handle_map
249272 . lock ( )
250273 . unwrap ( )
251- . insert ( name . into ( ) , new_one. get_handle ( ) ) ;
274+ . insert ( new_one . get_id ( ) , new_one. get_handle ( ) ) ;
252275 }
276+ new_one. start ( ) ;
253277 return new_one. get_handle ( ) ;
254278 }
255279 fn get_handle ( & self ) -> Arc < dyn Handle < Msg , ContextValue > + Send + Sync + ' static > {
@@ -277,4 +301,94 @@ where
277301#[ test]
278302fn test_actor_common ( ) {
279303 // assert_eq!(false, Maybe::just(None::<bool>).or(false));
304+
305+ #[ derive( Clone , Debug ) ]
306+ enum Value {
307+ // Str(String),
308+ Int ( i32 ) ,
309+ VecStr ( Vec < String > ) ,
310+ Spawn ,
311+ Shutdown ,
312+ }
313+
314+ let mut queue = BlockingQueue :: < i32 > :: new ( ) ;
315+ let queue_thread = queue. clone ( ) ;
316+ let mut root = ActorAsync :: new (
317+ move |this : & mut ActorAsync < _ , _ > , msg : Value , context : & mut HashMap < String , Value > | {
318+ match msg {
319+ Value :: Spawn => {
320+ println ! ( "Actor Spawn" ) ;
321+ let mut queue_thread = queue_thread. clone ( ) ;
322+ let spawned = this. spawn_with_handle ( Box :: new (
323+ move |this : & mut ActorAsync < _ , _ > , msg : Value , _| {
324+ match msg {
325+ Value :: Int ( v) => {
326+ println ! ( "Actor Child Int" ) ;
327+ queue_thread. put ( v * 10 ) ;
328+ }
329+ Value :: Shutdown => {
330+ println ! ( "Actor Child Shutdown" ) ;
331+ this. stop ( ) ;
332+ }
333+ _ => { }
334+ } ;
335+ } ,
336+ ) ) ;
337+ let list = context. get ( "children_ids" ) . cloned ( ) ;
338+ let mut list = match list {
339+ Some ( Value :: VecStr ( list) ) => list,
340+ _ => Vec :: new ( ) ,
341+ } ;
342+ list. push ( spawned. get_id ( ) ) ;
343+ context. insert ( "children_ids" . into ( ) , Value :: VecStr ( list) ) ;
344+ }
345+ Value :: Shutdown => {
346+ println ! ( "Actor Shutdown" ) ;
347+ if let Some ( Value :: VecStr ( ids) ) = context. get ( "children_ids" ) {
348+ for id in ids {
349+ println ! ( "Actor Shutdown id {:?}" , id) ;
350+ if let Some ( handle) = this. get_handle_child ( id) {
351+ handle. send ( Value :: Shutdown ) ;
352+ }
353+ }
354+ }
355+ this. stop ( ) ;
356+ }
357+ Value :: Int ( v) => {
358+ println ! ( "Actor Int" ) ;
359+ if let Some ( Value :: VecStr ( ids) ) = context. get ( "children_ids" ) {
360+ for id in ids {
361+ println ! ( "Actor Int id {:?}" , id) ;
362+ if let Some ( handle) = this. get_handle_child ( id) {
363+ handle. send ( Value :: Int ( v) ) ;
364+ }
365+ }
366+ }
367+ }
368+ _ => { }
369+ }
370+ } ,
371+ ) ;
372+
373+ let root_handle = root. get_handle ( ) ;
374+ root. start ( ) ;
375+
376+ root_handle. send ( Value :: Spawn ) ;
377+ root_handle. send ( Value :: Int ( 10 ) ) ;
378+ root_handle. send ( Value :: Spawn ) ;
379+ root_handle. send ( Value :: Int ( 20 ) ) ;
380+ root_handle. send ( Value :: Spawn ) ;
381+ root_handle. send ( Value :: Int ( 30 ) ) ;
382+
383+ root_handle. send ( Value :: Shutdown ) ;
384+
385+ let mut v = Vec :: < i32 > :: new ( ) ;
386+ for _ in 1 ..7 {
387+ let i = queue. take ( ) . unwrap ( ) ;
388+ println ! ( "Actor {:?}" , i) ;
389+ v. push ( i) ;
390+ }
391+ v. sort ( ) ;
392+
393+ assert_eq ! ( [ 100 , 200 , 200 , 300 , 300 , 300 ] , v. as_slice( ) )
280394}
0 commit comments