/*************************************************************************/ /* gdnative.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "gdnative.h" #include "global_config.h" #include "global_constants.h" #include "io/file_access_encrypted.h" #include "os/file_access.h" #include "os/os.h" #include "scene/main/scene_main_loop.h" #include "scene/resources/scene_format_text.h" #if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) #include "api_generator.h" #endif #ifdef TOOLS_ENABLED #include "editor/editor_node.h" #endif Error NativeLibrary::initialize(NativeLibrary *&p_native_lib, const StringName p_path) { if (GDNativeScriptLanguage::get_singleton()->initialized_libraries.has(p_path)) { p_native_lib = GDNativeScriptLanguage::get_singleton()->initialized_libraries[p_path]; return OK; } NativeLibrary *lib = memnew(NativeLibrary); lib->path = p_path; p_native_lib = lib; // Open the file Error error; error = OS::get_singleton()->open_dynamic_library(p_path, lib->handle); if (error) return error; ERR_FAIL_COND_V(!lib->handle, ERR_BUG); // Get the method void *library_init; error = OS::get_singleton()->get_dynamic_library_symbol_handle(lib->handle, GDNativeScriptLanguage::get_init_symbol_name(), library_init); if (error) return error; ERR_FAIL_COND_V(!library_init, ERR_BUG); void (*library_init_fpointer)(godot_native_init_options *) = (void (*)(godot_native_init_options *))library_init; 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? GDNativeScriptLanguage::get_singleton()->initialized_libraries[p_path] = lib; return OK; } Error NativeLibrary::terminate(NativeLibrary *&p_native_lib) { if (!GDNativeScriptLanguage::get_singleton()->initialized_libraries.has(p_native_lib->path)) { OS::get_singleton()->close_dynamic_library(p_native_lib->handle); p_native_lib->handle = 0; return OK; } Error error = OK; void *library_terminate; error = OS::get_singleton()->get_dynamic_library_symbol_handle(p_native_lib->handle, GDNativeScriptLanguage::get_terminate_symbol_name(), library_terminate); if (error) return OK; // no terminate? okay, not that important lol void (*library_terminate_pointer)(godot_native_terminate_options *) = (void (*)(godot_native_terminate_options *))library_terminate; godot_native_terminate_options options; options.in_editor = SceneTree::get_singleton()->is_editor_hint(); library_terminate_pointer(&options); GDNativeScriptLanguage::get_singleton()->initialized_libraries.erase(p_native_lib->path); OS::get_singleton()->close_dynamic_library(p_native_lib->handle); p_native_lib->handle = 0; return OK; } // Script #ifdef TOOLS_ENABLED void GDNativeScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) { ERR_FAIL_COND(!script_data); List pinfo; Map values; for (Map::Element *E = script_data->properties.front(); E; E = E->next()) { PropertyInfo p = E->get().info; p.name = String(E->key()); pinfo.push_back(p); values[p.name] = E->get().default_value; } p_placeholder->update(pinfo, values); } void GDNativeScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { placeholders.erase(p_placeholder); } #endif bool GDNativeScript::can_instance() const { #ifdef TOOLS_ENABLED return script_data || (!is_tool() && !ScriptServer::is_scripting_enabled()); #else // allow defaultlibrary without editor features if (!library.is_valid()) { String path = GLOBAL_GET("gdnative/default_gdnativelibrary"); RES lib = ResourceLoader::load(path); if (lib.is_valid() && lib->cast_to()) { return true; } } return script_data; #endif //return script_data || (!tool && !ScriptServer::is_scripting_enabled()); // change to true enable in editor stuff. } Ref