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

Add a flag to make the connection automatically emit the source object. #60143

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/object/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,7 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int
OBJ_DEBUG_LOCK

Error err = OK;
Variant appended_self;

for (int i = 0; i < ssize; i++) {
const Connection &c = slot_map.getv(i).conn;
Expand All @@ -1037,6 +1038,18 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int
const Variant **args = p_args;
int argc = p_argcount;

if (c.flags & CONNECT_APPEND_SOURCE_OBJECT) {
argc += 1;
args = (const Variant **)alloca(sizeof(Variant *) * argc);
for (int j = 0; j < p_argcount; j++) {
args[j] = (const Variant *)p_args[j];
}
if (unlikely(appended_self.get_type() == Variant::NIL)) {
appended_self = this;
}
args[p_argcount] = &appended_self;
}

if (c.flags & CONNECT_DEFERRED) {
MessageQueue::get_singleton()->push_callablep(c.callable, args, argc, true);
} else {
Expand Down Expand Up @@ -1582,6 +1595,7 @@ void Object::_bind_methods() {
BIND_ENUM_CONSTANT(CONNECT_PERSIST);
BIND_ENUM_CONSTANT(CONNECT_ONE_SHOT);
BIND_ENUM_CONSTANT(CONNECT_REFERENCE_COUNTED);
BIND_ENUM_CONSTANT(CONNECT_APPEND_SOURCE_OBJECT);
}

void Object::set_deferred(const StringName &p_property, const Variant &p_value) {
Expand Down
3 changes: 2 additions & 1 deletion core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,11 @@ class Object {
public:
enum ConnectFlags {
CONNECT_DEFERRED = 1,
CONNECT_PERSIST = 2, // hint for scene to save this connection
CONNECT_PERSIST = 2, // Hint for scene to save this connection
CONNECT_ONE_SHOT = 4,
CONNECT_REFERENCE_COUNTED = 8,
CONNECT_INHERITED = 16, // Used in editor builds.
CONNECT_APPEND_SOURCE_OBJECT = 32, // Hint for the connection dialog to append the source object as the last call argument.
};

struct Connection {
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/Object.xml
Original file line number Diff line number Diff line change
Expand Up @@ -955,5 +955,8 @@
<constant name="CONNECT_REFERENCE_COUNTED" value="8" enum="ConnectFlags">
Reference-counted connections can be assigned to the same [Callable] multiple times. Each disconnection decreases the internal counter. The signal fully disconnects only when the counter reaches 0.
</constant>
<constant name="CONNECT_APPEND_SOURCE_OBJECT" value="32" enum="ConnectFlags">
Automatically sends the source object when emitting the signal. Mainly used to improve the usability of the connection dialog. If this flag bit is enabled, the source object will be appended right after the original arguments of the signal.
</constant>
</constants>
</class>
43 changes: 41 additions & 2 deletions editor/connections_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ void ConnectDialog::_unbind_count_changed(double p_count) {
e->set_read_only(p_count > 0);
}
}

append_source->set_disabled(p_count > 0);
}

void ConnectDialog::_method_selected() {
Expand Down Expand Up @@ -532,6 +534,10 @@ bool ConnectDialog::get_one_shot() const {
return one_shot->is_pressed();
}

bool ConnectDialog::get_append_source() const {
return !append_source->is_disabled() && append_source->is_pressed();
}

/*
* Returns true if ConnectDialog is being used to edit an existing connection.
*/
Expand Down Expand Up @@ -563,12 +569,13 @@ void ConnectDialog::init(const ConnectionData &p_cd, const PackedStringArray &p_

bool b_deferred = (p_cd.flags & CONNECT_DEFERRED) == CONNECT_DEFERRED;
bool b_oneshot = (p_cd.flags & CONNECT_ONE_SHOT) == CONNECT_ONE_SHOT;
bool b_append_source = (p_cd.flags & CONNECT_APPEND_SOURCE_OBJECT) == CONNECT_APPEND_SOURCE_OBJECT;

deferred->set_pressed(b_deferred);
one_shot->set_pressed(b_oneshot);
append_source->set_pressed(b_append_source);

unbind_count->set_max(p_signal_args.size());

unbind_count->set_value(p_cd.unbinds);
_unbind_count_changed(p_cd.unbinds);

Expand Down Expand Up @@ -783,6 +790,12 @@ ConnectDialog::ConnectDialog() {
one_shot->set_tooltip_text(TTR("Disconnects the signal after its first emission."));
hbox->add_child(one_shot);

append_source = memnew(CheckBox);
append_source->set_h_size_flags(0);
append_source->set_text(TTR("Append source"));
append_source->set_tooltip_text(TTR("The source object is automatically sent when the signal is emitted."));
vbc_right->add_child(append_source);

cdbinds = memnew(ConnectDialogBinds);

error = memnew(AcceptDialog);
Expand Down Expand Up @@ -855,7 +868,8 @@ void ConnectionsDock::_make_or_edit_connection() {
}
bool b_deferred = connect_dialog->get_deferred();
bool b_oneshot = connect_dialog->get_one_shot();
cd.flags = CONNECT_PERSIST | (b_deferred ? CONNECT_DEFERRED : 0) | (b_oneshot ? CONNECT_ONE_SHOT : 0);
bool b_append_source = connect_dialog->get_append_source();
cd.flags = CONNECT_PERSIST | (b_deferred ? CONNECT_DEFERRED : 0) | (b_oneshot ? CONNECT_ONE_SHOT : 0) | (b_append_source ? CONNECT_APPEND_SOURCE_OBJECT : 0);

// Conditions to add function: must have a script and must not have the method already
// (in the class, the script itself, or inherited).
Expand Down Expand Up @@ -888,6 +902,28 @@ void ConnectionsDock::_make_or_edit_connection() {
if (add_script_function) {
PackedStringArray script_function_args = connect_dialog->get_signal_args();
script_function_args.resize(script_function_args.size() - cd.unbinds);

// Append the source.
if (b_append_source) {
String class_name = cd.source->get_class();
bool found = false;

Ref<Script> source_script = cd.source->get_script();
if (source_script.is_valid()) {
found = source_script->has_script_signal(cd.signal);
}
if (!found) {
found = ClassDB::has_signal(class_name, cd.signal, true);
}

while (!found) {
class_name = ClassDB::get_parent_class(class_name);
found = ClassDB::has_signal(class_name, cd.signal, true);
}

script_function_args.push_back("source:" + class_name);
}

for (int i = 0; i < cd.binds.size(); i++) {
script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(cd.binds[i].get_type()));
}
Expand Down Expand Up @@ -1365,6 +1401,9 @@ void ConnectionsDock::update_tree() {
if (cd.flags & CONNECT_ONE_SHOT) {
path += " (one-shot)";
}
if (cd.flags & CONNECT_APPEND_SOURCE_OBJECT) {
path += " (source)";
}
if (cd.unbinds > 0) {
path += " unbinds(" + itos(cd.unbinds) + ")";
} else if (!cd.binds.is_empty()) {
Expand Down
2 changes: 2 additions & 0 deletions editor/connections_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class ConnectDialog : public ConfirmationDialog {
OptionButton *type_list = nullptr;
CheckBox *deferred = nullptr;
CheckBox *one_shot = nullptr;
CheckBox *append_source = nullptr;
CheckButton *advanced = nullptr;
Vector<Control *> bind_controls;

Expand Down Expand Up @@ -178,6 +179,7 @@ class ConnectDialog : public ConfirmationDialog {

bool get_deferred() const;
bool get_one_shot() const;
bool get_append_source() const;
bool is_editing() const;

void init(const ConnectionData &p_cd, const PackedStringArray &p_signal_args, bool p_edit = false);
Expand Down