Trait ExtensionLibrary
pub unsafe trait ExtensionLibrary {
// Provided methods
fn editor_run_behavior() -> EditorRunBehavior { ... }
fn min_level() -> InitLevel { ... }
fn on_level_init(level: InitLevel) { ... }
fn on_level_deinit(level: InitLevel) { ... }
fn override_wasm_binary() -> Option<&'static str> { ... }
fn override_hot_reload() -> Option<bool> { ... }
}
Expand description
Defines the entry point for a GDExtension Rust library.
Every library should have exactly one implementation of this trait. It is always used in combination with the
#[gdextension]
proc-macro attribute.
§Example
The simplest usage is as follows. This will automatically perform the necessary init and cleanup routines, and register
all classes marked with #[derive(GodotClass)]
, without needing to mention them in a central list. The order in which
classes are registered is not specified.
use godot::init::*;
// This is just a type tag without any functionality.
// Its name is irrelevant.
struct MyExtension;
#[gdextension]
unsafe impl ExtensionLibrary for MyExtension {}
§Custom entry symbol
There is usually no reason to, but you can use a different entry point (C function in the dynamic library). This must match the key
that you specify in the .gdextension
file. Let’s say your .gdextension
file has such a section:
[configuration]
entry_symbol = "custom_name"
then you can implement the trait like this:
struct MyExtension;
#[gdextension(entry_symbol = custom_name)]
unsafe impl ExtensionLibrary for MyExtension {}
Note that this only changes the name. You cannot provide your own function – use the on_level_init()
hook for custom startup logic.
§Safety
The library cannot enforce any safety guarantees outside Rust code, which means that you as a user are responsible to uphold them: namely in GDScript code or other GDExtension bindings loaded by the engine. Violating this may cause undefined behavior, even when invoking safe functions.
Provided Methods§
fn editor_run_behavior() -> EditorRunBehavior
fn editor_run_behavior() -> EditorRunBehavior
Determines if and how an extension’s code is run in the editor.
fn min_level() -> InitLevel
fn min_level() -> InitLevel
Determines the initialization level at which the extension is loaded (Scene
by default).
If the level is lower than [InitLevel::Scene
], the engine needs to be restarted to take effect.
fn on_level_init(level: InitLevel)
fn on_level_init(level: InitLevel)
Custom logic when a certain init-level of Godot is loaded.
This will only be invoked for levels >= Self::min_level()
, in ascending order. Use if
or match
to hook to specific levels.
fn on_level_deinit(level: InitLevel)
fn on_level_deinit(level: InitLevel)
Custom logic when a certain init-level of Godot is unloaded.
This will only be invoked for levels >= Self::min_level()
, in descending order. Use if
or match
to hook to specific levels.
fn override_wasm_binary() -> Option<&'static str>
fn override_wasm_binary() -> Option<&'static str>
Whether to override the Wasm binary filename used by your GDExtension which the library should expect at runtime. Return None
to use the default where gdext expects either {YourCrate}.wasm
(default binary name emitted by Rust) or
{YourCrate}.threads.wasm
(for builds producing separate single-threaded and multi-threaded binaries).
Upon exporting a game to the web, the library has to know at runtime the exact name of the .wasm
binary file being used to load
each GDExtension. By default, Rust exports the binary as cratename.wasm
, so that is the name checked by godot-rust by default.
However, if you need to rename that binary, you can make the library aware of the new binary name by returning
Some("newname.wasm")
(don’t forget to include the .wasm
extension).
For example, to have two simultaneous versions, one supporting multi-threading and the other not, you could add a suffix to the
filename of the Wasm binary of the multi-threaded version in your build process. If you choose the suffix .threads.wasm
,
you’re in luck as godot-rust already accepts this suffix by default, but let’s say you want to use a different suffix, such as
-with-threads.wasm
. For this, you can have a "nothreads"
feature which, when absent, should produce a suffixed binary,
which can be informed to gdext as follows:
struct MyExtension;
#[gdextension]
unsafe impl ExtensionLibrary for MyExtension {
fn override_wasm_binary() -> Option<&'static str> {
// Binary name unchanged ("mycrate.wasm") without thread support.
#[cfg(feature = "nothreads")]
return None;
// Tell gdext we add a custom suffix to the binary with thread support.
// Please note that this is not needed if "mycrate.threads.wasm" is used.
// (You could return `None` as well in that particular case.)
#[cfg(not(feature = "nothreads"))]
Some("mycrate-with-threads.wasm")
}
}
Note that simply overriding this method won’t change the name of the Wasm binary produced by Rust automatically: you’ll still
have to rename it by yourself in your build process, as well as specify the updated binary name in your .gdextension
file.
This is just to ensure gdext is aware of the new name given to the binary, avoiding runtime errors.
fn override_hot_reload() -> Option<bool>
fn override_hot_reload() -> Option<bool>
Whether to enable hot reloading of this library. Return None
to use the default behavior.
Enabling this will ensure that the library can be hot reloaded. If this is disabled then hot reloading may still work, but there is no guarantee. Enabling this may also lead to memory leaks, so it should not be enabled for builds that are intended to be final builds.
By default, this is enabled for debug builds and disabled for release builds.
Note that this is only checked once upon initializing the library. Changing this from true
to false
will be picked up as the
library is then fully reloaded upon hot-reloading, however changing it from false
to true
is almost certainly not going to work
unless hot-reloading is already working regardless of this setting.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.