-
-
Notifications
You must be signed in to change notification settings - Fork 571
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
Hot reloading does not reload nodes in editor viewport #1502
Comments
I had a similar, although not sure if it's the same, problem. I have a C++ gdextension where I create a few Resource classes, and then a scene where I have several of those classes active. I observed the following issues after making changes followed by a hotreload:
So I was doing some good ol' printf-debugging and found out the following with regard to the hot reloading sequence:
So far so good. Especially that last step shows that the hot reload has succesfully tracked the new objects being created. Also when I compare values such as get_instance_id() it shows that my instances are correctly tied to the already existing Godot Object _owner. But whenever I create a Callable(this, ...) on my new instances then these fail complaining about objects being null pointers. Long story, it turns out that godot-cpp calls into Godot with a call gdextension_interface_object_get_instance_binding() to lookup my instance pointer that is tied to the _owner, but this binding has been cleared by the unloading of library. Possible solutionThere is a small kludge in the Wrapped constructor that upon hot reload restores the link to the original _owner. I think at this time, we also need to restore the instance_binding to the new this-pointer. This is also required to call the correct destructor (free_callback) for the new instances. I made a small change to wrapped.cpp to accomplish this: diff --git a/src/classes/wrapped.cpp b/src/classes/wrapped.cpp
index ffca4f9..3728d25 100644
--- a/src/classes/wrapped.cpp
+++ b/src/classes/wrapped.cpp
@@ -61,6 +61,10 @@ Wrapped::Wrapped(const StringName p_godot_class) {
while (recreate_data) {
if (recreate_data->wrapper == this) {
_owner = recreate_data->owner;
+ if (likely(_constructing_class_binding_callbacks)) {
+ godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _constructing_class_binding_callbacks);
+ _constructing_class_binding_callbacks = nullptr;
+ }
if (previous) {
previous->next = recreate_data->next;
} else { I don't know for sure if this fix is complete, but it at least fixes my problem. EDIT: my version information:
|
Also see #1589 |
I just posted PR #1590 which should fix this! If anyone has time to test it with their project, I'd appreciate it :-) |
Nope, sadly did not resolve the issue. :( |
Ok, thanks for testing! |
Godot version
v4.2.2.stable.official [15073afe3]
godot-cpp version
4.2 [9da6ecd]
System information
Windows 10, Intel Core i5-9300H
Issue description
Testing out the new hot-reloading feature, I have observed that changes do not appear in the editor view after recompiling a GDExtension. Or let's say, they only appear partly.
Two examples where I encountered this:
_ready()
and change it every time a button is pressed.) The only fix I see so far is to reload the project.In order to visualize what I mean (I'll also provide a minimal reproducible example project), I'll detail those two examples now. Let's say we start with this in a button class:
This is reflected in the editor view:
However, now change the text in the code, compile and see that the change is not reflected within the editor view. But, if the scene / game is run, the changes are correctly shown.
Now an example for renamed method bindings. Let's say we have a method like:
in the Sprite2D child. (And correctly bound in the
_bind_methods()
method.) This method is connected to thepressed()
signal of the button. Rename it to something else, for exampleon_start_button_pressed
, recompile and then we have this:The old name of the connected method is still visible:
If I now double click on the signal in order to pick another method, and I'm looking for the renamed one, it is correctly listed:
Yielding two methods, if the connection to the old one is not removed:
Running the scene like that is totally fine. Which is good but also problematic as I would expect Godot to throw an error or display an error message if the outdated signal handler can not be called. Which it really can't as it does not exist anymore in the code and resulting library.
If the whole project is reloaded after recompiling the code, those issues disappear. But that's not what I would expect from hot reloading.
Steps to reproduce
Minimal reproduction project
The minimal example, which I provided, should be fine to use for that. Note, that you need to change the
env
path in theSConstruct
file as I placed the godot-cpp compiled C++ API in a different directory and left the path in a probably unusable state now. And of course, don't forget to compile otherwise Godot will not find the libraries as I have not bundled them with the zip archive.GDExtension CPP Example V2.zip
The text was updated successfully, but these errors were encountered: