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_ecs::prelude::*;
9use std::fmt;
10
11#[derive(Clone, Debug)]
29pub struct AsyncWorld(CommandQueueSender);
30
31impl AsyncWorld {
32 pub fn sender(&self) -> CommandQueueSender {
34 self.0.clone()
35 }
36
37 pub async fn apply<C: Command>(&self, command: C) {
39 self.0.send_single(BoxedCommand::new(command)).await
40 }
41
42 pub fn start_queue(&self) -> CommandQueueBuilder {
44 CommandQueueBuilder::new(self.sender())
45 }
46
47 pub async fn register_system<M>(
49 &self,
50 system: impl IntoSystem<(), (), M> + Send,
51 ) -> AsyncSystem {
52 let system = Box::new(IntoSystem::into_system(system));
53 AsyncSystem::new(system, self.clone()).await
54 }
55
56 pub async fn register_io_system<I: Send + 'static, O: Send + 'static, M>(
59 &self,
60 system: impl IntoSystem<In<I>, O, M> + Send,
61 ) -> AsyncIOSystem<I, O> {
62 AsyncIOSystem::new(system, self.clone()).await
63 }
64
65 pub fn entity(&self, id: Entity) -> AsyncEntity {
68 AsyncEntity::new(id, self.clone())
69 }
70
71 pub async fn spawn_empty(&self) -> AsyncEntity {
74 let (command, receiver) = SpawnAndSendId::new_empty();
75 self.apply(command).await;
76 let id = recv(receiver).await;
77 AsyncEntity::new(id, self.clone())
78 }
79
80 pub async fn spawn<B: Bundle>(&self, bundle: B) -> AsyncEntity {
83 let (command, receiver) = SpawnAndSendId::new(bundle);
84 self.apply(command).await;
85 let id = recv(receiver).await;
86 AsyncEntity::new(id, self.clone())
87 }
88
89 pub async fn spawn_named(&self, name: impl Into<CowStr> + Send) -> AsyncEntity {
93 self.spawn(Name::new(name)).await
94 }
95
96 pub async fn insert_resource<R: Resource>(&self, resource: R) {
98 self.apply(insert_resource(resource)).await;
99 }
100
101 pub async fn remove_resource<R: Resource>(&self) {
103 self.apply(remove_resource::<R>()).await;
104 }
105
106 pub async fn start_waiting_for_resource<R: Resource + Clone>(&self) -> AsyncResource<R> {
112 let (start_waiting_for, rx) = StartWaitingFor::resource();
113 self.apply(start_waiting_for).await;
114 AsyncResource(rx)
115 }
116
117 pub async fn wait_for_resource<R: Resource + Clone>(&self) -> R {
122 self.start_waiting_for_resource().await.wait().await
123 }
124
125 pub async fn send_event<E: Event>(&self, event: E) {
127 self.apply(SendEvent(event)).await;
128 }
129
130 pub async fn start_waiting_for_events<E: Event + Clone>(&self) -> AsyncEvents<E> {
136 let (start_waiting_for, rx) = StartWaitingFor::events();
137 self.apply(start_waiting_for).await;
138 AsyncEvents(rx)
139 }
140
141 pub async fn wait_for_event<E: Event + Clone>(&self) -> E {
146 self.start_waiting_for_events().await.wait().await
147 }
148}
149
150impl From<CommandQueueSender> for AsyncWorld {
151 fn from(sender: CommandQueueSender) -> Self {
152 Self(sender)
153 }
154}
155
156impl FromWorld for AsyncWorld {
157 fn from_world(world: &mut World) -> Self {
158 let (sender, receiver) = async_channel::unbounded();
159 world.spawn((
160 CommandQueueReceiver::new(receiver),
161 Name::new("CommandQueueReceiver"),
162 ));
163 CommandQueueSender::new(sender).into()
164 }
165}
166
167pub struct AsyncResource<R: Resource>(Receiver<R>);
171
172impl<R: Resource> fmt::Debug for AsyncResource<R> {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 write!(f, "AsyncResource(..)")
175 }
176}
177
178impl<R: Resource> AsyncResource<R> {
179 pub async fn wait(self) -> R {
181 recv(self.0).await
182 }
183}
184
185struct SendEvent<E: Event>(E);
186
187impl<E: Event> Command for SendEvent<E> {
188 fn apply(self, world: &mut World) {
189 world
190 .send_event(self.0)
191 .ok_or("failed to send event")
192 .unwrap_or_else(die);
193 }
194}
195
196pub struct AsyncEvents<E: Event>(Receiver<E>);
200
201impl<E: Event> fmt::Debug for AsyncEvents<E> {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 write!(f, "AsyncEvents(..)")
204 }
205}
206
207impl<E: Event> AsyncEvents<E> {
208 pub async fn wait(&self) -> E {
211 recv(self.0.clone()).await
212 }
213}