Skip to content

Commit

Permalink
Removed cached Rc on accessors.
Browse files Browse the repository at this point in the history
  • Loading branch information
mintlu8 committed May 9, 2024
1 parent 8f6db38 commit a926b3a
Show file tree
Hide file tree
Showing 20 changed files with 315 additions and 413 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ to complete, instead of a single frame like a normal system.

```rust, ignore
commands.spawn_task(|| async move {
// This is an `AsyncWorldMut`.
// This is an `AsyncWorld`.
// like tokio::spawn() this only works in the async context.
let world = world();
// Wait for state to be `GameState::Animating`.
Expand Down Expand Up @@ -114,7 +114,7 @@ We provide types mimicking bevy's types:

| Query Type | Corresponding Bevy/Sync Type |
| ---- | ----- |
| `AsyncWorldMut` | `World` / `Commands` |
| `AsyncWorld` | `World` / `Commands` |
| `AsyncEntityMut` | `EntityMut` / `EntityCommands` |
| `AsyncQuery` | `WorldQuery` |
| `AsyncEntityQuery` | `WorldQuery` on `Entity` |
Expand Down
2 changes: 1 addition & 1 deletion examples/dance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub fn main() {
])));

app.spawn_task(async move {
// This is an `AsyncWorldMut`.
// This is an `AsyncWorld`.
// like tokio::spawn() this only works in the async context.
let world = world();
let mut three = pin!(&mut world.sleep(3.0));
Expand Down
4 changes: 2 additions & 2 deletions http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//! - [ ] WASM support.

use async_io::Async;
use bevy_defer::access::AsyncWorldMut;
use bevy_defer::access::AsyncWorld;
use bevy_defer::spawn;
use smol_hyper::rt::FuturesIo;
use std::{future::Future, net::TcpStream};
Expand Down Expand Up @@ -64,7 +64,7 @@ pub enum HttpError {
}

/// Extension methods for making web request.
impl HyperHttpClientExt for AsyncWorldMut {
impl HyperHttpClientExt for AsyncWorld {
/// Compose a quick `get` request and obtain the result.
async fn http_get(&self, uri: &str) -> Result<Vec<u8>, HttpError> {
let uri = uri.parse::<hyper::Uri>()?;
Expand Down
45 changes: 20 additions & 25 deletions src/access/async_asset.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
use crate::executor::{with_world_mut, ASSET_SERVER};
use crate::sync::oneshot::MaybeChannelOut;
use crate::{access::AsyncWorldMut, channel, queue::AsyncQueryQueue};
use crate::access::AsyncWorld;
use crate::{AccessError, AsyncResult};
use bevy_asset::{Asset, AssetPath, AssetServer, Assets, Handle, LoadState};
use bevy_ecs::world::World;
use futures::future::{ready, Either};
use std::rc::Rc;

/// Async version of [`Handle`].
#[derive(Debug, Clone)]
pub struct AsyncAsset<A: Asset> {
pub(crate) queue: Rc<AsyncQueryQueue>,
pub(crate) handle: Handle<A>,
#[derive(Debug)]
pub struct AsyncAsset<A: Asset> (
pub(crate) Handle<A>,
);

impl<A: Asset> Clone for AsyncAsset<A> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}

impl AsyncWorldMut {
impl AsyncWorld {
/// Obtain an [`AsyncAsset`] from a [`Handle`].
///
/// # Example
Expand All @@ -26,10 +30,7 @@ impl AsyncWorldMut {
/// # });
/// ```
pub fn asset<A: Asset>(&self, handle: Handle<A>) -> AsyncAsset<A> {
AsyncAsset {
queue: self.queue.clone(),
handle,
}
AsyncAsset(handle)
}

/// Load an asset from an [`AssetPath`], equivalent to `AssetServer::load`.
Expand All @@ -53,10 +54,7 @@ impl AsyncWorldMut {
if !ASSET_SERVER.is_set() {
panic!("AssetServer does not exist.")
}
AsyncAsset {
queue: self.queue.clone(),
handle: ASSET_SERVER.with(|s| s.load::<A>(path)),
}
AsyncAsset(ASSET_SERVER.with(|s| s.load::<A>(path)))
}

/// Add an asset and obtain its handle.
Expand All @@ -72,34 +70,31 @@ impl AsyncWorldMut {
impl<A: Asset> AsyncAsset<A> {
/// Obtain the underlying [`Handle`].
pub fn handle(&self) -> &Handle<A> {
&self.handle
&self.0
}

/// Obtain the underlying [`Handle`].
pub fn into_handle(self) -> Handle<A> {
self.handle
self.0
}

/// Repeat until the asset is loaded, returns false if loading failed.
pub fn loaded(&self) -> MaybeChannelOut<bool> {
if !ASSET_SERVER.is_set() {
panic!("AssetServer does not exist.")
}
match ASSET_SERVER.with(|server| server.load_state(&self.handle)) {
match ASSET_SERVER.with(|server| server.load_state(&self.0)) {
LoadState::Loaded => return Either::Right(ready(true)),
LoadState::Failed => return Either::Right(ready(false)),
_ => (),
};
let (sender, receiver) = channel();
let handle = self.handle.id();
self.queue.repeat(
let handle = self.0.id();
AsyncWorld.watch_left(
move |world: &mut World| match world.resource::<AssetServer>().load_state(handle) {
LoadState::Loaded => Some(true),
LoadState::Failed => Some(false),
_ => None,
},
sender,
);
Either::Left(receiver.into_out())
}
)
}
}
22 changes: 18 additions & 4 deletions src/access/async_event.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::access::AsyncWorldMut;
use crate::access::AsyncWorld;
use crate::async_systems::AsyncWorldParam;
use crate::executor::{with_world_mut, REACTORS};
use crate::reactors::Reactors;
Expand All @@ -15,7 +15,7 @@ use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use std::task::{Context, Poll, Waker};

impl AsyncWorldMut {
impl AsyncWorld {
/// Send an [`Event`].
pub fn send_event<E: Event>(&self, event: E) -> AsyncResult<EventId<E>> {
with_world_mut(move |world: &mut World| {
Expand Down Expand Up @@ -63,6 +63,16 @@ pub struct EventStream<E: Event + Clone> {
event: Arc<DoubleBufferedEvent<E>>,
}

impl<E: Event + Clone> Clone for EventStream<E> {
fn clone(&self) -> Self {
Self {
frame: self.frame,
index: self.index,
event: self.event.clone()
}
}
}

impl<E: Event + Clone> Unpin for EventStream<E> {}

impl<E: Event + Clone> Stream for EventStream<E> {
Expand Down Expand Up @@ -130,7 +140,11 @@ pub fn react_to_event<E: Event + Clone>(
}

impl<E: Event + Clone> AsyncWorldParam for EventStream<E> {
fn from_async_context(executor: &AsyncWorldMut) -> Option<Self> {
Some(executor.event_stream())
fn from_async_context(reactors: &Reactors) -> Option<Self> {
Some(EventStream {
frame: 0,
index: 0,
event: reactors.get_event(),
})
}
}
76 changes: 44 additions & 32 deletions src/access/async_query.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::reactors::Reactors;
use crate::{
access::AsyncWorldMut, async_systems::AsyncWorldParam, executor::with_world_mut,
async_systems::AsyncWorldParam, executor::with_world_mut,
signals::Signals,
};
use crate::{async_systems::AsyncEntityParam, AccessError, AsyncQueryQueue};
use crate::{async_systems::AsyncEntityParam, AccessError};
#[allow(unused)]
use bevy_ecs::system::Query;
use bevy_ecs::{
Expand All @@ -11,46 +12,64 @@ use bevy_ecs::{
system::{CommandQueue, Resource},
world::World,
};
use std::{borrow::Borrow, marker::PhantomData, ops::Deref, rc::Rc};
use std::{borrow::Borrow, marker::PhantomData, ops::Deref};

/// Async version of [`Query`]
#[derive(Debug, Clone)]
pub struct AsyncQuery<T: QueryData, F: QueryFilter = ()> {
pub(crate) queue: Rc<AsyncQueryQueue>,
pub(crate) p: PhantomData<(T, F)>,
#[derive(Debug)]
pub struct AsyncQuery<T: QueryData, F: QueryFilter = ()> (
pub(crate) PhantomData<(T, F)>
);

impl<T: QueryData, F: QueryFilter> Copy for AsyncQuery<T, F> {}

impl<T: QueryData, F: QueryFilter> Clone for AsyncQuery<T, F> {
fn clone(&self) -> Self {
*self
}
}

/// Async version of [`Query`] on a single entity.
#[derive(Debug, Clone)]
/// Async version of [`Query`] on a specific entity.
#[derive(Debug)]
pub struct AsyncEntityQuery<T: QueryData, F: QueryFilter = ()> {
pub(crate) entity: Entity,
pub(crate) queue: Rc<AsyncQueryQueue>,
pub(crate) p: PhantomData<(T, F)>,
}

/// Async version of [`Query`]
#[derive(Debug, Clone)]
pub struct AsyncQuerySingle<T: QueryData, F: QueryFilter = ()> {
pub(crate) queue: Rc<AsyncQueryQueue>,
pub(crate) p: PhantomData<(T, F)>,
impl<T: QueryData, F: QueryFilter> Copy for AsyncEntityQuery<T, F> {}

impl<T: QueryData, F: QueryFilter> Clone for AsyncEntityQuery<T, F> {
fn clone(&self) -> Self {
*self
}
}

/// Async version of [`Query`] on a unique entity.
#[derive(Debug)]
pub struct AsyncQuerySingle<T: QueryData, F: QueryFilter = ()> (
pub(crate) PhantomData<(T, F)>,
);

impl<T: QueryData, F: QueryFilter> Copy for AsyncQuerySingle<T, F> {}

impl<T: QueryData, F: QueryFilter> Clone for AsyncQuerySingle<T, F> {
fn clone(&self) -> Self {
*self
}
}


impl<T: QueryData, F: QueryFilter> AsyncQuery<T, F> {
/// Obtain an [`AsyncEntityQuery`] on a specific entity.
pub fn entity(&self, entity: impl Borrow<Entity>) -> AsyncEntityQuery<T, F> {
AsyncEntityQuery {
entity: *entity.borrow(),
queue: self.queue.clone(),
p: PhantomData,
}
}

/// Obtain an [`AsyncQuerySingle`] on a single entity.
pub fn single(&self) -> AsyncQuerySingle<T, F> {
AsyncQuerySingle {
queue: self.queue.clone(),
p: PhantomData,
}
AsyncQuerySingle(PhantomData)
}
}

Expand All @@ -67,20 +86,14 @@ impl<T: QueryData + 'static, F: QueryFilter + 'static> AsyncQuery<T, F> {
}

impl<T: QueryData, F: QueryFilter> AsyncWorldParam for AsyncQuery<T, F> {
fn from_async_context(executor: &AsyncWorldMut) -> Option<Self> {
Some(Self {
queue: executor.queue.clone(),
p: PhantomData,
})
fn from_async_context(_: &Reactors) -> Option<Self> {
Some(Self(PhantomData))
}
}

impl<T: QueryData, F: QueryFilter> AsyncWorldParam for AsyncQuerySingle<T, F> {
fn from_async_context(executor: &AsyncWorldMut) -> Option<Self> {
Some(Self {
queue: executor.queue.clone(),
p: PhantomData,
})
fn from_async_context(_: &Reactors) -> Option<Self> {
Some(Self(PhantomData))
}
}

Expand All @@ -93,13 +106,12 @@ impl<T: QueryData, F: QueryFilter> AsyncEntityParam for AsyncEntityQuery<T, F> {

fn from_async_context(
entity: Entity,
executor: &AsyncWorldMut,
_: &Reactors,
_: (),
_: &[Entity],
) -> Option<Self> {
Some(Self {
entity,
queue: executor.queue.clone(),
p: PhantomData,
})
}
Expand Down
Loading

0 comments on commit a926b3a

Please sign in to comment.