1use crate::CowStr;
2use crate::command::BoxedCommand;
3use crate::command::CommandQueueBuilder;
4use crate::command::CommandQueueReceiver;
5use crate::command::CommandQueueSender;
6use crate::die;
7use crate::entity::AsyncEntity;
8use crate::entity::SpawnAndSendId;
9use crate::recv;
10use crate::system::AsyncIOSystem;
11use crate::system::AsyncSystem;
12use crate::util::insert_resource;
13use crate::util::remove_resource;
14use crate::util::trigger_event;
15use crate::wait_for::StartWaitingFor;
16use async_channel::Receiver;
17use bevy_ecs::prelude::*;
18use bevy_ecs::system::RunSystemOnce;
19use std::fmt;
20
21#[derive(Clone, Debug)]
39pub struct AsyncWorld(CommandQueueSender);
40
41impl AsyncWorld {
42 pub fn sender(&self) -> CommandQueueSender {
44 self.0.clone()
45 }
46
47 pub async fn apply<C: Command>(&self, command: C) {
49 self.0.send_single(BoxedCommand::new(command)).await
50 }
51
52 pub fn start_queue(&self) -> CommandQueueBuilder {
54 CommandQueueBuilder::new(self.sender())
55 }
56
57 pub async fn run_system<M>(self, system: impl IntoSystem<(), (), M> + Send + 'static) {
59 self.apply(|world: &mut World| {
60 _ = world.run_system_once(system);
61 })
62 .await
63 }
64
65 pub async fn register_system<M>(
67 &self,
68 system: impl IntoSystem<(), (), M> + Send,
69 ) -> AsyncSystem {
70 let system = Box::new(IntoSystem::into_system(system));
71 AsyncSystem::new(system, self.clone()).await
72 }
73
74 pub async fn register_io_system<I: Send + 'static, O: Send + 'static, M>(
77 &self,
78 system: impl IntoSystem<In<I>, O, M> + Send,
79 ) -> AsyncIOSystem<I, O> {
80 AsyncIOSystem::new(system, self.clone()).await
81 }
82
83 pub fn entity(&self, id: Entity) -> AsyncEntity {
86 AsyncEntity::new(id, self.clone())
87 }
88
89 pub async fn spawn_empty(&self) -> AsyncEntity {
92 let (command, receiver) = SpawnAndSendId::new_empty();
93 self.apply(command).await;
94 let id = recv(receiver).await;
95 AsyncEntity::new(id, self.clone())
96 }
97
98 pub async fn spawn<B: Bundle>(&self, bundle: B) -> AsyncEntity {
101 let (command, receiver) = SpawnAndSendId::new(bundle);
102 self.apply(command).await;
103 let id = recv(receiver).await;
104 AsyncEntity::new(id, self.clone())
105 }
106
107 pub async fn spawn_named(&self, name: impl Into<CowStr> + Send) -> AsyncEntity {
111 self.spawn(Name::new(name)).await
112 }
113
114 pub async fn insert_resource<R: Resource>(&self, resource: R) {
116 self.apply(insert_resource(resource)).await;
117 }
118
119 pub async fn remove_resource<R: Resource>(&self) {
121 self.apply(remove_resource::<R>()).await;
122 }
123
124 pub async fn start_waiting_for_resource<R: Resource + Clone>(&self) -> AsyncResource<R> {
130 let (start_waiting_for, rx) = StartWaitingFor::resource();
131 self.apply(start_waiting_for).await;
132 AsyncResource(rx)
133 }
134
135 pub async fn wait_for_resource<R: Resource + Clone>(&self) -> R {
140 self.start_waiting_for_resource().await.wait().await
141 }
142
143 pub async fn send_message<M: Message>(&self, message: M) {
145 self.apply(WriteMessage(message)).await;
146 }
147
148 pub async fn start_waiting_for_messages<M: Message + Clone>(&self) -> AsyncMessages<M> {
154 let (start_waiting_for, rx) = StartWaitingFor::messages();
155 self.apply(start_waiting_for).await;
156 AsyncMessages(rx)
157 }
158
159 pub async fn wait_for_message<M: Message + Clone>(&self) -> M {
164 self.start_waiting_for_messages().await.wait().await
165 }
166
167 pub async fn trigger<'a, T: Default, E: Event<Trigger<'a> = T> + Send + Sync + 'static>(
169 &self,
170 event: E,
171 ) {
172 self.apply(trigger_event(event)).await;
173 }
174}
175
176impl From<CommandQueueSender> for AsyncWorld {
177 fn from(sender: CommandQueueSender) -> Self {
178 Self(sender)
179 }
180}
181
182impl FromWorld for AsyncWorld {
183 fn from_world(world: &mut World) -> Self {
184 let (sender, receiver) = async_channel::unbounded();
185 world.spawn((
186 CommandQueueReceiver::new(receiver),
187 Name::new("CommandQueueReceiver"),
188 ));
189 CommandQueueSender::new(sender).into()
190 }
191}
192
193pub struct AsyncResource<R: Resource>(Receiver<R>);
197
198impl<R: Resource> fmt::Debug for AsyncResource<R> {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 write!(f, "AsyncResource(..)")
201 }
202}
203
204impl<R: Resource> AsyncResource<R> {
205 pub async fn wait(self) -> R {
207 recv(self.0).await
208 }
209}
210
211struct WriteMessage<M: Message>(M);
212
213impl<M: Message> Command for WriteMessage<M> {
214 fn apply(self, world: &mut World) {
215 world
216 .write_message(self.0)
217 .ok_or("failed to write message")
218 .unwrap_or_else(die);
219 }
220}
221
222pub struct AsyncMessages<M: Message>(Receiver<M>);
226
227impl<M: Message> fmt::Debug for AsyncMessages<M> {
228 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229 write!(f, "AsyncMessages(..)")
230 }
231}
232
233impl<M: Message> AsyncMessages<M> {
234 pub async fn wait(&self) -> M {
237 recv(self.0.clone()).await
238 }
239}