use crate::cons::{Cons, Empty};
use crate::storage::world::archetype_storage::ArchetypeToStorage;
use crate::storage::world::archetype_storage::index_deduct::IndexDeduct;
use crate::storage::world::archetype_storage::ordered_selection::OrderedSelector;
use archetype_storage::{ArchetypeStorage, IterSeq};
use std::fmt::Debug;
mod archetype_storage;
mod world_view;
trait World<'a>: Sized {
type ExtendedWorldStorage<Archetype: ArchetypeToStorage<'a>>: World<'a>;
fn add_archetype_storage<NewArchetypeStorage: ArchetypeToStorage<'a>>(
self,
) -> Self::ExtendedWorldStorage<NewArchetypeStorage>;
fn query<Query>(&'a mut self) -> <Self as WorldStorageQuery<'a, Query>>::Result
where
Self: WorldStorageQuery<'a, Query>,
{
WorldStorageQuery::<'a, Query>::recursive_query(self)
}
}
type WorldStorage<Head, Tail> = Cons<Head, Tail>;
impl<'a, HeadArchetypeStorage : ArchetypeStorage<'a>, Tail: World<'a>> World<'a>
for WorldStorage<HeadArchetypeStorage, Tail> {
type ExtendedWorldStorage<NewArchetypeStorage: ArchetypeToStorage<'a>> = WorldStorage<
<NewArchetypeStorage as ArchetypeToStorage<'a>>::ArchetypeStorageType,
WorldStorage<HeadArchetypeStorage, Tail>,
>;
fn add_archetype_storage<NewArchetypeStorage: ArchetypeToStorage<'a>>(
self,
) -> Self::ExtendedWorldStorage<NewArchetypeStorage> {
WorldStorage {
head: <NewArchetypeStorage as ArchetypeToStorage>::ArchetypeStorageType::new(),
tail: self,
}
}
}
impl<'a> World<'a> for Empty {
type ExtendedWorldStorage<NewArchetypeStorage: ArchetypeToStorage<'a>> =
WorldStorage<<NewArchetypeStorage as ArchetypeToStorage<'a>>::ArchetypeStorageType, Empty>;
fn add_archetype_storage<NewArchetypeStorage: ArchetypeToStorage<'a>>(
self,
) -> Self::ExtendedWorldStorage<NewArchetypeStorage> {
WorldStorage {
head: <NewArchetypeStorage as ArchetypeToStorage>::ArchetypeStorageType::new(),
tail: self,
}
}
}
trait Create<'a, Query, Producer> {
fn create(value: &'a mut Producer) -> Self;
}
#[derive(Debug)]
struct RecursiveResultWrapper<'a, Tail, Query>
where
Tail: WorldStorageQuery<'a, Query>,
{
value: <Tail as WorldStorageQuery<'a, Query>>::Result,
}
impl<'a, AStorage: ArchetypeStorage<'a>, Tail: WorldStorageQuery<'a, Query>, Query>
Create<'a, Query, WorldStorage<AStorage, Tail>>
for RecursiveResultWrapper<'a, Tail, Query>
{
fn create(value: &'a mut WorldStorage<AStorage, Tail>) -> Self {
RecursiveResultWrapper {
value: <Tail as WorldStorageQuery<'a, Query>>::recursive_query(&mut value.tail),
}
}
}
impl<'a, AStorage: ArchetypeStorage<'a>, Tail: WorldStorageQuery<'a, Query>, Query>
Create<'a, Query, WorldStorage<AStorage, Tail>>
for Cons<
<AStorage as OrderedSelector<
'a,
Query,
<AStorage::Archetype as IndexDeduct<'a, Query>>::Index,
>>::Result,
<Tail as WorldStorageQuery<'a, Query>>::Result,
>
where
AStorage::Archetype: IndexDeduct<'a, Query>,
AStorage: OrderedSelector<'a, Query, <AStorage::Archetype as IndexDeduct<'a, Query>>::Index>,
{
fn create(value: &'a mut WorldStorage<AStorage, Tail>) -> Self {
Cons {
head: value.head.get_many_ordered(),
tail: value.tail.recursive_query(),
}
}
}
impl<'a, Query> Create<'a, Query, Empty> for Empty {
fn create(value: &'a mut Empty) -> Self {
Empty {}
}
}
trait WorldStorageQuery<'a, Query>: Sized {
type Result: Create<'a, Query, Self> + Debug;
fn recursive_query(&'a mut self) -> Self::Result;
}
impl<'a, Query: Debug, AStorage: ArchetypeStorage<'a>, Tail: WorldStorageQuery<'a, Query> + Debug>
WorldStorageQuery<'a, Query> for WorldStorage<AStorage, Tail>
{
default type Result = RecursiveResultWrapper<'a, Tail, Query>;
#[inline(always)]
default fn recursive_query(&'a mut self) -> Self::Result {
Self::Result::create(self)
}
}
impl<'a, Query: Debug, AStorage: ArchetypeStorage<'a>, Tail: WorldStorageQuery<'a, Query> + Debug>
WorldStorageQuery<'a, Query> for WorldStorage<AStorage, Tail>
where
AStorage::Archetype: IndexDeduct<'a, Query>,
AStorage: OrderedSelector<'a, Query, <AStorage::Archetype as IndexDeduct<'a, Query>>::Index>,
{
type Result = Cons<
<AStorage as OrderedSelector<
'a,
Query,
<AStorage::Archetype as IndexDeduct<'a, Query>>::Index,
>>::Result,
<Tail as WorldStorageQuery<'a, Query>>::Result,
>;
#[inline(always)]
fn recursive_query(&'a mut self) -> Self::Result {
Cons {
head: self.head.get_many_ordered(),
tail: <Tail as WorldStorageQuery<'a, Query>>::recursive_query(&mut self.tail),
}
}
}
impl<'a, Query> WorldStorageQuery<'a, Query> for Empty {
type Result = Empty;
fn recursive_query(&'a mut self) -> Self::Result {
Empty {}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cons::Empty;
use crate::cons::{Cons, Seq};
use crate::storage::world::archetype_storage::{ArchetypeSoa, create_storage};
#[test]
fn order_select() {
type A<'a> = Cons<u8, Cons<u16, Empty>>;
let archetype_a: A = Empty {}.extend(1u16).extend(2u8);
let mut archetype_storage_a = create_storage::<A>();
type B<'a> = Cons<u32, Cons<u16, Empty>>;
let archetype_b: B = Empty {}.extend(3u16).extend(4u32);
let mut archetype_storage_b = create_storage::<B>();
type WA<'a> = WorldStorage<ArchetypeSoa<'a, u8, ArchetypeSoa<'a, u16, Empty>>, Empty>;
let mut world: WA = Empty.add_archetype_storage::<A>();
world.head.insert(archetype_a);
{
let mut result = world.query::<Cons<&u8, Empty>>();
println!("{:?}", result);
assert_eq!(result.head.head.next().unwrap(), &2u8)
}
type WB<'a> = WorldStorage<ArchetypeSoa<'a, u32, ArchetypeSoa<'a, u16, Empty>>, WA<'a>>;
let mut next_world: WB = world.add_archetype_storage::<B>();
next_world.head.insert(archetype_b);
let mut result = next_world.query::<Cons<&u8, Empty>>();
println!("{:?}", result);
}
}