Godot: It's not possible to create a `Callable` from GDScript

Created on 22 Feb 2020  路  5Comments  路  Source: godotengine/godot

Godot version:
Commit: bf7d6de55662d7f4f9e82e69920582cf8ec55375

Issue description:
It's not possible to create a Callable from GDScript using this syntax:

var callable = Callable(self, "on_character_enter")

It returns this error message:
Screenshot from 2020-02-22 12-49-58

With the below code the error is not returned, but a loud crash happens if the scene is run.

var self_var = self
var callable = Callable(self_var, "on_character_enter")
Dumping the backtrace. Please include this when reporting the bug on https://github.com/godotengine/godot/issues
[1] /lib64/libc.so.6(+0x3c6b0) [0x7ffff77246b0] (??:0)
[2] List<Object::Connection, DefaultAllocator>::push_back(Object::Connection const&) (/home/andrea/Workspace/godot/./core/list.h:220)
[3] Object::connect(StringName const&, Callable const&, Vector<Variant> const&, unsigned int) (/home/andrea/Workspace/godot/core/object.cpp:1452 (discriminator 1))
[4] MethodBind4R<Error, StringName const&, Callable const&, Vector<Variant> const&, unsigned int>::call(Object*, Variant const**, int, Callable::CallError&) (/home/andrea/Workspace/godot/./core/method_bind.gen.inc:3325 (discriminator 20))
[5] Object::call(StringName const&, Variant const**, int, Callable::CallError&) (/home/andrea/Workspace/godot/core/object.cpp:903 (discriminator 1))
[6] Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Callable::CallError&) (/home/andrea/Workspace/godot/core/variant_call.cpp:1132 (discriminator 1))
[7] GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) (/home/andrea/Workspace/godot/modules/gdscript/gdscript_function.cpp:1105)
[8] GDScriptInstance::_ml_call_reversed(GDScript*, StringName const&, Variant const**, int) (/home/andrea/Workspace/godot/modules/gdscript/gdscript.cpp:1336)
[9] GDScriptInstance::call_multilevel_reversed(StringName const&, Variant const**, int) (/home/andrea/Workspace/godot/modules/gdscript/gdscript.cpp:1345)
[10] Node::_notification(int) (/home/andrea/Workspace/godot/scene/main/node.cpp:155)
[11] Node::_notificationv(int, bool) (/home/andrea/Workspace/godot/./scene/main/node.h:46 (discriminator 14))
[12] CanvasItem::_notificationv(int, bool) (/home/andrea/Workspace/godot/./scene/2d/canvas_item.h:166 (discriminator 3))
[13] Control::_notificationv(int, bool) (/home/andrea/Workspace/godot/./scene/gui/control.h:48 (discriminator 3))
[14] Object::notification(int, bool) (/home/andrea/Workspace/godot/core/object.cpp:915)
[15] Node::_propagate_ready() (/home/andrea/Workspace/godot/scene/main/node.cpp:200)
[16] Node::_propagate_ready() (/home/andrea/Workspace/godot/scene/main/node.cpp:189 (discriminator 2))
[17] Node::_propagate_ready() (/home/andrea/Workspace/godot/scene/main/node.cpp:189 (discriminator 2))
[18] Node::_propagate_ready() (/home/andrea/Workspace/godot/scene/main/node.cpp:189 (discriminator 2))
[19] Node::_set_tree(SceneTree*) (/home/andrea/Workspace/godot/scene/main/node.cpp:2643)
[20] SceneTree::init() (/home/andrea/Workspace/godot/scene/main/scene_tree.cpp:466)
[21] OS_X11::run() (/home/andrea/Workspace/godot/platform/x11/os_x11.cpp:3315)
[22] /home/andrea/Workspace/godot/bin/godot.x11.tools.64(main+0xfa) [0x1655840] (/home/andrea/Workspace/godot/platform/x11/godot_x11.cpp:57)
[23] /lib64/libc.so.6(__libc_start_main+0xf3) [0x7ffff770f1a3] (??:0)
[24] /home/andrea/Workspace/godot/bin/godot.x11.tools.64(_start+0x2e) [0x165568e] (??:?)
-- END OF BACKTRACE --

Related to #36393

bug gdscript

All 5 comments

I've just made a PR that allows to use the workaround without a crash, but it's still not possible to use self directly in the Callable constructor.

For me this somehow works for connecting signals from gdscript (runs without error):

signal connection_failed()
func _connected_fail():
    emit_signal("connection_failed")
func _ready():
    var self_var = self
    get_tree().connection_failed.connect(Callable(self_var, "_connected_fail"))

Edit: But I often get this or something similar: Invalid get index 'touched' (on base: 'Button (TouchButton.gd)') when I connect from another node and not from get_tree(), example:

for child in get_children():
    var self_var = self
    child.touched.connect(Callable(self_var, "_on_touch_button_touched"))

Yeah I'm having the same problem. It seems signals work for built in types, but do not work for gdscript signals

works - built in:

var t = get_tree();
var this = self;
t.network_peer_connected.connect(Callable(this, "screenshot_pressed"));

doesn't work - game_loading is a signal I setup in Game.gd autoload:

Game.game_loading.connect(Callable(this, "screenshot_pressed"));

Related to #36804

I started having a poke around at this issue as its stopping me using any gdscript.

so "Invalid get index ..." is coming from gdscript_function.cpp:696

this line fails when given a signal:
src->get_named(*index, &valid);

I step down into this method and end up in
bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const

this checks the gdscript if it has:
1) member indicies (not sure what these are)
2) constants
3) member functions

but there is NO checking for signals, so I starting adding code here assuming this is the correct place (~ line 1161 in gdscript.cpp):

`

    // FM ADDED - signal support
    {
        const Map<StringName, Vector<StringName>>::Element *E = sptr->_signals.find(p_name);
        if (E) {
            // do something here?

            return true; //index found
        }
    }

`

I am not sure what needs to be done next OR even if I have the right place/idea for solving this issue....

Was this page helpful?
0 / 5 - 0 ratings