-
-
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
Implement namespaces in GDScript #1566
Comments
On the project level, it's kind of possible, since you can create a single global class to load other classes (not necessarily inner classes), see concrete example in # utils.gd
# Note: no class_name here!
extends Node
static func say_hello():
print("Hello!") # namespace.gd
class_name Game
const Utils = preload("res://utils.gd")
# main.gd
extends Node2D
func _ready():
Game.Utils.say_hello() Not sure how efficient such solution would be compared to just using Avoiding using too many global classes can also speed up editor performance in Godot 3.2+: godotengine/godot#27333. But yeah namespace issues in general are must have to resolve if we aim for proper plugins support, and we have similar issues with C++ namespaces when it comes to exposing core classes to scripting, with some solutions: godotengine/godot#26990. |
As a workaround, you can add a prefix to your class names if you expect your class names to conflict with other plugins (or user code). Even a single letter will do, be creative 🙂 That said, if the class name isn't a single proper noun, it makes conflicts much less likely already. So far, I've mostly seen this be an issue in utility classes, not so much advanced nodes where you're unlikely to use several add-ons implementing the same feature. |
@Xrayez To an extent you can do that but 1) Cyclic References, so you can't be comprehensive and 2) This can still conflict with inner classes of the classes in that namespace, such as this state class conflict issue. Namespaces are essentially mandatory for plugin creators. |
Namespace collisions with already mentioned testing frameworks: bitwes/Gut#215. 😃 |
Also makes it more comparable to C# and increases organization of projects without cluttering the global space, tho at this point wouldn't it be better to stop relying upon files as classes? Its already a chore that if you need to keep using a bunch of classes, every single one has to have a class_name or preload (which tbh ends up requiring load most of the time because cyclical dependency issues) so with any moderately sized project you not only start running into global bloat in code that becomes difficult to manage, (especially without a dedicated IDE for GDScript) but massive amount of boilerplate that seems counterproductive. If I was to use GDScript, I would really hate to use "C-style namespaces", seems a bit poor of a solution especially in the modern environment where we're emulating python an awful lot. |
See previous related discussion in godotengine/godot#21215. |
Really would like to see this happening. I'm staying away from class_name (name_global ?) because of this, and also find the cyclic dependencys are a headache. Why can't I type a member in a class to itself ( say to have a ref to a parent of the same type ), if only for typing/autocomplete. As long as you don't instance it i don't see why that would give a cyclic dependency. I also have it sometimes when i want to type a return value. I tried all kinds of things... autoload with nodes seems to work well, but it always breaks at the last step. haven't tried one global class_name as the namespace yet. I don't think you can do nested namespace (name_space ?) with that workaround either ? Tried a const preloaded .tres too, since that is loaded only once... but tres is not the expected type,... or something.
A workaround indeed. With proper namespace support you can have something like author or studio initials and plugin_name or whatever as the first part, instead of on all the scripts. |
Also, when considering name_spaces, it would be nice to be able to have 'imports' with shorthands, like in import My_Stuff.Nested.NameSpace.Class as MyClass SomeObject : Myclass which would basically be like working with the consts now. could also be keyword uses or using, since it's not really an import. |
We could have a namespace approach if we can implement this #1709 where the folder structure could be determined at compile time and use that as namespaces. This also works well with Godot’s approach of organising assets by scene and logic. |
I appreciate the idea of introducing namespaces. I come from other languages having namespaces and already wondered if this is possible in GDScript. Found out it isn't. That being said, I upvote your request, @me2beats . For now I go for the workaround of prefixing my classnames as it has been done 10 years ago in PHP, for instance. So, I'd have something like The workaround as suggested by @Xrayez is somehow neat and odd at the same time. "Neat" because I like how the classes can be used, like As of writing this I am not sure what feels better in the end. 🤔 Just make namespaces happen! 😉 Also, I agree to @FrederickDesimpel. If namespaces are introduced to GDScript, some |
Anything new about namespaces ? |
GDScript in 4.0 is in feature freeze as the goal is now to stabilize it. Therefore, no new features will be added to it until 4.1 at least. |
Changed to For example you have many classes and you want to group them. |
godotengine/godot#67714 has effectively solved this issue by allowing users to create a named class of preloaded consts to other classes. There are a few elements that might cause a problem, like a global State class will conflict with a non-global State variable but overall the PR has added significant ability for namespacing. |
@AlexDarigan Does is mean casting to such |
Seems like it. |
To add to the discussion. Using class names and preloads to fake namespaces is the approach I've taken in my addon, and it works well enough. However, in 4.0 class names seem to be required to take advantage of the new custom resource exports, and the doc comment's class referencing. I suppose that would be resolved if they were changed to not require class names but namespaces in GDScript would still be ideal. |
Yeah. I've come across the issue with documentation comments. I don't think it is an unfair ask for plugin developers have some way to prevent polluting the global namespace. |
You also need to have a |
It would still be a problem if users of the addon would need to use the class name in their scripts. E.g. if you have a class @onready var flubbermator:Flubbermator = %Flubbermator then they need a proper class name unless they also do this |
Adding to what @Pyxus wrote, it's very possible to effectively have namespaces by using the A simple use case for me will be:
However, in the editor this will not let me select the relevant node. Only by using Is it possible to allow this method to work without adding the more complex namespace concept to gdscript? |
Could you try again? I tried in 4.2 and it works flawlessly. MRP: home-namespaces.zip |
This does not work. I looked at your MRP and you've added |
Describe the project you are working on:
GDScript plugins
Describe the problem or limitation you are having in your project:
class_name
is a great feature and I use it often when making plugins.But there are at least 3 problems which can occur when using
class_name
:If you use a custom class named say
Util
when creating a plugin, there is absolutely no guarantee that the user is not using a custom type with the same name.So you will get
As the number of your custom classes gets large (imagine a room with several hundred items on the floor), you will most likely want to structure them by dividing them into logical parts (arrange all items on their shelves) for easier access. But in this case, you will face various challenges, and it seems that none of the solutions will be truly convenient
especially if you want to keep having each class separately (i.e. don't use nested classes)
Littering the global namespace as a whole.
all custom classes are visible in the global namespace. The user might mistakenly try to use your class.
also a large number of custom classes clogs up the autocomplete.
thus, having a large number of custom classes is incompatible with ease of development, which, as the code base of the project grows, will force the developer to abandon their use or resort to hackу workarounds.
However, this deprives the user of the benefits of using
class_name
.Perhaps custom classes are the most convenient way to have classes as separate files that need global access.
It's just convenient. For example, I have many utility classes with static methods as custom classes.
The problem is especially acute when creating plugins.
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
Implementing namespaces system could solve the ploblem.
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
I imagine it as a new keyword -
namespace
For example
a.gd:
b.gd:
in this case, access to classes A and B could be done as follows:
new_script.gd
:when trying to get class
A
from the global namespace, an error will appear:new_script.gd
:As you can see, several scripts can use one namespace, which is one of the main advantages of namespaces over custom classes
using the same class inside the same namespace should lead to error:
a.gd:
a_new.gd:
Another important advantage of namespaces is the ability to use nested namespaces.
c.gd:
new_script.gd
:If namespace is not specified (keyword
namespace
is not used), then just the global namespace is used (as usual).That is, when creating a script
d.gd
withclass_name D
, class D will be visible in any script.d.gd:
new_script.gd
:If this enhancement will not be used often, can it be worked around with a few lines of script?:
No it can't
Is there a reason why this should be core and not an add-on in the asset library?:
Implementing this feature not at the core level would hardly be a good solution.
The text was updated successfully, but these errors were encountered: