use core::any::TypeId;
use crate::{
Access, archetype::Archetype, component::ComponentInfo, entity::EntityId, epoch::EpochId,
};
pub use self::{
alt::{Alt, FetchAlt, RefMut},
boolean::{
And, And2, And3, And4, And5, And6, And7, And8, BooleanFetch, BooleanFetchOp, BooleanQuery,
Or, Or2, Or3, Or4, Or5, Or6, Or7, Or8, Xor, Xor2, Xor3, Xor4, Xor5, Xor6, Xor7, Xor8,
},
borrow::{
BorrowAll, BorrowAny, BorrowOne, FetchBorrowAllRead, FetchBorrowAnyRead,
FetchBorrowAnyWrite, FetchBorrowOneRead, FetchBorrowOneWrite,
},
copied::{Cpy, FetchCpy},
entities::{Entities, EntitiesFetch},
fetch::{BatchFetch, Fetch, UnitFetch, VerifyFetch},
filter::{FilteredFetch, Not, With, Without},
modified::{
Modified, ModifiedFetchAlt, ModifiedFetchCopied, ModifiedFetchRead, ModifiedFetchWith,
ModifiedFetchWrite,
},
read::{FetchRead, Read},
with_epoch::{EpochOf, FetchEpoch, WithEpoch},
write::{FetchWrite, Write},
};
mod alt;
mod boolean;
mod borrow;
mod copied;
mod entities;
mod fetch;
mod filter;
mod modified;
mod option;
mod read;
mod tuple;
mod with_epoch;
mod write;
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a query type",
note = "If `{Self}` is a component type, use `&{Self}` or `&mut {Self}` instead"
)]
pub trait AsQuery {
type Query: Query;
}
pub struct WriteAlias;
#[diagnostic::on_unimplemented(label = "`{Self}` is not a query type")]
pub unsafe trait Query: IntoQuery<Query = Self> + Copy + Send + Sync + 'static {
type Item<'a>: 'a;
type Fetch<'a>: Fetch<'a, Item = Self::Item<'a>> + 'a;
const MUTABLE: bool;
const FILTERS_ENTITIES: bool = false;
fn component_access(&self, comp: &ComponentInfo) -> Result<Option<Access>, WriteAlias>;
#[must_use]
fn visit_archetype(&self, archetype: &Archetype) -> bool;
unsafe fn access_archetype(&self, archetype: &Archetype, f: impl FnMut(TypeId, Access));
#[must_use]
#[inline]
unsafe fn visit_archetype_late(&self, archetype: &Archetype) -> bool {
debug_assert!(self.visit_archetype(archetype));
let _ = archetype;
true
}
#[must_use]
unsafe fn fetch<'a>(
&self,
arch_idx: u32,
archetype: &'a Archetype,
epoch: EpochId,
) -> Self::Fetch<'a>;
#[must_use]
#[inline]
fn reserved_entity_item<'a>(&self, id: EntityId, idx: u32) -> Option<Self::Item<'a>> {
let _ = id;
let _ = idx;
None
}
}
pub type QueryItem<'a, Q> = <<Q as AsQuery>::Query as Query>::Item<'a>;
#[doc(hidden)]
pub trait BatchQueryHack<'a>: Query<Fetch<'a> = Self::BatchFetchHack> {
type BatchHack: 'a;
type BatchFetchHack: BatchFetch<'a, Batch = Self::BatchHack> + 'a;
}
pub trait BatchQuery: for<'a> BatchQueryHack<'a, BatchHack = Self::Batch<'a>> {
type Batch<'a>: 'a;
}
impl<'a, Q> BatchQueryHack<'a> for Q
where
Q: Query,
Q::Fetch<'a>: BatchFetch<'a>,
{
type BatchHack = <Q::Fetch<'a> as BatchFetch<'a>>::Batch;
type BatchFetchHack = Q::Fetch<'a>;
}
impl<Q> BatchQuery for Q
where
Q: Query,
for<'a> Q::Fetch<'a>: BatchFetch<'a>,
{
type Batch<'a> = <Q::Fetch<'a> as BatchFetch<'a>>::Batch;
}
pub type QueryBatch<'a, Q> = <<Q as AsQuery>::Query as BatchQuery>::Batch<'a>;
pub trait IntoQuery: AsQuery {
fn into_query(self) -> Self::Query;
}
#[diagnostic::on_unimplemented(label = "`{Self}` is not a default-constructible query type")]
pub trait DefaultQuery: Query {
fn default_query() -> Self;
}
impl<Q> DefaultQuery for Q
where
Q: Query + Default,
{
#[inline(always)]
fn default_query() -> Self {
Default::default()
}
}
#[diagnostic::on_unimplemented(label = "`{Self}` is not a default-constructible query type")]
pub trait AsDefaultQuery: AsQuery<Query = Self::DefaultQuery> {
type DefaultQuery: DefaultQuery;
#[inline(always)]
fn default_query() -> Self::DefaultQuery {
DefaultQuery::default_query()
}
}
impl<Q> AsDefaultQuery for Q
where
Q: AsQuery,
Q::Query: DefaultQuery,
{
type DefaultQuery = Q::Query;
}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a query type that can be used from non-main thread"
)]
pub unsafe trait SendQuery: Query {}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a query type that can be used from non-main thread"
)]
pub unsafe trait AsSendQuery: AsQuery<Query = Self::SendQuery> {
type SendQuery: SendQuery;
}
unsafe impl<Q> AsSendQuery for Q
where
Q: AsQuery,
Q::Query: SendQuery,
{
type SendQuery = Q::Query;
}
pub trait IntoSendQuery: IntoQuery + AsSendQuery {}
impl<Q> IntoSendQuery for Q where Q: IntoQuery + AsSendQuery {}
#[diagnostic::on_unimplemented(label = "`{Self}` mutates components")]
pub unsafe trait ImmutableQuery: Query {
const CHECK_VALID: () = {
if Self::MUTABLE {
panic!("Immutable query cannot fetch mutable components");
}
};
}
#[diagnostic::on_unimplemented(label = "`{Self}` mutates components")]
pub trait AsImmutableQuery: AsQuery<Query = Self::ImmutableQuery> {
type ImmutableQuery: ImmutableQuery;
}
impl<Q> AsImmutableQuery for Q
where
Q: AsQuery,
Q::Query: ImmutableQuery,
{
type ImmutableQuery = Q::Query;
}
pub trait IntoImmutableQuery: IntoQuery + AsImmutableQuery {}
impl<Q> IntoImmutableQuery for Q where Q: IntoQuery + AsImmutableQuery {}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a default-constructible query type or cannot be used from non-main thread"
)]
pub trait DefaultSendQuery: DefaultQuery + SendQuery {}
impl<Q> DefaultSendQuery for Q where Q: DefaultQuery + SendQuery {}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a default-constructible query type or cannot be used from non-main thread"
)]
pub trait AsDefaultSendQuery: AsQuery<Query = Self::DefaultSendQuery> {
type DefaultSendQuery: DefaultSendQuery;
}
impl<Q> AsDefaultSendQuery for Q
where
Q: AsQuery,
Q::Query: DefaultQuery + SendQuery,
{
type DefaultSendQuery = Q::Query;
}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a default-constructible query type or mutates components"
)]
pub trait DefaultImmutableQuery: DefaultQuery + ImmutableQuery {}
impl<Q> DefaultImmutableQuery for Q where Q: DefaultQuery + ImmutableQuery {}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a default-constructible query type or mutates components"
)]
pub trait AsDefaultImmutableQuery: AsQuery<Query = Self::DefaultImmutableQuery> {
type DefaultImmutableQuery: DefaultImmutableQuery;
}
impl<Q> AsDefaultImmutableQuery for Q
where
Q: AsQuery,
Q::Query: DefaultQuery + ImmutableQuery,
{
type DefaultImmutableQuery = Q::Query;
}
#[diagnostic::on_unimplemented(
label = "`{Self}` mutates components or cannot be used from non-main thread"
)]
pub trait SendImmutableQuery: SendQuery + ImmutableQuery {}
impl<Q> SendImmutableQuery for Q where Q: SendQuery + ImmutableQuery {}
#[diagnostic::on_unimplemented(
label = "`{Self}` mutates components or cannot be used from non-main thread"
)]
pub trait AsSendImmutableQuery: AsQuery<Query = Self::SendImmutableQuery> {
type SendImmutableQuery: SendImmutableQuery;
}
impl<Q> AsSendImmutableQuery for Q
where
Q: AsQuery,
Q::Query: SendImmutableQuery,
{
type SendImmutableQuery = Q::Query;
}
#[diagnostic::on_unimplemented(
label = "`{Self}` mutates components or cannot be used from non-main thread"
)]
pub trait IntoSendImmutableQuery: IntoQuery + AsSendImmutableQuery {}
impl<Q> IntoSendImmutableQuery for Q where Q: IntoQuery + AsSendImmutableQuery {}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a default-constructible query type or cannot be used from non-main thread"
)]
pub trait DefaultSendImmutableQuery: DefaultQuery + SendQuery + ImmutableQuery {}
impl<Q> DefaultSendImmutableQuery for Q where Q: DefaultQuery + SendQuery + ImmutableQuery {}
#[diagnostic::on_unimplemented(
label = "`{Self}` is not a default-constructible query type or cannot be used from non-main thread"
)]
pub trait AsDefaultSendImmutableQuery: AsQuery<Query = Self::DefaultSendImmutableQuery> {
type DefaultSendImmutableQuery: DefaultSendImmutableQuery;
}
impl<Q> AsDefaultSendImmutableQuery for Q
where
Q: AsQuery,
Q::Query: DefaultQuery + SendQuery + ImmutableQuery,
{
type DefaultSendImmutableQuery = Q::Query;
}