Mostly fix proc macro
This commit is contained in:
parent
d730eb586b
commit
bbee8a0041
6 changed files with 103 additions and 445 deletions
|
@ -6,7 +6,6 @@ pub mod get_disjoint_mut;
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
mod type_map;
|
mod type_map;
|
||||||
mod unsafe_component_store;
|
mod unsafe_component_store;
|
||||||
mod update_testing;
|
|
||||||
mod updates;
|
mod updates;
|
||||||
mod world;
|
mod world;
|
||||||
|
|
||||||
|
|
|
@ -1,168 +0,0 @@
|
||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::{ops::Deref, ops::DerefMut};
|
|
||||||
|
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct Query<C, F = EmptyFilter>
|
|
||||||
where
|
|
||||||
F: StaticCheckFilter,
|
|
||||||
{
|
|
||||||
entity: Entity,
|
|
||||||
c: C,
|
|
||||||
filter: PhantomData<F>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, F: StaticCheckFilter> Query<C, F> {
|
|
||||||
pub fn entity(&self) -> Entity {
|
|
||||||
self.entity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, F: StaticCheckFilter> Deref for Query<C, F> {
|
|
||||||
type Target = C;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, F: StaticCheckFilter> DerefMut for Query<C, F> {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
&mut self.c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait CreateQueryArchetype<T, R, Func, Filter> {
|
|
||||||
fn create(f: Func) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait StaticCheckFilter: Send + Sync + Default + Clone {
|
|
||||||
fn check(entity: &EntityObject) -> bool;
|
|
||||||
fn verify_dedup<O: EntityComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StaticCheckFilter for EmptyFilter {
|
|
||||||
fn check(_entity: &EntityObject) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify_dedup<O>() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct QueryArchetype {
|
|
||||||
check_entity: Box<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
|
||||||
create_callback: Box<
|
|
||||||
dyn Fn(
|
|
||||||
&EntityObject,
|
|
||||||
)
|
|
||||||
-> Result<Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>
|
|
||||||
+ Send
|
|
||||||
+ Sync,
|
|
||||||
>,
|
|
||||||
|
|
||||||
entities: Vec<Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_query_singleton_update {
|
|
||||||
( $($var:ident $(,)?)+ ) => {
|
|
||||||
impl<Func, Filter, $( $var, )+> CreateQueryArchetype<( $( $var, )+ ), (), Func, Filter> for QueryArchetype
|
|
||||||
where
|
|
||||||
Func: Fn(&mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
|
|
||||||
Filter: StaticCheckFilter,
|
|
||||||
$(
|
|
||||||
$var: EntityComponent + ComponentDebug,
|
|
||||||
)+
|
|
||||||
{
|
|
||||||
paste::item! {
|
|
||||||
fn create(f: Func) -> Self {
|
|
||||||
$(
|
|
||||||
Filter::verify_dedup::<$var>();
|
|
||||||
)+
|
|
||||||
|
|
||||||
Self {
|
|
||||||
check_entity: Box::new({
|
|
||||||
move |entity| {
|
|
||||||
$(
|
|
||||||
if !entity.components.contains::<$var>() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
|
|
||||||
if !Filter::check(entity) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
create_callback: Box::new(move |entity| {
|
|
||||||
$(
|
|
||||||
let [< $var:lower >] = UnsafeComponentStore::from(
|
|
||||||
entity.get_component::<$var>()?
|
|
||||||
);
|
|
||||||
)+
|
|
||||||
|
|
||||||
let e = entity.as_entity();
|
|
||||||
let f = f.clone();
|
|
||||||
|
|
||||||
Ok(Box::new(move |commands, _world| {
|
|
||||||
let q = Query {
|
|
||||||
entity: e,
|
|
||||||
c: unsafe { ($([< $var:lower >].as_mut(),)+) },
|
|
||||||
filter: PhantomData,
|
|
||||||
};
|
|
||||||
|
|
||||||
f(commands, q)
|
|
||||||
}))
|
|
||||||
}),
|
|
||||||
|
|
||||||
entities: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_query_singleton_update!(R, U);
|
|
||||||
|
|
||||||
struct T {}
|
|
||||||
|
|
||||||
impl EntityComponent for T {
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
Self::debug_name()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ComponentDebug for T {
|
|
||||||
fn debug_name() -> &'static str {
|
|
||||||
"T"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct U {}
|
|
||||||
|
|
||||||
impl EntityComponent for U {
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
Self::debug_name()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ComponentDebug for U {
|
|
||||||
fn debug_name() -> &'static str {
|
|
||||||
"U"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system(_commands: &mut Commands, mut _query: Query<(&mut T, &mut U)>) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test() {
|
|
||||||
let q = QueryArchetype::create(system);
|
|
||||||
}
|
|
|
@ -3,8 +3,6 @@
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::{any::TypeId, marker::PhantomData};
|
use std::{any::TypeId, marker::PhantomData};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use update_macros::implement_updates;
|
use update_macros::implement_updates;
|
||||||
|
@ -95,7 +93,7 @@ impl<C, F: CheckFilter> DerefMut for Query<C, F> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AddUpdates<T, R, Func, Filter> {
|
pub trait AddUpdates<T, R, Func, Filter> {
|
||||||
fn add_update(&mut self, name: &str, priority: u32, func: Func) -> Result<()>;
|
fn add_update(&mut self, priority: u32, func: Func) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CreateArchetype<T, R, Func, Filter> {
|
pub trait CreateArchetype<T, R, Func, Filter> {
|
||||||
|
@ -153,18 +151,31 @@ pub struct Archetype {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Archetype {
|
impl Archetype {
|
||||||
pub fn add_entity(&mut self, entity_object: &EntityObject) -> Result<()> {
|
pub fn add_entities(
|
||||||
if (self.check_entity)(entity_object) {
|
&mut self,
|
||||||
let cb = (self.create_callback)(entity_object)?;
|
new_entity: &EntityObject,
|
||||||
|
entity_objects: &[&EntityObject],
|
||||||
self.entities.insert(entity_object.as_entity(), cb);
|
) -> Result<()> {
|
||||||
|
if !(self.check_entity)(entity_objects) {
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cb = (self.create_callback)(entity_objects)?;
|
||||||
|
|
||||||
|
self.entities
|
||||||
|
.insert(entity_objects.iter().map(|e| e.as_entity()).collect(), cb);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_entity(&mut self, entity: Entity) {
|
pub fn remove_entity(&mut self, entity: Entity) {
|
||||||
self.entities.swap_remove(&entity);
|
while let Some(index) = self
|
||||||
|
.entities
|
||||||
|
.keys()
|
||||||
|
.position(|entities| entities.contains(&entity))
|
||||||
|
{
|
||||||
|
self.entities.swap_remove_index(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&self, world: &mut World) -> Result<()> {
|
pub fn execute(&self, world: &mut World) -> Result<()> {
|
||||||
|
@ -183,7 +194,7 @@ impl Archetype {
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<
|
) -> impl Iterator<
|
||||||
Item = (
|
Item = (
|
||||||
&Entity,
|
&Vec<Entity>,
|
||||||
&Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>,
|
&Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>,
|
||||||
),
|
),
|
||||||
> {
|
> {
|
||||||
|
@ -191,103 +202,8 @@ impl Archetype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ArchetypePair {
|
|
||||||
check_left_entity: Box<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
|
||||||
check_right_entity: Box<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
|
||||||
|
|
||||||
create_callback: Box<
|
|
||||||
dyn Fn(
|
|
||||||
&EntityObject,
|
|
||||||
&EntityObject,
|
|
||||||
) -> Result<Box<dyn Fn(&mut Commands) -> Result<()> + Send + Sync>>
|
|
||||||
+ Send
|
|
||||||
+ Sync,
|
|
||||||
>,
|
|
||||||
|
|
||||||
entities: IndexMap<(Entity, Entity), Box<dyn Fn(&mut Commands) -> Result<()> + Send + Sync>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ArchetypePair {
|
|
||||||
pub(crate) fn add_entity(
|
|
||||||
&mut self,
|
|
||||||
entity_object: &EntityObject,
|
|
||||||
entities: &IndexMap<Entity, EntityObject>,
|
|
||||||
) -> Result<()> {
|
|
||||||
for (other_entity, other_entity_object) in entities.iter() {
|
|
||||||
if entity_object.as_entity() == *other_entity {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the entities can be on both sides
|
|
||||||
if (self.check_left_entity)(entity_object)
|
|
||||||
&& (self.check_right_entity)(other_entity_object)
|
|
||||||
{
|
|
||||||
let cb = (self.create_callback)(entity_object, other_entity_object)?;
|
|
||||||
|
|
||||||
self.entities.insert(
|
|
||||||
(entity_object.as_entity(), other_entity_object.as_entity()),
|
|
||||||
cb,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.check_left_entity)(other_entity_object)
|
|
||||||
&& (self.check_right_entity)(entity_object)
|
|
||||||
{
|
|
||||||
let cb = (self.create_callback)(other_entity_object, entity_object)?;
|
|
||||||
|
|
||||||
self.entities.insert(
|
|
||||||
(other_entity_object.as_entity(), entity_object.as_entity()),
|
|
||||||
cb,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn remove_entity(&mut self, entity: Entity) {
|
|
||||||
while let Some((left_entity, right_entity)) = self
|
|
||||||
.entities
|
|
||||||
.keys()
|
|
||||||
.find(|(left_entity, right_entity)| *left_entity == entity || *right_entity == entity)
|
|
||||||
.cloned()
|
|
||||||
{
|
|
||||||
self.entities.swap_remove(&(left_entity, right_entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn execute(&self, world: &mut World) -> Result<()> {
|
|
||||||
let mut commands = Commands::new(world.now());
|
|
||||||
|
|
||||||
for callback in self.entities.values() {
|
|
||||||
callback(&mut commands)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
commands.apply_deferred(world)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Update {
|
|
||||||
Single(Archetype),
|
|
||||||
Pair(ArchetypePair),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Archetype> for Update {
|
|
||||||
fn from(archetype: Archetype) -> Self {
|
|
||||||
Self::Single(archetype)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ArchetypePair> for Update {
|
|
||||||
fn from(pair: ArchetypePair) -> Self {
|
|
||||||
Self::Pair(pair)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Updates {
|
pub struct Updates {
|
||||||
updates: Vec<(u32, Update)>,
|
updates: Vec<(u32, Archetype)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Updates {
|
impl Default for Updates {
|
||||||
|
@ -302,20 +218,7 @@ impl Updates {
|
||||||
pub(crate) fn update(&mut self, world: &mut World) -> Result<()> {
|
pub(crate) fn update(&mut self, world: &mut World) -> Result<()> {
|
||||||
self.updates
|
self.updates
|
||||||
.iter()
|
.iter()
|
||||||
.try_for_each(|(_, update)| -> Result<()> {
|
.try_for_each(|(_, archetype)| archetype.execute(world))
|
||||||
match update {
|
|
||||||
Update::Single(archetype) => {
|
|
||||||
archetype.execute(world)?;
|
|
||||||
}
|
|
||||||
Update::Pair(archetype_pair) => {
|
|
||||||
archetype_pair.execute(world)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_entity(
|
pub(crate) fn add_entity(
|
||||||
|
@ -323,101 +226,47 @@ impl Updates {
|
||||||
entity_object: &EntityObject,
|
entity_object: &EntityObject,
|
||||||
entities: &IndexMap<Entity, EntityObject>,
|
entities: &IndexMap<Entity, EntityObject>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (_, update) in self.updates.iter_mut() {
|
for (_, archetype) in self.updates.iter_mut() {
|
||||||
match update {
|
todo!();
|
||||||
Update::Single(archetype) => {
|
// archetype.add_entity(entity_object, entities)?;
|
||||||
archetype.add_entity(entity_object)?;
|
|
||||||
}
|
|
||||||
Update::Pair(archetype_pair) => {
|
|
||||||
archetype_pair.add_entity(entity_object, entities)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove_entity(&mut self, entity: Entity) {
|
pub(crate) fn remove_entity(&mut self, entity: Entity) {
|
||||||
for (_, update) in self.updates.iter_mut() {
|
for (_, archetype) in self.updates.iter_mut() {
|
||||||
match update {
|
|
||||||
Update::Single(archetype) => {
|
|
||||||
archetype.remove_entity(entity);
|
archetype.remove_entity(entity);
|
||||||
}
|
}
|
||||||
Update::Pair(archetype_pair) => {
|
|
||||||
archetype_pair.remove_entity(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub(crate) fn clear(&mut self) {
|
pub(crate) fn add(&mut self, priority: u32, archetype: Archetype) -> Result<()> {
|
||||||
// self.updates.clear();
|
self.updates.push((priority, archetype));
|
||||||
|
self.updates.sort_by_key(|(prio, _)| *prio);
|
||||||
// #[cfg(feature = "timings")]
|
|
||||||
// self.timings.clear();
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub(crate) fn add(&mut self, priority: u32, update: Update) -> Result<()> {
|
|
||||||
self.updates.push((priority, update));
|
|
||||||
self.updates
|
|
||||||
.sort_by(|(lhs_prio, _), (rhs_prio, _)| lhs_prio.cmp(rhs_prio));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[rustfmt::skip]
|
||||||
pub struct Archetypes {
|
impl_update_filter!(Monuple, [R, r]);
|
||||||
archetypes: HashMap<String, Archetype>,
|
#[rustfmt::skip]
|
||||||
}
|
impl_update_filter!(Couple, [R, r], [S, s]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Triple, [R, r], [S, s], [T, t]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Quadruple, [R, r], [S, s], [T, t], [U, u]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Quintuple, [R, r], [S, s], [T, t], [U, u], [V, v]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Sextuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Septuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Octuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Nonuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z]);
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_update_filter!(Decuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z], [A, a]);
|
||||||
|
|
||||||
impl Archetypes {
|
implement_updates!(8);
|
||||||
pub(crate) fn add_entity(&mut self, entity_object: &EntityObject) -> Result<()> {
|
|
||||||
for archetype in self.archetypes.values_mut() {
|
|
||||||
archetype.add_entity(entity_object)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn remove_entity(&mut self, entity: Entity) {
|
|
||||||
for archetype in self.archetypes.values_mut() {
|
|
||||||
archetype.remove_entity(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn insert(&mut self, name: String, archetype: Archetype) {
|
|
||||||
assert!(self.archetypes.insert(name, archetype).is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get(&self, name: &String) -> Option<&Archetype> {
|
|
||||||
self.archetypes.get(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn execute(&self, name: &String, world: &mut World) -> Result<()> {
|
|
||||||
self.archetypes[name].execute(world)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
implement_updates!(10, 4);
|
|
||||||
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Monuple, [R, r]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Couple, [R, r], [S, s]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Triple, [R, r], [S, s], [T, t]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Quadruple, [R, r], [S, s], [T, t], [U, u]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Quintuple, [R, r], [S, s], [T, t], [U, u], [V, v]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Sextuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Septuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Octuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Nonuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z]);
|
|
||||||
// #[rustfmt::skip]
|
|
||||||
// impl_update_filter!(Decuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z], [A, a]);
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{Error, Result, bail};
|
use anyhow::{Result, bail};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use utilities::prelude::{remove_life_time, remove_life_time_mut};
|
use utilities::prelude::{remove_life_time, remove_life_time_mut};
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ pub struct WorldBuilder {
|
||||||
pub(crate) updates: Updates,
|
pub(crate) updates: Updates,
|
||||||
pub events: Events,
|
pub events: Events,
|
||||||
pub resources: Resources,
|
pub resources: Resources,
|
||||||
archetypes: Archetypes,
|
|
||||||
systems: Vec<(
|
systems: Vec<(
|
||||||
u32,
|
u32,
|
||||||
Box<dyn Fn(&mut World) -> Result<bool> + Send + Sync + 'static>,
|
Box<dyn Fn(&mut World) -> Result<bool> + Send + Sync + 'static>,
|
||||||
|
@ -29,10 +28,6 @@ impl WorldBuilder {
|
||||||
self.systems.push((priority, Box::new(f)));
|
self.systems.push((priority, Box::new(f)));
|
||||||
self.systems.sort_by_key(|(priority, _)| *priority);
|
self.systems.sort_by_key(|(priority, _)| *priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_archetype(&mut self, name: impl ToString, archetype: Archetype) {
|
|
||||||
self.archetypes.insert(name.to_string(), archetype);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldBuilder {
|
impl WorldBuilder {
|
||||||
|
@ -42,7 +37,6 @@ impl WorldBuilder {
|
||||||
events: self.events,
|
events: self.events,
|
||||||
resources: self.resources,
|
resources: self.resources,
|
||||||
entities: Default::default(),
|
entities: Default::default(),
|
||||||
archetypes: self.archetypes,
|
|
||||||
|
|
||||||
entities_to_remove: Default::default(),
|
entities_to_remove: Default::default(),
|
||||||
entities_to_add: Default::default(),
|
entities_to_add: Default::default(),
|
||||||
|
@ -68,7 +62,6 @@ pub struct World {
|
||||||
pub events: Events,
|
pub events: Events,
|
||||||
pub resources: Resources,
|
pub resources: Resources,
|
||||||
pub(crate) entities: IndexMap<Entity, EntityObject>,
|
pub(crate) entities: IndexMap<Entity, EntityObject>,
|
||||||
archetypes: Archetypes,
|
|
||||||
|
|
||||||
entities_to_remove: Vec<Entity>,
|
entities_to_remove: Vec<Entity>,
|
||||||
entities_to_add: Vec<EntityObject>,
|
entities_to_add: Vec<EntityObject>,
|
||||||
|
@ -89,7 +82,6 @@ impl World {
|
||||||
events: Default::default(),
|
events: Default::default(),
|
||||||
resources: Default::default(),
|
resources: Default::default(),
|
||||||
systems: Default::default(),
|
systems: Default::default(),
|
||||||
archetypes: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,33 +255,6 @@ impl World {
|
||||||
pub fn remove_entity(&mut self, entity: Entity) {
|
pub fn remove_entity(&mut self, entity: Entity) {
|
||||||
self.entities_to_remove.push(entity);
|
self.entities_to_remove.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_archetype(&mut self, name: impl ToString) -> Result<()> {
|
|
||||||
let archetypes = unsafe { remove_life_time_mut(&mut self.archetypes) };
|
|
||||||
archetypes.execute(&name.to_string(), self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn archetype_info(&self, name: impl ToString) -> Result<ArchetypeInfo> {
|
|
||||||
let name = name.to_string();
|
|
||||||
let archetype = self
|
|
||||||
.archetypes
|
|
||||||
.get(&name)
|
|
||||||
.ok_or_else(|| Error::msg(format!("requested archetype ({}) not found", name)))?;
|
|
||||||
|
|
||||||
let mut entities = Vec::new();
|
|
||||||
|
|
||||||
for (&entity, _) in archetype.entities() {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
let debug_name = self.entity(entity)?.debug_name.clone();
|
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
let debug_name = None;
|
|
||||||
|
|
||||||
entities.push((entity, debug_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(ArchetypeInfo::new(entities))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// async application of changes
|
// async application of changes
|
||||||
|
@ -305,7 +270,6 @@ impl World {
|
||||||
let e = entity.as_entity();
|
let e = entity.as_entity();
|
||||||
|
|
||||||
self.updates.add_entity(&mut entity, &self.entities)?;
|
self.updates.add_entity(&mut entity, &self.entities)?;
|
||||||
self.archetypes.add_entity(&entity)?;
|
|
||||||
assert!(self.entities.insert(e, entity).is_none());
|
assert!(self.entities.insert(e, entity).is_none());
|
||||||
|
|
||||||
Ok(e)
|
Ok(e)
|
||||||
|
@ -319,7 +283,6 @@ impl World {
|
||||||
|
|
||||||
entity_object.activation_state.apply_change();
|
entity_object.activation_state.apply_change();
|
||||||
self.updates.remove_entity(entity);
|
self.updates.remove_entity(entity);
|
||||||
self.archetypes.remove_entity(entity);
|
|
||||||
|
|
||||||
return Ok(Some(entity_object));
|
return Ok(Some(entity_object));
|
||||||
}
|
}
|
||||||
|
@ -339,7 +302,6 @@ impl World {
|
||||||
.ok_or_else(|| EntityNotFoundError::new(entity))?;
|
.ok_or_else(|| EntityNotFoundError::new(entity))?;
|
||||||
|
|
||||||
self.updates.remove_entity(entity);
|
self.updates.remove_entity(entity);
|
||||||
self.archetypes.remove_entity(entity);
|
|
||||||
|
|
||||||
entity_object.activation_state.apply_change();
|
entity_object.activation_state.apply_change();
|
||||||
|
|
||||||
|
@ -351,7 +313,6 @@ impl World {
|
||||||
entity_object.activation_state.apply_change();
|
entity_object.activation_state.apply_change();
|
||||||
|
|
||||||
self.updates.add_entity(entity_object, &self.entities)?;
|
self.updates.add_entity(entity_object, &self.entities)?;
|
||||||
self.archetypes.add_entity(entity_object)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -367,7 +328,6 @@ impl World {
|
||||||
.ok_or_else(|| EntityNotFoundError::new(entity))?;
|
.ok_or_else(|| EntityNotFoundError::new(entity))?;
|
||||||
|
|
||||||
self.updates.remove_entity(entity);
|
self.updates.remove_entity(entity);
|
||||||
self.archetypes.remove_entity(entity);
|
|
||||||
|
|
||||||
entity_object.activation_state.apply_change();
|
entity_object.activation_state.apply_change();
|
||||||
|
|
||||||
|
@ -378,7 +338,6 @@ impl World {
|
||||||
entity_object.activation_state.apply_change();
|
entity_object.activation_state.apply_change();
|
||||||
|
|
||||||
self.updates.add_entity(entity_object, &self.entities)?;
|
self.updates.add_entity(entity_object, &self.entities)?;
|
||||||
self.archetypes.add_entity(entity_object)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -416,7 +375,6 @@ impl World {
|
||||||
|
|
||||||
for (entity, changes) in core::mem::take(&mut self.entities_updates) {
|
for (entity, changes) in core::mem::take(&mut self.entities_updates) {
|
||||||
self.updates.remove_entity(entity);
|
self.updates.remove_entity(entity);
|
||||||
self.archetypes.remove_entity(entity);
|
|
||||||
|
|
||||||
if let Ok(entity_object) = unsafe { self.entity_mut_unchecked(entity) } {
|
if let Ok(entity_object) = unsafe { self.entity_mut_unchecked(entity) } {
|
||||||
entity_object.activation_state.apply_change();
|
entity_object.activation_state.apply_change();
|
||||||
|
@ -447,7 +405,6 @@ impl World {
|
||||||
entity_object.activation_state.apply_change();
|
entity_object.activation_state.apply_change();
|
||||||
|
|
||||||
self.updates.add_entity(entity_object, &self.entities)?;
|
self.updates.add_entity(entity_object, &self.entities)?;
|
||||||
self.archetypes.add_entity(entity_object)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,19 +17,13 @@ use syn::{
|
||||||
|
|
||||||
struct UpdateInfo {
|
struct UpdateInfo {
|
||||||
max_components: usize,
|
max_components: usize,
|
||||||
max_queries: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for UpdateInfo {
|
impl Parse for UpdateInfo {
|
||||||
fn parse(input: ParseStream) -> Result<Self> {
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
let max_components = input.parse::<LitInt>()?.base10_parse()?;
|
let max_components = input.parse::<LitInt>()?.base10_parse()?;
|
||||||
input.parse::<Comma>()?;
|
|
||||||
let max_queries = input.parse::<LitInt>()?.base10_parse()?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self { max_components })
|
||||||
max_components,
|
|
||||||
max_queries,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +31,7 @@ impl Parse for UpdateInfo {
|
||||||
pub fn implement_updates(input: TokenStream) -> TokenStream {
|
pub fn implement_updates(input: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(input as UpdateInfo);
|
let input = parse_macro_input!(input as UpdateInfo);
|
||||||
|
|
||||||
update(input.max_components, input.max_queries)
|
update(input.max_components)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InputInfo {
|
struct InputInfo {
|
||||||
|
|
|
@ -66,7 +66,7 @@ impl Query {
|
||||||
pub fn component_store_and_query(&self, index: usize) -> (TokenStream2, TokenStream2, Ident) {
|
pub fn component_store_and_query(&self, index: usize) -> (TokenStream2, TokenStream2, Ident) {
|
||||||
let components = &self.components;
|
let components = &self.components;
|
||||||
let entity_name = format_ident!("entity_{index}");
|
let entity_name = format_ident!("entity_{index}");
|
||||||
let component_name = self
|
let component_names = self
|
||||||
.components
|
.components
|
||||||
.iter()
|
.iter()
|
||||||
.map(|component| format_ident!("q_{index}_{component}"))
|
.map(|component| format_ident!("q_{index}_{component}"))
|
||||||
|
@ -80,17 +80,30 @@ impl Query {
|
||||||
let #entity_ident = #entity_name.as_entity();
|
let #entity_ident = #entity_name.as_entity();
|
||||||
|
|
||||||
#(
|
#(
|
||||||
let #component_name = UnsafeComponentStore::from(
|
#[allow(non_snake_case)]
|
||||||
|
let #component_names = UnsafeComponentStore::from(
|
||||||
#entity_name.get_component::<#components>()?
|
#entity_name.get_component::<#components>()?
|
||||||
);
|
);
|
||||||
)*
|
)*
|
||||||
},
|
},
|
||||||
|
if component_names.len() == 1 {
|
||||||
|
let component_name = &component_names[0];
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
let #query_ident = Query {
|
let #query_ident = Query {
|
||||||
entity: #entity_ident,
|
entity: #entity_ident,
|
||||||
c: unsafe { ( #( #component_name.as_mut() )* ) },
|
c: unsafe { #component_name.as_mut() },
|
||||||
filter: PhantomData,
|
filter: PhantomData,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
let #query_ident = Query {
|
||||||
|
entity: #entity_ident,
|
||||||
|
c: unsafe { ( #( #component_names.as_mut(), )* ) },
|
||||||
|
filter: PhantomData,
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
query_ident,
|
query_ident,
|
||||||
)
|
)
|
||||||
|
@ -138,7 +151,6 @@ impl Update {
|
||||||
const MIN_RESOURCE: usize = 0;
|
const MIN_RESOURCE: usize = 0;
|
||||||
const MAX_RESOURCE: usize = 10;
|
const MAX_RESOURCE: usize = 10;
|
||||||
const MIN_COMPONENTS: usize = 1;
|
const MIN_COMPONENTS: usize = 1;
|
||||||
const MIN_QUERIES: usize = 1;
|
|
||||||
|
|
||||||
pub fn new(queries: impl Iterator<Item = usize>, resources: usize) -> Self {
|
pub fn new(queries: impl Iterator<Item = usize>, resources: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -255,6 +267,7 @@ impl Update {
|
||||||
|
|
||||||
(
|
(
|
||||||
quote! {
|
quote! {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
let (
|
let (
|
||||||
#( #resource_idents, )*
|
#( #resource_idents, )*
|
||||||
): (
|
): (
|
||||||
|
@ -378,7 +391,7 @@ impl ToTokens for Update {
|
||||||
#( #query_structs )*
|
#( #query_structs )*
|
||||||
#resource_store
|
#resource_store
|
||||||
|
|
||||||
f(commands, #( #query_idents, )* #( #resource_idents, )*)
|
f(commands, #( #query_idents, )* #( #resource_idents, )* )
|
||||||
}))
|
}))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -423,19 +436,25 @@ impl ToTokens for Update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(max_components: usize, max_queries: usize) -> TokenStream {
|
pub fn update(max_components: usize) -> TokenStream {
|
||||||
// let updates = (Update::MIN_QUERIES..max_queries)
|
let mut queries: Vec<Vec<usize>> = Vec::new();
|
||||||
// .map(|query_count| {
|
|
||||||
// let queries = (1..query_count).map(|q| {
|
|
||||||
|
|
||||||
// })
|
for c in Update::MIN_COMPONENTS..=max_components {
|
||||||
// })
|
queries.push(vec![c]);
|
||||||
// .collect::<Vec<_>>();
|
}
|
||||||
|
|
||||||
let mut query_counts = Vec::new();
|
for x in Update::MIN_COMPONENTS..=max_components {
|
||||||
|
for y in Update::MIN_COMPONENTS..=max_components {
|
||||||
|
queries.push(vec![x, y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for components in Update::MIN_COMPONENTS..=max_components {
|
for x in Update::MIN_COMPONENTS..=max_components {
|
||||||
query_counts.push(components);
|
for y in Update::MIN_COMPONENTS..=max_components {
|
||||||
|
for z in Update::MIN_COMPONENTS..=max_components {
|
||||||
|
queries.push(vec![x, y, z]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut resources = Vec::new();
|
let mut resources = Vec::new();
|
||||||
|
@ -444,7 +463,15 @@ pub fn update(max_components: usize, max_queries: usize) -> TokenStream {
|
||||||
resources.push(resource);
|
resources.push(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
let updates = vec![Update::new(vec![2, 2].into_iter(), 1)];
|
let mut updates = Vec::new();
|
||||||
|
|
||||||
|
for query in queries.iter() {
|
||||||
|
for resource_count in resources.iter() {
|
||||||
|
updates.push(Update::new(query.iter().cloned(), *resource_count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// updates.push(Update::new(vec![1].into_iter(), 0));
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
#( #updates )*
|
#( #updates )*
|
||||||
|
|
Loading…
Reference in a new issue