Open jkulawik opened 10 months ago
Well, after trying to make a pull request for this, it seems that the issue is that the autoload is called in classes which don't inherit from node, e.g. Resource and RefCounted. These can't use get_node
nor get_tree()
.
To remove the autoload call from them, a reference to it would have to be injected in _init
or right after. These classes also seem to have a reference to the main plugin script/class, so the autoload ref could be acquired from there instead.
Alternatively to make the code more robust, don't touch the autoload in those at all and instead get data from these classes and save the autoload settings externally (i.e. wherever they're instanced).
I've worked on this a bit more and here's what I found.
The remaining (i.e. in code which doesn't inherit from Node) direct CyclopsAutoload
usage consists of 6 calls to calc_snap_to_grid_util()
and one CyclopsAutoload.settings.get_property(CyclopsGlobalScene.SNAPPING_GRID_ANGLE)
. calc_snap_to_grid_util()
heavily references the settings as well.
Settings seems to reimplement features which already exist in Godot, such as:
var_to_str
and str_to_var
which handle all built-in type conversionDictionary.get()
which checks whether a key exists and returns a supplied default value if neededIn general, I have a gut feeling this whole thing could be replaced with built-in ConfigFile
. But I can't be sure because the codebase is really complex and it's hard for me to know how everything works. Anyway, the point being: rewriting the settings would enable getting rid of the direct CyclopsAutoload
usage.
Here's a few proposals for that, and other adjacent things mentioned above:
CyclopsSettings.get_property()
.calc_snap_to_grid_util
to SnapToGridUtil
, perhaps even to its _init
. This would relegate this responsibility where it belongs and remove the need to reference the settings each time that SnapToGridUtil
is needed.I might work on these myself, but the test project seems broken (I get tons of errors in most scenes and on project start) so I can't really test if these changes would influence other parts of the code, so I'm afraid my changes might cause some bugs.
Which test project are you talking about? The files named test_* in the root of the project?
The main purpose of the autoload is to let various tools draw to the screen, which is currently implemented by having a global scene draw blocks, wireframes, points, etc between input events. I'm hoping that moving to a separate viewport will eliminate the need for this class, but it's going to be a while before I can do that.
I mean the entire project from this repo. When I launched it the first few times, I got many errors (mostly related to GUT if I remember correctly) and cyclops blocks didn't get drawn in the editor viewport, instead spamming the log with thousands of errors. I can't seem to replicate this now unfortunately.
However, I still do get errors, despite the autoload and plugin being enabled. When opening a scene with cyclops blocks, I get one or a few of these:
Can't take value from empty array.
But that's almost off-topic. How can I test the settings save/load?
It's hard for me to debug an error that I can't replicate on my machine. I'm not sure why. I also don't have the time to look into this just now. I hope to get to it soon.
I don't know what's causing the Can't take value from empty array.
error. Godot is giving me no additional info.
The settings cache is meant to hold changes you've made to tools property window. Also potentially other things as the project evolves. You should see things written there if you make changes to the tool properties. You might need to switch between several tools to make sure the changes flush to the cache.
I've looked into this and implemented some of your suggestions. I think some of this would likely best wait on moving Cyclops to its own window, which should get rid of the CyclopsAutoload as part of the move. I also do need to come up with some sort of settings system - I'm not been sure how to design it since it should likely be a singleton but not outside of the Autoload system so that non-nodes can refer to it too.
Out of curiosity, why not use add_autoload_singleton()
in the EditorPlugin's _enter_tree()
method to automatically register the autoload (in a way that persists to project.godot
)? The user can then reload the editor.
I am in res://addons/cyclops_level_builder/cyclops_level_builder.gd on line 108. However, it doesn't seem to work for some reason. I'd look into fixing it, but I'm hoping to remove the need for this autoload all together by creating a new main window for editing.
There's a long story here, but the short version is that I misspelled the autoload name (CyclopsAutoLoad instead of CyclopsAutoload, perhaps worth pointing out in the upgrade instruction) and spent a good 1.5h debugging the plugin and noticed something.
As far as I can tell, the plugin already mostly follows this undocumented guideline:
Looking through the source code, that approach is already used, but I also found many references to
CyclopsAutoload
as if it was an existing singleton:While I can't guarantee it, it seems to me that changing all of this to use
get_node("/root/CyclopsAutoload")
should remove the need for the workaround of manually adding the autoload before enabling the plugin, leading to a much smoother and issue-free user experience. Is there a reason why you would need to use the "direct" approach over theget_node
approach in some places?