diff --git a/core/object.cpp b/core/object.cpp index 9184fb9cd04..000cefcac74 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1723,7 +1723,7 @@ void Object::_bind_methods() { BIND_VMETHOD(MethodInfo("_set", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value"))); #ifdef TOOLS_ENABLED MethodInfo miget("_get", PropertyInfo(Variant::STRING, "property")); - miget.return_val.name = "var"; + miget.return_val.name = "Variant"; BIND_VMETHOD(miget); MethodInfo plget("_get_property_list"); diff --git a/modules/gdnative/api_generator.cpp b/modules/gdnative/api_generator.cpp index d5f22ee7a3a..a9d1f962876 100644 --- a/modules/gdnative/api_generator.cpp +++ b/modules/gdnative/api_generator.cpp @@ -268,6 +268,8 @@ List generate_c_api_classes() { method_api.method_name = method_api.method_name.get_slice(":", 0); } else if (m->get().return_val.type != Variant::NIL) { method_api.return_type = m->get().return_val.hint == PROPERTY_HINT_RESOURCE_TYPE ? m->get().return_val.hint_string : Variant::get_type_name(m->get().return_val.type); + } else if (m->get().return_val.name != "") { + method_api.return_type = m->get().return_val.name; } else { method_api.return_type = "void"; } diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 12d806250b6..348d8533ad2 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -847,6 +847,16 @@ bool GDNativeInstance::set(const StringName &p_name, const Variant &p_value) { script->script_data->properties[p_name].setter.set_func((godot_object *)owner, script->script_data->properties[p_name].setter.method_data, userdata, *(godot_variant *)&p_value); return true; } + + Map::Element *E = script->script_data->methods.find("_set"); + if (E) { + Variant name = p_name; + const Variant *args[2] = { &name, &p_value }; + + E->get().method.method((godot_object *)owner, E->get().method.method_data, userdata, 2, (godot_variant **)args); + return true; + } + return false; } @@ -856,14 +866,66 @@ bool GDNativeInstance::get(const StringName &p_name, Variant &r_ret) const { if (script->script_data->properties.has(p_name)) { godot_variant value = script->script_data->properties[p_name].getter.get_func((godot_object *)owner, script->script_data->properties[p_name].getter.method_data, userdata); r_ret = *(Variant *)&value; + godot_variant_destroy(&value); return true; } + + Map::Element *E = script->script_data->methods.find("_get"); + if (E) { + Variant name = p_name; + const Variant *args[1] = { &name }; + + godot_variant result = E->get().method.method((godot_object *)owner, E->get().method.method_data, userdata, 1, (godot_variant **)args); + r_ret = *(Variant *)&result; + godot_variant_destroy(&result); + return true; + } + return false; } void GDNativeInstance::get_property_list(List *p_properties) const { script->get_script_property_list(p_properties); // TODO: dynamic properties + + Map::Element *E = script->script_data->methods.find("_get_property_list"); + if (E) { + godot_variant result = E->get().method.method((godot_object *)owner, E->get().method.method_data, userdata, 0, NULL); + Variant ret = *(Variant *)&result; + godot_variant_destroy(&result); + + if (ret.get_type() != Variant::ARRAY) { + ERR_EXPLAIN("Wrong type for _get_property_list, must be an array of dictionaries."); + ERR_FAIL(); + } + + Array arr = ret; + for (int i = 0; i < arr.size(); i++) { + Dictionary d = arr[i]; + ERR_CONTINUE(!d.has("name")) + ERR_CONTINUE(!d.has("type")) + + PropertyInfo pinfo; + + pinfo.type = Variant::Type(d["type"].operator int()); + ERR_CONTINUE(pinfo.type < 0 || pinfo.type >= Variant::VARIANT_MAX); + + pinfo.name = d["name"]; + ERR_CONTINUE(pinfo.name == ""); + + if (d.has("hint")) { + pinfo.hint = PropertyHint(d["hint"].operator int()); + } + if (d.has("hint_string")) { + pinfo.hint_string = d["hint_string"]; + } + if (d.has("usage")) { + pinfo.usage = d["usage"]; + } + + p_properties->push_back(pinfo); + } + } } Variant::Type GDNativeInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {