add an example for static automatic registration

This commit is contained in:
eugineerd 2025-03-25 13:10:02 +00:00
parent 21a5ba0873
commit fa60c51f44
6 changed files with 105 additions and 0 deletions

View File

@ -28,6 +28,8 @@ members = [
"examples/mobile",
# Examples of using Bevy on no_std platforms.
"examples/no_std/*",
# Examples of compiling Bevy with automatic reflect type registration for platforms without `inventory` support.
"examples/reflection/auto_register_static",
# Benchmarks
"benches",
# Internal tools that are not published.
@ -2669,6 +2671,17 @@ description = "Demonstrates how to create and use type data"
category = "Reflection"
wasm = false
[[example]]
name = "auto_register_static"
path = "examples/reflection/auto_register_static/src/main.rs"
doc-scrape-examples = true
[package.metadata.example.auto_register_static]
name = "Automatic types registartion"
description = "Demonstrates how to set up automatic reflect types registration for platforms without `inventory` support"
category = "Reflection"
wasm = false
# Scene
[[example]]
name = "scene"

View File

@ -0,0 +1,18 @@
[package]
name = "auto_register_static"
version = "0.1.0"
edition = "2024"
[lib]
# Our app must be a lib for static auto registration to work.
crate-type = ["lib"]
[[bin]]
# Name of the binary must be the same as the name of the lib.
name = "auto_register_static"
[dependencies]
bevy = { path = "../../../" }
[lints]
workspace = true

View File

@ -0,0 +1,4 @@
.PHONEY: run
run:
BEVY_REFLECT_AUTO_REGISTER_STATIC=1 cargo run --features bevy/reflect_auto_register_static

View File

@ -0,0 +1,16 @@
# Automatic registration example for platforms without inventory support
This example illustrates how to use automatic type registration of `bevy_reflect` on platforms that don't support `inventory`.
To run the example, use the provided `Makefile` with `make run` or run manually by setting env var and enabling the required feature:
```sh
BEVY_REFLECT_AUTO_REGISTER_STATIC=1 cargo run --features bevy/reflect_auto_register_static
```
This approach should generally work on all platforms, however it is less convenient and a slows down linking and it's recommended to use it only as a fallback.
Here's a list of caveats of this approach:
1. `load_type_registrations!` macro must be called before constructing `App` or using `TypeRegistry::register_derived_types`.
2. All of the types to be automatically registered must be declared in a separate from `load_type_registrations!` crate. This is why this example uses separate `lib` and `bin` setup.
3. Registration function names are cached in `target/type_registrations`. Due to incremental compilation the only way to rebuild this cache is to build without `bevy/reflect_auto_register_static` (or `auto_register_static` if just using `bevy_reflect`) feature enabled and then rebuild again with this feature and `BEVY_REFLECT_AUTO_REGISTER_STATIC=1` environment variable set. Running `cargo clean` before recompiling is also an option, but it is even slower to do.
If you're experiencing linking issues try running `cargo clean` before rebuilding.

View File

@ -0,0 +1,44 @@
//! Demonstrates how to set up automatic reflect types registration for platforms without `inventory` support
use bevy::prelude::*;
// The type that should be automatically registered.
// All types subject to automatic registration must be defined in `lib`,
// any `#[derive(Reflect)]` registration without the `bin` are not guaranteed to be registered automatically.
#[derive(Reflect)]
struct Struct {
a: i32,
}
mod private {
mod very_private {
use bevy::prelude::*;
// Works with private types too!
#[derive(Reflect)]
struct PrivateStruct {
a: i32,
}
}
}
/// This is the main entrypoint, bin just forwards to it.
pub fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, startup)
.run();
}
fn startup(reg: Res<AppTypeRegistry>) {
let registry = reg.read();
info!(
"Is `Struct` get registered? {}",
registry.contains(core::any::TypeId::of::<Struct>())
);
info!(
"Type info of `PrivateStruct`: {:?}",
registry
.get_with_short_type_path("PrivateStruct")
.expect("Not registered")
);
}

View File

@ -0,0 +1,10 @@
//! Demonstrates how to set up automatic reflect types registration for platforms without `inventory` support
use auto_register_static::main as lib_main;
use bevy::reflect::load_type_registrations;
fn main() {
// This must be called before our main to collect all type registration functions.
load_type_registrations!();
// After running load_type_registrations! we just forward to our main.
lib_main();
}