FromResource and derive macro

This commit is contained in:
Carter Anderson 2020-04-30 13:26:01 -07:00
parent 4923ac02de
commit 98f9639050
5 changed files with 67 additions and 11 deletions

View File

@ -1,7 +1,7 @@
use crate::{
plugin::{load_plugin, AppPlugin},
schedule_plan::SchedulePlan,
stage, App, AppExit, Events, System,
stage, App, AppExit, Events, System, FromResources,
};
use legion::prelude::{Resources, Universe, World};
@ -209,10 +209,10 @@ impl AppBuilder {
pub fn add_resource_init<R>(&mut self) -> &mut Self
where
R: for<'a> From<&'a mut Resources> + Send + Sync + 'static,
R: FromResources + Send + Sync + 'static,
{
let resources = self.resources_mut();
let resource = R::from(resources);
let resource = R::from_resources(resources);
resources.insert(resource);
self
}

View File

@ -1,3 +1,4 @@
#![feature(min_specialization)]
mod app;
mod app_builder;
mod entity_archetype;
@ -7,6 +8,7 @@ pub mod schedule_plan;
pub mod schedule_runner;
pub mod stage;
mod system;
mod resources;
pub use app::*;
pub use app_builder::*;
@ -14,3 +16,4 @@ pub use entity_archetype::*;
pub use event::*;
pub use plugin::*;
pub use system::*;
pub use resources::*;

View File

@ -0,0 +1,21 @@
use crate::{EventReader, GetEventReader};
use legion::prelude::Resources;
pub trait FromResources {
fn from_resources(resources: &mut Resources) -> Self;
}
impl<T> FromResources for T
where
T: Default,
{
default fn from_resources(_resources: &mut Resources) -> Self {
Self::default()
}
}
impl<T> FromResources for EventReader<T> where T: Send + Sync + 'static {
fn from_resources(resources: &mut Resources) -> Self {
resources.get_event_reader::<T>()
}
}

View File

@ -118,6 +118,45 @@ fn get_path(path_str: &str) -> Path {
syn::parse(path_str.parse::<TokenStream>().unwrap()).unwrap()
}
#[proc_macro_derive(Resource)]
pub fn derive_resource(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let fields = match &ast.data {
Data::Struct(DataStruct {
fields: Fields::Named(fields),
..
}) => &fields.named,
_ => panic!("expected a struct with named fields"),
};
let modules = get_modules(&ast);
let bevy_app_path = get_path(&modules.bevy_app);
let field_types = fields
.iter()
.map(|field| &field.ty);
let fields = fields
.iter()
.map(|field| field.ident.as_ref().unwrap());
let generics = ast.generics;
let (impl_generics, ty_generics, _where_clause) = generics.split_for_impl();
let struct_name = &ast.ident;
TokenStream::from(quote! {
impl #impl_generics #bevy_app_path::FromResources for #struct_name#ty_generics {
fn from_resources(resources: &mut Resources) -> Self {
use #bevy_app_path::FromResources;
#struct_name {
#(#fields: <#field_types>::from_resources(resources),)*
}
}
}
})
}
#[proc_macro_derive(EntityArchetype, attributes(tag, module))]
pub fn derive_entity_archetype(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);

View File

@ -36,18 +36,11 @@ fn event_trigger_system(
}
}
#[derive(Resource)]
struct EventListenerState {
my_event_reader: EventReader<MyEvent>,
}
impl From<&mut Resources> for EventListenerState {
fn from(resources: &mut Resources) -> Self {
EventListenerState {
my_event_reader: resources.get_event_reader::<MyEvent>(),
}
}
}
// prints events as they come in
fn event_listener_system(
mut state: ResourceMut<EventListenerState>,