diff options
Diffstat (limited to 'modules/gdnative/gdnative.cpp')
| -rw-r--r-- | modules/gdnative/gdnative.cpp | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 43b309ae36..09859d95bd 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -77,11 +77,9 @@ Error NativeLibrary::initialize(NativeLibrary *&p_native_lib, const StringName p godot_native_init_options options; options.in_editor = SceneTree::get_singleton()->is_editor_hint(); - /* options.core_api_hash = ClassDB::get_api_hash(ClassDB::API_CORE); options.editor_api_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR); options.no_api_hash = ClassDB::get_api_hash(ClassDB::API_NONE); - */ library_init_fpointer(&options); // Catch errors? @@ -393,6 +391,54 @@ void GDNativeScript::get_script_signal_list(List<MethodInfo> *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<Reference>(); + 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_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<GDNativeLibrary> GDNativeScript::get_library() const { return library; } @@ -440,6 +486,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"); } @@ -1167,27 +1215,25 @@ void GDNativeReloadNode::_notification(int p_what) { // update placeholders (if any) - GDNativeScript *script = NULL; + Set<GDNativeScript *> scripts; for (Set<GDNativeScript *>::Element *S = GDNativeScriptLanguage::get_singleton()->script_list.front(); S; S = S->next()) { if (lib->native_library->scripts.has(S->get()->get_script_name())) { - script = S->get(); + GDNativeScript *script = S->get(); script->script_data = lib->get_script_data(script->get_script_name()); - break; + scripts.insert(script); } } - if (script == NULL) { - // new class, cool. Nothing to do here - continue; - } - - if (script->placeholders.size() == 0) - continue; + for (Set<GDNativeScript *>::Element *S = scripts.front(); S; S = S->next()) { + GDNativeScript *script = S->get(); + if (script->placeholders.size() == 0) + continue; - for (Set<PlaceHolderScriptInstance *>::Element *P = script->placeholders.front(); P; P = P->next()) { - PlaceHolderScriptInstance *p = P->get(); - script->_update_placeholder(p); + for (Set<PlaceHolderScriptInstance *>::Element *P = script->placeholders.front(); P; P = P->next()) { + PlaceHolderScriptInstance *p = P->get(); + script->_update_placeholder(p); + } } } |