-
-
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
GDScript: Add keyword to access the current class #391
Comments
What if we go full-Ruby and just make |
since self should return an instance of the class self is not accessible from most of the cases: |
You can use |
I know, but this is not consistent, for example, in an inner class, would this line create an instance of the inner class, or of the top-level class in the script? |
If only static func instance():
return load(get_script().resource_path.get_basename() + ".tscn").instance() It means that I could instance a scene from within global var player = Player.instance() See also #260. |
Should a static function be called "static" in such a case? |
The problem with The same mechanism exists in Rust, and there it is called |
The problem I have now is I can't make these functions static and move them to my Utils class (NodeUtils): func get_children_sorted_by_x(node:Control)->Array:
var children = node.get_children().duplicate()
children.sort_custom(self, '_sort_by_x')
return children
func _sort_by_x(a:Control, b:Control):
if a.rect_position.x<b.rect_position.x:
return true
return false this is because of I work-round it by creating node_utils.gd: const SortUtils = preload("res://sort_utils.gd")
static func get_children_sorted_by_x(node:Control)->Array:
var children = node.get_children().duplicate()
children.sort_custom(SortUtils, '_sort_by_x')
return children sort_utils.gd: static func _sort_by_x(a:Control, b:Control):
if a.rect_position.x<b.rect_position.x:
return true
return false this is not so convenient tho. The thing I tried to achieve is reusable |
Another use case is handling the following warning: It feels wrong to make a script require a global reference to itself or to preload itself in order to handle this warning. |
To avoid introducing keywords and breaking changes, I suggest the following:
# TypeA.gd
const TypeA := preload() # or const Self := preload()
static func create() -> TypeA:
return new()
If |
For legacy reasons AFAIK, and it can not, changing return types is breaking compatibility, see godotengine/godot#81734 Changing the return type at all should generally be considered compatibility breaking, but specifically changing to a non-compatible type is absolutely compatibility breaking (regardless of the behaviour, even if the code errors with an "invalid" type), in this case even with an error message feeding it an invalid type the error changes from a message to a compile error (as you now can't call the method at all) |
I don't understand why moving a correct error message from runtime to compile time is supposed to be a bad thing instead of a good thing. This would only lead to the developer being able to catch and fix hidden bugs, no? |
It breaks compatibility? It goes from an error (which doesn't stop things or prevent you from compiling) to a compile time error, this very obviously breaks compatibility, as the code goes from "this compiles and works but errors" to "you can't run this code" It is an improvement, but you are missing the point, this is about how that breaks compatibility 🙃 |
Another syntax I thought would make sense for the current class/script object without having to introduce a new keyword is const Self := static self
static var instance: Self = new()
static func get_instance() -> Self:
return (static self).instance # == return Self.instance == return instance
static func this_script() -> GDScript:
return static self # == return Self Could also be The difference between this and my |
For the top-level class you can use const Self := preload('this_filename.gd')
func get_this() -> Self:
return self If you don't want to depend on the filename, there's a workaround, but it's a bit iffy (tested on 4.2.1). It's working even on static functions to get the class (or inner class) at that location in the code. You just can't use it on type hints, since it can't be static var Self: GDScript = (func() -> void:).get_object() as GDScript |
I recently stumbled on this myself. @geekley thank you for the preload workaround! This feels pretty clunky, but at least it lets me still use type annotations in my code. A general way to refer to the class defined within the current file would be great. I would ideally like to be able to generically refer to the type of |
My use case for this is as follows: class_name LobbyPlayer extends Node
var me: LobbyPlayer = null
def _enter_tree():
LobbyPlayer.me = self However, this is designed to be subclassed. class_name MyPlayer extends LobbyPlayer I would use this elsewhere as a singleton; after I create one with: var my_player = MyPlayer.new()
add_child(my_player) ... then I can access it anywhere with MyPlayer.me The problem is ... it'll be typed as Not sure if there's another way to handle this? But having the ability to type as "current class" which works with subclasses would be fantastic and help with this. |
Describe the project you are working on:
gdscript
Describe the problem or limitation you are having in your project:
No access to class from the following places:
From static functions when unnamed Can't use
new()
or reference own class name in static function (fixed inmaster
) godot#27491Mostly for factory methods trying to call new
As type from within the same class when unnamed
For example:
As type from within the same class even when named
Allow scripts marked with
class_name
to use their class within the script without causing a cyclic dependency godot#25252Describe how this feature / enhancement will help you overcome this problem or limitation:
The keyword will allow access to the “static_class” Type, thus allowing access to the class type without giving it a name
Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
Factory function with this_class return type, this_class local variable and access to this_class.new:
Describe implementation detail for your proposal (in code), if possible:
This will be implemented as an additional keyword to the parser and compiler of gdscript
the keyword I used for my POC was "this_class" but I would be more than happy to hear any better suggestions.
See Commit for actual code:
ChibiDenDen/godot@2ff8c1b
If this enhancement will not be used often, can it be worked around with a few lines of script?:
The current “script” solution is to use the following expression to get the static class
load(“res://path_to_script_file.gd”)
Which is a hacky way, creates a dependency on the scripts path and looks bad
Furthermore, this is not documented and very hard for new users to find.
Is there a reason why this should be core and not an add-on in the asset library?:
This is part of gdscript syntax
The text was updated successfully, but these errors were encountered: