Skip to content

Confusing error message when signal calls callable with wrong number of arguments #1345

Description

@oddfacade

Godot version

4.1.2.stable.arch_linux

godot-cpp version

godot-4.1.2-stable

System information

Arch Linux, x86_64, 6.5.8-arch1-1

Issue description

I have a custom class, and the custom class has a method that takes a single variant argument (though the argument type doesn't seem to matter). This class has a signal that does not have any arguments/parameters. In gdscript, it is possible to produce a Callable which refers to this method, but has its arguments "bound". After doing so, it should be possible to connect this signal to the callable. With godot-cpp, this connection seems to work, but when the signal is emitted, the method is not called, and I instead get a perplexing error message:

E 0:00:02:0097   emit_signalp: Error calling from signal 'pressed' to callable: 'MyButton::_on_pressed': Method expected 0 arguments, but called with 0.
  <C++ Source>   core/object/object.cpp:1082 @ emit_signalp()

Calling the callable directly (with callv) fails silently.

Steps to reproduce

  1. Create a scene and add a MyButton node. (See minimal repro for source.)
  2. Run the game.
  3. Click the button.

Minimal reproduction project

MyButton.hpp

#pragma once

#include <godot_cpp/classes/button.hpp>
#include <godot_cpp/classes/wrapped.hpp>
#include <godot_cpp/variant/variant.hpp>

class MyButton : public godot::Button
{
	GDCLASS(MyButton, godot::Button)
public:
	void _ready() override;
	void _on_pressed(const godot::Variant& value);
protected:
	static void _bind_methods();
};

MyButton.cpp

#include "my_button.hpp"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/array.hpp>
#include <godot_cpp/variant/callable.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/variant/variant.hpp>

void MyButton::_ready()
{
	godot::Callable fn(this, "_on_pressed");

	// Bind argument array.
	{
		godot::Array args;
		godot::StringName my_value = "My Value.";
		args.append(my_value);
		// bindv because the bind template fails to specialize... maybe related but could also be user error.
		fn.bindv(args);
	}

	/* This also doesn't work. No error message; it just fails to run.
	{
		godot::Array args;
		fn.callv(args);
	}
	*/

	connect("pressed", fn);
}

void MyButton::_on_pressed(const godot::Variant& value)
{
	godot::UtilityFunctions::print("Pressed! value=", value);
}

void MyButton::_bind_methods()
{
	godot::ClassDB::bind_method(
		godot::D_METHOD("_on_pressed", "value"), &MyButton::_on_pressed);
}

register_types.cpp

Registered the usual way:

// ...
void initialize_gdextension(const godot::ModuleInitializationLevel p_level)
{
	if (p_level == godot::MODULE_INITIALIZATION_LEVEL_SCENE) {
		godot::ClassDB::register_class<MyButton>();
	}
}
// ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions