Reworked signal connection system, added support for Callable and Signal objects and made them default.

This commit is contained in:
Juan Linietsky 2020-02-19 16:27:19 -03:00 committed by Juan Linietsky
parent 1a4be2cd8f
commit 69c95f4b4c
275 changed files with 3831 additions and 2948 deletions

View file

@ -84,7 +84,7 @@ Object *GDScriptNativeClass::instance() {
return ClassDB::instance(name);
}
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) {
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
/* STEP 1, CREATE */
@ -116,7 +116,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
initializer->call(instance, p_args, p_argcount, r_error);
if (r_error.error != Variant::CallError::CALL_OK) {
if (r_error.error != Callable::CallError::CALL_OK) {
instance->script = Ref<GDScript>();
instance->owner->set_script_instance(NULL);
#ifndef NO_THREADS
@ -127,23 +127,23 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
GDScriptLanguage::singleton->lock->unlock();
#endif
ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, NULL); //error constructing
}
//@TODO make thread safe
return instance;
}
Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
/* STEP 1, CREATE */
if (!valid) {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
r_error.error = Variant::CallError::CALL_OK;
r_error.error = Callable::CallError::CALL_OK;
REF ref;
Object *owner = NULL;
@ -329,7 +329,7 @@ ScriptInstance *GDScript::instance_create(Object *p_this) {
}
}
Variant::CallError unchecked_error;
Callable::CallError unchecked_error;
return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error);
}
@ -739,7 +739,7 @@ MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) co
return get_rset_mode_by_id(get_rset_property_id(p_variable));
}
Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *top = this;
while (top) {
@ -1081,18 +1081,18 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
const GDScript::MemberInfo *member = &E->get();
if (member->setter) {
const Variant *val = &p_value;
Variant::CallError err;
Callable::CallError err;
call(member->setter, &val, 1, err);
if (err.error == Variant::CallError::CALL_OK) {
if (err.error == Callable::CallError::CALL_OK) {
return true; //function exists, call was successful
}
} else {
if (!member->data_type.is_type(p_value)) {
// Try conversion
Variant::CallError ce;
Callable::CallError ce;
const Variant *value = &p_value;
Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce);
if (ce.error == Variant::CallError::CALL_OK) {
if (ce.error == Callable::CallError::CALL_OK) {
members.write[member->index] = converted;
return true;
} else {
@ -1115,9 +1115,9 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
Variant name = p_name;
const Variant *args[2] = { &name, &p_value };
Variant::CallError err;
Callable::CallError err;
Variant ret = E->get()->call(this, (const Variant **)args, 2, err);
if (err.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool())
if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool())
return true;
}
sptr = sptr->_base;
@ -1135,9 +1135,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
if (E) {
if (E->get().getter) {
Variant::CallError err;
Callable::CallError err;
r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, NULL, 0, err);
if (err.error == Variant::CallError::CALL_OK) {
if (err.error == Callable::CallError::CALL_OK) {
return true;
}
}
@ -1166,9 +1166,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
Variant name = p_name;
const Variant *args[1] = { &name };
Variant::CallError err;
Callable::CallError err;
Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), (const Variant **)args, 1, err);
if (err.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
if (err.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
r_ret = ret;
return true;
}
@ -1209,9 +1209,9 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list);
if (E) {
Variant::CallError err;
Callable::CallError err;
Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), NULL, 0, err);
if (err.error == Variant::CallError::CALL_OK) {
if (err.error == Callable::CallError::CALL_OK) {
ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries.");
@ -1296,7 +1296,7 @@ bool GDScriptInstance::has_method(const StringName &p_method) const {
return false;
}
Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *sptr = script.ptr();
while (sptr) {
@ -1306,14 +1306,14 @@ Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_arg
}
sptr = sptr->_base;
}
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
GDScript *sptr = script.ptr();
Variant::CallError ce;
Callable::CallError ce;
while (sptr) {
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
@ -1329,7 +1329,7 @@ void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_met
if (sptr->_base)
_ml_call_reversed(sptr->_base, p_method, p_args, p_argcount);
Variant::CallError ce;
Callable::CallError ce;
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
if (E) {
@ -1354,9 +1354,9 @@ void GDScriptInstance::notification(int p_notification) {
while (sptr) {
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._notification);
if (E) {
Variant::CallError err;
Callable::CallError err;
E->get()->call(this, args, 1, err);
if (err.error != Variant::CallError::CALL_OK) {
if (err.error != Callable::CallError::CALL_OK) {
//print error about notification call
}
}
@ -1366,9 +1366,9 @@ void GDScriptInstance::notification(int p_notification) {
String GDScriptInstance::to_string(bool *r_valid) {
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
Variant::CallError ce;
Callable::CallError ce;
Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
if (ce.error == Variant::CallError::CALL_OK) {
if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;