diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index b543a486d32..a4c9085f454 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -391,6 +391,55 @@ void GDNativeScript::get_script_signal_list(List *r_signals) const { } } +Variant GDNativeScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { + + /* STEP 1, CREATE */ + + if (!library.is_valid() || ((String)script_name).empty() || !script_data) { + r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + + r_error.error = Variant::CallError::CALL_OK; + REF ref; + Object *owner = NULL; + + GDNativeScriptData *_baseptr = script_data; + while (_baseptr->base_data) { + _baseptr = _baseptr->base_data; + } + + if (!(_baseptr->base_native_type == "")) { + owner = ClassDB::instance(_baseptr->base_native_type); + } else { + owner = memnew(Reference); //by default, no base means use reference + } + + Reference *r = owner->cast_to(); + if (r) { + ref = REF(r); + } + + // GDScript does it like this: _create_instance(p_args, p_argcount, owner, r != NULL, r_error); + // @Todo support varargs for constructors. + GDNativeInstance *instance = (GDNativeInstance *)instance_create(owner); + + owner->set_script(Ref(this).get_ref_ptr()); + owner->set_script_instance(instance); + if (!instance) { + if (ref.is_null()) { + memdelete(owner); //no owner, sorry + } + return Variant(); + } + + if (ref.is_valid()) { + return ref; + } else { + return owner; + } +} + Ref GDNativeScript::get_library() const { return library; } @@ -438,6 +487,8 @@ void GDNativeScript::_bind_methods() { ClassDB::bind_method(D_METHOD("get_script_name"), &GDNativeScript::get_script_name); ClassDB::bind_method(D_METHOD("set_script_name", "script_name"), &GDNativeScript::set_script_name); + ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDNativeScript::_new, MethodInfo(Variant::OBJECT, "new")); + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "GDNativeLibrary"), "set_library", "get_library"); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "script_name"), "set_script_name", "get_script_name"); } diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 89270b4e265..27e0c3788b3 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -184,6 +184,8 @@ public: virtual void get_script_method_list(List *p_list) const; virtual void get_script_property_list(List *p_list) const; + Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Ref get_library() const; void set_library(Ref p_library); diff --git a/modules/gdnative/godot/godot_string.h b/modules/gdnative/godot/godot_string.h index 9289531c5e2..4deec0922cd 100644 --- a/modules/gdnative/godot/godot_string.h +++ b/modules/gdnative/godot/godot_string.h @@ -35,6 +35,7 @@ extern "C" { #endif #include +#include #ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED typedef struct godot_string {