Almost every major part of Godot uses a singleton. Singletons are convenient but they cause lots of problems when trying to extend the platform.
A quick examples is you are limited to only one window at a time because the Os and VisualServer classes are singletons. While most games only need one window there are many applications outside of games that may need multiple windows.
Is there any way we can move away from this pattern to more of an injection pattern? I'd be willing to assist in this effort.
IMO it is still possible to have multiple windows even keeping OS and VisualServer as singletons, if you consider a Window
is a kind of Viewport
(which is not currently a singleton). Maybe a few functions would need to move though (such as screen size, mouse pos etc).
VisualServer and OS are singletons because your computer has one graphics card, and has one OS (at least these two are legit for me)
Support for multiple windows would be nice (if not for games, then for the editor), but like Zylann said, it probably doesn't require engine singletons to be rewritten.
Also, I feel like doing that would probably break things API-wise, or at least make it difficult not to break them, and we're just barely coming in hot from a massive breaking release that is 3.0 - something that we probably don't want to do again too soon.
It doesn't really have anything to do with singletons. As mentioned above,
multiple windows can be done with viewports (when that is supported,
probably in the future as there is not really much of a priority right now).
On Tue, Jan 30, 2018 at 11:38 PM, River Mesa notifications@github.com
wrote:
Support for multiple windows would be nice (if not for games, then for the
editor), but like Zylann said, it probably doesn't require engine
singletons to be rewritten.Also, I feel like doing that would probably break things API-wise, or at
least make it difficult not to break them, and we're just barely coming
in hot from a massive breaking release that is 3.0 - something that we
probably don't want to do again too soon.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/16216#issuecomment-361805034,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF-Z2zzEY_NcXS2JiBlBCuSOrMC6ICkOks5tP9IegaJpZM4RzPax
.
I agree with pretty much all points above, and just want to throw in my 2 cents about singletons.
Singletons are very convenient, but also very limiting and very bad for having testable code as Godot will need as much of as possible at some point in the future for the sake of reliability. I found a way about 2 years ago to both get rid of, and still use singletons at the same time :)
For instance, in C# a typical very basic singleton will look something like this:
``` C#
public class MyClass
{
public static MyClass Instance { get; private set; }
public MyClass()
{
Instance = this;
}
}
However, since this essentially breaks the OOP paradigm and is also bad if you want to have a non-flaky testing harness, what I do is this instead:
``` C#
public class MyClass
{
// My class stuff here... nothing static
}
But, then I make a container that contains only a single static instance of "MyClass"
``` C#
public static class MyClassContainer
{
public static MyClass myClass;
static MyClassContainer
{
myClass = new MyClass();
}
}
```
Which could be accessed simply like: MyClassContainer.myClass.DoMyClassStuff();
But, you can still spawn instances of MyClass without them overriding or conflicting with your singleton.
This makes it much easier to keep MyClass as its own object and also makes it testable without the need of resetting the singleton.
Just some food for thought, I hope someone finds it useful :)
I vote for closing this, as I think there is some serious misunderstanding about the API.
I agree, if there actually is a serious problem with them in the future it will probably become pretty obvious.
I think it's still worth discussing in the long term. I think the problems will become more apparent as time goes on. As @NathanWarden mentioned the singletons can be detrimental to unit tests. And if Godot wants to have many contributors having unit tests is going to be important. There's currently 68 types of singletons in the code base, to me that's concerning.
If that number is correct then that is a very high number and probably warrants further discussion. But, I think for now any singletons that are "core" singletons should definitely be off the table, at least for now.
If it's possible to get rid of some of them without breaking Godot or having to make any user facing API changes, and if someone wants to tackle it, then I think it would be good to get started with any that might be safe and easy to replace, especially if it affects how testable Godot is.
Again, any that are core to Godot, even if they really need to be replaced, would probably need to wait until it's ready for another major revision.
Singletons are not inherently bad or good, they have advantages and drawbacks. By now they fulfill our need, and they did not showed any limitations, while providing a straightforward API.
There is no reason to question this design until we have a specific use case where singletons are not enough to provide a simple and easy to use solution.
I would also close this, as for me there's is no factual limitation provided. And if we have to remove a singleton someday, it should be decided one at a time, and proven that it is worth changing the design.
I think everything that can really be said about this on an issue has been said now. I'm closing this issue, thanks for the positive discussion guys.
@mfrancis107 My feel is that you are suggesting something without much knowledge on how those singletons work or what function they do. If you find a specific use case you would like to discuss, I am super welcome to do it, but I don't believe in promoting or following design patterns for the sake of it. Everything in Godot follows a specific use case. We don't design thinking of using "the right" design patterns.
Instead of thinking how Godot could be improved by applying the right design patterns, I invite you guys to think about how Godot actually came to exist and why people enjoys working with it.
In my view, API ease of use is way more important than using "the right design patterns". With this common mistake, I saw in the past dozens of teams force patterns such as MVC and making their codebase a complete mess just to keep sticking to it.
Design patterns are useful for communication, but not something you must find how to apply. This is the most common mistake young programmers make.
While most games only need one window there are many applications outside of games that may need multiple windows.
lol wat do you mean by this?
@girng VR, multi-window in editor, interactive multi-displays, to say a few, but the issue misses the point imo
Theres no need to change any godots internal design.
This feature can be simply archieved by adding simple switch to ViewPort node - show_as_popup true/false
If set to true
, it could create simple popup window and display this ViewPort surface within separate window.
If set to false
while popup window exists, - destroy window (close), and thats it.
But we have now more important things to focus on, like fixing 3.0 bugs and implementing GL2 support.
Most helpful comment
Instead of thinking how Godot could be improved by applying the right design patterns, I invite you guys to think about how Godot actually came to exist and why people enjoys working with it.
In my view, API ease of use is way more important than using "the right design patterns". With this common mistake, I saw in the past dozens of teams force patterns such as MVC and making their codebase a complete mess just to keep sticking to it.
Design patterns are useful for communication, but not something you must find how to apply. This is the most common mistake young programmers make.