1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! See how we can have a collection of addresses to differnt actors. In this example
//! we want to store several actors that all accept the same message type.
//
use
{
thespis :: { * } ,
thespis_impl :: { * } ,
async_executors :: { AsyncStd } ,
std :: { error::Error } ,
};
#[ derive( Actor ) ] struct Actor1;
#[ derive( Actor ) ] struct Actor2;
struct Ping;
impl Message for Ping { type Return = (); }
impl Handler< Ping > for Actor1
{
#[async_fn] fn handle( &mut self, _msg: Ping ) {}
}
impl Handler< Ping > for Actor2
{
#[async_fn] fn handle( &mut self, _msg: Ping ) {}
}
#[async_std::main]
//
async fn main() -> Result< (), Box<dyn Error> >
{
// As you can see, the addresses are generic over the actor type.
// So we can't just store them in a collection.
//
let addr1: Addr<Actor1> = Addr::builder( "actor 1" ).spawn( Actor1, &AsyncStd )?;
let addr2: Addr<Actor2> = Addr::builder( "actor 2" ).spawn( Actor2, &AsyncStd )?;
// pub type BoxAddress<M, E> = Box< dyn Address<M, Error=E> + Send + Unpin >;
// Type can be elided here. It's just there for illustrative purposes.
//
// Obviously if we have a known number of types, we could use an enum. If
// not, we can use a dynamic type.
//
let col: Vec<BoxAddress<Ping, ThesErr>> = vec!
[
addr1.clone_box() ,
addr2.clone_box() ,
];
for mut addr in col
{
addr.send( Ping ).await?;
}
Ok(())
}