-
Notifications
You must be signed in to change notification settings - Fork 208
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
Use inventory or linkme to register scripts automatically #350
Comments
Added the "help wanted" tag for |
Update: iOS is now supported by |
In my game that uses godot-rust I've tried using the For every NativeClass I only need this bit of code to register it... (which could easily be turned into a derive macro to reduce boilerplate) inventory::submit! {
AutoRegisterInfo::new("MyClass", 0, |handle| {
handle.add_class::<MyClass>();
})
} Using a simple struct AutoRegisterInfo, that holds a closure for automatic class registration, and a priority for ordering purposes (the order of registrations seem to matter sometimes? I've had it crash on me before when the order was wrong)... pub struct AutoRegisterInfo {
pub name: String, //Only used for debugging
pub priority: i32, //Use this to put registrations in the right order (higher = first)
pub register: fn(InitHandle),
}
impl AutoRegisterInfo {
pub fn new(name: &str, priority: i32, register: fn(InitHandle)) -> Self {
Self {
name: name.to_owned(),
priority,
register,
}
}
}
inventory::collect!(AutoRegisterInfo); Then, in godot_init!(init);
fn init(handle: InitHandle) {
for info in inventory::iter::<AutoRegisterInfo>
.into_iter()
.sorted_by_key(|info| -info.priority)
{
println!("Registering class {}", info.name);
(info.register)(handle);
}
} By the way, as a con for |
Both Update: unarchived, since the underlying rustc bug rust-lang/rust#95604 was resolved. |
Hello, does this improvement also applies to |
I'm planning to do something like that for GDExtension. Not sure about GDNative -- the added value at this point is relatively little, as so many tests already exist, and this would burden the library with more dependencies. |
999: Implement automatic `NativeClass` registration via inventory. Implement mix-ins. r=chitoyuu a=chitoyuu ## Implement automatic NativeClass registration via inventory This adds the optional `inventory` feature, which allows `NativeClass` types to be automatically registered on supported platforms (everything that OSS Godot currently supports except WASM). Run-time diagnostic functions are added to help debug missing registration problems that are highly likely to arise when porting `inventory`-enabled projects to WASM. An internal `cfg_ex` attribute macro is added to help manage cfg conditions. Close #350. Note that the standalone registration attribute syntax proposed by the original issue isn't implemented, for the limited usefulness -- there are much fewer cases where manual `NativeClass` impls are necessary thanks to all the improvements since the original issue. ## Implement mix-in `#[methods]` blocks Adds the `#[methods(mixin = "Name")]` syntax for declaring mix-in blocks. Mix-in blocks have a many-to-many relationship with `NativeClass` types. Both `impl Type` and `impl Trait for Type` blocks are accepted. The argument name is changed from `as` in the original proposal to `mixin`, because we might still want to keep universal `#[methods]` blocks in the future for ease of use with WASM. `#[methods(mixin)]` makes a lot more sense for a future auto-registered mixin block than `#[methods(as /* as what? */)]`. All mix-in blocks have to be manually registered for gdnative v0.11.x. Some difficulty was encountered when trying to make auto-mixins compatible with existing code. It might still be possible with some tricks like autoref-specialization, but that might be too much effort given that we likely want to re-design much of the hierarchy for 0.12. Close #984. ## Allow `#[register_with]` for `#[monomorphize]` Enables `#[monomorphize]` to take the same standalone `#[register_with]` attribute as `#[derive(NativeClass)]`. This is chosen for short term consistency, but will probably change in a later version w/ #848, which might not still get implemented for a fair bit of time. Co-authored-by: Chitose Yuuzaki <chitoyuu@potatoes.gay>
999: Implement automatic `NativeClass` registration via inventory. Implement mix-ins. r=chitoyuu a=chitoyuu ## Implement automatic NativeClass registration via inventory This adds the optional `inventory` feature, which allows `NativeClass` types to be automatically registered on supported platforms (everything that OSS Godot currently supports except WASM). Run-time diagnostic functions are added to help debug missing registration problems that are highly likely to arise when porting `inventory`-enabled projects to WASM. An internal `cfg_ex` attribute macro is added to help manage cfg conditions. Close #350. Note that the standalone registration attribute syntax proposed by the original issue isn't implemented, for the limited usefulness -- there are much fewer cases where manual `NativeClass` impls are necessary thanks to all the improvements since the original issue. ## Implement mix-in `#[methods]` blocks Adds the `#[methods(mixin = "Name")]` syntax for declaring mix-in blocks. Mix-in blocks have a many-to-many relationship with `NativeClass` types. Both `impl Type` and `impl Trait for Type` blocks are accepted. The argument name is changed from `as` in the original proposal to `mixin`, because we might still want to keep universal `#[methods]` blocks in the future for ease of use with WASM. `#[methods(mixin)]` makes a lot more sense for a future auto-registered mixin block than `#[methods(as /* as what? */)]`. All mix-in blocks have to be manually registered for gdnative v0.11.x. Some difficulty was encountered when trying to make auto-mixins compatible with existing code. It might still be possible with some tricks like autoref-specialization, but that might be too much effort given that we likely want to re-design much of the hierarchy for 0.12. Close #984. ## Allow `#[register_with]` for `#[monomorphize]` Enables `#[monomorphize]` to take the same standalone `#[register_with]` attribute as `#[derive(NativeClass)]`. This is chosen for short term consistency, but will probably change in a later version w/ #848, which might not still get implemented for a fair bit of time. Co-authored-by: Chitose Yuuzaki <chitoyuu@potatoes.gay>
While using the bindings, one might create a new script type but forget to register it in
init
. It's a minor annoyance, but one that often leads to confusing errors when the new type is used, and is not handled by the compiler. Implementing automatic script registration improves usability and reduces the chances of runtime bugs.Provisions for automatic script registration seem to exist in the bindings for D, Kotlin, and Nim.
Currently, there are two crates in the Rust ecosystem that enable relatively easy automatic registration:
inventory
andlinkme
. The former is implemented through module initialization/teardown functions. The latter is based onlink_section
attributes. Both allow us to collect a list offn(&mut InitHandle) -> ()
pointers beforenativescript_init
and use them to automatically register all script types that derivedNativeClass
. The expected user-facing API is the same regardless of the implementation detail:Manual registration should still be possible for types with manual
NativeClass
impls:Implementation options
As mentioned before, there are two crates that can be used. They have slightly different pros/cons from each other, that are given here. In any case, this will be an implementation detail, and we should be able to swap implementations freely at a later time.
Both crates need some support with platform compatibility before they can be used in godot-rust.
inventory
Pros:
Cons:
inventory
currently usesctor
under the hood, which is life-before-main.ctor
lacks support for iOS (Support iOS dylib/executables mmastrac/rust-ctor#10). Implementation is supposedly very easy, but they need help testing.linkme
Pros:
Cons:
Considerations
Compatibility
It's possible to maintain compatibility with current manually registering code by making
InitHandle
track registered types, and ignore types that are already registered.Tool scripts
A
#[gdnative::tool]
attribute may be added for tool scripts, alongsidegdnative::register
.The text was updated successfully, but these errors were encountered: