diff options
Diffstat (limited to 'modules/gdnative')
34 files changed, 1210 insertions, 210 deletions
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index acfb83bc10..116a86b27b 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -5,6 +5,7 @@ Import('env') gdn_env = env.Clone() gdn_env.add_source_files(env.modules_sources, "gdnative.cpp") gdn_env.add_source_files(env.modules_sources, "register_types.cpp") +gdn_env.add_source_files(env.modules_sources, "android/*.cpp") gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp") gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp") gdn_env.add_source_files(env.modules_sources, "gdnative_library_singleton_editor.cpp") @@ -12,6 +13,7 @@ gdn_env.add_source_files(env.modules_sources, "gdnative_library_editor_plugin.cp gdn_env.Append(CPPPATH=['#modules/gdnative/include/']) +SConscript("net/SCsub") SConscript("arvr/SCsub") SConscript("pluginscript/SCsub") @@ -23,7 +25,8 @@ def _build_gdnative_api_struct_header(api): '\textern const godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct;' ] - for name in api['extensions']: + for ext in api['extensions']: + name = ext['name'] gdnative_api_init_macro.append( '\textern const godot_gdnative_ext_{0}_api_struct *_gdnative_wrapper_{0}_api_struct;'.format(name)) @@ -31,9 +34,10 @@ def _build_gdnative_api_struct_header(api): gdnative_api_init_macro.append('\tfor (unsigned int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { ') gdnative_api_init_macro.append('\t\tswitch (_gdnative_wrapper_api_struct->extensions[i]->type) {') - for name in api['extensions']: + for ext in api['extensions']: + name = ext['name'] gdnative_api_init_macro.append( - '\t\t\tcase GDNATIVE_EXT_%s:' % api['extensions'][name]['type']) + '\t\t\tcase GDNATIVE_EXT_%s:' % ext['type']) gdnative_api_init_macro.append( '\t\t\t\t_gdnative_wrapper_{0}_api_struct = (godot_gdnative_ext_{0}_api_struct *)' ' _gdnative_wrapper_api_struct->extensions[i];'.format(name)) @@ -47,6 +51,7 @@ def _build_gdnative_api_struct_header(api): '#define GODOT_GDNATIVE_API_STRUCT_H', '', '#include <gdnative/gdnative.h>', + '#include <android/godot_android.h>', '#include <arvr/godot_arvr.h>', '#include <nativescript/godot_nativescript.h>', '#include <pluginscript/godot_pluginscript.h>', @@ -61,8 +66,8 @@ def _build_gdnative_api_struct_header(api): '\tGDNATIVE_' + api['core']['type'] + ',' ] - for name in api['extensions']: - out += ['\tGDNATIVE_EXT_' + api['extensions'][name]['type'] + ','] + for ext in api['extensions']: + out += ['\tGDNATIVE_EXT_' + ext['type'] + ','] out += ['};', ''] @@ -88,8 +93,9 @@ def _build_gdnative_api_struct_header(api): return ret_val - for name in api['extensions']: - out += generate_extension_struct(name, api['extensions'][name], False) + for ext in api['extensions']: + name = ext['name'] + out += generate_extension_struct(name, ext, False) out += [ 'typedef struct godot_gdnative_core_api_struct {', @@ -151,12 +157,14 @@ def _build_gdnative_api_struct_source(api): return ret_val - for name in api['extensions']: - out += get_extension_struct_definition(name, api['extensions'][name], False) + for ext in api['extensions']: + name = ext['name'] + out += get_extension_struct_definition(name, ext, False) out += ['', 'const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {'] - for name in api['extensions']: + for ext in api['extensions']: + name = ext['name'] out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,'] out += ['};\n'] @@ -189,7 +197,7 @@ def build_gdnative_api_struct(target, source, env): with open(source.path, 'w') as fd: fd.write(_build_gdnative_api_struct_source(api)) -_, gensource = gdn_env.Command(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'], +_, gensource = gdn_env.CommandNoCache(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'], 'gdnative_api.json', build_gdnative_api_struct) gdn_env.add_source_files(env.modules_sources, [gensource]) @@ -214,7 +222,8 @@ def _build_gdnative_wrapper_code(api): 'godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;', ] - for name in api['extensions']: + for ext in api['extensions']: + name = ext['name'] out.append('godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct = 0;') out += [''] @@ -232,8 +241,9 @@ def _build_gdnative_wrapper_code(api): out.append('}') out.append('') - for name in api['extensions']: - for funcdef in api['extensions'][name]['api']: + for ext in api['extensions']: + name = ext['name'] + for funcdef in ext['api']: args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args)) @@ -267,16 +277,16 @@ def build_gdnative_wrapper_code(target, source, env): if ARGUMENTS.get('gdnative_wrapper', False): - #build wrapper code - gensource, = gdn_env.Command('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', build_gdnative_wrapper_code) +#build wrapper code + gensource, = gdn_env.CommandNoCache('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', build_gdnative_wrapper_code) gd_wrapper_env = env.Clone() gd_wrapper_env.Append(CPPPATH=['#modules/gdnative/include/']) if gd_wrapper_env['use_lto']: if not env.msvc: - gd_wrapper_env.Append(CCFLAGS=['--no-lto']) - gd_wrapper_env.Append(LINKFLAGS=['--no-lto']) + gd_wrapper_env.Append(CCFLAGS=['-fno-lto']) + gd_wrapper_env.Append(LINKFLAGS=['-fno-lto']) else: gd_wrapper_env.Append(CCFLAGS=['/GL-']) gd_wrapper_env.Append(LINKFLAGS=['/LTCG:OFF']) diff --git a/modules/gdnative/android/android_gdn.cpp b/modules/gdnative/android/android_gdn.cpp new file mode 100644 index 0000000000..edc948e086 --- /dev/null +++ b/modules/gdnative/android/android_gdn.cpp @@ -0,0 +1,73 @@ +/*************************************************************************/ +/* android_gdn.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "modules/gdnative/gdnative.h" + +// Code by Paritosh97 with minor tweaks by Mux213 +// These entry points are only for the android platform and are simple stubs in all others. + +#ifdef __ANDROID__ +#include "platform/android/thread_jandroid.h" +#else +#define JNIEnv void +#define jobject void * +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEnv *GDAPI godot_android_get_env() { +#ifdef __ANDROID__ + return ThreadAndroid::get_env(); +#else + return NULL; +#endif +} + +jobject GDAPI godot_android_get_activity() { +#ifdef __ANDROID__ + JNIEnv *env = ThreadAndroid::get_env(); + + jclass activityThread = env->FindClass("android/app/ActivityThread"); + jmethodID currentActivityThread = env->GetStaticMethodID(activityThread, "currentActivityThread", "()Landroid/app/ActivityThread;"); + jobject at = env->CallStaticObjectMethod(activityThread, currentActivityThread); + jmethodID getApplication = env->GetMethodID(activityThread, "getApplication", "()Landroid/app/Application;"); + jobject context = env->CallObjectMethod(at, getApplication); + + return env->NewGlobalRef(context); +#else + return NULL; +#endif +} + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp index 49e0a19d9e..385c020a78 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp @@ -217,6 +217,10 @@ void ARVRInterfaceGDNative::process() { extern "C" { void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface) { + // If our major version is 0 or bigger then 10, we're likely looking at our constructor pointer from an older plugin + ERR_EXPLAINC("GDNative ARVR interfaces build for Godot 3.0 are not supported"); + ERR_FAIL_COND((p_interface->version.major == 0) || (p_interface->version.major > 10)); + Ref<ARVRInterfaceGDNative> new_interface; new_interface.instance(); new_interface->set_interface((godot_arvr_interface_gdnative *const)p_interface); diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py index 68148c4d87..c5b37d35b4 100644 --- a/modules/gdnative/config.py +++ b/modules/gdnative/config.py @@ -1,4 +1,4 @@ -def can_build(platform): +def can_build(env, platform): return True def configure(env): @@ -10,6 +10,7 @@ def get_doc_classes(): "GDNative", "GDNativeLibrary", "NativeScript", + "PacketPeerGDNative", "PluginScript", ] diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml index 998460eee1..be86ff0541 100644 --- a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml +++ b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" category="Core" version="3.1-dev"> +<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" category="Core" version="3.1"> <brief_description> GDNative wrapper for an ARVR interface </brief_description> diff --git a/modules/gdnative/doc_classes/GDNative.xml b/modules/gdnative/doc_classes/GDNative.xml index 4e87cbf450..ca0457623f 100644 --- a/modules/gdnative/doc_classes/GDNative.xml +++ b/modules/gdnative/doc_classes/GDNative.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDNative" inherits="Reference" category="Core" version="3.1-dev"> +<class name="GDNative" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml index ca1bae0598..754a6d2514 100644 --- a/modules/gdnative/doc_classes/GDNativeLibrary.xml +++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDNativeLibrary" inherits="Resource" category="Core" version="3.1-dev"> +<class name="GDNativeLibrary" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> @@ -9,12 +9,6 @@ <demos> </demos> <methods> - <method name="get_config_file"> - <return type="ConfigFile"> - </return> - <description> - </description> - </method> <method name="get_current_dependencies" qualifiers="const"> <return type="PoolStringArray"> </return> @@ -29,6 +23,8 @@ </method> </methods> <members> + <member name="config_file" type="ConfigFile" setter="set_config_file" getter="get_config_file"> + </member> <member name="load_once" type="bool" setter="set_load_once" getter="should_load_once"> </member> <member name="reloadable" type="bool" setter="set_reloadable" getter="is_reloadable"> diff --git a/modules/gdnative/doc_classes/NativeScript.xml b/modules/gdnative/doc_classes/NativeScript.xml index 6a71cd8d4d..1d3053244b 100644 --- a/modules/gdnative/doc_classes/NativeScript.xml +++ b/modules/gdnative/doc_classes/NativeScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NativeScript" inherits="Script" category="Core" version="3.1-dev"> +<class name="NativeScript" inherits="Script" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/doc_classes/PluginScript.xml b/modules/gdnative/doc_classes/PluginScript.xml index 3783d9d0a4..27c6adae3f 100644 --- a/modules/gdnative/doc_classes/PluginScript.xml +++ b/modules/gdnative/doc_classes/PluginScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PluginScript" inherits="Script" category="Core" version="3.1-dev"> +<class name="PluginScript" inherits="Script" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 42c3028f2c..e7ebcc73af 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -66,8 +66,169 @@ GDNativeLibrary::GDNativeLibrary() { GDNativeLibrary::~GDNativeLibrary() { } +bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_property) { + + String name = p_name; + + if (name.begins_with("entry/")) { + String key = name.substr(6, name.length() - 6); + + config_file->set_value("entry", key, p_property); + + set_config_file(config_file); + + return true; + } + + if (name.begins_with("dependency/")) { + String key = name.substr(11, name.length() - 11); + + config_file->set_value("dependencies", key, p_property); + + set_config_file(config_file); + + return true; + } + + return false; +} + +bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_property) const { + String name = p_name; + + if (name.begins_with("entry/")) { + String key = name.substr(6, name.length() - 6); + + r_property = config_file->get_value("entry", key); + + return true; + } + + if (name.begins_with("dependency/")) { + String key = name.substr(11, name.length() - 11); + + r_property = config_file->get_value("dependencies", key); + + return true; + } + + return false; +} + +void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { + // set entries + List<String> entry_key_list; + + if (config_file->has_section("entry")) + config_file->get_section_keys("entry", &entry_key_list); + + for (List<String>::Element *E = entry_key_list.front(); E; E = E->next()) { + String key = E->get(); + + PropertyInfo prop; + + prop.type = Variant::STRING; + prop.name = "entry/" + key; + + p_list->push_back(prop); + } + + // set dependencies + List<String> dependency_key_list; + + if (config_file->has_section("dependencies")) + config_file->get_section_keys("dependencies", &dependency_key_list); + + for (List<String>::Element *E = dependency_key_list.front(); E; E = E->next()) { + String key = E->get(); + + PropertyInfo prop; + + prop.type = Variant::STRING; + prop.name = "dependency/" + key; + + p_list->push_back(prop); + } +} + +void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) { + + set_singleton(p_config_file->get_value("general", "singleton", default_singleton)); + set_load_once(p_config_file->get_value("general", "load_once", default_load_once)); + set_symbol_prefix(p_config_file->get_value("general", "symbol_prefix", default_symbol_prefix)); + set_reloadable(p_config_file->get_value("general", "reloadable", default_reloadable)); + + String entry_lib_path; + { + + List<String> entry_keys; + + if (p_config_file->has_section("entry")) + p_config_file->get_section_keys("entry", &entry_keys); + + for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + entry_lib_path = p_config_file->get_value("entry", key); + break; + } + } + + Vector<String> dependency_paths; + { + + List<String> dependency_keys; + + if (p_config_file->has_section("dependencies")) + p_config_file->get_section_keys("dependencies", &dependency_keys); + + for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + dependency_paths = p_config_file->get_value("dependencies", key); + break; + } + } + + current_library_path = entry_lib_path; + current_dependencies = dependency_paths; +} + void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("get_config_file"), &GDNativeLibrary::get_config_file); + ClassDB::bind_method(D_METHOD("set_config_file", "config_file"), &GDNativeLibrary::set_config_file); ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path); ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies); @@ -82,6 +243,8 @@ void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_symbol_prefix", "symbol_prefix"), &GDNativeLibrary::set_symbol_prefix); ClassDB::bind_method(D_METHOD("set_reloadable", "reloadable"), &GDNativeLibrary::set_reloadable); + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "config_file", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile"), "set_config_file", "get_config_file"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "load_once"), "set_load_once", "should_load_once"); ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton"), "set_singleton", "is_singleton"); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "symbol_prefix"), "set_symbol_prefix", "get_symbol_prefix"); @@ -306,7 +469,9 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced godot_variant result = E->get()(procedure_handle, (godot_array *)&p_arguments); - return *(Variant *)&result; + Variant res = *(Variant *)&result; + godot_variant_destroy(&result); + return res; } Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional) { @@ -337,73 +502,7 @@ RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_or *r_error = err; } - lib->set_singleton(config->get_value("general", "singleton", default_singleton)); - lib->set_load_once(config->get_value("general", "load_once", default_load_once)); - lib->set_symbol_prefix(config->get_value("general", "symbol_prefix", default_symbol_prefix)); - lib->set_reloadable(config->get_value("general", "reloadable", default_reloadable)); - - String entry_lib_path; - { - - List<String> entry_keys; - config->get_section_keys("entry", &entry_keys); - - for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - for (int i = 0; i < tags.size(); i++) { - bool has_feature = OS::get_singleton()->has_feature(tags[i]); - - if (!has_feature) { - skip = true; - break; - } - } - - if (skip) { - continue; - } - - entry_lib_path = config->get_value("entry", key); - break; - } - } - - Vector<String> dependency_paths; - { - - List<String> dependency_keys; - config->get_section_keys("dependencies", &dependency_keys); - - for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - for (int i = 0; i < tags.size(); i++) { - bool has_feature = OS::get_singleton()->has_feature(tags[i]); - - if (!has_feature) { - skip = true; - break; - } - } - - if (skip) { - continue; - } - - dependency_paths = config->get_value("dependencies", key); - break; - } - } - - lib->current_library_path = entry_lib_path; - lib->current_dependencies = dependency_paths; + lib->set_config_file(config); return lib; } diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 3298ea950f..b17bb94f1c 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -66,8 +66,14 @@ public: GDNativeLibrary(); ~GDNativeLibrary(); + virtual bool _set(const StringName &p_name, const Variant &p_property); + virtual bool _get(const StringName &p_name, Variant &r_property) const; + virtual void _get_property_list(List<PropertyInfo> *p_list) const; + _FORCE_INLINE_ Ref<ConfigFile> get_config_file() { return config_file; } + void set_config_file(Ref<ConfigFile> p_config_file); + // things that change per-platform // so there are no setters for this _FORCE_INLINE_ String get_current_library_path() const { diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index a8919f7130..217fd87c3e 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -5756,8 +5756,9 @@ } ] }, - "extensions": { - "nativescript": { + "extensions": [ + { + "name": "nativescript", "type": "NATIVESCRIPT", "version": { "major": 1, @@ -5822,6 +5823,23 @@ ] }, { + "name": "godot_nativescript_set_global_type_tag", + "return_type": "void", + "arguments": [ + ["int", "p_idx"], + ["const char *", "p_name"], + ["const void *", "p_type_tag"] + ] + }, + { + "name": "godot_nativescript_get_global_type_tag", + "return_type": "const void *", + "arguments": [ + ["int", "p_idx"], + ["const char *", "p_name"] + ] + }, + { "name": "godot_nativescript_set_type_tag", "return_type": "void", "arguments": [ @@ -5925,7 +5943,8 @@ } ] }, - "pluginscript": { + { + "name": "pluginscript", "type": "PLUGINSCRIPT", "version": { "major": 1, @@ -5942,8 +5961,9 @@ } ] }, - "arvr": { - "type": "ARVR", + { + "name": "android", + "type": "ANDROID", "version": { "major": 1, "minor": 0 @@ -5951,6 +5971,29 @@ "next": null, "api": [ { + "name": "godot_android_get_env", + "return_type": "JNIEnv*", + "arguments": [ + ] + }, + { + "name": "godot_android_get_activity", + "return_type": "jobject", + "arguments": [ + ] + } + ] + }, + { + "name": "arvr", + "type": "ARVR", + "version": { + "major": 1, + "minor": 1 + }, + "next": null, + "api": [ + { "name": "godot_arvr_register_interface", "return_type": "void", "arguments": [ @@ -6038,5 +6081,5 @@ } ] } - } + ] } diff --git a/modules/gdnative/include/android/godot_android.h b/modules/gdnative/include/android/godot_android.h new file mode 100644 index 0000000000..832dac9ac3 --- /dev/null +++ b/modules/gdnative/include/android/godot_android.h @@ -0,0 +1,54 @@ +/*************************************************************************/ +/* godot_android.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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. */ +/*************************************************************************/ + +#ifndef GODOT_ANDROID_GDN_H +#define GODOT_ANDROID_GDN_H + +#include <gdnative/gdnative.h> + +#ifdef __ANDROID__ +#include <jni.h> +#else +#define JNIEnv void +#define jobject void * +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEnv *GDAPI godot_android_get_env(); +jobject GDAPI godot_android_get_activity(); + +#ifdef __cplusplus +} +#endif + +#endif /* !GODOT_ANDROID_GDN_H */ diff --git a/modules/gdnative/include/arvr/godot_arvr.h b/modules/gdnative/include/arvr/godot_arvr.h index b9aedc0bef..63de62b507 100644 --- a/modules/gdnative/include/arvr/godot_arvr.h +++ b/modules/gdnative/include/arvr/godot_arvr.h @@ -37,7 +37,15 @@ extern "C" { #endif +// For future versions of the API we should only add new functions at the end of the structure and use the +// version info to detect whether a call is available + +// Use these to populate version in your plugin +#define GODOTVR_API_MAJOR 1 +#define GODOTVR_API_MINOR 0 + typedef struct { + godot_gdnative_api_version version; /* version of our API */ void *(*constructor)(godot_object *); void (*destructor)(void *); godot_string (*get_name)(const void *); diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 747328bc41..f28ba352ab 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -43,6 +43,9 @@ typedef enum { GODOT_METHOD_RPC_MODE_SYNC, GODOT_METHOD_RPC_MODE_MASTER, GODOT_METHOD_RPC_MODE_SLAVE, + GODOT_METHOD_RPC_MODE_REMOTESYNC, + GODOT_METHOD_RPC_MODE_MASTERSYNC, + GODOT_METHOD_RPC_MODE_SLAVESYNC, } godot_method_rpc_mode; typedef enum { @@ -214,16 +217,19 @@ void GDAPI godot_nativescript_set_signal_documentation(void *p_gdnative_handle, // type tag API +void GDAPI godot_nativescript_set_global_type_tag(int p_idx, const char *p_name, const void *p_type_tag); +const void GDAPI *godot_nativescript_get_global_type_tag(int p_idx, const char *p_name); + void GDAPI godot_nativescript_set_type_tag(void *p_gdnative_handle, const char *p_name, const void *p_type_tag); const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object); // instance binding API typedef struct { - void *(*alloc_instance_binding_data)(void *, godot_object *); - void (*free_instance_binding_data)(void *, void *); + GDCALLINGCONV void *(*alloc_instance_binding_data)(void *, const void *, godot_object *); + GDCALLINGCONV void (*free_instance_binding_data)(void *, void *); void *data; - void (*free_func)(void *); + GDCALLINGCONV void (*free_func)(void *); } godot_instance_binding_functions; int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_instance_binding_functions p_binding_functions); diff --git a/modules/gdnative/include/net/godot_net.h b/modules/gdnative/include/net/godot_net.h new file mode 100644 index 0000000000..bfa688592d --- /dev/null +++ b/modules/gdnative/include/net/godot_net.h @@ -0,0 +1,118 @@ +/*************************************************************************/ +/* godot_net.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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. */ +/*************************************************************************/ + +#ifndef GODOT_NATIVENET_H +#define GODOT_NATIVENET_H + +#include <gdnative/gdnative.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// For future versions of the API we should only add new functions at the end of the structure and use the +// version info to detect whether a call is available + +// Use these to populate version in your plugin +#define GODOT_NET_API_MAJOR 3 +#define GODOT_NET_API_MINOR 1 + +typedef struct { + + godot_gdnative_api_version version; /* version of our API */ + godot_object *data; /* User reference */ + + /* This is StreamPeer */ + godot_error (*get_data)(void *user, uint8_t *p_buffer, int p_bytes); + godot_error (*get_partial_data)(void *user, uint8_t *p_buffer, int p_bytes, int &r_received); + godot_error (*put_data)(void *user, const uint8_t *p_data, int p_bytes); + godot_error (*put_partial_data)(void *user, const uint8_t *p_data, int p_bytes, int &r_sent); + + int (*get_available_bytes)(const void *user); + + void *next; /* For extension? */ +} godot_net_stream_peer; + +/* Binds a StreamPeerGDNative to the provided interface */ +void godot_net_bind_stream_peer(godot_object *p_obj, godot_net_stream_peer *p_interface); + +typedef struct { + godot_gdnative_api_version version; /* version of our API */ + + godot_object *data; /* User reference */ + + /* This is PacketPeer */ + godot_error (*get_packet)(void *, const uint8_t **, int &); + godot_error (*put_packet)(void *, const uint8_t *, int); + godot_int (*get_available_packet_count)(const void *); + godot_int (*get_max_packet_size)(const void *); + + void *next; /* For extension? */ +} godot_net_packet_peer; + +/* Binds a PacketPeerGDNative to the provided interface */ +void GDAPI godot_net_bind_packet_peer(godot_object *p_obj, const godot_net_packet_peer *); + +typedef struct { + godot_gdnative_api_version version; /* version of our API */ + + godot_object *data; /* User reference */ + + /* This is PacketPeer */ + godot_error (*get_packet)(void *, const uint8_t **, int &); + godot_error (*put_packet)(void *, const uint8_t *, int); + godot_int (*get_available_packet_count)(const void *); + godot_int (*get_max_packet_size)(const void *); + + /* This is NetworkedMultiplayerPeer */ + void (*set_transfer_mode)(void *, godot_int); + godot_int (*get_transfer_mode)(const void *); + // 0 = broadcast, 1 = server, <0 = all but abs(value) + void (*set_target_peer)(void *, godot_int); + godot_int (*get_packet_peer)(const void *); + godot_bool (*is_server)(const void *); + void (*poll)(void *); + // Must be > 0, 1 is for server + int32_t (*get_unique_id)(const void *); + void (*set_refuse_new_connections)(void *, godot_bool); + godot_bool (*is_refusing_new_connections)(const void *); + godot_int (*get_connection_status)(const void *); + + void *next; /* For extension? Or maybe not... */ +} godot_net_multiplayer_peer; + +/* Binds a MultiplayerPeerGDNative to the provided interface */ +void GDAPI godot_net_bind_multiplayer_peer(godot_object *p_obj, const godot_net_multiplayer_peer *); + +#ifdef __cplusplus +} +#endif + +#endif /* GODOT_NATIVENET_H */ diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index aea595d0f0..ace2ecac5c 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -313,6 +313,14 @@ void GDAPI godot_nativescript_set_signal_documentation(void *p_gdnative_handle, signal->get().documentation = *(String *)&p_documentation; } +void GDAPI godot_nativescript_set_global_type_tag(int p_idx, const char *p_name, const void *p_type_tag) { + NativeScriptLanguage::get_singleton()->set_global_type_tag(p_idx, StringName(p_name), p_type_tag); +} + +const void GDAPI *godot_nativescript_get_global_type_tag(int p_idx, const char *p_name) { + return NativeScriptLanguage::get_singleton()->get_global_type_tag(p_idx, StringName(p_name)); +} + void GDAPI godot_nativescript_set_type_tag(void *p_gdnative_handle, const char *p_name, const void *p_type_tag) { String *s = (String *)p_gdnative_handle; @@ -331,13 +339,11 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object) const Object *o = (Object *)p_object; if (!o->get_script_instance()) { - ERR_EXPLAIN("Attempted to get type tag on an object without a script!"); - ERR_FAIL_V(NULL); + return NULL; } else { NativeScript *script = Object::cast_to<NativeScript>(o->get_script_instance()->get_script().ptr()); if (!script) { - ERR_EXPLAIN("Attempted to get type tag on an object without a nativescript attached"); - ERR_FAIL_V(NULL); + return NULL; } if (script->get_script_desc()) @@ -347,10 +353,6 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object) return NULL; } -#ifdef __cplusplus -} -#endif - int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_instance_binding_functions p_binding_functions) { return NativeScriptLanguage::get_singleton()->register_binding_functions(p_binding_functions); } @@ -362,3 +364,7 @@ void GDAPI godot_nativescript_unregister_instance_binding_data_functions(int p_i void GDAPI *godot_nativescript_get_instance_binding_data(int p_idx, godot_object *p_object) { return NativeScriptLanguage::get_singleton()->get_instance_binding_data(p_idx, (Object *)p_object); } + +#ifdef __cplusplus +} +#endif diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index f2e9bef467..d6abbc1bcf 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -55,12 +55,6 @@ #include "editor/editor_node.h" #endif -// -// -// Script stuff -// -// - void NativeScript::_bind_methods() { ClassDB::bind_method(D_METHOD("set_class_name", "class_name"), &NativeScript::set_class_name); ClassDB::bind_method(D_METHOD("get_class_name"), &NativeScript::get_class_name); @@ -363,14 +357,13 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const { NativeScriptDesc *script_data = get_script_desc(); Set<StringName> existing_properties; + List<PropertyInfo>::Element *original_back = p_list->back(); while (script_data) { - List<PropertyInfo>::Element *insert_position = p_list->front(); - bool insert_before = true; + List<PropertyInfo>::Element *insert_position = original_back; for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { if (!existing_properties.has(E.key())) { - insert_position = insert_before ? p_list->insert_before(insert_position, E.get().info) : p_list->insert_after(insert_position, E.get().info); - insert_before = false; + insert_position = p_list->insert_after(insert_position, E.get().info); existing_properties.insert(E.key()); } } @@ -528,12 +521,6 @@ NativeScript::~NativeScript() { #endif } - // - // - // ScriptInstance stuff - // - // - #define GET_SCRIPT_DESC() script->get_script_desc() void NativeScriptInstance::_ml_call_reversed(NativeScriptDesc *script_data, const StringName &p_method, const Variant **p_args, int p_argcount) { @@ -760,7 +747,7 @@ Ref<Script> NativeScriptInstance::get_script() const { return script; } -NativeScriptInstance::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const { +MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const { NativeScriptDesc *script_data = GET_SCRIPT_DESC(); @@ -770,27 +757,33 @@ NativeScriptInstance::RPCMode NativeScriptInstance::get_rpc_mode(const StringNam if (E) { switch (E->get().rpc_mode) { case GODOT_METHOD_RPC_MODE_DISABLED: - return RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; case GODOT_METHOD_RPC_MODE_REMOTE: - return RPC_MODE_REMOTE; + return MultiplayerAPI::RPC_MODE_REMOTE; case GODOT_METHOD_RPC_MODE_SYNC: - return RPC_MODE_SYNC; + return MultiplayerAPI::RPC_MODE_SYNC; case GODOT_METHOD_RPC_MODE_MASTER: - return RPC_MODE_MASTER; + return MultiplayerAPI::RPC_MODE_MASTER; case GODOT_METHOD_RPC_MODE_SLAVE: - return RPC_MODE_SLAVE; + return MultiplayerAPI::RPC_MODE_SLAVE; + case GODOT_METHOD_RPC_MODE_REMOTESYNC: + return MultiplayerAPI::RPC_MODE_REMOTESYNC; + case GODOT_METHOD_RPC_MODE_MASTERSYNC: + return MultiplayerAPI::RPC_MODE_MASTERSYNC; + case GODOT_METHOD_RPC_MODE_SLAVESYNC: + return MultiplayerAPI::RPC_MODE_SLAVESYNC; default: - return RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } } script_data = script_data->base_data; } - return RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } -NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const { +MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const { NativeScriptDesc *script_data = GET_SCRIPT_DESC(); @@ -800,24 +793,24 @@ NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringNa if (E) { switch (E.get().rset_mode) { case GODOT_METHOD_RPC_MODE_DISABLED: - return RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; case GODOT_METHOD_RPC_MODE_REMOTE: - return RPC_MODE_REMOTE; + return MultiplayerAPI::RPC_MODE_REMOTE; case GODOT_METHOD_RPC_MODE_SYNC: - return RPC_MODE_SYNC; + return MultiplayerAPI::RPC_MODE_SYNC; case GODOT_METHOD_RPC_MODE_MASTER: - return RPC_MODE_MASTER; + return MultiplayerAPI::RPC_MODE_MASTER; case GODOT_METHOD_RPC_MODE_SLAVE: - return RPC_MODE_SLAVE; + return MultiplayerAPI::RPC_MODE_SLAVE; default: - return RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } } script_data = script_data->base_data; } - return RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } ScriptLanguage *NativeScriptInstance::get_language() { @@ -872,15 +865,12 @@ NativeScriptInstance::~NativeScriptInstance() { } } -// -// -// ScriptingLanguage stuff -// -// - NativeScriptLanguage *NativeScriptLanguage::singleton; void NativeScriptLanguage::_unload_stuff(bool p_reload) { + + Map<String, Ref<GDNative> > erase_and_unload; + for (Map<String, Map<StringName, NativeScriptDesc> >::Element *L = library_classes.front(); L; L = L->next()) { String lib_path = L->key(); @@ -916,18 +906,6 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { gdn = E->get(); } - if (gdn.is_valid() && gdn->get_library().is_valid()) { - Ref<GDNativeLibrary> lib = gdn->get_library(); - void *terminate_fn; - Error err = gdn->get_symbol(lib->get_symbol_prefix() + _terminate_call_name, terminate_fn, true); - - if (err == OK) { - void (*terminate)(void *) = (void (*)(void *))terminate_fn; - - terminate((void *)&lib_path); - } - } - for (Map<StringName, NativeScriptDesc>::Element *C = classes.front(); C; C = C->next()) { // free property stuff first @@ -952,12 +930,34 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { if (C->get().destroy_func.free_func) C->get().destroy_func.free_func(C->get().destroy_func.method_data); } + + erase_and_unload.insert(lib_path, gdn); + } + + for (Map<String, Ref<GDNative> >::Element *E = erase_and_unload.front(); E; E = E->next()) { + String lib_path = E->key(); + Ref<GDNative> gdn = E->get(); + + library_classes.erase(lib_path); + + if (gdn.is_valid() && gdn->get_library().is_valid()) { + Ref<GDNativeLibrary> lib = gdn->get_library(); + void *terminate_fn; + Error err = gdn->get_symbol(lib->get_symbol_prefix() + _terminate_call_name, terminate_fn, true); + + if (err == OK) { + void (*terminate)(void *) = (void (*)(void *))terminate_fn; + + terminate((void *)&lib_path); + } + } } } NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::singleton = this; #ifndef NO_THREADS + has_objects_to_register = false; mutex = Mutex::create(); #endif } @@ -1182,8 +1182,11 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec } if (!(*binding_data)[p_idx]) { + + const void *global_type_tag = global_type_tags[p_idx].get(p_object->get_class_name()); + // no binding data yet, soooooo alloc new one \o/ - (*binding_data)[p_idx] = binding_functions[p_idx].second.alloc_instance_binding_data(binding_functions[p_idx].second.data, (godot_object *)p_object); + (*binding_data)[p_idx] = binding_functions[p_idx].second.alloc_instance_binding_data(binding_functions[p_idx].second.data, global_type_tag, (godot_object *)p_object); } return (*binding_data)[p_idx]; @@ -1225,6 +1228,27 @@ void NativeScriptLanguage::free_instance_binding_data(void *p_data) { delete &binding_data; } +void NativeScriptLanguage::set_global_type_tag(int p_idx, StringName p_class_name, const void *p_type_tag) { + if (!global_type_tags.has(p_idx)) { + global_type_tags.insert(p_idx, HashMap<StringName, const void *>()); + } + + HashMap<StringName, const void *> &tags = global_type_tags[p_idx]; + + tags.set(p_class_name, p_type_tag); +} + +const void *NativeScriptLanguage::get_global_type_tag(int p_idx, StringName p_class_name) const { + if (!global_type_tags.has(p_idx)) + return NULL; + + const HashMap<StringName, const void *> &tags = global_type_tags[p_idx]; + + const void *tag = tags.get(p_class_name); + + return tag; +} + #ifndef NO_THREADS void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script) { MutexLock lock(mutex); @@ -1362,6 +1386,7 @@ void NativeReloadNode::_notification(int p_what) { MutexLock lock(NSL->mutex); #endif NSL->_unload_stuff(true); + for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { Ref<GDNative> gdn = L->get(); @@ -1375,7 +1400,6 @@ void NativeReloadNode::_notification(int p_what) { } gdn->terminate(); - NSL->library_classes.erase(L->key()); } unloaded = true; diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 17b6ddc747..b47962dc37 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -36,6 +36,7 @@ #include "core/self_list.h" #include "io/resource_loader.h" #include "io/resource_saver.h" +#include "oa_hash_map.h" #include "ordered_hash_map.h" #include "os/thread_safe.h" #include "scene/main/node.h" @@ -195,8 +196,8 @@ public: virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); virtual void notification(int p_notification); virtual Ref<Script> get_script() const; - virtual RPCMode get_rpc_mode(const StringName &p_method) const; - virtual RPCMode get_rset_mode(const StringName &p_variable) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual ScriptLanguage *get_language(); virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); @@ -240,6 +241,8 @@ private: Vector<Pair<bool, godot_instance_binding_functions> > binding_functions; Set<Vector<void *> *> binding_instances; + Map<int, HashMap<StringName, const void *> > global_type_tags; + public: // These two maps must only be touched on the main thread Map<String, Map<StringName, NativeScriptDesc> > library_classes; @@ -323,6 +326,9 @@ public: virtual void *alloc_instance_binding_data(Object *p_object); virtual void free_instance_binding_data(void *p_data); + + void set_global_type_tag(int p_idx, StringName p_class_name, const void *p_type_tag); + const void *get_global_type_tag(int p_idx, StringName p_class_name) const; }; inline NativeScriptDesc *NativeScript::get_script_desc() const { diff --git a/modules/gdnative/net/SCsub b/modules/gdnative/net/SCsub new file mode 100644 index 0000000000..53f9271128 --- /dev/null +++ b/modules/gdnative/net/SCsub @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import os +import methods + +Import('env') +Import('env_modules') + +env_net_gdnative = env_modules.Clone() + +env_net_gdnative.Append(CPPPATH=['#modules/gdnative/include/']) +env_net_gdnative.add_source_files(env.modules_sources, '*.cpp') diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.cpp b/modules/gdnative/net/multiplayer_peer_gdnative.cpp new file mode 100644 index 0000000000..e2d710b5ad --- /dev/null +++ b/modules/gdnative/net/multiplayer_peer_gdnative.cpp @@ -0,0 +1,124 @@ +/*************************************************************************/ +/* multiplayer_peer_gdnative.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "multiplayer_peer_gdnative.h" + +MultiplayerPeerGDNative::MultiplayerPeerGDNative() { + interface = NULL; +} + +MultiplayerPeerGDNative::~MultiplayerPeerGDNative() { +} + +void MultiplayerPeerGDNative::set_native_multiplayer_peer(const godot_net_multiplayer_peer *p_interface) { + interface = p_interface; +} + +Error MultiplayerPeerGDNative::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->get_packet(interface->data, r_buffer, r_buffer_size); +} + +Error MultiplayerPeerGDNative::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->put_packet(interface->data, p_buffer, p_buffer_size); +} + +int MultiplayerPeerGDNative::get_max_packet_size() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_max_packet_size(interface->data); +} + +int MultiplayerPeerGDNative::get_available_packet_count() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_available_packet_count(interface->data); +} + +/* NetworkedMultiplayerPeer */ +void MultiplayerPeerGDNative::set_transfer_mode(TransferMode p_mode) { + ERR_FAIL_COND(interface == NULL); + interface->set_transfer_mode(interface->data, (godot_int)p_mode); +} + +NetworkedMultiplayerPeer::TransferMode MultiplayerPeerGDNative::get_transfer_mode() const { + ERR_FAIL_COND_V(interface == NULL, TRANSFER_MODE_UNRELIABLE); + return (TransferMode)interface->get_transfer_mode(interface->data); +} + +void MultiplayerPeerGDNative::set_target_peer(int p_peer_id) { + ERR_FAIL_COND(interface == NULL); + interface->set_target_peer(interface->data, p_peer_id); +} + +int MultiplayerPeerGDNative::get_packet_peer() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_packet_peer(interface->data); +} + +bool MultiplayerPeerGDNative::is_server() const { + ERR_FAIL_COND_V(interface == NULL, false); + return interface->is_server(interface->data); +} + +void MultiplayerPeerGDNative::poll() { + ERR_FAIL_COND(interface == NULL); + interface->poll(interface->data); +} + +int MultiplayerPeerGDNative::get_unique_id() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_unique_id(interface->data); +} + +void MultiplayerPeerGDNative::set_refuse_new_connections(bool p_enable) { + ERR_FAIL_COND(interface == NULL); + interface->set_refuse_new_connections(interface->data, p_enable); +} + +bool MultiplayerPeerGDNative::is_refusing_new_connections() const { + ERR_FAIL_COND_V(interface == NULL, true); + return interface->is_refusing_new_connections(interface->data); +} + +NetworkedMultiplayerPeer::ConnectionStatus MultiplayerPeerGDNative::get_connection_status() const { + ERR_FAIL_COND_V(interface == NULL, CONNECTION_DISCONNECTED); + return (ConnectionStatus)interface->get_connection_status(interface->data); +} + +void MultiplayerPeerGDNative::_bind_methods() { +} + +extern "C" { + +void GDAPI godot_net_bind_multiplayer_peer(godot_object *p_obj, const godot_net_multiplayer_peer *p_impl) { + + ((MultiplayerPeerGDNative *)p_obj)->set_native_multiplayer_peer(p_impl); +} +} diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.h b/modules/gdnative/net/multiplayer_peer_gdnative.h new file mode 100644 index 0000000000..c8c95b3dd7 --- /dev/null +++ b/modules/gdnative/net/multiplayer_peer_gdnative.h @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* multiplayer_peer_gdnative.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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. */ +/*************************************************************************/ + +#ifndef MULTIPLAYER_PEER_GDNATIVE_H +#define MULTIPLAYER_PEER_GDNATIVE_H + +#include "core/io/networked_multiplayer_peer.h" +#include "modules/gdnative/gdnative.h" +#include "modules/gdnative/include/net/godot_net.h" + +class MultiplayerPeerGDNative : public NetworkedMultiplayerPeer { + GDCLASS(MultiplayerPeerGDNative, NetworkedMultiplayerPeer) + +protected: + static void _bind_methods(); + const godot_net_multiplayer_peer *interface; + +public: + MultiplayerPeerGDNative(); + ~MultiplayerPeerGDNative(); + + /* Sets the interface implementation from GDNative */ + void set_native_multiplayer_peer(const godot_net_multiplayer_peer *p_impl); + + /* Specific to PacketPeer */ + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); + virtual int get_max_packet_size() const; + virtual int get_available_packet_count() const; + + /* Specific to NetworkedMultiplayerPeer */ + virtual void set_transfer_mode(TransferMode p_mode); + virtual TransferMode get_transfer_mode() const; + virtual void set_target_peer(int p_peer_id); + + virtual int get_packet_peer() const; + + virtual bool is_server() const; + + virtual void poll(); + + virtual int get_unique_id() const; + + virtual void set_refuse_new_connections(bool p_enable); + virtual bool is_refusing_new_connections() const; + + virtual ConnectionStatus get_connection_status() const; +}; + +#endif // MULTIPLAYER_PEER_GDNATIVE_H diff --git a/modules/gdnative/net/packet_peer_gdnative.cpp b/modules/gdnative/net/packet_peer_gdnative.cpp new file mode 100644 index 0000000000..ceae79edc0 --- /dev/null +++ b/modules/gdnative/net/packet_peer_gdnative.cpp @@ -0,0 +1,73 @@ +/*************************************************************************/ +/* packet_peer_gdnative.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "packet_peer_gdnative.h" + +PacketPeerGDNative::PacketPeerGDNative() { + interface = NULL; +} + +PacketPeerGDNative::~PacketPeerGDNative() { +} + +void PacketPeerGDNative::set_native_packet_peer(const godot_net_packet_peer *p_impl) { + interface = p_impl; +} + +void PacketPeerGDNative::_bind_methods() { +} + +Error PacketPeerGDNative::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->get_packet(interface->data, r_buffer, r_buffer_size); +} + +Error PacketPeerGDNative::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->put_packet(interface->data, p_buffer, p_buffer_size); +} + +int PacketPeerGDNative::get_max_packet_size() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_max_packet_size(interface->data); +} + +int PacketPeerGDNative::get_available_packet_count() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_available_packet_count(interface->data); +} + +extern "C" { + +void GDAPI godot_net_bind_packet_peer(godot_object *p_obj, const godot_net_packet_peer *p_impl) { + + ((PacketPeerGDNative *)p_obj)->set_native_packet_peer(p_impl); +} +} diff --git a/modules/gdnative/net/packet_peer_gdnative.h b/modules/gdnative/net/packet_peer_gdnative.h new file mode 100644 index 0000000000..71814177ed --- /dev/null +++ b/modules/gdnative/net/packet_peer_gdnative.h @@ -0,0 +1,59 @@ +/*************************************************************************/ +/* packet_peer_gdnative.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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. */ +/*************************************************************************/ + +#ifndef PACKET_PEER_GDNATIVE_H +#define PACKET_PEER_GDNATIVE_H + +#include "core/io/packet_peer.h" +#include "modules/gdnative/gdnative.h" +#include "modules/gdnative/include/net/godot_net.h" + +class PacketPeerGDNative : public PacketPeer { + GDCLASS(PacketPeerGDNative, PacketPeer) + +protected: + static void _bind_methods(); + const godot_net_packet_peer *interface; + +public: + PacketPeerGDNative(); + ~PacketPeerGDNative(); + + /* Sets the interface implementation from GDNative */ + void set_native_packet_peer(const godot_net_packet_peer *p_impl); + + /* Specific to PacketPeer */ + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); + virtual int get_max_packet_size() const; + virtual int get_available_packet_count() const; +}; + +#endif // PACKET_PEER_GDNATIVE_H diff --git a/modules/gdnative/net/register_types.cpp b/modules/gdnative/net/register_types.cpp new file mode 100644 index 0000000000..c3fb4d8008 --- /dev/null +++ b/modules/gdnative/net/register_types.cpp @@ -0,0 +1,43 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "register_types.h" +#include "multiplayer_peer_gdnative.h" +#include "packet_peer_gdnative.h" +#include "stream_peer_gdnative.h" + +void register_net_types() { + ClassDB::register_class<MultiplayerPeerGDNative>(); + ClassDB::register_class<PacketPeerGDNative>(); + ClassDB::register_class<StreamPeerGDNative>(); +} + +void unregister_net_types() { +} diff --git a/modules/gdnative/net/register_types.h b/modules/gdnative/net/register_types.h new file mode 100644 index 0000000000..9545a2ba8f --- /dev/null +++ b/modules/gdnative/net/register_types.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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. */ +/*************************************************************************/ + +void register_net_types(); +void unregister_net_types(); diff --git a/modules/gdnative/net/stream_peer_gdnative.cpp b/modules/gdnative/net/stream_peer_gdnative.cpp new file mode 100644 index 0000000000..4d1f2ec9a5 --- /dev/null +++ b/modules/gdnative/net/stream_peer_gdnative.cpp @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* stream_peer_gdnative.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "stream_peer_gdnative.h" + +StreamPeerGDNative::StreamPeerGDNative() { + interface = NULL; +} + +StreamPeerGDNative::~StreamPeerGDNative() { +} + +void StreamPeerGDNative::set_native_stream_peer(godot_net_stream_peer *p_interface) { + interface = p_interface; +} + +void StreamPeerGDNative::_bind_methods() { +} + +Error StreamPeerGDNative::put_data(const uint8_t *p_data, int p_bytes) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->put_data(interface->data, p_data, p_bytes)); +} + +Error StreamPeerGDNative::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->put_partial_data(interface->data, p_data, p_bytes, r_sent)); +} + +Error StreamPeerGDNative::get_data(uint8_t *p_buffer, int p_bytes) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->get_data(interface->data, p_buffer, p_bytes)); +} + +Error StreamPeerGDNative::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->get_partial_data(interface->data, p_buffer, p_bytes, r_received)); +} + +int StreamPeerGDNative::get_available_bytes() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_available_bytes(interface->data); +} + +extern "C" { + +void GDAPI godot_net_bind_stream_peer(godot_object *p_obj, godot_net_stream_peer *p_interface) { + ((StreamPeerGDNative *)p_obj)->set_native_stream_peer(p_interface); +} +} diff --git a/modules/gdnative/net/stream_peer_gdnative.h b/modules/gdnative/net/stream_peer_gdnative.h new file mode 100644 index 0000000000..654234e6ab --- /dev/null +++ b/modules/gdnative/net/stream_peer_gdnative.h @@ -0,0 +1,61 @@ +/*************************************************************************/ +/* stream_peer_gdnative.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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. */ +/*************************************************************************/ + +#ifndef STREAM_PEER_GDNATIVE_H +#define STREAM_PEER_GDNATIVE_H + +#include "core/io/stream_peer.h" +#include "modules/gdnative/gdnative.h" +#include "modules/gdnative/include/net/godot_net.h" + +class StreamPeerGDNative : public StreamPeer { + + GDCLASS(StreamPeerGDNative, StreamPeer); + +protected: + static void _bind_methods(); + godot_net_stream_peer *interface; + +public: + StreamPeerGDNative(); + ~StreamPeerGDNative(); + + /* Sets the interface implementation from GDNative */ + void set_native_stream_peer(godot_net_stream_peer *p_interface); + + /* Specific to StreamPeer */ + Error put_data(const uint8_t *p_data, int p_bytes); + Error put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent); + Error get_data(uint8_t *p_buffer, int p_bytes); + Error get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received); + int get_available_bytes() const; +}; + +#endif // STREAM_PEER_GDNATIVE_H diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index 931ab0bfe4..13026e8e7a 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.cpp +++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp @@ -138,11 +138,11 @@ void PluginScriptInstance::notification(int p_notification) { _desc->notification(_data, p_notification); } -ScriptInstance::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const { +MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const { return _script->get_rpc_mode(p_method); } -ScriptInstance::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const { +MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const { return _script->get_rset_mode(p_variable); } diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index 3c7b360ad9..8be6a4ccaa 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -76,8 +76,8 @@ public: void set_path(const String &p_path); - virtual RPCMode get_rpc_mode(const StringName &p_method) const; - virtual RPCMode get_rset_mode(const StringName &p_variable) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual void refcount_incremented(); virtual bool refcount_decremented(); diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index 5ae7926f1b..c3a623e9a1 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -84,35 +84,20 @@ StringName PluginScript::get_instance_base_type() const { } void PluginScript::update_exports() { -// TODO #ifdef TOOLS_ENABLED -#if 0 ASSERT_SCRIPT_VALID(); - if (/*changed &&*/ placeholders.size()) { //hm :( + if (placeholders.size()) { //update placeholders if any Map<StringName, Variant> propdefvalues; List<PropertyInfo> propinfos; - const String *props = (const String *)pybind_get_prop_list(_py_exposed_class); - for (int i = 0; props[i] != ""; ++i) { - const String propname = props[i]; - pybind_get_prop_default_value(_py_exposed_class, propname.c_str(), (godot_variant *)&propdefvalues[propname]); - pybind_prop_info raw_info; - pybind_get_prop_info(_py_exposed_class, propname.c_str(), &raw_info); - PropertyInfo info; - info.type = (Variant::Type)raw_info.type; - info.name = propname; - info.hint = (PropertyHint)raw_info.hint; - info.hint_string = *(String *)&raw_info.hint_string; - info.usage = raw_info.usage; - propinfos.push_back(info); - } + + get_script_property_list(&propinfos); for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) { - E->get()->update(propinfos, propdefvalues); + E->get()->update(propinfos, _properties_default_values); } } #endif -#endif } // TODO: rename p_this "p_owner" ? @@ -245,9 +230,9 @@ Error PluginScript::reload(bool p_keep_state) { // rpc_mode is passed as an optional field and is not part of MethodInfo Variant var = v["rpc_mode"]; if (var == Variant()) { - _methods_rpc_mode[mi.name] = ScriptInstance::RPC_MODE_DISABLED; + _methods_rpc_mode[mi.name] = MultiplayerAPI::RPC_MODE_DISABLED; } else { - _methods_rpc_mode[mi.name] = ScriptInstance::RPCMode(int(var)); + _methods_rpc_mode[mi.name] = MultiplayerAPI::RPCMode(int(var)); } } Array *signals = (Array *)&manifest.signals; @@ -265,9 +250,9 @@ Error PluginScript::reload(bool p_keep_state) { // rset_mode is passed as an optional field and is not part of PropertyInfo Variant var = v["rset_mode"]; if (var == Variant()) { - _methods_rpc_mode[pi.name] = ScriptInstance::RPC_MODE_DISABLED; + _methods_rpc_mode[pi.name] = MultiplayerAPI::RPC_MODE_DISABLED; } else { - _methods_rpc_mode[pi.name] = ScriptInstance::RPCMode(int(var)); + _methods_rpc_mode[pi.name] = MultiplayerAPI::RPCMode(int(var)); } } // Manifest's attributes must be explicitly freed @@ -402,23 +387,23 @@ int PluginScript::get_member_line(const StringName &p_member) const { return -1; } -ScriptInstance::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { - ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED); - const Map<StringName, ScriptInstance::RPCMode>::Element *e = _methods_rpc_mode.find(p_method); +MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _methods_rpc_mode.find(p_method); if (e != NULL) { return e->get(); } else { - return ScriptInstance::RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } } -ScriptInstance::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { - ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED); - const Map<StringName, ScriptInstance::RPCMode>::Element *e = _variables_rset_mode.find(p_variable); +MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _variables_rset_mode.find(p_variable); if (e != NULL) { return e->get(); } else { - return ScriptInstance::RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } } diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 1be9e907c2..31c6c4d67f 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -62,8 +62,8 @@ private: Map<StringName, PropertyInfo> _properties_info; Map<StringName, MethodInfo> _signals_info; Map<StringName, MethodInfo> _methods_info; - Map<StringName, ScriptInstance::RPCMode> _variables_rset_mode; - Map<StringName, ScriptInstance::RPCMode> _methods_rpc_mode; + Map<StringName, MultiplayerAPI::RPCMode> _variables_rset_mode; + Map<StringName, MultiplayerAPI::RPCMode> _methods_rpc_mode; Set<Object *> _instances; //exported members @@ -116,8 +116,8 @@ public: virtual int get_member_line(const StringName &p_member) const; - ScriptInstance::RPCMode get_rpc_mode(const StringName &p_method) const; - ScriptInstance::RPCMode get_rset_mode(const StringName &p_variable) const; + MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; PluginScript(); void init(PluginScriptLanguage *language); diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp index 8888f9e157..924abf29df 100644 --- a/modules/gdnative/pluginscript/register_types.cpp +++ b/modules/gdnative/pluginscript/register_types.cpp @@ -64,7 +64,7 @@ static Error _check_language_desc(const godot_pluginscript_language_desc *desc) // desc->make_function is not mandatory // desc->complete_code is not mandatory // desc->auto_indent_code is not mandatory - // desc->add_global_constant is not mandatory + ERR_FAIL_COND_V(!desc->add_global_constant, ERR_BUG); // desc->debug_get_error is not mandatory // desc->debug_get_stack_level_count is not mandatory // desc->debug_get_stack_level_line is not mandatory @@ -78,7 +78,7 @@ static Error _check_language_desc(const godot_pluginscript_language_desc *desc) // desc->profiling_stop is not mandatory // desc->profiling_get_accumulated_data is not mandatory // desc->profiling_get_frame_data is not mandatory - // desc->frame is not mandatory + // desc->profiling_frame is not mandatory ERR_FAIL_COND_V(!desc->script_desc.init, ERR_BUG); ERR_FAIL_COND_V(!desc->script_desc.finish, ERR_BUG); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index a0b6fbeb75..d18297f2f8 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -38,6 +38,7 @@ #include "arvr/register_types.h" #include "nativescript/register_types.h" +#include "net/register_types.h" #include "pluginscript/register_types.h" #include "core/engine.h" @@ -321,6 +322,7 @@ void register_gdnative_types() { GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall); + register_net_types(); register_arvr_types(); register_nativescript_types(); register_pluginscript_types(); @@ -379,6 +381,7 @@ void unregister_gdnative_types() { unregister_pluginscript_types(); unregister_nativescript_types(); unregister_arvr_types(); + unregister_net_types(); memdelete(GDNativeCallRegistry::singleton); |