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

A way to include in-editor class documentation for GDExtension plugins #8245

Closed
chocola-mint opened this issue Oct 24, 2023 · 4 comments
Closed

Comments

@chocola-mint
Copy link

chocola-mint commented Oct 24, 2023

Describe the project you are working on

I'm working on a project that aims to automate boilerplate around the development of C++ GDExtension plugins.

Describe the problem or limitation you are having in your project

When Godot loads a GDExtension in-editor, it's possible to open the documentation for registered classes and see their members. But of course, aside from that there's no actual documentation included outside of the default description, which incorrectly asks the user to consider contributing to the Godot class reference.
image

Currently, GDExtension developers usually provide documentation on self-hosted websites and/or GitHub wikis, but it would improve the user experience of GDExtension addons if we could also somehow include documentation that's visible inside Godot.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

When loading the GDExtension configuration file (.gdextension), add a "documentation" section that allows the GDExtension developer to specify directories containing documentation files. Paths to different localizations can be specified, and the localization that matches the user's OS locale the best will be loaded.

For a hypothetical GDExtension plugin called "GDExample", the configuration file would look something like this. Note that [configuration] and [libraries] keys are pre-existing keys.

[configuration]
...
[libraries]
...
[documentation]

en = "res://addons/gdexample/doc/en/"
ja = "res://addons/gdexample/doc/ja/"
...

Each documentation directory should look like Godot's doc/classes directory, containing XML for every class.

The documentation format is identical to the one used by Godot's engine classes (see AcceptDialog.xml for example).

Lastly, documentation is optional. If documentation isn't provided or the paths can't be accessed, the editor help page will just show the aforementioned error message instead.

With these changes, developers can now ship documentation with their addons, and their users wouldn't need to keep switching away from Godot for documentation whenever they encounter GDExtension classes. Furthermore, this system supports localization as well, so a developer could provide documentation for multiple languages, improving accessibility if they wish to.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Documentation Format

We could go with either XML (same as Godot's engine class documentation format) or JSON.

An XML implementation could possibly be implemented using DocTools::load_classes. This function is currently being used to load XML documentation from the doc/classes directory when dumping the engine API reference (--doctool), but could theoretically be used to load user-specified XML documentation as well.

A JSON implementation would be able to take advantage of the JSON resource class and avoid using DocTools::load_classes in-editor. It would also support documentation hot reload out of the box as a bonus. But this would result in two documentation formats for pretty much the same purpose, and would be much harder to maintain down the line.

I believe using XML is the right way forward.

Possible Implementation

In GDExtensionResourceLoader::load_gdextension_resource, use ConfigFile::get_section_keys("documentation") to get a list of localizations available. We then find the best version for the user's OS locale, using the following rules:

  • If there's an exact match, use that one.
  • If not, use any localization that has the same language. (So if the user's OS locale is en-US and a GDExtension has documentation for en and ja, en will be selected)
  • If there is still no match, the first localization listed in the config will be used as the fallback option.

The selected localization's documentation path is stored inside GDExtension as GDExtension::doc_dir_path. This property being empty implies that the GDExtension has no documentation attached.

In EditorHelp::generate_doc, call doc->load_classes() with every loaded GDExtension's doc_dir_path. This will allow GDExtension documentations to be cached. However, to invalidate the cache, we'll need a hash based on every loaded GDExtension's documentation. I'm considering the following scheme, implemented in EditorHelp::_compute_doc_version_hash:

  • For each documentation directory, find the most recently modified file's time (FileAccess:get_modified_time).
  • Append every documentation directory's most recently modified file's time to the version hash.

If this enhancement will not be used often, can it be worked around with a few lines of script?

This enhancement will be used by most GDExtension plugin developers. There's no workaround at the moment without engine modification.

Is there a reason why this should be core and not an add-on in the asset library?

DocTools is not exposed to the GDExtension interface nor GDScript (and rightfully so), and so it's impossible to provide this feature as an addon.

@dsnopek
Copy link

dsnopek commented Oct 24, 2023

Thanks for the proposal!

However, there's already PR godotengine/godot#83747 in the works, which is pursuing a different approach to the same problem. Unfortunately, a proposal was never made for it, instead it was based on a number of discussions on other issues/PRs, in RocketChat and at GDExtension meetings.

@chocola-mint
Copy link
Author

Ahh, so that's why I couldn't find it here. That PR seems to be pretty close to completion, which is really nice to know. It looks a lot more involved than what I had in mind too, so I'm probably missing a lot of details here.

Sorry for the duplicate proposal in any case!

@aaronfranke
Copy link
Member

godotengine/godot#83747 was merged, but is not in godot-cpp yet. Once it is, when 4.3 is released, will this proposal be closed, or is there more that needs to be done?

@dsnopek
Copy link

dsnopek commented May 23, 2024

godotengine/godot#83747 was merged, but is not in godot-cpp yet. Once it is, when 4.3 is released, will this proposal be closed, or is there more that needs to be done?

The godot-cpp PR was recently merged! I think we can close this proposal. There is certainly more details that could be iterated on, but the feature now exists.

@dsnopek dsnopek closed this as completed May 23, 2024
@AThousandShips AThousandShips added this to the 4.3 milestone May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants