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

GDScript: Transparent funcref and _call #15486

Closed
wants to merge 1 commit into from

Conversation

poke1024
Copy link
Contributor

@poke1024 poke1024 commented Jan 8, 2018

On my 3.1 wish list for gdscript: make funcref transparent.

This PR is a proof of concept, enabling everything you'd expect:

Variant 1:

func my_print(text):
	print("my_print ", text)

func f2(f):
	f("ok!")
	
func _ready():
	f2(self.my_print)

>> my_print ok!
Variant 2:

class A:
	func f(text):
		print("my_print ", text)
		
class B:
	var work
	
func do_it(b):
	b.work("ok2!")
	
func _ready():
	var a = A.new()
	var b = B.new()
	b.work = a.f
	
	do_it(b)

>> my_print ok2!

It's still a funcref underneath, but the syntax let's you use them like first-class values.

@Zylann
Copy link
Contributor

Zylann commented Jan 8, 2018

Wasn't this also adressed in a more general way by the lambda PR? (which sadly sunk into limbo twice^^")

@poke1024
Copy link
Contributor Author

poke1024 commented Jan 8, 2018

I found the lambda PR now you mentioned it. This PR here is a much smaller change. Lambdas could be added on top of this as a special kind of FuncRef.

@Geequlim
Copy link
Contributor

Geequlim commented Jan 9, 2018

Who is the self when you call b.work in your Variant 2 ?

@HummusSamurai
Copy link
Contributor

HummusSamurai commented Jan 9, 2018

@Geequlim it's the implicit "Class" of the file (in OOP terms, much like Python).

@poke1024
Copy link
Contributor Author

poke1024 commented Jan 9, 2018

@Geequlim Yes, it's just the current class instance itself. This could be amended to allow for writing just the name of any class method (i.e. f2(my_print)), but on the other hand I think writing self.some_method is actually not so bad for indicating that a function ref is taken here.

@poke1024 poke1024 force-pushed the gdscript-funcref branch 2 times, most recently from 2d68d1f to b72d7fc Compare January 10, 2018 18:35
@poke1024 poke1024 changed the title GDScript: Nicer funcref integration GDScript: Transparent funcref and _call Jan 19, 2018
@poke1024
Copy link
Contributor Author

I've revised the underlying implementation for this one. Variant 1 and variant 2 above are unchanged. In addition, GDScript users can now access the underlying mechanism that is used for funcref calling by implementing a _call method similar to Python's __call__ method:

class Addition:
	var x
	
	func _init(p_x):
		x = p_x	
	
	func _call(p_y):
		return x + p_y

func _ready():
	var x = Addition.new(7)
	print(x(3))

> 10

This new implementation is cleaner. While the old implementation had several core changes and an opcode change, the new implementation has only one very small change to funcref (adding _call).

@akien-mga
Copy link
Member

As we discussed together in our IRC meeting on June 20 (http://godot.eska.me/irc-logs/devel/2018-06-20.log from 21:10), this should be added in Godot 3.2 following the GDScript roadmap that we agreed upon: godotengine/godot-roadmap#23.

I'll close this PR for now, but it will likely be used as a reference for implementing this feature which is planned on the roadmap (and gladly by you or with your help :)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants