Skip to content
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

#[gdextension(discovery)] to expose static information about registered classes #986

Closed
wants to merge 3 commits into from

Conversation

Bromeon
Copy link
Member

@Bromeon Bromeon commented Dec 19, 2024

Note

It's completely unclear if we can merge this feature, and in which form. There are quite a few open points, and there may be better approaches to achieve the same.


Allows dependent crates to statically discover classes registered by a Rust extension.

Rationale

The idea is to provide a mechanism that allows tools and integrations to query information about an extension at build time. For example, this allows validations, data extraction/generation, etc. It is limited to downstream crates depending on the crate declaring the extension, in particular their build.rs file. If a crate is used for discovery, then it must declare crate-type = ["cdylib", "rlib"], i.e. both a C dynamic library for GDExtension and a Rust library.

The API is kept deliberately minimal -- it does not strive to cover the entire reflection API that Godot provides. Many tools may be better fitted as a direct integration into the Godot editor, or as runtime code querying Godot's ClassDB API.

Usage

To make use of discovery, your entry point trait needs to have the discover attribute:

/// Your tag must be public.
pub struct MyCoolGame;

/// The `discovery` attributes adds an associated `MyExtension::discover()` function to the `MyExtension` 
/// tag. It also declares a module `godot_discovery` in the current scope, which re-exports symbols
/// from `godot::init::discovery`. This allows your dependent crate to not depend on `godot` directly.
#[gdextension(discovery)]
unsafe impl ExtensionLibrary for MyCoolGame {}

To access the exposed API in a dependent crate in build.rs, you can call MyExtension::discover():

use my_crate::MyCoolGame;
use my_crate::godot_discovery::DiscoveredExtension;

fn main() {
   let api: DiscoveredExtension = MyCoolGame::discover();
   for c in api.classes() {
       println!("Discovered class {}.", c.name());
   }
}

Problems

On one hand, the Cargo.toml option

[lib]
crate-type = ["cdylib", "rlib"]

causes the following warning:

The lib target my_crate in package my-crate v0.1.0 (.. path ..) has the same output filename as the lib target my_crate in package my-crate v0.1.0 (.. same path ..).
Colliding filename is: /path/to/libmy_crate.so.dwp
The targets should have unique names.
Consider changing their names to be unique or compiling them separately.

On the other, there are several CI issues. I'm also not sure if hot-reload is a good place, but I'd rather add two extra crates just for this.

The reason for choosing this approach is to enable post-build actions (by moving them into a dependent crate). Given the issues and the need for another crate just for this, I'm not fully convinced this is the best approach. Maybe a custom tool as actual post-build step, which can invoke headless Godot via ClassDB introspection, is more versatile. Or maybe a binary which loads the cdylib via existing or separate entry point, thus not causing the rlib conflict.

@Bromeon Bromeon added feature Adds functionality to the library c: register Register classes, functions and other symbols to GDScript labels Dec 19, 2024
@GodotRust
Copy link

API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-986

@Bromeon
Copy link
Member Author

Bromeon commented Jan 12, 2025

I'm not sure if my above proposal is the right way to approach the problem, and I don't plan to work on this in the near future. The code is around in case we want to revisit it.

@Bromeon Bromeon closed this Jan 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: register Register classes, functions and other symbols to GDScript feature Adds functionality to the library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants