General MixinScript improvement discussion #150
Replies: 4 comments 3 replies
-
This problem is described in godotengine/godot#8546. This is in fact one of the reasons why I renamed
At the very least, I think it makes sense to emit a warning if there are multiple callbacks defined for the same callback. The "squashed" state you mention is what describes this behavior. Imagine that you defined the same method in multiple files and mixed them together. In text-based languages, how would you resolve the name conflict? You would either throw a compilation error/warning, or choose to pick the first method included. Of course, all of this could be further clarified and documented, regardless of future improvements.
I think this is already possible if I understand correctly: extends Node2D
func _ready():
var creeper = preload("res://creeper.tscn").instance()
if Monster in creeper.script.mixins:
print("It is a monster!")
if Player in creeper.script.mixins:
print("It is a player!") Test project: |
Beta Was this translation helpful? Give feedback.
-
I did a bit of more in depth research regarding notifications. Only specific nodes receive the notifications (not just the 1st one)
So it doesn't get called in the first one but rather in the first one that has one of those callbacks defined. Which would be quite difficult to track. Properties or methods should emit a warning when shadowedI believe all other properties or methods are not that important even when shadowed by other scripts. They do need to emit a warning, however. This would tell the user about the status or functionality of the script. This should be a setting in Project Settings somewhere near GDScript warnings. Forced calls for
|
Beta Was this translation helpful? Give feedback.
-
I have tried using
Note that I think that
See my point 2 above. You can't still manually call other readies from the owner and you can only call the top level ready. Tihs means you would need to make a specific ready for each Mixin and call them from the top level call but you cannot guarantee is going to be the first one.
I agree :)
Yes works perfectly. In fact I think it also works with GDNative, JavaScript module, Nim addon, and possibly Python addon as they all use the same
I think it has to be better thought out. See end of this comment for additional ideas.
Yes completely agree.
I believe the system should actually not enforce Mixin. See below. Mixin inter-compatibility should be handled by the MixinScript rather than by the userUsers should ideally put any scripts together and just work (in dream land :)) ) Practically this means MixinScript should abstract some of the complexities of Mixins and allow users to spend more time scripting. Only add scripts that extend nothing or Mixin that's it.I think the Mixin requirement should be optional to gain access to the rest of the scripts. It should only be used by scripts that act more like controllers for the etire MixinScript. Additionally base level class should be set for mixin scripts to the parent node class in order to get local autocomplete from the parent into each Mixins. Haven't figured out how to do this yet. All nodes should be force readiedForce readying works well because it already reduces much of the complexities and works out of the box.
Multi-superIn Godot 4 they implemented something called super (as you have said). I think giving access to shadowed calls may create more powerful scripting. In addition to the squashed For example With forced calls
|
Beta Was this translation helpful? Give feedback.
-
@Xrayez Give Unity's Component System a look, it might help you build this MixinScript. |
Beta Was this translation helpful? Give feedback.
-
Mixin Script Observations
I took a bit of time to play around with MixinScripts. I didn't do anything complex just basic stuff trying to test out various interactions.
Here are some observations:
_init()
runs for all mixins but all other default functions appear to only run for the top most Mixin_init
can only initialize local variables before node is ready while_ready
will only run for the top Mixin and I couldn't find a way to manually call the_ready
of other Mixins eitherowner
provides all the members of all the scripts in the MixinScript but only in a mixed up "squashed" stateA few ideas that could improve the MixinScript system
I think MixinScript has a lot of potential but I think it can be improved on to make it a more robust and usable system overall. The idea of combining various scripts into one can be very powerful. Is the closest GDScript had to multiple inheritance.
1. Allow access to any Mixin from any Mixin in the same MixinScript
Expose the MixinScript
mixins
property in C++ is listed asVector<Ref<Script> > mixins;
inMixinScript.h
as a Mixin classget_mixins()
ormixins
without the ability to set it. This would allow for some crazy next level meta interaction between Mixins (at your own risk) including the ability to call functions that are not "squashed" like calling _ready or _input from manually as a kind of super.EDIT: So I have played around and I found that there is a way to access all mixins from everywhere. The owner is actually the parent node (simialr to get_parent()) and doing
owner.script
gives you full access to the MixinScript but all the scripts are Mixins. Doesn't seem to recognize the members though but source_code shows appropriate source.2. Add a global class_name list that can be checked against or an internal trait system or both.
Class list system
MixinScript would collect all the scripts with a global
class_name
in an internal array which can be checked against externally to see if that MixinScript belongs to a specific class (kinda like a multiple inheritance system)For example say you have two scripts with
class_name Monster
andclass_name Skeleton
added as Mixins to a MixinScript attached to a node calledenemy
. The code to check if thisenemy
is aSkeleton
would look something like thisif Skeleton in $enemy.script.class_list:
do stuff. I have tested this in GDScript and it allows creating a list ofclass_name
references so it should also work internally as well.Trait system
Mixin class would have a built in variable
trait
pre-set to "" empty string. All you would need to do is change that trait to something meaningful and the MixinScript would collect that as atraits
variable which can be checked againstif "monster" in ms.script.traits
similar to how you would check in a multiple inheritance system..
I also have some other wacky ideas but I think that's it for now.
Beta Was this translation helpful? Give feedback.
All reactions