1use super::{ActorRunningError, System};
2use crate::actor::abstract_actor::{Actor, Handler};
3use crate::actor::message::Message;
4use crate::actor::select::ActorSelect;
5use crate::aliases::ActorName;
6use crate::dependency_injection::Inject;
7use crate::system::builder::SystemBuilder;
8use std::sync::{Arc, LazyLock};
9use tokio::sync::mpsc::UnboundedSender;
10use tokio::sync::RwLock;
11use tokio::task::JoinHandle;
12
13static GLOBAL_SYSTEM: LazyLock<Arc<RwLock<System>>> =
14 LazyLock::new(|| Arc::new(RwLock::new(SystemBuilder::new_global().build())));
15
16pub struct GlobalSystem {}
17
18impl GlobalSystem {
19 pub async fn register_ref<A, M, R>(
20 &mut self,
21 actor_name: &str,
22 ) -> (R, tokio::sync::mpsc::UnboundedReceiver<M>)
23 where
24 A: Actor,
25 A::State: Default,
26 M: Message + Send + 'static,
27 R: From<(ActorName, UnboundedSender<M>, A::State)>,
28 {
29 let mut system = GLOBAL_SYSTEM.write().await;
30 system.register_ref::<A, M, R>(actor_name).await
31 }
32
33 pub async fn register_ref_with_state<A, M, R>(
34 &mut self,
35 actor_name: &str,
36 state: A::State,
37 ) -> (R, tokio::sync::mpsc::UnboundedReceiver<M>)
38 where
39 A: Actor,
40 A::State: Default,
41 M: Message + Send + 'static,
42 R: From<(ActorName, UnboundedSender<M>, A::State)>,
43 {
44 let mut system = GLOBAL_SYSTEM.write().await;
45 system
46 .register_ref_with_state::<A, M, R>(actor_name, state)
47 .await
48 }
49
50 pub async fn spawn_actor<A, S>(
51 &mut self,
52 actor_name: Arc<str>,
53 actor: A,
54 state: A::State,
55 aggregator: S,
56 ) -> Result<(<A as Actor>::State, JoinHandle<()>), ActorRunningError>
57 where
58 A: Actor + Send + Handler<<A as Actor>::RouteMessage>,
59 S: ActorSelect<A> + Send + 'static,
60 <A as Actor>::Inject: Inject + Sized + Send,
61 {
62 let mut system = GLOBAL_SYSTEM.write().await;
63 system
64 .spawn_actor::<A, S>(actor_name, actor, state, aggregator)
65 .await
66 }
67
68 pub async fn with(&mut self, with: impl FnOnce(&mut System)) -> Self {
69 let mut system = GLOBAL_SYSTEM.write().await;
70 with(&mut system);
71 GlobalSystem {}
72 }
73
74 pub async fn insert_service<T: Send + Sync + 'static>(&mut self, data: T) {
75 let mut system = GLOBAL_SYSTEM.write().await;
76 system.insert_service(data)
77 }
78}
79