Generate resource updates
This commit is contained in:
parent
0136eb0a0b
commit
a72a72f8c1
5 changed files with 178 additions and 21 deletions
|
@ -149,6 +149,7 @@ macro_rules! impl_get_disjoint_mut {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_get_disjoint_mut!(Resources < T > { Error });
|
||||||
impl_get_disjoint_mut!(Resources < T, U > { Error });
|
impl_get_disjoint_mut!(Resources < T, U > { Error });
|
||||||
impl_get_disjoint_mut!(Resources < T, U, V > { Error });
|
impl_get_disjoint_mut!(Resources < T, U, V > { Error });
|
||||||
impl_get_disjoint_mut!(Resources < T, U, V, W > { Error });
|
impl_get_disjoint_mut!(Resources < T, U, V, W > { Error });
|
||||||
|
@ -157,3 +158,4 @@ impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y > { Error });
|
||||||
impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y, Z > { Error });
|
impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y, Z > { Error });
|
||||||
impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y, Z, A > { Error });
|
impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y, Z, A > { Error });
|
||||||
impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y, Z, A, B > { Error });
|
impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y, Z, A, B > { Error });
|
||||||
|
impl_get_disjoint_mut!(Resources < T, U, V, W, X, Y, Z, A, B, C > { Error });
|
||||||
|
|
|
@ -13,12 +13,14 @@ use indexmap::IndexMap;
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
use super::super::timings::Timings;
|
use super::super::timings::Timings;
|
||||||
|
|
||||||
|
use crate::resources::Resource as ResourceTrait;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use update_macros::{implement_pair_update, implement_single_update};
|
use update_macros::{implement_pair_update, implement_single_update};
|
||||||
|
|
||||||
macro_rules! impl_singleton_update {
|
macro_rules! impl_singleton_update {
|
||||||
|
// without resources
|
||||||
( $($var:ident $(,)?)+ ) => {
|
( $($var:ident $(,)?)+ ) => {
|
||||||
impl<Func, Filter, $( $var, )+> CreateArchetype<( $( $var, )+ ), Func, Filter> for Archetype
|
impl<Func, Filter, $( $var, )+> CreateArchetype<( $( $var, )+ ), (), Func, Filter> for Archetype
|
||||||
where
|
where
|
||||||
Func: Fn(&mut Commands, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
Func: Fn(&mut Commands, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
Filter: CheckFilter + 'static,
|
Filter: CheckFilter + 'static,
|
||||||
|
@ -58,7 +60,7 @@ macro_rules! impl_singleton_update {
|
||||||
|
|
||||||
let f = f.clone();
|
let f = f.clone();
|
||||||
|
|
||||||
Ok(Box::new(move |e, commands| {
|
Ok(Box::new(move |e, commands, _world| {
|
||||||
unsafe { f(commands, e, $([< $var:lower >].as_mut(),)+) }
|
unsafe { f(commands, e, $([< $var:lower >].as_mut(),)+) }
|
||||||
}))
|
}))
|
||||||
}),
|
}),
|
||||||
|
@ -69,7 +71,7 @@ macro_rules! impl_singleton_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), Func, Filter> for Updates
|
impl<Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), (), Func, Filter> for Updates
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$var: EntityComponent + ComponentDebug,
|
$var: EntityComponent + ComponentDebug,
|
||||||
|
@ -90,7 +92,7 @@ macro_rules! impl_singleton_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), Func, Filter> for WorldBuilder
|
impl<Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), (), Func, Filter> for WorldBuilder
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$var: EntityComponent + ComponentDebug,
|
$var: EntityComponent + ComponentDebug,
|
||||||
|
@ -109,6 +111,119 @@ macro_rules! impl_singleton_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// with resources
|
||||||
|
( $($var:ident $(,)?)+ [$($res:ident $(,)?)+] ) => {
|
||||||
|
impl<Func, Filter, $( $var, )+ $( $res, )+> CreateArchetype<( $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for Archetype
|
||||||
|
where
|
||||||
|
Func: Fn(&mut Commands, Entity, $(&mut $var,)+ $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
|
Filter: CheckFilter + 'static,
|
||||||
|
$(
|
||||||
|
$var: EntityComponent + ComponentDebug,
|
||||||
|
)+
|
||||||
|
$(
|
||||||
|
$res: ResourceTrait,
|
||||||
|
)+
|
||||||
|
{
|
||||||
|
paste::item! {
|
||||||
|
fn create(f: Func, filter: Filter) -> 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 f = f.clone();
|
||||||
|
|
||||||
|
Ok(Box::new(move |e, commands, world| {
|
||||||
|
|
||||||
|
let (
|
||||||
|
$(
|
||||||
|
[< $res:lower _var >],
|
||||||
|
)+
|
||||||
|
): (
|
||||||
|
$(
|
||||||
|
&mut $res,
|
||||||
|
)+
|
||||||
|
) = world.resources.get_mut()?;
|
||||||
|
|
||||||
|
unsafe { f(commands, e, $([< $var:lower >].as_mut(),)+ $([< $res:lower _var >],)+) }
|
||||||
|
}))
|
||||||
|
}),
|
||||||
|
|
||||||
|
entities: IndexMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Func, Filter, $( $var, )+ $( $res, )+> AddUpdates<( $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for Updates
|
||||||
|
where
|
||||||
|
$(
|
||||||
|
$var: EntityComponent + ComponentDebug,
|
||||||
|
)+
|
||||||
|
$(
|
||||||
|
$res: ResourceTrait,
|
||||||
|
)+
|
||||||
|
Func: Fn(& mut Commands, Entity, $(&mut $var,)+ $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
|
Filter: CheckFilter + 'static
|
||||||
|
{
|
||||||
|
fn add_update(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
priority: u32,
|
||||||
|
func: Func,
|
||||||
|
filter: Filter
|
||||||
|
) -> Result<()> {
|
||||||
|
paste::item! {
|
||||||
|
self.add(name, priority, Update::Single(Archetype::create(func, filter)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Func, Filter, $( $var, )+ $( $res, )+> AddUpdates<( $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for WorldBuilder
|
||||||
|
where
|
||||||
|
$(
|
||||||
|
$var: EntityComponent + ComponentDebug,
|
||||||
|
)+
|
||||||
|
$(
|
||||||
|
$res: ResourceTrait,
|
||||||
|
)+
|
||||||
|
Func: Fn(& mut Commands, Entity, $(&mut $var,)+ $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
|
||||||
|
Filter: CheckFilter + 'static
|
||||||
|
{
|
||||||
|
fn add_update(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
priority: u32,
|
||||||
|
func: Func,
|
||||||
|
filter: Filter,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.updates.add_update(name, priority, func, filter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_pair_update {
|
macro_rules! impl_pair_update {
|
||||||
|
@ -199,7 +314,7 @@ macro_rules! impl_pair_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, (LhsFilter, RhsFilter)> for Updates
|
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), (), Func, (LhsFilter, RhsFilter)> for Updates
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$rhs_big: EntityComponent + ComponentDebug,
|
$rhs_big: EntityComponent + ComponentDebug,
|
||||||
|
@ -226,7 +341,7 @@ macro_rules! impl_pair_update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), Func, (LhsFilter, RhsFilter)> for WorldBuilder
|
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), (), Func, (LhsFilter, RhsFilter)> for WorldBuilder
|
||||||
where
|
where
|
||||||
$(
|
$(
|
||||||
$rhs_big: EntityComponent + ComponentDebug,
|
$rhs_big: EntityComponent + ComponentDebug,
|
||||||
|
@ -312,11 +427,11 @@ where
|
||||||
d: PhantomData<F>,
|
d: PhantomData<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AddUpdates<T, Func, Filter> {
|
pub trait AddUpdates<T, R, Func, Filter> {
|
||||||
fn add_update(&mut self, name: &str, priority: u32, func: Func, filter: Filter) -> Result<()>;
|
fn add_update(&mut self, name: &str, priority: u32, func: Func, filter: Filter) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait CreateArchetype<T, Func, Filter> {
|
trait CreateArchetype<T, R, Func, Filter> {
|
||||||
fn create(f: Func, filter: Filter) -> Self;
|
fn create(f: Func, filter: Filter) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,12 +476,15 @@ pub struct Archetype {
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&EntityObject,
|
&EntityObject,
|
||||||
)
|
)
|
||||||
-> Result<Box<dyn Fn(Entity, &mut Commands) -> Result<()> + Send + Sync>>
|
-> Result<Box<dyn Fn(Entity, &mut Commands, &mut World) -> Result<()> + Send + Sync>>
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync,
|
+ Sync,
|
||||||
>,
|
>,
|
||||||
|
|
||||||
entities: IndexMap<Entity, Box<dyn Fn(Entity, &mut Commands) -> Result<()> + Send + Sync>>,
|
entities: IndexMap<
|
||||||
|
Entity,
|
||||||
|
Box<dyn Fn(Entity, &mut Commands, &mut World) -> Result<()> + Send + Sync>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Archetype {
|
impl Archetype {
|
||||||
|
@ -387,7 +505,7 @@ impl Archetype {
|
||||||
pub fn execute(&self, world: &mut World) -> Result<()> {
|
pub fn execute(&self, world: &mut World) -> Result<()> {
|
||||||
for (entity, callback) in self.entities.iter() {
|
for (entity, callback) in self.entities.iter() {
|
||||||
let mut commands = Commands::default();
|
let mut commands = Commands::default();
|
||||||
callback(*entity, &mut commands)?;
|
callback(*entity, &mut commands, world)?;
|
||||||
commands.apply_deferred(world)?;
|
commands.apply_deferred(world)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +514,8 @@ impl Archetype {
|
||||||
|
|
||||||
pub fn entities(
|
pub fn entities(
|
||||||
&self,
|
&self,
|
||||||
) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut Commands) -> Result<()> + Send + Sync>> {
|
) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut Commands, &mut World) -> Result<()> + Send + Sync>>
|
||||||
|
{
|
||||||
&self.entities
|
&self.entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,6 @@ impl Parse for InputInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TupleType {
|
|
||||||
little: Ident,
|
|
||||||
big: Ident,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn implement_pair_update(input: TokenStream) -> TokenStream {
|
pub fn implement_pair_update(input: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(input as InputInfo);
|
let input = parse_macro_input!(input as InputInfo);
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::{Span, TokenStream as TokenStream2};
|
use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use syn::LitInt;
|
use syn::{Ident, LitInt};
|
||||||
|
|
||||||
use crate::InputInfo;
|
use crate::InputInfo;
|
||||||
use crate::TupleType;
|
|
||||||
|
struct TupleType {
|
||||||
|
little: Ident,
|
||||||
|
big: Ident,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn pair_update(input: InputInfo) -> TokenStream {
|
pub fn pair_update(input: InputInfo) -> TokenStream {
|
||||||
let mut generic_count = Vec::new();
|
let mut generic_count = Vec::new();
|
||||||
|
|
|
@ -5,7 +5,43 @@ use syn::Ident;
|
||||||
|
|
||||||
use crate::InputInfo;
|
use crate::InputInfo;
|
||||||
|
|
||||||
|
const MIN_RESOURCE: usize = 1;
|
||||||
|
|
||||||
pub fn single_update(input: InputInfo) -> TokenStream {
|
pub fn single_update(input: InputInfo) -> TokenStream {
|
||||||
|
let mut generic_counts = Vec::new();
|
||||||
|
|
||||||
|
for components in input.start..=input.end {
|
||||||
|
for resources in MIN_RESOURCE..=input.end {
|
||||||
|
generic_counts.push((components, resources));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let generics: Vec<(Vec<Ident>, Vec<Ident>)> = generic_counts
|
||||||
|
.into_iter()
|
||||||
|
.map(|(component_count, resource_count)| {
|
||||||
|
let components = (input.start..(input.start + component_count))
|
||||||
|
.map(|i| format_ident!("t{}", i))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let resources = (MIN_RESOURCE..(MIN_RESOURCE + resource_count))
|
||||||
|
.map(|i| format_ident!("r{}", i))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
(components, resources)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let resource_invocations: Vec<TokenStream2> = generics
|
||||||
|
.iter()
|
||||||
|
.map(|(components, resources)| {
|
||||||
|
let macro_ident = &input.macro_ident;
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#macro_ident!(#(#components,)* [#(#resources,)*]);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let generate_inputs: Vec<Vec<Ident>> = (input.start..=input.end)
|
let generate_inputs: Vec<Vec<Ident>> = (input.start..=input.end)
|
||||||
.map(|count| {
|
.map(|count| {
|
||||||
(input.start..(input.start + count))
|
(input.start..(input.start + count))
|
||||||
|
@ -14,7 +50,7 @@ pub fn single_update(input: InputInfo) -> TokenStream {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let invocations: Vec<TokenStream2> = generate_inputs
|
let empty_resource_invocations: Vec<TokenStream2> = generate_inputs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
let macro_ident = &input.macro_ident;
|
let macro_ident = &input.macro_ident;
|
||||||
|
@ -27,7 +63,8 @@ pub fn single_update(input: InputInfo) -> TokenStream {
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
#(
|
#(
|
||||||
#invocations
|
#empty_resource_invocations
|
||||||
|
#resource_invocations
|
||||||
)*
|
)*
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue