1use crate::command::{BoxedCommand, CommandQueueBuilder, CommandQueueReceiver, CommandQueueSender};
2use crate::entity::{AsyncEntity, SpawnAndSendId};
3use crate::system::{AsyncIOSystem, AsyncSystem};
4use crate::util::{insert_resource, remove_resource};
5use crate::wait_for::StartWaitingFor;
6use crate::{die, recv, CowStr};
7use async_channel::Receiver;
8use bevy_core::Name;
9use bevy_ecs::prelude::*;
10use bevy_ecs::world::Command;
11use std::fmt;
12
13#[derive(Clone, Debug)]
31pub struct AsyncWorld(CommandQueueSender);
32
33impl AsyncWorld {
34 pub fn sender(&self) -> CommandQueueSender {
36 self.0.clone()
37 }
38
39 pub async fn apply<C: Command>(&self, command: C) {
41 self.0.send_single(BoxedCommand::new(command)).await
42 }
43
44 pub fn start_queue(&self) -> CommandQueueBuilder {
46 CommandQueueBuilder::new(self.sender())
47 }
48
49 pub async fn register_system<M>(
51 &self,
52 system: impl IntoSystem<(), (), M> + Send,
53 ) -> AsyncSystem {
54 let system = Box::new(IntoSystem::into_system(system));
55 AsyncSystem::new(system, self.clone()).await
56 }
57
58 pub async fn register_io_system<I: Send + 'static, O: Send + 'static, M>(
61 &self,
62 system: impl IntoSystem<In<I>, O, M> + Send,
63 ) -> AsyncIOSystem<I, O> {
64 AsyncIOSystem::new(system, self.clone()).await
65 }
66
67 pub fn entity(&self, id: Entity) -> AsyncEntity {
70 AsyncEntity::new(id, self.clone())
71 }
72
73 pub async fn spawn_empty(&self) -> AsyncEntity {
76 let (command, receiver) = SpawnAndSendId::new_empty();
77 self.apply(command).await;
78 let id = recv(receiver).await;
79 AsyncEntity::new(id, self.clone())
80 }
81
82 pub async fn spawn<B: Bundle>(&self, bundle: B) -> AsyncEntity {
85 let (command, receiver) = SpawnAndSendId::new(bundle);
86 self.apply(command).await;
87 let id = recv(receiver).await;
88 AsyncEntity::new(id, self.clone())
89 }
90
91 pub async fn spawn_named(&self, name: impl Into<CowStr> + Send) -> AsyncEntity {
95 self.spawn(Name::new(name)).await
96 }
97
98 pub async fn insert_resource<R: Resource>(&self, resource: R) {
100 self.apply(insert_resource(resource)).await;
101 }
102
103 pub async fn remove_resource<R: Resource>(&self) {
105 self.apply(remove_resource::<R>()).await;
106 }
107
108 pub async fn start_waiting_for_resource<R: Resource + Clone>(&self) -> AsyncResource<R> {
114 let (start_waiting_for, rx) = StartWaitingFor::resource();
115 self.apply(start_waiting_for).await;
116 AsyncResource(rx)
117 }
118
119 pub async fn wait_for_resource<R: Resource + Clone>(&self) -> R {
124 self.start_waiting_for_resource().await.wait().await
125 }
126
127 pub async fn send_event<E: Event>(&self, event: E) {
129 self.apply(SendEvent(event)).await;
130 }
131
132 pub async fn start_waiting_for_events<E: Event + Clone>(&self) -> AsyncEvents<E> {
138 let (start_waiting_for, rx) = StartWaitingFor::events();
139 self.apply(start_waiting_for).await;
140 AsyncEvents(rx)
141 }
142
143 pub async fn wait_for_event<E: Event + Clone>(&self) -> E {
148 self.start_waiting_for_events().await.wait().await
149 }
150}
151
152impl From<CommandQueueSender> for AsyncWorld {
153 fn from(sender: CommandQueueSender) -> Self {
154 Self(sender)
155 }
156}
157
158impl FromWorld for AsyncWorld {
159 fn from_world(world: &mut World) -> Self {
160 let (sender, receiver) = async_channel::unbounded();
161 world.spawn((
162 CommandQueueReceiver::new(receiver),
163 Name::new("CommandQueueReceiver"),
164 ));
165 CommandQueueSender::new(sender).into()
166 }
167}
168
169pub struct AsyncResource<R: Resource>(Receiver<R>);
173
174impl<R: Resource> fmt::Debug for AsyncResource<R> {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 write!(f, "AsyncResource(..)")
177 }
178}
179
180impl<R: Resource> AsyncResource<R> {
181 pub async fn wait(self) -> R {
183 recv(self.0).await
184 }
185}
186
187struct SendEvent<E: Event>(E);
188
189impl<E: Event> Command for SendEvent<E> {
190 fn apply(self, world: &mut World) {
191 world
192 .send_event(self.0)
193 .ok_or("failed to send event")
194 .unwrap_or_else(die);
195 }
196}
197
198pub struct AsyncEvents<E: Event>(Receiver<E>);
202
203impl<E: Event> fmt::Debug for AsyncEvents<E> {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 write!(f, "AsyncEvents(..)")
206 }
207}
208
209impl<E: Event> AsyncEvents<E> {
210 pub async fn wait(&self) -> E {
213 recv(self.0.clone()).await
214 }
215}