-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Add animation node extension #99181
Add animation node extension #99181
Conversation
AnimationNode::NodeTimeInfo node_time_info; | ||
}; | ||
|
||
class PlaybackInfoRC : public RefCounted { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same criticism of RC suffix as the last comment.
I have concerns about future compatibility breakdown if struct is implemented in GDScript. We will need to consider whether we need to rush. |
61f3ab5
to
b764317
Compare
@TokageItLab what were your concerns? I don't have any strong opinions, I though this was the cleanest of the ways to do this but I'm open to suggestions! |
b764317
to
69c6e4a
Compare
More specifically, I am concerned that I guess that GDScript struct will not be implemented as refcounted (maybe it should be one of the Variant types) in the future. In the discussion regarding the implementation of struct, there was mention of it being implemented as a similar to a typed Dictionary. NodeTimeInfo is composed of several properties and a get_remain_time() method that returns a value based on them. It is like a combination of a typed Dictionary and a Callable, but both are built-in types in the variant, not extends RefCounted class. So what you are trying to do should actually be one of the struct as one of the Variant types, not Refcounted. Even if we rush to merge this with inheriting Refcounted because we don't have struct, we will still need to replace it with struct in the future. Then it is doubtful that we can migrate Refcounted into Variant since base classes are fundamentally different. |
@TokageItLab are you suggesting waiting until structs are implemented? That might not be coming to the engine any time soon, and I wouldn't mind refactoring this code once it is available. Another idea would be to do what the AudioStreamPlayback _mix method does and use pointers instead. That way it wouldn't be exposed to GDScript, and would be easy to convert to using structs once avaiable. |
Right, that's the direction that should be most recommended. Insteads, you can use the custom module.
Since the PR is already there #82198, you could help with that work and feedback to support it. Then, it is fine to include that PR before this PR and mentions " If we are in a hurry to implement something, we will need to expose NodeTimeInfo as some Variant type instead of RefCounted. RefCounted is referential, so compatibility will be hard broken in the future if there are scripts that reference the same NodeTimeInfo. From a performance point of view, we should avoid this but you can use Dictionary in some cases, but there is a problem that the get_remain() method is not available. Or you can use a encoded PackedByteArray, or a Callable object to exchange information. Strictly, these are also referential, but since they are Variant types, if a reference is broken, only the Initial value is passed, allowing for relatively safe compatibility breaking and migration. |
69c6e4a
to
389180c
Compare
Hi @TokageItLab! I updated this PR before having read your comment! You make very valid points, and I think you might prefer these last changes I pushed, I'm no longer using ref counted objects and instead encoding the return value on a As for the struct PR, I do like the idea you suggested. I'm not familiar with the struct changes, but I can least help with feedback. Nonetheless, if possible I'd like to submit these changes first, and later refactor the return value to use a struct instead. |
PackedFloat32Array looks fine than RefCounted. This is not a blocking opinion of this PR in particular, but I have two more concerns (as above your comment, probably do you work in progress?)
|
8baefdb
to
8c3c569
Compare
@TokageItLab agree with all your comments, just updated the PR to include them. |
ea20df2
to
5a56fe1
Compare
The documentation changed and requires to be generated with --doctool. |
64e39ed
to
a339573
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, those API should be almost identical to the virtual function of the AnimationNode class provided in cpp, except for the struct format.
We don't know what struct will be in the future, but it is probably a Variant type, so it should be able to provide a migration path.
a339573
to
b808b97
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For posterity: there was discussion on RocketChat & in the most recent GDExtension meeting on the potential to only use *Extension classes when necessary; that is, if they're exposing functions/methods that could not be utilized with standard scripting (eg: anything with pointers). In this case, the virtual functions could be added to AnimationRootNode
instead, removing the need for AnimationNodeExtension
entirely
However, as no "official" stance was taken, this is perfectly fine to be merged as-is
I'll defer to the animation team for this one, I have no strong opinion on this either (@TokageItLab @fire @lyuma ) |
This probably needs it's own proposal/discussion at this point, but I personally think the "official stance" (if/when we have one) should only be a recommendation. Like, we recommend using |
I am not against replacing AnimationNode with this. Since the AnimationNodeExtention does not add any additional properties to the AnimationNode, so replacing the AnimationNode with it is not expected to cause any significant loss, at least from a memory usage perspective. However, if we replace AnimationNode with this, it breaks compatibility with the old As @reduz explained earlier, GDVIRTUAL declarations can affect the performance of the process, but I think it should not be a problem as long as the registration with GDREGISTER_VIRTUAL_CLASS is used. Well, I believe it is reliable and safe to have @reduz take a look at this PR once. |
class AnimationNodeExtension : public AnimationRootNode { | ||
GDCLASS(AnimationNodeExtension, AnimationRootNode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related to the comment above, AnimationNodeExtention should replace AnimationNode, not AnimationRootNode.
The AnimationRootNode does not need an input port and can be placed in a StateMachine. If not, it is because that would imply that an input port is required.
I guess you want it to be the AnimationRootNode for placing it in the BlendSpace or StateMachine purposes, but if you replace it and replace the AnimationNode with the AnimationNodeExtention, the AnimationRootNode will extend it, thus solving this classification problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, was this comment overlooked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I think if it is an Extension, we will need two (or three) Extensions, AnimationRootNodeExtension and AnimationNodeSyncExtension (and AnimationNodeExtention). If it is not an Extension by replacement, then only the AnimationNode needs to be replaced. cc @GuilhermeGSousa
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Completely missed this comment, my bad @TokageItLab. I agree with you, do you want me to make PRs for those other extension nodes as well?
b808b97
to
d2f4f26
Compare
d2f4f26
to
d7462d2
Compare
Just updated with the latest comments. I do like having extension specific logic be separated in an extension class, and avoid having experimental stuff mixed in with core classes like |
Thanks! |
Thank you @Repiteo ! How does the workflow go for godot-cpp, should I open a PR there? |
The added virtual method in func _process(playback_info: PackedFloat64Array, test_only: bool) -> PackedFloat32Array is in conflict with the method of same name in func _process(time: float, seek: bool, is_external_seeking: bool, test_only: bool) -> float You added a deprecation warning in the docs. However, in GDExtension, such deprecation can currently not be communicated in This breaks godot-rust codegen, but likely affects other bindings as well. Multiple methods of the same name in the same class aren't occuring anywhere else, to my knowledge. Is it not possible to register |
Dang, I'm surprised a conflict like this wasn't caught in the CI |
In C++, having multiple methods of the same name is generally not a problem, and I don't know if there are CI checks beyond that (especially for virtual functions). But I was also wondering what might be a good way to detect this 🤔 |
How could I help fix this, would @TokageItLab 's PR do it? Should I rename this method? |
No, that one changes a different thing (the base class).
Yes, I think that would fix the problem 🙂 |
Here goes! |
The documentation for this new node makes no mention of what the |
TODO:
Bugsquad edit:
Fixes: godotengine/godot-proposals#11123