Merge pull request #53313 from KoBeWi/debinded_konnekt
This commit is contained in:
commit
42312f066b
11 changed files with 184 additions and 60 deletions
|
@ -51,6 +51,9 @@ public:
|
|||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const;
|
||||
virtual const Callable *get_base_comparator() const;
|
||||
|
||||
Callable get_callable() { return callable; }
|
||||
Vector<Variant> get_binds() { return binds; }
|
||||
|
||||
CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds);
|
||||
virtual ~CallableCustomBind();
|
||||
};
|
||||
|
@ -72,6 +75,9 @@ public:
|
|||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const;
|
||||
virtual const Callable *get_base_comparator() const;
|
||||
|
||||
Callable get_callable() { return callable; }
|
||||
int get_unbinds() { return argcount; }
|
||||
|
||||
CallableCustomUnbind(const Callable &p_callable, int p_argcount);
|
||||
virtual ~CallableCustomUnbind();
|
||||
};
|
||||
|
|
|
@ -59,6 +59,13 @@
|
|||
Returns the path to the node that owns the method connected to the signal at [code]idx[/code], relative to the root node.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_unbinds" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="idx" type="int" />
|
||||
<description>
|
||||
Returns the number of unbound parameters for the signal at [code]idx[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_node_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "plugins/script_editor_plugin.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/gui/spin_box.h"
|
||||
|
||||
static Node *_find_first_script(Node *p_root, Node *p_node) {
|
||||
if (p_node != p_root && p_node->get_owner() != p_root) {
|
||||
|
@ -164,6 +165,20 @@ void ConnectDialog::_tree_node_selected() {
|
|||
_update_ok_enabled();
|
||||
}
|
||||
|
||||
void ConnectDialog::_unbind_count_changed(double p_count) {
|
||||
for (Control *control : bind_controls) {
|
||||
BaseButton *b = Object::cast_to<BaseButton>(control);
|
||||
if (b) {
|
||||
b->set_disabled(p_count > 0);
|
||||
}
|
||||
|
||||
EditorInspector *e = Object::cast_to<EditorInspector>(control);
|
||||
if (e) {
|
||||
e->set_read_only(p_count > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a new parameter bind to connection.
|
||||
*/
|
||||
|
@ -305,6 +320,10 @@ void ConnectDialog::set_dst_method(const StringName &p_method) {
|
|||
dst_method->set_text(p_method);
|
||||
}
|
||||
|
||||
int ConnectDialog::get_unbinds() const {
|
||||
return int(unbind_count->get_value());
|
||||
}
|
||||
|
||||
Vector<Variant> ConnectDialog::get_binds() const {
|
||||
return cdbinds->params;
|
||||
}
|
||||
|
@ -350,6 +369,8 @@ void ConnectDialog::init(ConnectionData c, bool bEdit) {
|
|||
|
||||
deferred->set_pressed(bDeferred);
|
||||
oneshot->set_pressed(bOneshot);
|
||||
unbind_count->set_value(c.unbinds);
|
||||
_unbind_count_changed(c.unbinds);
|
||||
|
||||
cdbinds->params.clear();
|
||||
cdbinds->params = c.binds;
|
||||
|
@ -449,23 +470,33 @@ ConnectDialog::ConnectDialog() {
|
|||
type_list->add_item("Transform3D", Variant::TRANSFORM3D);
|
||||
type_list->add_item("Color", Variant::COLOR);
|
||||
type_list->select(0);
|
||||
bind_controls.push_back(type_list);
|
||||
|
||||
Button *add_bind = memnew(Button);
|
||||
add_bind->set_text(TTR("Add"));
|
||||
add_bind_hb->add_child(add_bind);
|
||||
add_bind->connect("pressed", callable_mp(this, &ConnectDialog::_add_bind));
|
||||
bind_controls.push_back(add_bind);
|
||||
|
||||
Button *del_bind = memnew(Button);
|
||||
del_bind->set_text(TTR("Remove"));
|
||||
add_bind_hb->add_child(del_bind);
|
||||
del_bind->connect("pressed", callable_mp(this, &ConnectDialog::_remove_bind));
|
||||
bind_controls.push_back(del_bind);
|
||||
|
||||
vbc_right->add_margin_child(TTR("Add Extra Call Argument:"), add_bind_hb);
|
||||
|
||||
bind_editor = memnew(EditorInspector);
|
||||
bind_controls.push_back(bind_editor);
|
||||
|
||||
vbc_right->add_margin_child(TTR("Extra Call Arguments:"), bind_editor, true);
|
||||
|
||||
unbind_count = memnew(SpinBox);
|
||||
unbind_count->set_tooltip(TTR("Allows to drop arguments sent by signal emitter."));
|
||||
unbind_count->connect("value_changed", callable_mp(this, &ConnectDialog::_unbind_count_changed));
|
||||
|
||||
vbc_right->add_margin_child(TTR("Unbind Signal Arguments:"), unbind_count);
|
||||
|
||||
HBoxContainer *dstm_hb = memnew(HBoxContainer);
|
||||
vbc_left->add_margin_child(TTR("Receiver Method:"), dstm_hb);
|
||||
|
||||
|
@ -541,26 +572,29 @@ void ConnectionsDock::_make_or_edit_connection() {
|
|||
Node *target = selectedNode->get_node(dst_path);
|
||||
ERR_FAIL_COND(!target);
|
||||
|
||||
ConnectDialog::ConnectionData cToMake;
|
||||
cToMake.source = connect_dialog->get_source();
|
||||
cToMake.target = target;
|
||||
cToMake.signal = connect_dialog->get_signal_name();
|
||||
cToMake.method = connect_dialog->get_dst_method_name();
|
||||
cToMake.binds = connect_dialog->get_binds();
|
||||
ConnectDialog::ConnectionData connection;
|
||||
connection.source = connect_dialog->get_source();
|
||||
connection.target = target;
|
||||
connection.signal = connect_dialog->get_signal_name();
|
||||
connection.method = connect_dialog->get_dst_method_name();
|
||||
connection.unbinds = connect_dialog->get_unbinds();
|
||||
if (connection.unbinds == 0) {
|
||||
connection.binds = connect_dialog->get_binds();
|
||||
}
|
||||
bool defer = connect_dialog->get_deferred();
|
||||
bool oshot = connect_dialog->get_oneshot();
|
||||
cToMake.flags = CONNECT_PERSIST | (defer ? CONNECT_DEFERRED : 0) | (oshot ? CONNECT_ONESHOT : 0);
|
||||
connection.flags = CONNECT_PERSIST | (defer ? CONNECT_DEFERRED : 0) | (oshot ? CONNECT_ONESHOT : 0);
|
||||
|
||||
// Conditions to add function: must have a script and must not have the method already
|
||||
// (in the class, the script itself, or inherited).
|
||||
bool add_script_function = false;
|
||||
Ref<Script> script = target->get_script();
|
||||
if (!target->get_script().is_null() && !ClassDB::has_method(target->get_class(), cToMake.method)) {
|
||||
if (!target->get_script().is_null() && !ClassDB::has_method(target->get_class(), connection.method)) {
|
||||
// There is a chance that the method is inherited from another script.
|
||||
bool found_inherited_function = false;
|
||||
Ref<Script> inherited_script = script->get_base_script();
|
||||
while (!inherited_script.is_null()) {
|
||||
int line = inherited_script->get_language()->find_function(cToMake.method, inherited_script->get_source_code());
|
||||
int line = inherited_script->get_language()->find_function(connection.method, inherited_script->get_source_code());
|
||||
if (line != -1) {
|
||||
found_inherited_function = true;
|
||||
break;
|
||||
|
@ -575,23 +609,23 @@ void ConnectionsDock::_make_or_edit_connection() {
|
|||
if (add_script_function) {
|
||||
// Pick up args here before "it" is deleted by update_tree.
|
||||
script_function_args = it->get_metadata(0).operator Dictionary()["args"];
|
||||
for (int i = 0; i < cToMake.binds.size(); i++) {
|
||||
script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(cToMake.binds[i].get_type()));
|
||||
for (int i = 0; i < connection.binds.size(); i++) {
|
||||
script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(connection.binds[i].get_type()));
|
||||
}
|
||||
}
|
||||
|
||||
if (connect_dialog->is_editing()) {
|
||||
_disconnect(*it);
|
||||
_connect(cToMake);
|
||||
_connect(connection);
|
||||
} else {
|
||||
_connect(cToMake);
|
||||
_connect(connection);
|
||||
}
|
||||
|
||||
// IMPORTANT NOTE: _disconnect and _connect cause an update_tree, which will delete the object "it" is pointing to.
|
||||
it = nullptr;
|
||||
|
||||
if (add_script_function) {
|
||||
editor->emit_signal(SNAME("script_add_function_request"), target, cToMake.method, script_function_args);
|
||||
editor->emit_signal(SNAME("script_add_function_request"), target, connection.method, script_function_args);
|
||||
hide();
|
||||
}
|
||||
|
||||
|
@ -601,20 +635,18 @@ void ConnectionsDock::_make_or_edit_connection() {
|
|||
/*
|
||||
* Creates single connection w/ undo-redo functionality.
|
||||
*/
|
||||
void ConnectionsDock::_connect(ConnectDialog::ConnectionData cToMake) {
|
||||
Node *source = static_cast<Node *>(cToMake.source);
|
||||
Node *target = static_cast<Node *>(cToMake.target);
|
||||
void ConnectionsDock::_connect(ConnectDialog::ConnectionData p_connection) {
|
||||
Node *source = Object::cast_to<Node>(p_connection.source);
|
||||
Node *target = Object::cast_to<Node>(p_connection.target);
|
||||
|
||||
if (!source || !target) {
|
||||
return;
|
||||
}
|
||||
|
||||
undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(cToMake.signal), String(cToMake.method)));
|
||||
|
||||
Callable c(target, cToMake.method);
|
||||
|
||||
undo_redo->add_do_method(source, "connect", cToMake.signal, c, cToMake.binds, cToMake.flags);
|
||||
undo_redo->add_undo_method(source, "disconnect", cToMake.signal, c);
|
||||
Callable callable = p_connection.get_callable();
|
||||
undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(p_connection.signal), String(p_connection.method)));
|
||||
undo_redo->add_do_method(source, "connect", p_connection.signal, callable, varray(), p_connection.flags);
|
||||
undo_redo->add_undo_method(source, "disconnect", p_connection.signal, callable);
|
||||
undo_redo->add_do_method(this, "update_tree");
|
||||
undo_redo->add_undo_method(this, "update_tree");
|
||||
undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
|
||||
|
@ -634,8 +666,9 @@ void ConnectionsDock::_disconnect(TreeItem &item) {
|
|||
|
||||
undo_redo->create_action(vformat(TTR("Disconnect '%s' from '%s'"), c.signal, c.method));
|
||||
|
||||
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
|
||||
undo_redo->add_undo_method(selectedNode, "connect", c.signal, Callable(c.target, c.method), c.binds, c.flags);
|
||||
Callable callable = c.get_callable();
|
||||
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, callable);
|
||||
undo_redo->add_undo_method(selectedNode, "connect", c.signal, callable, c.binds, c.flags);
|
||||
undo_redo->add_do_method(this, "update_tree");
|
||||
undo_redo->add_undo_method(this, "update_tree");
|
||||
undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); // To force redraw of scene tree.
|
||||
|
@ -662,8 +695,8 @@ void ConnectionsDock::_disconnect_all() {
|
|||
while (child) {
|
||||
Connection cd = child->get_metadata(0);
|
||||
ConnectDialog::ConnectionData c = cd;
|
||||
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
|
||||
undo_redo->add_undo_method(selectedNode, "connect", c.signal, Callable(c.target, c.method), c.binds, c.flags);
|
||||
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, c.get_callable());
|
||||
undo_redo->add_undo_method(selectedNode, "connect", c.signal, c.get_callable(), c.binds, c.flags);
|
||||
child = child->get_next();
|
||||
}
|
||||
|
||||
|
@ -752,8 +785,8 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
|
|||
* Open connection dialog with Connection data to EDIT an existing connection.
|
||||
*/
|
||||
void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToEdit) {
|
||||
Node *src = static_cast<Node *>(cToEdit.source);
|
||||
Node *dst = static_cast<Node *>(cToEdit.target);
|
||||
Node *src = Object::cast_to<Node>(cToEdit.source);
|
||||
Node *dst = Object::cast_to<Node>(cToEdit.target);
|
||||
|
||||
if (src && dst) {
|
||||
const String &signalname = cToEdit.signal;
|
||||
|
@ -1044,7 +1077,9 @@ void ConnectionsDock::update_tree() {
|
|||
if (c.flags & CONNECT_ONESHOT) {
|
||||
path += " (oneshot)";
|
||||
}
|
||||
if (c.binds.size()) {
|
||||
if (c.unbinds > 0) {
|
||||
path += " unbinds(" + itos(c.unbinds) + ")";
|
||||
} else if (!c.binds.is_empty()) {
|
||||
path += " binds(";
|
||||
for (int i = 0; i < c.binds.size(); i++) {
|
||||
if (i > 0) {
|
||||
|
@ -1057,8 +1092,7 @@ void ConnectionsDock::update_tree() {
|
|||
|
||||
TreeItem *connection_item = tree->create_item(signal_item);
|
||||
connection_item->set_text(0, path);
|
||||
Connection cd = c;
|
||||
connection_item->set_metadata(0, cd);
|
||||
connection_item->set_metadata(0, cn);
|
||||
connection_item->set_icon(0, get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
class PopupMenu;
|
||||
class ConnectDialogBinds;
|
||||
class SpinBox;
|
||||
|
||||
class ConnectDialog : public ConfirmationDialog {
|
||||
GDCLASS(ConnectDialog, ConfirmationDialog);
|
||||
|
@ -59,25 +60,45 @@ public:
|
|||
StringName signal;
|
||||
StringName method;
|
||||
uint32_t flags = 0;
|
||||
int unbinds = 0;
|
||||
Vector<Variant> binds;
|
||||
|
||||
ConnectionData() {
|
||||
}
|
||||
ConnectionData() {}
|
||||
|
||||
ConnectionData(const Connection &p_connection) {
|
||||
source = Object::cast_to<Node>(p_connection.signal.get_object());
|
||||
signal = p_connection.signal.get_name();
|
||||
target = Object::cast_to<Node>(p_connection.callable.get_object());
|
||||
method = p_connection.callable.get_method();
|
||||
flags = p_connection.flags;
|
||||
binds = p_connection.binds;
|
||||
|
||||
Callable base_callable;
|
||||
if (p_connection.callable.is_custom()) {
|
||||
CallableCustomBind *ccb = dynamic_cast<CallableCustomBind *>(p_connection.callable.get_custom());
|
||||
if (ccb) {
|
||||
binds = ccb->get_binds();
|
||||
base_callable = ccb->get_callable();
|
||||
}
|
||||
|
||||
CallableCustomUnbind *ccu = dynamic_cast<CallableCustomUnbind *>(p_connection.callable.get_custom());
|
||||
if (ccu) {
|
||||
unbinds = ccu->get_unbinds();
|
||||
base_callable = ccu->get_callable();
|
||||
}
|
||||
} else {
|
||||
base_callable = p_connection.callable;
|
||||
}
|
||||
method = base_callable.get_method();
|
||||
}
|
||||
operator Connection() {
|
||||
Connection c;
|
||||
c.signal = ::Signal(source, signal);
|
||||
c.callable = Callable(target, method);
|
||||
c.flags = flags;
|
||||
c.binds = binds;
|
||||
return c;
|
||||
|
||||
Callable get_callable() {
|
||||
if (unbinds > 0) {
|
||||
return Callable(target, method).unbind(unbinds);
|
||||
} else if (!binds.is_empty()) {
|
||||
const Variant *args = binds.ptr();
|
||||
return Callable(target, method).bind(&args, binds.size());
|
||||
} else {
|
||||
return Callable(target, method);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -94,11 +115,13 @@ private:
|
|||
|
||||
SceneTreeEditor *tree;
|
||||
AcceptDialog *error;
|
||||
SpinBox *unbind_count;
|
||||
EditorInspector *bind_editor;
|
||||
OptionButton *type_list;
|
||||
CheckBox *deferred;
|
||||
CheckBox *oneshot;
|
||||
CheckButton *advanced;
|
||||
Vector<Control *> bind_controls;
|
||||
|
||||
Label *error_label;
|
||||
|
||||
|
@ -107,6 +130,7 @@ private:
|
|||
void _item_activated();
|
||||
void _text_submitted(const String &_text);
|
||||
void _tree_node_selected();
|
||||
void _unbind_count_changed(double p_count);
|
||||
void _add_bind();
|
||||
void _remove_bind();
|
||||
void _advanced_pressed();
|
||||
|
@ -123,6 +147,7 @@ public:
|
|||
void set_dst_node(Node *p_node);
|
||||
StringName get_dst_method_name() const;
|
||||
void set_dst_method(const StringName &p_method);
|
||||
int get_unbinds() const;
|
||||
Vector<Variant> get_binds() const;
|
||||
|
||||
bool get_deferred() const;
|
||||
|
@ -176,7 +201,7 @@ class ConnectionsDock : public VBoxContainer {
|
|||
void _filter_changed(const String &p_text);
|
||||
|
||||
void _make_or_edit_connection();
|
||||
void _connect(ConnectDialog::ConnectionData cToMake);
|
||||
void _connect(ConnectDialog::ConnectionData p_connection);
|
||||
void _disconnect(TreeItem &item);
|
||||
void _disconnect_all();
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#define INSPECTOR_DOCK_H
|
||||
|
||||
#include "editor/animation_track_editor.h"
|
||||
#include "editor/connections_dialog.h"
|
||||
#include "editor/create_dialog.h"
|
||||
#include "editor/editor_data.h"
|
||||
#include "editor/editor_inspector.h"
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "node_dock.h"
|
||||
|
||||
#include "connections_dialog.h"
|
||||
#include "editor_node.h"
|
||||
#include "editor_scale.h"
|
||||
|
||||
|
|
|
@ -31,9 +31,10 @@
|
|||
#ifndef NODE_DOCK_H
|
||||
#define NODE_DOCK_H
|
||||
|
||||
#include "connections_dialog.h"
|
||||
#include "groups_editor.h"
|
||||
|
||||
class ConnectionsDock;
|
||||
|
||||
class NodeDock : public VBoxContainer {
|
||||
GDCLASS(NodeDock, VBoxContainer);
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#ifndef SCENE_TREE_DOCK_H
|
||||
#define SCENE_TREE_DOCK_H
|
||||
|
||||
#include "editor/connections_dialog.h"
|
||||
#include "editor/create_dialog.h"
|
||||
#include "editor/editor_data.h"
|
||||
#include "editor/groups_editor.h"
|
||||
|
|
|
@ -353,15 +353,23 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
|||
continue;
|
||||
}
|
||||
|
||||
Vector<Variant> binds;
|
||||
if (c.binds.size()) {
|
||||
binds.resize(c.binds.size());
|
||||
for (int j = 0; j < c.binds.size(); j++) {
|
||||
binds.write[j] = props[c.binds[j]];
|
||||
Callable callable(cto, snames[c.method]);
|
||||
if (c.unbinds > 0) {
|
||||
callable = callable.unbind(c.unbinds);
|
||||
} else if (!c.binds.is_empty()) {
|
||||
Vector<Variant> binds;
|
||||
if (c.binds.size()) {
|
||||
binds.resize(c.binds.size());
|
||||
for (int j = 0; j < c.binds.size(); j++) {
|
||||
binds.write[j] = props[c.binds[j]];
|
||||
}
|
||||
}
|
||||
|
||||
const Variant *args = binds.ptr();
|
||||
callable = callable.bind(&args, binds.size());
|
||||
}
|
||||
|
||||
cfrom->connect(snames[c.signal], Callable(cto, snames[c.method]), binds, CONNECT_PERSIST | c.flags);
|
||||
cfrom->connect(snames[c.signal], callable, varray(), CONNECT_PERSIST | c.flags);
|
||||
}
|
||||
|
||||
//Node *s = ret_nodes[0];
|
||||
|
@ -652,6 +660,26 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
|||
continue;
|
||||
}
|
||||
|
||||
Vector<Variant> binds;
|
||||
int unbinds = 0;
|
||||
Callable base_callable;
|
||||
|
||||
if (c.callable.is_custom()) {
|
||||
CallableCustomBind *ccb = dynamic_cast<CallableCustomBind *>(c.callable.get_custom());
|
||||
if (ccb) {
|
||||
binds = ccb->get_binds();
|
||||
base_callable = ccb->get_callable();
|
||||
}
|
||||
|
||||
CallableCustomUnbind *ccu = dynamic_cast<CallableCustomUnbind *>(c.callable.get_custom());
|
||||
if (ccu) {
|
||||
unbinds = ccu->get_unbinds();
|
||||
base_callable = ccu->get_callable();
|
||||
}
|
||||
} else {
|
||||
base_callable = c.callable;
|
||||
}
|
||||
|
||||
//find if this connection already exists
|
||||
Node *common_parent = target->find_common_parent_with(p_node);
|
||||
|
||||
|
@ -677,7 +705,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
|||
NodePath signal_from = common_parent->get_path_to(p_node);
|
||||
NodePath signal_to = common_parent->get_path_to(target);
|
||||
|
||||
if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, c.callable.get_method())) {
|
||||
if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, base_callable.get_method())) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
|
@ -708,7 +736,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
|||
|
||||
if (from_node >= 0 && to_node >= 0) {
|
||||
//this one has state for this node, save
|
||||
if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) {
|
||||
if (state->is_connection(from_node, c.signal.get_name(), to_node, base_callable.get_method())) {
|
||||
exists2 = true;
|
||||
break;
|
||||
}
|
||||
|
@ -726,7 +754,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
|||
|
||||
if (from_node >= 0 && to_node >= 0) {
|
||||
//this one has state for this node, save
|
||||
if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) {
|
||||
if (state->is_connection(from_node, c.signal.get_name(), to_node, base_callable.get_method())) {
|
||||
exists2 = true;
|
||||
break;
|
||||
}
|
||||
|
@ -773,12 +801,16 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
|||
ConnectionData cd;
|
||||
cd.from = src_id;
|
||||
cd.to = target_id;
|
||||
cd.method = _nm_get_string(c.callable.get_method(), name_map);
|
||||
cd.method = _nm_get_string(base_callable.get_method(), name_map);
|
||||
cd.signal = _nm_get_string(c.signal.get_name(), name_map);
|
||||
cd.flags = c.flags;
|
||||
for (int i = 0; i < c.binds.size(); i++) {
|
||||
cd.unbinds = unbinds;
|
||||
for (int i = 0; i < c.binds.size(); i++) { // TODO: This could be removed now.
|
||||
cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map));
|
||||
}
|
||||
for (int i = 0; i < binds.size(); i++) {
|
||||
cd.binds.push_back(_vm_get_variant(binds[i], variant_map));
|
||||
}
|
||||
connections.push_back(cd);
|
||||
}
|
||||
}
|
||||
|
@ -1390,6 +1422,11 @@ int SceneState::get_connection_flags(int p_idx) const {
|
|||
return connections[p_idx].flags;
|
||||
}
|
||||
|
||||
int SceneState::get_connection_unbinds(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, connections.size(), -1);
|
||||
return connections[p_idx].unbinds;
|
||||
}
|
||||
|
||||
Array SceneState::get_connection_binds(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, connections.size(), Array());
|
||||
Array binds;
|
||||
|
@ -1494,7 +1531,7 @@ void SceneState::set_base_scene(int p_idx) {
|
|||
base_scene_idx = p_idx;
|
||||
}
|
||||
|
||||
void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) {
|
||||
void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, int p_unbinds, const Vector<int> &p_binds) {
|
||||
ERR_FAIL_INDEX(p_signal, names.size());
|
||||
ERR_FAIL_INDEX(p_method, names.size());
|
||||
|
||||
|
@ -1507,6 +1544,7 @@ void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method
|
|||
c.signal = p_signal;
|
||||
c.method = p_method;
|
||||
c.flags = p_flags;
|
||||
c.unbinds = p_unbinds;
|
||||
c.binds = p_binds;
|
||||
connections.push_back(c);
|
||||
}
|
||||
|
@ -1549,6 +1587,7 @@ void SceneState::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_connection_method", "idx"), &SceneState::get_connection_method);
|
||||
ClassDB::bind_method(D_METHOD("get_connection_flags", "idx"), &SceneState::get_connection_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_connection_binds", "idx"), &SceneState::get_connection_binds);
|
||||
ClassDB::bind_method(D_METHOD("get_connection_unbinds", "idx"), &SceneState::get_connection_unbinds);
|
||||
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
||||
|
|
|
@ -77,6 +77,7 @@ class SceneState : public RefCounted {
|
|||
int signal = 0;
|
||||
int method = 0;
|
||||
int flags = 0;
|
||||
int unbinds = 0;
|
||||
Vector<int> binds;
|
||||
};
|
||||
|
||||
|
@ -163,6 +164,7 @@ public:
|
|||
NodePath get_connection_target(int p_idx) const;
|
||||
StringName get_connection_method(int p_idx) const;
|
||||
int get_connection_flags(int p_idx) const;
|
||||
int get_connection_unbinds(int p_idx) const;
|
||||
Array get_connection_binds(int p_idx) const;
|
||||
|
||||
bool has_connection(const NodePath &p_node_from, const StringName &p_signal, const NodePath &p_node_to, const StringName &p_method);
|
||||
|
@ -178,7 +180,7 @@ public:
|
|||
void add_node_property(int p_node, int p_name, int p_value);
|
||||
void add_node_group(int p_node, int p_group);
|
||||
void set_base_scene(int p_idx);
|
||||
void add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds);
|
||||
void add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, int p_unbinds, const Vector<int> &p_binds);
|
||||
void add_editable_instance(const NodePath &p_path);
|
||||
|
||||
virtual void set_last_modified_time(uint64_t p_time) { last_modified_time = p_time; }
|
||||
|
|
|
@ -313,6 +313,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
|
|||
StringName method = next_tag.fields["method"];
|
||||
StringName signal = next_tag.fields["signal"];
|
||||
int flags = Object::CONNECT_PERSIST;
|
||||
int unbinds = 0;
|
||||
Array binds;
|
||||
|
||||
if (next_tag.fields.has("flags")) {
|
||||
|
@ -323,6 +324,10 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
|
|||
binds = next_tag.fields["binds"];
|
||||
}
|
||||
|
||||
if (next_tag.fields.has("unbinds")) {
|
||||
unbinds = next_tag.fields["unbinds"];
|
||||
}
|
||||
|
||||
Vector<int> bind_ints;
|
||||
for (int i = 0; i < binds.size(); i++) {
|
||||
bind_ints.push_back(packed_scene->get_state()->add_value(binds[i]));
|
||||
|
@ -334,6 +339,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
|
|||
packed_scene->get_state()->add_name(signal),
|
||||
packed_scene->get_state()->add_name(method),
|
||||
flags,
|
||||
unbinds,
|
||||
bind_ints);
|
||||
|
||||
error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser);
|
||||
|
@ -1909,6 +1915,11 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
|
|||
connstr += " flags=" + itos(flags);
|
||||
}
|
||||
|
||||
int unbinds = state->get_connection_unbinds(i);
|
||||
if (unbinds > 0) {
|
||||
connstr += " unbinds=" + itos(unbinds);
|
||||
}
|
||||
|
||||
Array binds = state->get_connection_binds(i);
|
||||
f->store_string(connstr);
|
||||
if (binds.size()) {
|
||||
|
|
Loading…
Reference in a new issue