use std::any::TypeId;
use seq_macro::seq;
use crate::entity::entity_set::{EntitySet, EntitySetIterator, SourceSet};
use crate::entity::index::IndexSetResult;
use crate::entity::property::Property;
use crate::entity::query::QueryInternal;
use crate::entity::{ContextEntitiesExt, Entity, EntityId};
use crate::Context;
impl<E: Entity> QueryInternal<E> for () {
type QueryParts<'a>
= [&'a dyn std::any::Any; 0]
where
Self: 'a;
fn get_type_ids(&self) -> Vec<TypeId> {
Vec::new()
}
fn multi_property_id(&self) -> Option<usize> {
None
}
fn is_empty_query(&self) -> bool {
true
}
fn query_parts(&self) -> Self::QueryParts<'_> {
[]
}
fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
EntitySet::from_source(SourceSet::PopulationRange(
0..context.get_entity_count::<E>(),
))
}
fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
EntitySetIterator::from_population_iterator(context.get_entity_iterator::<E>())
}
fn match_entity(&self, _entity_id: EntityId<E>, _context: &Context) -> bool {
true
}
fn filter_entities(&self, _entities: &mut Vec<EntityId<E>>, _context: &Context) {
}
}
impl<E: Entity> QueryInternal<E> for E {
type QueryParts<'a>
= [&'a dyn std::any::Any; 0]
where
Self: 'a;
fn get_type_ids(&self) -> Vec<TypeId> {
Vec::new()
}
fn multi_property_id(&self) -> Option<usize> {
None
}
fn is_empty_query(&self) -> bool {
true
}
fn query_parts(&self) -> Self::QueryParts<'_> {
[]
}
fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
EntitySet::from_source(SourceSet::PopulationRange(
0..context.get_entity_count::<E>(),
))
}
fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
let population_iterator = context.get_entity_iterator::<E>();
EntitySetIterator::from_population_iterator(population_iterator)
}
fn match_entity(&self, _entity_id: EntityId<E>, _context: &Context) -> bool {
true
}
fn filter_entities(&self, _entities: &mut Vec<EntityId<E>>, _context: &Context) {
}
}
impl<E: Entity, P1: Property<E>> QueryInternal<E> for (P1,) {
type QueryParts<'a>
= P1::QueryParts<'a>
where
Self: 'a;
fn get_type_ids(&self) -> Vec<TypeId> {
vec![P1::type_id()]
}
fn multi_property_id(&self) -> Option<usize> {
Some(P1::index_id())
}
fn query_parts(&self) -> Self::QueryParts<'_> {
P1::query_parts_for_value(&self.0)
}
fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
let property_store = context.entity_store.get_property_store::<E>();
if let Some(multi_property_id) = self.multi_property_id() {
let query_parts = P1::query_parts_for_value(&self.0);
let lookup_result = property_store
.get_index_set_for_query_parts(multi_property_id, query_parts.as_ref());
match lookup_result {
IndexSetResult::Set(people_set) => {
return EntitySet::from_source(SourceSet::IndexSet(people_set));
}
IndexSetResult::Empty => {
return EntitySet::empty();
}
IndexSetResult::Unsupported => {}
}
}
let mut sources: Vec<SourceSet<E>> = Vec::new();
if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
sources.push(source_set);
} else {
return EntitySet::empty();
}
EntitySet::from_intersection_sources(sources)
}
fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
let property_store = context.entity_store.get_property_store::<E>();
if let Some(multi_property_id) = self.multi_property_id() {
let query_parts = P1::query_parts_for_value(&self.0);
let lookup_result = property_store
.get_index_set_for_query_parts(multi_property_id, query_parts.as_ref());
match lookup_result {
IndexSetResult::Set(people_set) => {
return EntitySetIterator::from_index_set(people_set);
}
IndexSetResult::Empty => {
return EntitySetIterator::empty();
}
IndexSetResult::Unsupported => {}
}
}
let mut sources: Vec<SourceSet<E>> = Vec::new();
if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
sources.push(source_set);
} else {
return EntitySetIterator::empty();
}
EntitySetIterator::from_sources(sources)
}
fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
let found_value: P1 = context.get_property(entity_id);
found_value == self.0
}
fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
let property_value_store = context.get_property_value_store::<E, P1>();
entities.retain(|entity| self.0 == property_value_store.get(*entity));
}
}
macro_rules! impl_query {
($ct:expr) => {
seq!(N in 0..$ct {
impl<
E: Entity,
#(
T~N : Property<E>,
)*
> QueryInternal<E> for (
#(
T~N,
)*
)
{
type QueryParts<'a> = [&'a dyn std::any::Any; $ct] where Self: 'a;
fn get_type_ids(&self) -> Vec<TypeId> {
vec![
#(
<T~N as $crate::entity::property::Property<E>>::type_id(),
)*
]
}
fn query_parts(&self) -> Self::QueryParts<'_> {
let keys = [
#(
<T~N as $crate::entity::property::Property<E>>::name(),
)*
];
let mut query_parts = [
#(
&self.N as &dyn std::any::Any,
)*
];
$crate::entity::multi_property::static_reorder_by_keys(&keys, &mut query_parts);
query_parts
}
fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
let property_store = context.entity_store.get_property_store::<E>();
let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
let lookup_result = property_store.get_index_set_for_query_parts(
multi_property_id,
query_parts.as_ref(),
);
match lookup_result {
$crate::entity::index::IndexSetResult::Set(entity_set) => {
return EntitySet::from_source(SourceSet::IndexSet(entity_set));
}
$crate::entity::index::IndexSetResult::Empty => {
return EntitySet::empty();
}
$crate::entity::index::IndexSetResult::Unsupported => {}
}
}
let mut sources: Vec<SourceSet<E>> = Vec::new();
#(
if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
sources.push(source_set);
} else {
return EntitySet::empty();
}
)*
EntitySet::from_intersection_sources(sources)
}
fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
let property_store = context.entity_store.get_property_store::<E>();
let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
let lookup_result = property_store.get_index_set_for_query_parts(
multi_property_id,
query_parts.as_ref(),
);
match lookup_result {
$crate::entity::index::IndexSetResult::Set(entity_set) => {
return EntitySetIterator::from_index_set(entity_set);
}
$crate::entity::index::IndexSetResult::Empty => {
return EntitySetIterator::empty();
}
$crate::entity::index::IndexSetResult::Unsupported => {}
}
}
let mut sources: Vec<SourceSet<E>> = Vec::new();
#(
if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
sources.push(source_set);
} else {
return EntitySetIterator::empty();
}
)*
EntitySetIterator::from_sources(sources)
}
fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
#(
{
let found_value: T~N = context.get_property(entity_id);
if found_value != self.N {
return false
}
}
)*
true
}
fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
let property_store = context.entity_store.get_property_store::<E>();
let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
let lookup_result = property_store.get_index_set_for_query_parts(
multi_property_id,
query_parts.as_ref(),
);
match lookup_result {
$crate::entity::index::IndexSetResult::Set(entity_set) => {
entities.retain(|entity_id| entity_set.contains(entity_id));
return;
}
$crate::entity::index::IndexSetResult::Empty => {
entities.clear();
return;
}
$crate::entity::index::IndexSetResult::Unsupported => {}
}
}
#(
{
let property_value_store = context.get_property_value_store::<E, T~N>();
entities.retain(
|entity|{
self.N == property_value_store.get(*entity)
}
);
}
)*
}
}
});
}
}
seq!(Z in 2..20 {
impl_query!(Z);
});