-
-
Notifications
You must be signed in to change notification settings - Fork 98
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
Move the "Singleton" concept out of the autoload one #5832
Comments
I bring to your attention the |
I'm not sure if I got what you want to be implemented, because atm singletons just work fine, do you have some end-user cases? |
Autoloads are, as their name imply, simply nodes that are instantiated as a child of the root node automatically. In the project settings, an autoload can be marked as a "global variable", which makes it available as a singleton. However, there are situations where you would want a singleton that is either not a node, or not automatically loaded. As an example, you may have a single 3D camera system in your game (if you are doing a strategy game for example), and would like to access it from anywhere as it's more convenient. One solution would be to create a custom autoload called In the end, it seems like this |
makes sense for me now! thanks for the explanation!!! |
Just FYI,
I think I misunderstood. If singletons are instantiated at runtime, then I suppose splitting does make more sense. But in that case, I don't see why the list would also show the autoloads with global variables again, if those are the only singletons that automagically get created on game start. As it stands it's a bit confusing to introduce another "global variable / instance" system, and it would be better to improve the existing ones and integrate into those. Sorry if I misunderstood some of the proposal still! |
The list would show them, but they would not be editable. This is mainly to make it clear which singletons exist, even if they are automatically created. As you cannot create two singletons with the same name, I think it is pretty important to show all existing singletons in the same list.
The problem is the following. Right now you can have autoloaded nodes that can be exposed as singletons or not. The proposal aims to allow for singletons not to be autoloads, and to not necessarily be nodes (they could be any type of object). |
There seem to be two things going on here:
While load() could be considered clunky, it does force explicit access. You are not polluting the global name space with Resources. There is one drawback: You risk accidentally losing the instance if all objects that have load()ed your Resource happen to be freed. (Reference count hits 0. Realistically you could prevent this by calling reference() within the Singleton Resource on itself, and then dereferencing it when you quit the application. But we can file that under 'advanced user' knowledge.)
This way, it seems, there's no fundamentally new feature / rework of autoloads required either. I am personally against allowing Nodes to be Singletons. It's bound to invite bad practices and complications. |
@TheDuriel As you correctly point out, |
preloading is not safe. If you discard every object which has preloaded a resource, you also discard that resource. The only safe way to ensure it is kept is to manually tick up the ref counter. Since you are mentioning the Reference typo though. One could extend the idea in 2. of my post to mean Reference types instead of Resource types. But, I think Resource is universally more useful than plain references, and less trouble to implement. |
You would also have to remove it from the |
YES please oh god YES, I wholeheartedly support this proposal. For two reasons: 1) this overlap in concepts is just not right as a matter of principle. You don't just "steal" the word "singleton" (which means the same thing in every single language) and suddenly give it a different meaning in Godot. 2) in practice it makes it hard to Google questions related to programming patterns in Godot. More generally, Godot needs to stop trying so hard to be different from other languages. If the concept exists somewhere else then take it as-is and use the same keywords (looking at you, GDscript pretending to be python but having weird keywords like class_name and extends and func) (looking at you, signals). |
I can sort of understand why people would want this but I'm not a fan of the proposal. Splitting autoloads into two (effectively "Autoloads" and "Singletons") will make the system way more complicated than it has to be. I can already imagine the questions confusing the two. If you need autoload scripts, is there any real downside to having a Node hold the script and use that as an autoload? If you need to have global variables and resources, why not make an autoload hold variables and data and access it from there? I get that some people dislike that pattern but making a whole separate tab for singletons seems a bit rough. I'm a bigger fan of #4854 which suggests making autoloads easier to manage at runtime, rather than creating a whole separate system that almost does the same thing. I've always thought the autoload system reinforces the node structure of Godot rather than have random data floating around as singletons. |
To avoid some confusion, in my PR, I renamed is to "global variables". I believe this is indeed more accurate. So in general, you would have a tab for "nodes automatically loaded at startup" and another for "things that are globally accessible". Those are in fact quite different concept IMO. Also, the fact that autoloads would be configurable as globally accessible would just become a nicety. As, technically, you could also assign the global variable value in the
It is just less practical to have to use something like |
The worry of breaking tutorials is legitimate, however if the name "Autoload" is dropped altogether in favour of two things mentionned by @groud ("Singletons" and the other one, whatever it gets named) then yes it's not ideal but at least there's no possible confusion. |
I am not sure why would those be problems. The proposal is clear that it does not change how autoloads work right now, so there's no problem possible with existing tutorials.
The proposal would not break compatibility in any way. But sure, I guess it will be in the release notes anyway.
I didn't stated anywhere I would drop autoloads. On my mockups they are still visible as a dedicated tab. |
This approach was proposed as an alternative to static variables (see godotengine/godot#6840 (comment)), but static variables are now implemented. What happens if you delete/rename an autoload, will the linked global (with the same name) change? I find it confusing that they are in different tabs, it's not obvious and inconvenient when adding/editing an autoload/global. I would prefer to combine this in one tab: Also, we discussed on the |
I'd say yes. The idea would simply have the "global variables" tab just list the autoloads registered as globals in the other panel. Technically, this would only help listing all your global variables in one single place.
I don't mind much if we only have this implemented for nodes. But for other types of global variables it would probably be a bit annoying to have the management of autoloaded nodes in the same place as the global variables list. So well, as it was discussed indeed, it might be something to keep in mind. |
Describe the project you are working on
Godot
Describe the problem or limitation you are having in your project
I common feature that has been asked for a while is the possibility to register a node as globally accessible from anywhere. This is quite similar to what autoloaded nodes marked as "global variable" provide, but it means that you cannot register your own node, at runtime, as a singleton.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
The idea would be to split the the autoload tab into an autoload tab, and a singleton one. That means user would be able to register their own objects/nodes as singletons.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The autoload tab would look a bit like the current one. I just added and "Enabled" tickbox at the left, so that an autoload can be disabled without the removing the line. I also changed the "Global variable" column title to "Use as singleton".
When a node is marked a "used as a singleton", it is automatically moved as a non-editable entry in the Singleton tab, with its autoload name used as the singleton name. It's type is also set according to the script/scene you used to create the singleton.
Then, on the Singleton tab, you would be able to add / remove other singletons to the list (provided they have unique names of course) and define a optional type for it. This type will mainly be used for autocompletion.
If you try to add a singleton with an already used name, either by adding it manually, or by setting "use as singleton" on an autoload, the operation would fail with an error message.
When the game starts, singletons are not instantiated. Aside from autoloaded nodes, for which the singleton would be automatically set by the engine, users will have to register an object of the correct type as a singleton using something like
SceneTree->register_singleton(&"MySingleton", my_object_to_register_as_singleton)
(it could be added to any global-scope API, not necessarily SceneTree.). Then, any code runningMySingleton.do_something()
would calldo_something()
on the registered object.If this enhancement will not be used often, can it be worked around with a few lines of script?
Yes.
It can be worked around with an autoload whose properties are set to handle the list of singletons, that's what most users do. But it is less convenient for something that could be used often.
Is there a reason why this should be core and not an add-on in the asset library?
This is core.
Edit: Related:
#4854
#4831
#165
The text was updated successfully, but these errors were encountered: