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

Nonexistent function 'rpc' in base 'Callable' #78545

Closed
AncRad opened this issue Jun 22, 2023 · 9 comments · Fixed by #78551
Closed

Nonexistent function 'rpc' in base 'Callable' #78545

AncRad opened this issue Jun 22, 2023 · 9 comments · Fixed by #78551

Comments

@AncRad
Copy link

AncRad commented Jun 22, 2023

Godot version

v4.1.dev3.official [a67d37f]

System information

Linux 5.4.0-135-generic

Issue description

I am trying to call Callable.rpc() and Callable.rpc_id(...) method but it doesn't work with some Callable.
If I call the .bind method and then call .rpc, I get the error "Invalid call. Nonexistent function 'rpc' in base 'Callable'.", execution aborts.

Issue is that we know for sure that the .rpc method in the Callable type is always present, and we would get a different error, but definitely not this one.

Steps to reproduce

Create an empty project, a new scene with Node at the root, and attach the following script to it:

extends Node

@rpc
func foo(value = null):
	print("foo(%s)" % value)

func _ready():
	
	rpc("foo") # ok
	
	rpc("foo", 123) # ok
	
	foo.rpc() # ok
	
	foo.rpc(123) # ok
	
	foo.bind(123).rpc() # error: "invalid call. Nonexistent function 'rpc' in base 'Callable'."
	
	foo.bindv([123]).rpc() # error: "invalid call. Nonexistent function 'rpc' in base 'Callable'."
	
	foo.bind(123).unbind(1).rpc() # error: "invalid call. Nonexistent function 'rpc' in base 'Callable'."
	
	foo.bindv([123]).unbind(1).rpc() # error: "invalid call. Nonexistent function 'rpc' in base 'Callable'."
	

Run the scene and observe the error. After an error, execution is interrupted, so comment out the found line to find the next error. Run the scene again.

See all available function values for these Callables. Except Callable.get_method() but that's a whole other issue.

	for callable in [foo, foo.bind(123), foo.bindv([123]), foo.bind(123).unbind(1), foo.bindv([123]).unbind(1)]:
		print("%6s ".repeat(11) % [
			callable,
			callable.get_bound_arguments(), callable.get_bound_arguments_count(), "callable.get_method()", callable.get_object(), callable.get_object_id(),
			callable.hash(), callable.is_custom(), callable.is_null(), callable.is_standard(), callable.is_valid()
		])

Minimal reproduction project

N / A

@akien-mga
Copy link
Member

CC @KoBeWi

@dalexeev
Copy link
Member

dalexeev commented Jun 22, 2023

	foo.bind(123).unbind(1).rpc() # error: "invalid call. Nonexistent function 'rpc' in base 'Callable'."
	
	foo.bindv([123]).unbind(1).rpc() # error: "invalid call. Nonexistent function 'rpc' in base 'Callable'."

It has nothing to do with this bug, I just want to draw your attention to the fact that bind/unbind/call/rpc are applied from right to left. It's counterintuitive, but that's how things work. See #76141.

@AncRad
Copy link
Author

AncRad commented Jun 22, 2023

It's counterintuitive, but that's how things work. See #76141.

Thank you. Now I understand it.

@AThousandShips
Copy link
Member

AThousandShips commented Jun 22, 2023

The bind callables don't implement rpc unsure why, that's what's causing this

Will take a look at an approach for this

@KoBeWi
Copy link
Member

KoBeWi commented Jun 22, 2023

Callable.bind() returns a Callable though.

@AThousandShips
Copy link
Member

AThousandShips commented Jun 22, 2023

Yes but calling rpc on it calls the one on custom, which is not implemented for the bind versions

Got a working fix

@KoBeWi
Copy link
Member

KoBeWi commented Jun 22, 2023

Seems like only GDScriptRPCCallable implements rpc() (likely for security reasons). It's the Callable created with @rpc annotation; if you use bind(), you get a different Callable.
Looks like a limitation, but if we were to implement rpc() for bind() and unbind(), it'd need to work only with the RPC callable.

@AThousandShips
Copy link
Member

They will only do so, calling them elsewhere will cause the same error

@AncRad
Copy link
Author

AncRad commented Jun 22, 2023

Yes. The .rpc methods were indeed not implemented in the CallableCustomUnbind and CallableCustomBind classes. But there is another problem - the .get_method method does not work. I am creating another Issue: #78554.

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.

6 participants