godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.35k stars 21.25k forks source link

EditorPlugin Popup member called from a custom control hangs editor when hiding #18826

Closed nobuyukinyuu closed 4 years ago

nobuyukinyuu commented 6 years ago

Godot version: 3.0.2 stable

OS/device including version: Windows 10 x64

Issue description:

I'm having a heck of a time dealing with a particularly nasty issue which is plaguing a plugin I'm writing.

I'm writing an EditorPlugin which adds a child control to the inspector's bottom panel, as seen here: image

The SceneTree here for this button contains a PopupMenu whose sole purpose is to launch a modal WindowDialog whose instance was originally created in the script for the EditorPlugin. Now, the popup displays and works just fine, but when I press one of the OK/Cancel/Apply buttons made for this dialog, the editor becomes completely unresponsive.

Interestingly, this does not happen if the WindowDialog popup routine is called from the EditorPlugin script, only in the script for the ToolButton seen in the screenshot, where it is given a reference from EditorPlugin. Even more interestingly, the editor remains responsive if and only if the Output window is collapsed. After hiding the WindowDialog when called from the button, trying to show the debug output at any point will cause the editor to hang.

Update 1: It seems that attempting to go to the script editor will also cause the plugin to hang under the latter set of circumstances, regardless of the output window's visibility. Update 2: The behavior doesn't seem consistent, and stdout shows nothing. Force-closing the main editor when running from a separate console shows that the process seems completely hung, with no helpful output, even with -d -v args set. Some kind of leak?

Steps to reproduce: Install the plugin from the repository below and activate it. The plugin will display a modal popup (not all functionality is implemented yet). Add an association, for example "Resource" / "cmd.exe". It doesn't matter, as all we need to do is be able to get the button to display in the editor. Close the dialog. The editor should remain responsive.

Now, select a resource in your project (such as icon.png). The button should appear in the resource preview. Right-click it and a drop-down will appear which should allow you to see the popup again. Close the popup. If your output window is open, the editor should hang. If the output window is collapsed, the editor should remain responsive. In case of the latter, clicking the output window will cause the editor to hang.

Minimal reproduction project: Use the commit located here. I may commit a workaround if I find one, so please use this specific commit. https://github.com/nobuyukinyuu/launchy/tree/2c5582852678f8d8c04fb1eafe5afb7201985cf7

nobuyukinyuu commented 6 years ago

Made a new observation. The editor also hangs when the submenu popup in my project is closed by clicking away from it without launching the config popup. Maybe this has something to do with how popups work in a tool script if it's not called from an EditorPlugin. image

If you right click on the external editor button, but click away from this submenu popup, the editor will hang just like in the scenario given in my original post. The hang happens after a short delay.

Update 1: I managed to get the editor to remain responsive after the config popup closed, by causing the plugin script to crash before closing the popup. This left the editor responsive after closing, but kept the dark semitransparent black overlay 'stuck' on. The editor then hung after clicking the main menu (but before the popup appeared).

I tried repeating this again, only this time quitting using Ctrl+Shift+Q and finally managed to get the editor to spit this out after it closed:

ERROR: SelfList<class GDScriptFunction>::List::~List: Condition ' _first != 0 ' is true.
   At: c:\projects\godot-builds\godot\core\self_list.h:100
ERROR: SelfList<class GDScript>::List::~List: Condition ' _first != 0 ' is true.
   At: c:\projects\godot-builds\godot\core\self_list.h:100
WARNING: ObjectDB::cleanup: ObjectDB Instances still exist!
     At: core\object.cpp:1989
ERROR: ResourceCache::clear: Resources Still in use at Exit!
   At: core\resource.cpp:418
ERROR: There are still MemoryPool allocs in use at exit!
   At: core\dvector.cpp:70

Hope this helps tracking the problem down!

nobuyukinyuu commented 6 years ago

Hi, one last update from me for this issue to say that I implemented a workaround for my plugin. I believe the issue may be related to making more than one call per EditorPlugin to attach multiple scene members to the editor using the add_control_to_x() functions. The only thing which seemed to have solved the majority of my issues in the end was to de-instance all scenes until they were all inlined to a single instance from a single scene. The error from the previous post still persists, but the editor no longer hangs and (at least on projects without other toolscript problems) doesn't necessarily crash on exit.

I believe that the previous post regarding MemoryPool allocation has something to do with this, but that kinda stuff is over my head, so I'll leave it to whoever wants to try tackling this to close the issue. Perhaps the normal reference counting gets messed up somewhere pretty badly in this type of situation.

Calinou commented 4 years ago

@nobuyukinyuu Can you (or anyone else) still reproduce this bug in Godot 3.2.1 or 3.2.2beta4?

nobuyukinyuu commented 4 years ago

Issue no longer occurs for that specific build on 3.2.2beta4 using the specified commit. I'll close this issue for now.