Skip to content
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 an @override annotation to GDScript #10586

Closed
Sheep26 opened this issue Aug 29, 2024 · 1 comment
Closed

Add an @override annotation to GDScript #10586

Sheep26 opened this issue Aug 29, 2024 · 1 comment

Comments

@Sheep26
Copy link

Sheep26 commented Aug 29, 2024

Describe the project you are working on

I've been working on a dungeon crawler in Godot. I'm making a enchantment station where there's a base_enchantment class and signal would be linked to a builtin function inside the base_enchantment class, said function would be overridden in a child/extention of the base_enchantment class.

Describe the problem or limitation you are having in your project

The limitation is where a child can't override the arguments off a parents builtin function.

class Base_Enchantment:
	var event: Signal
	var enchantmentCost: int
	var bought: bool
	var enchantmentName: String
	var player: Player
	
	func _init(_player: Player, _event: Signal, _mutationCost: int, _mutationName: String):
		self.player = _player
		self.event = _event
		self.mutationCost = _mutationCost
		self.mutationName = _mutationName
	
	func buy():
		bought = true
		event.connect(handle)
	
	func handle(_arg0): pass

class ThornsMutation:
	extends Mutation

	func handle(enemy: Enemy, amount: float): # Error here
		enemy.take_damage(amount / 4)

Now func handle(enemy: Enemy, amount: float): doesn't match the parents version of such function, in other languages there is an @OverRide annotation which would make this code to work if added into Godot.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

@OverRide allows a class extending off another class to override a builtin function in said parent class, this allows arguments and return types to differ from parent to child.

This would overcome the limitation as it would allow the function to keep the same name allowing it to be handled from the base script while having different arguments to be handled by a signal.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

This would work like any other annotation for a function

An example of which is:

@override
func handle(enemy: Enemy, amount: float):

If this enhancement will not be used often, can it be worked around with a few lines of script?

There isn't currently isn't a work around to be able to do this in Godot 4.3.
This would be an enhancement because it would allow event systems and consoles to be built much easier.

Is there a reason why this should be core and not an add-on in the asset library?

This wouldn't work if added to the asset library because the gdscript source code would need to be edited (which I have already started doing).

@dalexeev dalexeev changed the title Add an @override annotation to gdscript (Note: I have started working on a solution in the Godot source code.) Add an @override annotation to GDScript Aug 29, 2024
@dalexeev
Copy link
Member

@override allows a class extending off another class to override a builtin function in said parent class, this allows arguments and return types to differ from parent to child.

Usually oveload has a different meaning, see:

It seems you are trying to achieve something like function overloading (#1571), but with method inheritance and without proper checks.

Arbitrarily replacing the number of arguments in a method signature when overriding a method violates the Liskov Substitution Principle. If the original method takes [N, M] arguments, then the overriding method must take [P, Q] arguments, where P <= N <= M <= Q, to preserve argument contravariance (also return type must be covariant). This is already implemented in my variadic functions PR (godotengine/godot#82808), you can do it like this:

class A:
    func f(a, b, c): pass # [3, 3]

class B extends A:
    func f(a, ...args): pass # [1, ∞]

@Sheep26 Sheep26 closed this as not planned Won't fix, can't repro, duplicate, stale Aug 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants