minimal example auto registration for reflect types
This commit is contained in:
parent
d2624765d0
commit
4b48e235bc
@ -92,8 +92,12 @@ impl Debug for App {
|
||||
impl Default for App {
|
||||
fn default() -> Self {
|
||||
let mut app = App::empty();
|
||||
|
||||
app.sub_apps.main.update_schedule = Some(Main.intern());
|
||||
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
bevy_reflect::wasm_init::wasm_init();
|
||||
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
app.init_resource::<AppTypeRegistry>();
|
||||
|
||||
|
||||
@ -39,6 +39,8 @@ glam = { version = "0.28", features = ["serde"], optional = true }
|
||||
petgraph = { version = "0.6", features = ["serde-1"], optional = true }
|
||||
smol_str = { version = "0.2.0", optional = true }
|
||||
uuid = { version = "1.0", optional = true, features = ["v4", "serde"] }
|
||||
inventory = "0.3"
|
||||
wasm-init = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
ron = "0.8.0"
|
||||
|
||||
@ -60,6 +60,22 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS
|
||||
.generics()
|
||||
.split_for_impl();
|
||||
|
||||
let auto_reflect = if ty_generics.clone().into_token_stream().is_empty() {
|
||||
quote! {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#bevy_reflect_path::wasm_init::wasm_init!{
|
||||
#bevy_reflect_path::AUTOMATIC_REFLECT_TYPES
|
||||
.write()
|
||||
.unwrap()
|
||||
.push(|reg: &mut #bevy_reflect_path::TypeRegistry| reg.register::<#struct_path>());
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#bevy_reflect_path::inventory::submit!(#bevy_reflect_path::AUTOMATIC_REFLECT_TYPES(|reg: &mut #bevy_reflect_path::TypeRegistry| reg.register::<#struct_path>()));
|
||||
}
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
|
||||
let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
|
||||
|
||||
quote! {
|
||||
@ -73,6 +89,8 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS
|
||||
|
||||
#function_impls
|
||||
|
||||
#auto_reflect
|
||||
|
||||
impl #impl_generics #bevy_reflect_path::Struct for #struct_path #ty_generics #where_reflect_clause {
|
||||
fn field(&self, name: &str) -> #FQOption<&dyn #bevy_reflect_path::PartialReflect> {
|
||||
match name {
|
||||
|
||||
@ -597,6 +597,9 @@ pub use type_registry::*;
|
||||
pub use bevy_reflect_derive::*;
|
||||
pub use erased_serde;
|
||||
|
||||
pub extern crate inventory;
|
||||
pub extern crate wasm_init;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
/// Exports used by the reflection macros.
|
||||
|
||||
@ -9,6 +9,13 @@ use std::{
|
||||
sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub static AUTOMATIC_REFLECT_TYPES: RwLock<Vec<fn(&mut TypeRegistry)>> = RwLock::new(Vec::new());
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub struct AUTOMATIC_REFLECT_TYPES(pub fn(&mut TypeRegistry));
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
inventory::collect!(AUTOMATIC_REFLECT_TYPES);
|
||||
|
||||
/// A registry of [reflected] types.
|
||||
///
|
||||
/// This struct is used as the central store for type information.
|
||||
@ -108,6 +115,14 @@ impl TypeRegistry {
|
||||
registry.register::<f32>();
|
||||
registry.register::<f64>();
|
||||
registry.register::<String>();
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
for f in AUTOMATIC_REFLECT_TYPES.read().unwrap().iter() {
|
||||
f(&mut registry)
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
for f in inventory::iter::<AUTOMATIC_REFLECT_TYPES> {
|
||||
f.0(&mut registry)
|
||||
}
|
||||
registry
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
//! by their string name. Reflection is a core part of Bevy and enables a number of interesting
|
||||
//! features (like scenes).
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
use bevy::{
|
||||
prelude::*,
|
||||
reflect::{
|
||||
@ -17,7 +19,7 @@ fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
// Bar will be automatically registered as it's a dependency of Foo
|
||||
.register_type::<Foo>()
|
||||
// .register_type::<Foo>()
|
||||
.add_systems(Startup, setup)
|
||||
.run();
|
||||
}
|
||||
@ -101,6 +103,8 @@ fn setup(type_registry: Res<AppTypeRegistry>) {
|
||||
let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap();
|
||||
let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||
|
||||
assert!(type_registry.contains(value.type_id()));
|
||||
|
||||
// Deserializing returns a `Box<dyn PartialReflect>` value.
|
||||
// Generally, deserializing a value will return the "dynamic" variant of a type.
|
||||
// For example, deserializing a struct will return the DynamicStruct type.
|
||||
@ -118,4 +122,6 @@ fn setup(type_registry: Res<AppTypeRegistry>) {
|
||||
// By "patching" `Foo` with the deserialized DynamicStruct, we can "Deserialize" Foo.
|
||||
// This means we can serialize and deserialize with a single `Reflect` derive!
|
||||
value.apply(&*reflect_value);
|
||||
|
||||
info!("{}", type_registry.iter().collect::<Vec<_>>().len());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user