#![allow(deprecated)]
use crate::access::get_entity::VirtualEntity;
use crate::access::{AsyncComponent, AsyncEntityQuery, AsyncNonSend, AsyncQuery, AsyncResource};
use crate::executor::{with_world_ref, QUERY_QUEUE, WORLD};
use crate::{in_async_context, AccessResult};
use bevy::ecs::{
component::Component,
entity::Entity,
name::Name,
query::{QueryData, QueryFilter},
resource::Resource,
};
use std::borrow::Borrow;
use std::fmt::Display;
use std::marker::PhantomData;
use std::time::Duration;
#[allow(unused)]
use bevy::ecs::{system::Commands, world::World};
#[allow(unused)]
use crate::{AsyncExecutor, QueryQueue};
use super::AsyncQuerySingle;
#[derive(Debug, Copy, Clone)]
pub struct AsyncWorld;
impl AsyncWorld {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
if !in_async_context() {
panic!("AsyncWorld can only be used in a bevy_defer future.")
}
AsyncWorld
}
pub fn entity(&self, entity: Entity) -> AsyncEntity {
AsyncEntity(entity)
}
pub fn resource<R: Resource>(&self) -> AsyncResource<R> {
AsyncResource(PhantomData)
}
pub fn non_send<R: 'static>(&self) -> AsyncNonSend<R> {
AsyncNonSend(PhantomData)
}
pub fn query<Q: QueryData>(&self) -> AsyncQuery<Q> {
AsyncQuery(PhantomData)
}
pub fn query_single<Q: QueryData>(&self) -> AsyncQuerySingle<Q> {
AsyncQuerySingle(PhantomData)
}
pub fn query_filtered<Q: QueryData, F: QueryFilter>(&self) -> AsyncQuery<Q, F> {
AsyncQuery(PhantomData)
}
pub fn now(&self) -> Duration {
QUERY_QUEUE.with(|q| q.now.get())
}
pub fn frame_count(&self) -> u32 {
QUERY_QUEUE.with(|q| q.frame.get())
}
}
#[derive(Debug, Clone, Copy)]
pub struct AsyncEntity<E: VirtualEntity = Entity>(pub(crate) E);
impl Display for AsyncEntity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let e = self.0;
if WORLD.is_set() {
WORLD.with(|world| {
if let Some(name) = world.get_entity(e).ok().and_then(|e| e.get::<Name>()) {
write!(f, "Entity(\"{}\", {}, {})", name, e.index(), e.generation())
} else {
write!(f, "Entity({}, {})", e.index(), e.generation())
}
})
} else {
write!(f, "Entity({}, {})", e.index(), e.generation())
}
}
}
impl From<Entity> for AsyncEntity {
fn from(value: Entity) -> Self {
AsyncEntity(value)
}
}
impl Borrow<Entity> for AsyncEntity {
fn borrow(&self) -> &Entity {
&self.0
}
}
impl Borrow<Entity> for &AsyncEntity {
fn borrow(&self) -> &Entity {
&self.0
}
}
impl Borrow<Entity> for &&AsyncEntity {
fn borrow(&self) -> &Entity {
&self.0
}
}
impl AsyncEntity {
pub fn id(&self) -> Entity {
self.0
}
}
impl<E: VirtualEntity> AsyncEntity<E> {
pub fn from_virtual(entity: E) -> Self {
Self(entity)
}
pub fn realize_entity(&self) -> AccessResult<AsyncEntity> {
with_world_ref(|world| self.0.try_get_entity(world).map(AsyncEntity))
}
pub fn try_get_id(&self) -> AccessResult<Entity> {
self.realize_entity().map(|x| x.0)
}
pub fn component<C: Component>(self) -> AsyncComponent<C, E> {
AsyncComponent {
entity: self.0,
p: PhantomData,
}
}
pub fn query<T: QueryData>(self) -> AsyncEntityQuery<T, (), E> {
AsyncEntityQuery {
entity: self.0,
p: PhantomData,
}
}
pub fn query_filtered<T: QueryData, F: QueryFilter>(self) -> AsyncEntityQuery<T, F, E> {
AsyncEntityQuery {
entity: self.0,
p: PhantomData,
}
}
}