Open Meorge opened 4 weeks ago
I was going to make a proposal like this eventually. It would benefit many places, although I do think that the example provided in this proposal does not showcase this well enough. Both Node2D and Control already inherit CanvasItem so a lot of their internals are actually quite similar.
What's a more powerful use case of built-in Traits is for classes with entirely different inheritance. AudioStreamPlayer & co., AnimatedSprite2D & AnimatedSprite3D, Label & Label3D, some InputEvent resources, etc. These classes share many aspects. Even though some can't be fully integrated into a trait (Vector2 vs. Vector3 properties), the potential is there.
I do think that this is an issue that should be first solved internally. The existing codebase has almost concept of multiple inheritance, so code is duplicated all over. An effort was made in the past to unify the audio stream players' logic, but it isn't quite ideal because the calling functions are still, inevitably, duplicated.
Funnily enough, while frustration with Node2D and Control were what motivated me to actually sit down and write this proposal, I think the AudioStreamPlayer collection of nodes is what I've run into this problem more with before!
I can start putting together a list of nodes grouped by shared behaviors on this proposal. That way, if/when we have some sort of API for making native classes compatible with traits, we have some traits to implement.
Describe the project you are working on
Various games and the Godot engine
Describe the problem or limitation you are having in your project
There have been times I've wanted to access properties or methods of an object that could be one of a few different types, where the properties/methods aren't all covered by a single ancestor class.
The
Node2D.position
andControl.position
properties are examples that come to mind for me; it would be nice to be able to access and modify theposition
of a node whether it inherits from either of those two base classes.Describe the feature / enhancement and how it helps to overcome the problem or limitation
Once GDScript traits have been merged, create an API that allows native/C++ classes to be marked as implementing traits. Then, particular traits could be defined and applied to existing classes.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The
Node2D
andControl
classes could implement a traitPositionable2D
. If the classes were written in GDScript, they might look like so:Then, a GDScript user could do something like the following:
I'm not entirely certain how the C++ API for assigning traits to classes would work at this point. If this idea gains traction, we can discuss that in more detail.
Possible groupings
position
)text
)play()
,stop()
,stream
,volume_db
, etc)play()
,stop()
,animation
, etc)If this enhancement will not be used often, can it be worked around with a few lines of script?
Frequently, yes. For my example above, I think the same thing could be accomplished with multiple
is
checks:This exact approach might fall apart for more complex operations, and if the user wants to ensure static typing, since
some_node
's type can't be defined as a union of eitherNode2D
orControl
.Is there a reason why this should be core and not an add-on in the asset library?
I don't believe this would be possible to implement as an addon.