-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reflect auto registration #15030
base: main
Are you sure you want to change the base?
Reflect auto registration #15030
Conversation
…atic registration
…omatic reflect registration functionality at compile time
Is this compared to the equivalent manual registration? Can / should we feature flag this for authors who particularly care? |
You added a new feature but didn't update the readme. Please run |
As far as I understand it, wasm-init works by exporting a bunch of symbols to final wasm and calling them from outside when |
All sizes are in KB as reported by
Update: Disregard that, I misunderstood how reflection works and missed registering type data. |
Automatic reflect registration registeres all reflect types within testing module. This creates multiple type registrations with the same type path, which breaks `ReflectDeserializer` in `bevy_reflect` tests.
Registering types on `AppTypeRegistry` creation breaks dynamic scene builder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall the implementation looks good to me, though I guess the PR might be controversial due to e.g. maybe missing support for consoles which cart mentioned.
IIUC, this documentation section should probably be updated: https://docs.rs/bevy_reflect/latest/bevy_reflect/#manual-registration |
Objective
This PR adds automatic registration of non-generic types annotated with
#[derive(Reflect)]
.Manually registering all reflect types can be error-prone, failing to reflect during runtime if some type is not registered. #5781 fixed this for nested types, improving ergonomics of using reflection dramatically, but top-level types still need to be registered manually.
Solution
Automatically register all types that derive Reflect. This works for all non-generic types, allowing users to just add
#[derive(Reflect)]
to any compatible type and not think about where to register it.Automatic registration can be opted-out of by adding
#[reflect(no_auto_register)]
reflect attribute to a type:Registration normally happens at app creation time, but
TypeRegistry
itself has a newregister_derived_types
method to register all collected types at any appropriate time:All functionality is currently feature-gated behindreflect_auto_register
due to reasons explained in considerations, but maybe it should be enabled by default instead?Testing
reflect
example and removing explicit type registration, both on native and onwasm32-unknown-unknown
.register_derived_types
Impact on startup time is negligible: <40ms on debug wasm build and <25ms on debug native build for 1614 registered types .
Wasm binary size comparison. All sizes are in KB as reported by
du
on the modifiedreflection
example.Considerations
While automatic type registration improves ergonomics quite a bit for projects that make heavy use of it, there are also some problems:
Update: This seems to not be as big of a problem as I thought. I tried compiling a file with 1000 reflect types with automatic registration and manual type registration, and after optimizing withwasm-opt -Oz
the file with automatic registration was actually smaller than the file using manual registration (14508KB vs. 15580KB, -6.9%). Maybe because automatic registration avoids monomorphization of.register_type
?Update 2: After fixing
TypeData
registration, wasm file size for auto registration isn't smaller than manual.register_type
registration anymore. The difference between manual and automatic registration doesn't grow with the number of registered types at least, as can be seen from the table bellow:1000 simple structs with reflect wasm size comparison
Update 3: Disabling automatic type registration for engine types and using it only for user-defined types seems to not impact wasm file size as much. I'm not sure which types exactly increase the binary size that much, but it seems to be related to registering
TypeData
, because skipping it produced a much smaller wasm file. Here is a table of wasm file sizes with automatic type registration for user-defined types only:1000 simple structs with reflect wasm size comparison, no engine types