From cb3d60a87f728ff4ac130451d0c41fbc9eb1cd8d Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 25 May 2020 18:27:04 -0700 Subject: [PATCH] props: add Property derive and implement Properties for Camera --- .../bevy_property_derive/src/lib.rs | 66 +++++++++++++++++-- crates/bevy_render/Cargo.toml | 2 + crates/bevy_render/src/camera.rs | 10 +-- crates/bevy_render/src/lib.rs | 2 + 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/crates/bevy_property/bevy_property_derive/src/lib.rs b/crates/bevy_property/bevy_property_derive/src/lib.rs index 2fe91032ce..56f5cde7b2 100644 --- a/crates/bevy_property/bevy_property_derive/src/lib.rs +++ b/crates/bevy_property/bevy_property_derive/src/lib.rs @@ -6,7 +6,7 @@ use darling::FromMeta; use modules::{get_modules, get_path}; use proc_macro::TokenStream; 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)] struct PropAttributeArgs { @@ -45,7 +45,7 @@ pub fn derive_properties(input: TokenStream) -> TokenStream { PropAttributeArgs::from_meta(&a.parse_meta().unwrap()) .unwrap_or_else(|_err| PropAttributeArgs::default()) }), - i + i, ) }) .collect::, usize)>>(); @@ -66,11 +66,23 @@ pub fn derive_properties(input: TokenStream) -> TokenStream { let field_names = active_fields .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::>(); let field_idents = active_fields .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::>(); let field_count = active_fields.len(); let field_indices = (0..field_count).collect::>(); @@ -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 { + 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 = prop.clone(); + } else { + panic!("prop value is not {}", std::any::type_name::()); + } + } + } + }) +} diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index f88d2b7db4..f85b764c18 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -9,6 +9,7 @@ edition = "2018" # bevy bevy_app = { path = "../bevy_app" } bevy_asset = { path = "../bevy_asset" } +bevy_component_registry = { path = "../bevy_component_registry" } bevy_core = { path = "../bevy_core" } bevy_derive = { path = "../bevy_derive" } bevy_property = { path = "../bevy_property" } @@ -26,6 +27,7 @@ png = "0.16.0" log = { version = "0.4", features = ["release_max_level_info"] } uuid = { version = "0.8", features = ["v4", "serde"] } glam = { path = "../bevy_glam" } +serde = { version = "1", features = ["derive"] } zerocopy = "0.3" bitflags = "1.0" smallvec = "1.4.0" diff --git a/crates/bevy_render/src/camera.rs b/crates/bevy_render/src/camera.rs index bef70e45be..242da10ae4 100644 --- a/crates/bevy_render/src/camera.rs +++ b/crates/bevy_render/src/camera.rs @@ -1,7 +1,9 @@ use bevy_app::{Events, GetEventReader}; use bevy_window::WindowResized; +use bevy_property::{Properties, Property}; use glam::Mat4; use legion::prelude::*; +use serde::{Serialize, Deserialize}; #[derive(Default)] pub struct ActiveCamera; @@ -9,7 +11,7 @@ pub struct ActiveCamera; #[derive(Default)] pub struct ActiveCamera2d; -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct OrthographicCamera { pub left: f32, pub right: f32, @@ -46,7 +48,7 @@ impl Default for OrthographicCamera { } } -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct PerspectiveCamera { pub fov: f32, pub aspect_ratio: f32, @@ -72,7 +74,7 @@ impl Default for PerspectiveCamera { } } -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize, Property)] pub enum CameraType { Perspective(PerspectiveCamera), Orthographic(OrthographicCamera), @@ -94,7 +96,7 @@ impl Default for CameraType { } } -#[derive(Default, Debug)] +#[derive(Default, Debug, Properties)] pub struct Camera { pub view_matrix: Mat4, pub camera_type: CameraType, diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index b8342ba68d..bc41958120 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -41,6 +41,7 @@ use self::{ use base_render_graph::{BaseRenderGraphBuilder, BaseRenderGraphConfig}; use bevy_app::{stage, AppBuilder, AppPlugin}; +use bevy_component_registry::RegisterComponent; use bevy_asset::AddAsset; use legion::prelude::IntoSystem; use mesh::mesh_resource_provider_system; @@ -73,6 +74,7 @@ impl AppPlugin for RenderPlugin { .add_asset::() .add_asset::() .add_asset_loader::() + .register_component::() .init_resource::() .init_resource::() .init_resource::()