-
-
Notifications
You must be signed in to change notification settings - Fork 217
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
Class without init
cannot be returned from Rust to GDScript
#194
Comments
Notice that the editor calls #[godot_api]
impl GodotExt for World {
func init(_base: Base<RefCounted>) {
unimplemented!("should never be called");
}
} It seems to have something to do with generating documentation:
|
Checking the godot source-code, we need to set the bool ClassDB::can_instantiate(const StringName &p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'.");
#ifdef TOOLS_ENABLED
if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) {
return false;
}
#endif
return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance));
} Alternatively we can set a class to be virtual. When generating documentation godot will try to instantiate a new object of that class. This is so that godot can call |
godotengine/godot#58972 see also here for a guide on what abstract vs virtual means and such. but the basic point is that we do need to properly set our class as not being instantiable. |
I just tested the original snippet. Nowadays, the API expects explicit error[E0277]: Class `World` requires either an `init` constructor, or explicit opt-out
--> itest/rust/src/register_tests/var_test.rs:27:12
|
27 | pub struct World {
| ^^^^^ needs `init`
|
= help: the trait `GodotDefault` is not implemented for `World`
= note: To provide a default constructor, use `#[class(init)]` or implement an `init` method
= note: To opt out, use `#[class(no_init)]`
= note: see also: https://godot-rust.github.io/book/register/constructors.html So, after adding #[derive(GodotClass)]
#[class(no_init)]
pub struct World {}
#[derive(GodotClass)]
#[class(init)]
pub struct WorldGen {}
#[godot_api]
impl WorldGen {
#[func]
fn generate(&mut self) -> Gd<World> {
Gd::from_object(World {})
}
} Now, calling from GDScript: func test_world_gen():
var w = WorldGen.new().generate()
print(w) This works as expected, prints |
When calling
WorldGen.new().generate()
from GDScript, Godot prints an error:If I put
#[class(init)]
on World instead of bare#[class]
, it starts working. Same if I manually implementinit
onGodotExt
.I did expect
World
not to be instantiable from GDScript or addable in the editor, but when instantiated from Rust it should still be possible tot pass it back to GDScript.The text was updated successfully, but these errors were encountered: