summaryrefslogtreecommitdiff
path: root/core/object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/object.cpp')
-rw-r--r--core/object.cpp269
1 files changed, 126 insertions, 143 deletions
diff --git a/core/object.cpp b/core/object.cpp
index 0a7a46a7d2..a61c4ae392 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -335,10 +335,8 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr
Object::Connection::operator Variant() const {
Dictionary d;
- d["source"] = source;
d["signal"] = signal;
- d["target"] = target;
- d["method"] = method;
+ d["callable"] = callable;
d["flags"] = flags;
d["binds"] = binds;
return d;
@@ -346,34 +344,19 @@ Object::Connection::operator Variant() const {
bool Object::Connection::operator<(const Connection &p_conn) const {
- if (source == p_conn.source) {
-
- if (signal == p_conn.signal) {
-
- if (target == p_conn.target) {
-
- return method < p_conn.method;
- } else {
-
- return target < p_conn.target;
- }
- } else
- return signal < p_conn.signal;
+ if (signal == p_conn.signal) {
+ return callable < p_conn.callable;
} else {
- return source < p_conn.source;
+ return signal < p_conn.signal;
}
}
Object::Connection::Connection(const Variant &p_variant) {
Dictionary d = p_variant;
- if (d.has("source"))
- source = d["source"];
if (d.has("signal"))
signal = d["signal"];
- if (d.has("target"))
- target = d["target"];
- if (d.has("method"))
- method = d["method"];
+ if (d.has("callable"))
+ callable = d["callable"];
if (d.has("flags"))
flags = d["flags"];
if (d.has("binds"))
@@ -655,18 +638,18 @@ void Object::get_method_list(List<MethodInfo> *p_list) const {
}
}
-Variant Object::_call_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return Variant();
}
- if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::STRING;
+ r_error.expected = Variant::STRING_NAME;
return Variant();
}
@@ -675,22 +658,22 @@ Variant Object::_call_bind(const Variant **p_args, int p_argcount, Variant::Call
return call(method, &p_args[1], p_argcount - 1, r_error);
}
-Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return Variant();
}
- if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::STRING;
+ r_error.expected = Variant::STRING_NAME;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
StringName method = *p_args[0];
@@ -700,29 +683,29 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Vari
}
#ifdef DEBUG_ENABLED
-static void _test_call_error(const StringName &p_func, const Variant::CallError &error) {
+static void _test_call_error(const StringName &p_func, const Callable::CallError &error) {
switch (error.error) {
- case Variant::CallError::CALL_OK:
- case Variant::CallError::CALL_ERROR_INVALID_METHOD:
+ case Callable::CallError::CALL_OK:
+ case Callable::CallError::CALL_ERROR_INVALID_METHOD:
break;
- case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
- ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(error.expected) + ".");
+ ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(Variant::Type(error.expected)) + ".");
break;
}
- case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument) + ".");
break;
}
- case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument) + ".");
break;
}
- case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL:
+ case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL:
break;
}
}
@@ -749,7 +732,7 @@ void Object::call_multilevel(const StringName &p_method, const Variant **p_args,
//Variant ret;
OBJ_DEBUG_LOCK
- Variant::CallError error;
+ Callable::CallError error;
if (script_instance) {
script_instance->call_multilevel(p_method, p_args, p_argcount);
@@ -769,7 +752,7 @@ void Object::call_multilevel_reversed(const StringName &p_method, const Variant
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
- Variant::CallError error;
+ Callable::CallError error;
OBJ_DEBUG_LOCK
if (method) {
@@ -823,9 +806,9 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
}
}
- Variant::CallError ce;
+ Callable::CallError ce;
Variant ret = call(p_method, argptrs, p_args.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_V_MSG(Variant(), "Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce) + ".");
}
return ret;
@@ -842,7 +825,7 @@ Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) {
argc++;
}
- Variant::CallError error;
+ Callable::CallError error;
Variant ret = call(p_name, argptr, argc, error);
return ret;
@@ -859,38 +842,38 @@ void Object::call_multilevel(const StringName &p_name, VARIANT_ARG_DECLARE) {
argc++;
}
- //Variant::CallError error;
+ //Callable::CallError error;
call_multilevel(p_name, argptr, argc);
}
-Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
if (p_method == CoreStringNames::get_singleton()->_free) {
//free must be here, before anything, always ready
#ifdef DEBUG_ENABLED
if (p_argcount != 0) {
r_error.argument = 0;
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
return Variant();
}
if (Object::cast_to<Reference>(this)) {
r_error.argument = 0;
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_V_MSG(Variant(), "Can't 'free' a reference.");
}
if (_lock_index.get() > 1) {
r_error.argument = 0;
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_V_MSG(Variant(), "Object is locked and can't be freed.");
}
#endif
//must be here, must be before everything,
memdelete(this);
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
return Variant();
}
@@ -901,15 +884,15 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
//force jumptable
switch (r_error.error) {
- case Variant::CallError::CALL_OK:
+ case Callable::CallError::CALL_OK:
return ret;
- case Variant::CallError::CALL_ERROR_INVALID_METHOD:
+ case Callable::CallError::CALL_ERROR_INVALID_METHOD:
break;
- case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT:
- case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
- case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
+ case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
+ case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
return ret;
- case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
+ case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
}
}
}
@@ -917,10 +900,9 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
if (method) {
-
ret = method->call(this, p_args, p_argcount, r_error);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
return ret;
@@ -1103,7 +1085,7 @@ void Object::add_user_signal(const MethodInfo &p_signal) {
ERR_FAIL_COND_MSG(p_signal.name == "", "Signal name cannot be empty.");
ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), "User signal's name conflicts with a built-in signal of '" + get_class_name() + "'.");
ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), "Trying to add already existing signal '" + p_signal.name + "'.");
- Signal s;
+ SignalData s;
s.user = p_signal;
signal_map[p_signal.name] = s;
}
@@ -1118,23 +1100,22 @@ bool Object::_has_user_signal(const StringName &p_name) const {
struct _ObjectSignalDisconnectData {
StringName signal;
- Object *target;
- StringName method;
+ Callable callable;
};
-Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
ERR_FAIL_COND_V(p_argcount < 1, Variant());
- if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::STRING;
- ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING, Variant());
+ r_error.expected = Variant::STRING_NAME;
+ ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING, Variant());
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
StringName signal = *p_args[0];
@@ -1155,7 +1136,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
if (_block_signals)
return ERR_CANT_ACQUIRE_RESOURCE; //no emit, signals blocked
- Signal *s = signal_map.getptr(p_name);
+ SignalData *s = signal_map.getptr(p_name);
if (!s) {
#ifdef DEBUG_ENABLED
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_name);
@@ -1171,7 +1152,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
//copy on write will ensure that disconnecting the signal or even deleting the object will not affect the signal calling.
//this happens automatically and will not change the performance of calling.
//awesome, isn't it?
- VMap<Signal::Target, Signal::Slot> slot_map = s->slot_map;
+ VMap<Callable, SignalData::Slot> slot_map = s->slot_map;
int ssize = slot_map.size();
@@ -1185,7 +1166,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
const Connection &c = slot_map.getv(i).conn;
- Object *target = ObjectDB::get_instance(slot_map.getk(i)._id);
+ Object *target = c.callable.get_object();
if (!target) {
// Target might have been deleted during signal callback, this is expected and OK.
continue;
@@ -1210,22 +1191,23 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
}
if (c.flags & CONNECT_DEFERRED) {
- MessageQueue::get_singleton()->push_call(target->get_instance_id(), c.method, args, argc, true);
+ MessageQueue::get_singleton()->push_callable(c.callable, args, argc, true);
} else {
- Variant::CallError ce;
+ Callable::CallError ce;
_emitting = true;
- target->call(c.method, args, argc, ce);
+ Variant ret;
+ c.callable.call(args, argc, ret, ce);
_emitting = false;
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
#ifdef DEBUG_ENABLED
if (c.flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (script.is_null() || !Ref<Script>(script)->is_tool()))
continue;
#endif
- if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
+ if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
//most likely object is not initialized yet, do not throw error.
} else {
- ERR_PRINT("Error calling method from signal '" + String(p_name) + "': " + Variant::get_call_error_text(target, c.method, args, argc, ce) + ".");
+ ERR_PRINT("Error calling from signal '" + String(p_name) + "' to callable: " + Variant::get_callable_error_text(c.callable, args, argc, ce) + ".");
err = ERR_METHOD_NOT_FOUND;
}
}
@@ -1242,8 +1224,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
_ObjectSignalDisconnectData dd;
dd.signal = p_name;
- dd.target = target;
- dd.method = c.method;
+ dd.callable = c.callable;
disconnect_data.push_back(dd);
}
}
@@ -1251,7 +1232,8 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
while (!disconnect_data.empty()) {
const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get();
- disconnect(dd.signal, dd.target, dd.method);
+
+ _disconnect(dd.signal, dd.callable);
disconnect_data.pop_front();
}
@@ -1323,15 +1305,8 @@ Array Object::_get_signal_connection_list(const String &p_signal) const {
for (List<Connection>::Element *E = conns.front(); E; E = E->next()) {
Connection &c = E->get();
- if (c.signal == p_signal) {
- Dictionary rc;
- rc["signal"] = c.signal;
- rc["method"] = c.method;
- rc["source"] = c.source;
- rc["target"] = c.target;
- rc["binds"] = c.binds;
- rc["flags"] = c.flags;
- ret.push_back(rc);
+ if (c.signal.get_name() == p_signal) {
+ ret.push_back(c);
}
}
@@ -1343,11 +1318,7 @@ Array Object::_get_incoming_connections() const {
Array ret;
int connections_amount = connections.size();
for (int idx_conn = 0; idx_conn < connections_amount; idx_conn++) {
- Dictionary conn_data;
- conn_data["source"] = connections[idx_conn].source;
- conn_data["signal_name"] = connections[idx_conn].signal;
- conn_data["method_name"] = connections[idx_conn].method;
- ret.push_back(conn_data);
+ ret.push_back(connections[idx_conn]);
}
return ret;
@@ -1381,7 +1352,7 @@ void Object::get_all_signal_connections(List<Connection> *p_connections) const {
while ((S = signal_map.next(S))) {
- const Signal *s = &signal_map[*S];
+ const SignalData *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
@@ -1392,7 +1363,7 @@ void Object::get_all_signal_connections(List<Connection> *p_connections) const {
void Object::get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const {
- const Signal *s = signal_map.getptr(p_signal);
+ const SignalData *s = signal_map.getptr(p_signal);
if (!s)
return; //nothing
@@ -1407,7 +1378,7 @@ int Object::get_persistent_signal_connection_count() const {
while ((S = signal_map.next(S))) {
- const Signal *s = &signal_map[*S];
+ const SignalData *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) {
@@ -1426,11 +1397,15 @@ void Object::get_signals_connected_to_this(List<Connection> *p_connections) cons
}
}
-Error Object::connect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) {
+Error Object::connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) {
+
+ return connect(p_signal, Callable(p_to_object, p_to_method), p_binds, p_flags);
+}
+Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
- ERR_FAIL_NULL_V(p_to_object, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(p_callable.is_null(), ERR_INVALID_PARAMETER);
- Signal *s = signal_map.getptr(p_signal);
+ SignalData *s = signal_map.getptr(p_signal);
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
//check in script
@@ -1449,33 +1424,32 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
#endif
}
- ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'.");
+ ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to callable '" + p_callable + "'.");
- signal_map[p_signal] = Signal();
+ signal_map[p_signal] = SignalData();
s = &signal_map[p_signal];
}
- Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+ Callable target = p_callable;
+
if (s->slot_map.has(target)) {
if (p_flags & CONNECT_REFERENCE_COUNTED) {
s->slot_map[target].reference_count++;
return OK;
} else {
- ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given method '" + p_to_method + "' in that object.");
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given callable '" + p_callable + "' in that object.");
}
}
- Signal::Slot slot;
+ SignalData::Slot slot;
Connection conn;
- conn.source = this;
- conn.target = p_to_object;
- conn.method = p_to_method;
- conn.signal = p_signal;
+ conn.callable = target;
+ conn.signal = ::Signal(this, p_signal);
conn.flags = p_flags;
conn.binds = p_binds;
slot.conn = conn;
- slot.cE = p_to_object->connections.push_back(conn);
+ slot.cE = p_callable.get_object()->connections.push_back(conn);
if (p_flags & CONNECT_REFERENCE_COUNTED) {
slot.reference_count = 1;
}
@@ -1485,10 +1459,15 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
return OK;
}
-bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const {
+bool Object::is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const {
+
+ return is_connected(p_signal, Callable(p_to_object, p_to_method));
+}
- ERR_FAIL_NULL_V(p_to_object, false);
- const Signal *s = signal_map.getptr(p_signal);
+bool Object::is_connected(const StringName &p_signal, const Callable &p_callable) const {
+
+ ERR_FAIL_COND_V(p_callable.is_null(), false);
+ const SignalData *s = signal_map.getptr(p_signal);
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
if (signal_is_valid)
@@ -1500,28 +1479,31 @@ bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const
ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + ".");
}
- Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+ Callable target = p_callable;
return s->slot_map.has(target);
//const Map<Signal::Target,Signal::Slot>::Element *E = s->slot_map.find(target);
//return (E!=NULL);
}
-void Object::disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) {
+void Object::disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) {
- _disconnect(p_signal, p_to_object, p_to_method);
+ _disconnect(p_signal, Callable(p_to_object, p_to_method));
}
-void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force) {
- ERR_FAIL_NULL(p_to_object);
- Signal *s = signal_map.getptr(p_signal);
- ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
+void Object::disconnect(const StringName &p_signal, const Callable &p_callable) {
+ _disconnect(p_signal, p_callable);
+}
+
+void Object::_disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force) {
- Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+ ERR_FAIL_COND(p_callable.is_null());
+ SignalData *s = signal_map.getptr(p_signal);
+ ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
- ERR_FAIL_COND_MSG(!s->slot_map.has(target), "Disconnecting nonexistent signal '" + p_signal + "', slot: " + itos(target._id) + ":" + target.method + ".");
+ ERR_FAIL_COND_MSG(!s->slot_map.has(p_callable), "Disconnecting nonexistent signal '" + p_signal + "', callable: " + p_callable + ".");
- Signal::Slot *slot = &s->slot_map[target];
+ SignalData::Slot *slot = &s->slot_map[p_callable];
if (!p_force) {
slot->reference_count--; // by default is zero, if it was not referenced it will go below it
@@ -1529,9 +1511,10 @@ void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const
return;
}
}
-
- p_to_object->connections.erase(slot->cE);
- s->slot_map.erase(target);
+ Object *object = p_callable.get_object();
+ ERR_FAIL_COND(!object);
+ object->connections.erase(slot->cE);
+ s->slot_map.erase(p_callable);
if (s->slot_map.empty() && ClassDB::has_signal(get_class_name(), p_signal)) {
//not user signal, delete
@@ -1680,7 +1663,7 @@ void Object::_bind_methods() {
{
MethodInfo mi;
mi.name = "emit_signal";
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "signal"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "emit_signal", &Object::_emit_signal, mi, varray(), false);
}
@@ -1688,7 +1671,7 @@ void Object::_bind_methods() {
{
MethodInfo mi;
mi.name = "call";
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "method"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call", &Object::_call_bind, mi);
}
@@ -1696,7 +1679,7 @@ void Object::_bind_methods() {
{
MethodInfo mi;
mi.name = "call_deferred";
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "method"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_deferred", &Object::_call_deferred_bind, mi, varray(), false);
}
@@ -1711,9 +1694,9 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_signal_connection_list", "signal"), &Object::_get_signal_connection_list);
ClassDB::bind_method(D_METHOD("get_incoming_connections"), &Object::_get_incoming_connections);
- ClassDB::bind_method(D_METHOD("connect", "signal", "target", "method", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0));
- ClassDB::bind_method(D_METHOD("disconnect", "signal", "target", "method"), &Object::disconnect);
- ClassDB::bind_method(D_METHOD("is_connected", "signal", "target", "method"), &Object::is_connected);
+ ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("disconnect", "signal", "callable"), &Object::disconnect);
+ ClassDB::bind_method(D_METHOD("is_connected", "signal", "callable"), &Object::is_connected);
ClassDB::bind_method(D_METHOD("set_block_signals", "enable"), &Object::set_block_signals);
ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals);
@@ -1730,9 +1713,9 @@ void Object::_bind_methods() {
ADD_SIGNAL(MethodInfo("script_changed"));
BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
#ifdef TOOLS_ENABLED
- MethodInfo miget("_get", PropertyInfo(Variant::STRING, "property"));
+ MethodInfo miget("_get", PropertyInfo(Variant::STRING_NAME, "property"));
miget.return_val.name = "Variant";
miget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_VMETHOD(miget);
@@ -1830,7 +1813,7 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName>
return Variant::NIL;
}
- Variant::CallError ce;
+ Callable::CallError ce;
Variant check = Variant::construct(t, NULL, 0, ce);
for (int i = 1; i < p_path.size(); i++) {
@@ -1957,15 +1940,15 @@ Object::~Object() {
while ((S = signal_map.next(NULL))) {
- Signal *s = &signal_map[*S];
+ SignalData *s = &signal_map[*S];
//brute force disconnect for performance
int slot_count = s->slot_map.size();
- const VMap<Signal::Target, Signal::Slot>::Pair *slot_list = s->slot_map.get_array();
+ const VMap<Callable, SignalData::Slot>::Pair *slot_list = s->slot_map.get_array();
for (int i = 0; i < slot_count; i++) {
- slot_list[i].value.conn.target->connections.erase(slot_list[i].value.cE);
+ slot_list[i].value.conn.callable.get_object()->connections.erase(slot_list[i].value.cE);
}
signal_map.erase(*S);
@@ -1975,7 +1958,7 @@ Object::~Object() {
while (connections.size()) {
Connection c = connections.front()->get();
- c.source->_disconnect(c.signal, c.target, c.method, true);
+ c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true);
}
ObjectDB::remove_instance(this);