props: add Property derive and implement Properties for Camera

This commit is contained in:
Carter Anderson 2020-05-25 18:27:04 -07:00
parent a837741c64
commit cb3d60a87f
4 changed files with 72 additions and 8 deletions

View file

@ -6,7 +6,7 @@ use darling::FromMeta;
use modules::{get_modules, get_path}; use modules::{get_modules, get_path};
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, Member, Index}; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, Index, Member};
#[derive(FromMeta, Debug, Default)] #[derive(FromMeta, Debug, Default)]
struct PropAttributeArgs { struct PropAttributeArgs {
@ -45,7 +45,7 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
PropAttributeArgs::from_meta(&a.parse_meta().unwrap()) PropAttributeArgs::from_meta(&a.parse_meta().unwrap())
.unwrap_or_else(|_err| PropAttributeArgs::default()) .unwrap_or_else(|_err| PropAttributeArgs::default())
}), }),
i i,
) )
}) })
.collect::<Vec<(&Field, Option<PropAttributeArgs>, usize)>>(); .collect::<Vec<(&Field, Option<PropAttributeArgs>, usize)>>();
@ -66,11 +66,23 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
let field_names = active_fields let field_names = active_fields
.iter() .iter()
.map(|(field, index)| field.ident.as_ref().map(|i| i.to_string()).unwrap_or_else(|| index.to_string())) .map(|(field, index)| {
field
.ident
.as_ref()
.map(|i| i.to_string())
.unwrap_or_else(|| index.to_string())
})
.collect::<Vec<String>>(); .collect::<Vec<String>>();
let field_idents = active_fields let field_idents = active_fields
.iter() .iter()
.map(|(field, index)| field.ident.as_ref().map(|ident| Member::Named(ident.clone())).unwrap_or_else(|| Member::Unnamed(Index::from(*index)))) .map(|(field, index)| {
field
.ident
.as_ref()
.map(|ident| Member::Named(ident.clone()))
.unwrap_or_else(|| Member::Unnamed(Index::from(*index)))
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let field_count = active_fields.len(); let field_count = active_fields.len();
let field_indices = (0..field_count).collect::<Vec<usize>>(); let field_indices = (0..field_count).collect::<Vec<usize>>();
@ -181,3 +193,49 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
} }
}) })
} }
#[proc_macro_derive(Property)]
pub fn derive_property(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let modules = get_modules(&ast);
let bevy_property_path = get_path(&modules.bevy_property);
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_property_path::Property for #struct_name#ty_generics {
#[inline]
fn any(&self) -> &dyn std::any::Any {
self
}
#[inline]
fn any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
#[inline]
fn clone_prop(&self) -> Box<dyn #bevy_property_path::Property> {
Box::new(self.clone())
}
#[inline]
fn apply(&mut self, value: &dyn #bevy_property_path::Property) {
self.set(value);
}
#[inline]
fn set(&mut self, value: &dyn #bevy_property_path::Property) {
let value = value.any();
if let Some(prop) = value.downcast_ref::<Self>() {
*self = prop.clone();
} else {
panic!("prop value is not {}", std::any::type_name::<Self>());
}
}
}
})
}

View file

@ -9,6 +9,7 @@ edition = "2018"
# bevy # bevy
bevy_app = { path = "../bevy_app" } bevy_app = { path = "../bevy_app" }
bevy_asset = { path = "../bevy_asset" } bevy_asset = { path = "../bevy_asset" }
bevy_component_registry = { path = "../bevy_component_registry" }
bevy_core = { path = "../bevy_core" } bevy_core = { path = "../bevy_core" }
bevy_derive = { path = "../bevy_derive" } bevy_derive = { path = "../bevy_derive" }
bevy_property = { path = "../bevy_property" } bevy_property = { path = "../bevy_property" }
@ -26,6 +27,7 @@ png = "0.16.0"
log = { version = "0.4", features = ["release_max_level_info"] } log = { version = "0.4", features = ["release_max_level_info"] }
uuid = { version = "0.8", features = ["v4", "serde"] } uuid = { version = "0.8", features = ["v4", "serde"] }
glam = { path = "../bevy_glam" } glam = { path = "../bevy_glam" }
serde = { version = "1", features = ["derive"] }
zerocopy = "0.3" zerocopy = "0.3"
bitflags = "1.0" bitflags = "1.0"
smallvec = "1.4.0" smallvec = "1.4.0"

View file

@ -1,7 +1,9 @@
use bevy_app::{Events, GetEventReader}; use bevy_app::{Events, GetEventReader};
use bevy_window::WindowResized; use bevy_window::WindowResized;
use bevy_property::{Properties, Property};
use glam::Mat4; use glam::Mat4;
use legion::prelude::*; use legion::prelude::*;
use serde::{Serialize, Deserialize};
#[derive(Default)] #[derive(Default)]
pub struct ActiveCamera; pub struct ActiveCamera;
@ -9,7 +11,7 @@ pub struct ActiveCamera;
#[derive(Default)] #[derive(Default)]
pub struct ActiveCamera2d; pub struct ActiveCamera2d;
#[derive(Debug)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrthographicCamera { pub struct OrthographicCamera {
pub left: f32, pub left: f32,
pub right: f32, pub right: f32,
@ -46,7 +48,7 @@ impl Default for OrthographicCamera {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerspectiveCamera { pub struct PerspectiveCamera {
pub fov: f32, pub fov: f32,
pub aspect_ratio: f32, pub aspect_ratio: f32,
@ -72,7 +74,7 @@ impl Default for PerspectiveCamera {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone, Serialize, Deserialize, Property)]
pub enum CameraType { pub enum CameraType {
Perspective(PerspectiveCamera), Perspective(PerspectiveCamera),
Orthographic(OrthographicCamera), Orthographic(OrthographicCamera),
@ -94,7 +96,7 @@ impl Default for CameraType {
} }
} }
#[derive(Default, Debug)] #[derive(Default, Debug, Properties)]
pub struct Camera { pub struct Camera {
pub view_matrix: Mat4, pub view_matrix: Mat4,
pub camera_type: CameraType, pub camera_type: CameraType,

View file

@ -41,6 +41,7 @@ use self::{
use base_render_graph::{BaseRenderGraphBuilder, BaseRenderGraphConfig}; use base_render_graph::{BaseRenderGraphBuilder, BaseRenderGraphConfig};
use bevy_app::{stage, AppBuilder, AppPlugin}; use bevy_app::{stage, AppBuilder, AppPlugin};
use bevy_component_registry::RegisterComponent;
use bevy_asset::AddAsset; use bevy_asset::AddAsset;
use legion::prelude::IntoSystem; use legion::prelude::IntoSystem;
use mesh::mesh_resource_provider_system; use mesh::mesh_resource_provider_system;
@ -73,6 +74,7 @@ impl AppPlugin for RenderPlugin {
.add_asset::<Shader>() .add_asset::<Shader>()
.add_asset::<PipelineDescriptor>() .add_asset::<PipelineDescriptor>()
.add_asset_loader::<Texture, PngTextureLoader>() .add_asset_loader::<Texture, PngTextureLoader>()
.register_component::<Camera>()
.init_resource::<RenderGraph>() .init_resource::<RenderGraph>()
.init_resource::<PipelineAssignments>() .init_resource::<PipelineAssignments>()
.init_resource::<PipelineCompiler>() .init_resource::<PipelineCompiler>()