diff options
Diffstat (limited to 'modules/gdnative/nativescript')
-rw-r--r-- | modules/gdnative/nativescript/api_generator.cpp | 479 | ||||
-rw-r--r-- | modules/gdnative/nativescript/api_generator.h | 7 | ||||
-rw-r--r-- | modules/gdnative/nativescript/godot_nativescript.cpp | 28 | ||||
-rw-r--r-- | modules/gdnative/nativescript/nativescript.cpp | 76 | ||||
-rw-r--r-- | modules/gdnative/nativescript/nativescript.h | 146 | ||||
-rw-r--r-- | modules/gdnative/nativescript/register_types.cpp | 4 | ||||
-rw-r--r-- | modules/gdnative/nativescript/register_types.h | 4 |
7 files changed, 569 insertions, 175 deletions
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 62f2ec5024..3e75478cd8 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 */ @@ -32,11 +32,12 @@ #ifdef TOOLS_ENABLED -#include "core/class_db.h" -#include "core/engine.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/core_constants.h" +#include "core/object/class_db.h" #include "core/os/file_access.h" -#include "core/pair.h" +#include "core/string/string_builder.h" +#include "core/templates/pair.h" // helper stuff @@ -65,14 +66,14 @@ struct MethodAPI { Map<int, Variant> default_arguments; - int argument_count; - bool has_varargs; - bool is_editor; - bool is_noscript; - bool is_const; - bool is_reverse; - bool is_virtual; - bool is_from_script; + int argument_count = 0; + bool has_varargs = false; + bool is_editor = false; + bool is_noscript = false; + bool is_const = false; + bool is_reverse = false; + bool is_virtual = false; + bool is_from_script = false; }; struct PropertyAPI { @@ -80,12 +81,14 @@ struct PropertyAPI { String getter; String setter; String type; - int index; + int index = 0; }; struct ConstantAPI { String constant_name; - int constant_value; + int constant_value = 0; + Variant builtin_constant_value; // For builtin types; + String builtin_constant_type; // For builtin types; }; struct SignalAPI { @@ -100,23 +103,35 @@ struct EnumAPI { List<Pair<int, String>> values; }; +struct OperatorAPI { // For builtin types; + String name; + int oper = Variant::OP_MAX; + String other_type; + String return_type; +}; + struct ClassAPI { String class_name; String super_class_name; - ClassDB::APIType api_type; + ClassDB::APIType api_type = ClassDB::API_NONE; - bool is_singleton; + bool is_singleton = false; String singleton_name; - bool is_instanciable; + bool is_instantiable = false; // @Unclear - bool is_reference; + bool is_reference = false; + bool has_indexing = false; // For builtin types. + String indexed_type; // For builtin types. + bool is_keyed = false; // For builtin types. List<MethodAPI> methods; + List<MethodAPI> constructors; // For builtin types. List<PropertyAPI> properties; List<ConstantAPI> constants; List<SignalAPI> signals_; List<EnumAPI> enums; + List<OperatorAPI> operators; // For builtin types. }; static String get_type_name(const PropertyInfo &info) { @@ -127,7 +142,7 @@ static String get_type_name(const PropertyInfo &info) { return info.class_name; } if (info.hint == PROPERTY_HINT_RESOURCE_TYPE) { - return info.hint_string; + return info.class_name; } if (info.type == Variant::NIL && (info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) { return "Variant"; @@ -139,7 +154,7 @@ static String get_type_name(const PropertyInfo &info) { } /* - * Some comparison helper functions we need + * Some comparison helper functions we need */ struct MethodInfoComparator { @@ -173,20 +188,41 @@ List<ClassAPI> generate_c_api_classes() { ClassDB::get_class_list(&classes); classes.sort_custom<StringName::AlphCompare>(); - // Register global constants as a fake GlobalConstants singleton class + // Register global constants as a fake CoreConstants singleton class { ClassAPI global_constants_api; - global_constants_api.class_name = L"GlobalConstants"; + global_constants_api.class_name = "CoreConstants"; global_constants_api.api_type = ClassDB::API_CORE; global_constants_api.is_singleton = true; - global_constants_api.singleton_name = L"GlobalConstants"; - global_constants_api.is_instanciable = false; - const int constants_count = GlobalConstants::get_global_constant_count(); + global_constants_api.singleton_name = "CoreConstants"; + global_constants_api.is_instantiable = false; + const int constants_count = CoreConstants::get_global_constant_count(); + + Map<StringName, EnumAPI> enum_api_map; for (int i = 0; i < constants_count; ++i) { - ConstantAPI constant_api; - constant_api.constant_name = GlobalConstants::get_global_constant_name(i); - constant_api.constant_value = GlobalConstants::get_global_constant_value(i); - global_constants_api.constants.push_back(constant_api); + StringName enum_name = CoreConstants::get_global_constant_enum(i); + String name = String(CoreConstants::get_global_constant_name(i)); + int value = CoreConstants::get_global_constant_value(i); + + if (enum_name == StringName()) { + ConstantAPI constant_api; + constant_api.constant_name = name; + constant_api.constant_value = value; + global_constants_api.constants.push_back(constant_api); + } else { + EnumAPI enum_api; + if (enum_api_map.has(enum_name)) { + enum_api = enum_api_map[enum_name]; + } else { + enum_api.name = String(enum_name); + } + enum_api.values.push_back(Pair(value, name)); + + enum_api_map[enum_name] = enum_api; + } + } + for (const Map<StringName, EnumAPI>::Element *E = enum_api_map.front(); E; E = E->next()) { + global_constants_api.enums.push_back(E->get()); } global_constants_api.constants.sort_custom<ConstantAPIComparator>(); api.push_back(global_constants_api); @@ -195,6 +231,10 @@ List<ClassAPI> generate_c_api_classes() { for (List<StringName>::Element *e = classes.front(); e != nullptr; e = e->next()) { StringName class_name = e->get(); + if (!ClassDB::is_class_exposed(class_name)) { + continue; + } + ClassAPI class_api; class_api.api_type = ClassDB::get_api_type(e->get()); class_api.class_name = class_name; @@ -209,12 +249,12 @@ List<ClassAPI> generate_c_api_classes() { class_api.singleton_name = name; } } - class_api.is_instanciable = !class_api.is_singleton && ClassDB::can_instance(class_name); + class_api.is_instantiable = !class_api.is_singleton && ClassDB::can_instance(class_name); { List<StringName> inheriters; ClassDB::get_inheriters_from_class("Reference", &inheriters); - bool is_reference = !!inheriters.find(class_name); + bool is_reference = !!inheriters.find(class_name) || class_name == "Reference"; // @Unclear class_api.is_reference = !class_api.is_singleton && is_reference; } @@ -290,12 +330,14 @@ List<ClassAPI> generate_c_api_classes() { property_api.type = p->get().name.get_slice(":", 1); property_api.name = p->get().name.get_slice(":", 0); } else { - property_api.type = get_type_name(p->get()); + MethodInfo minfo; + ClassDB::get_method_info(class_name, property_api.getter, &minfo, true, false); + property_api.type = get_type_name(minfo.return_val); } property_api.index = ClassDB::get_property_index(class_name, p->get().name); - if (!property_api.setter.empty() || !property_api.getter.empty()) { + if (!property_api.setter.is_empty() || !property_api.getter.is_empty()) { class_api.properties.push_back(property_api); } } @@ -352,7 +394,7 @@ List<ClassAPI> generate_c_api_classes() { arg_type = arg_info.name.get_slice(":", 1); arg_name = arg_info.name.get_slice(":", 0); } else if (arg_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { - arg_type = arg_info.hint_string; + arg_type = arg_info.class_name; } else if (arg_info.type == Variant::NIL) { arg_type = "Variant"; } else if (arg_info.type == Variant::OBJECT) { @@ -402,6 +444,192 @@ List<ClassAPI> generate_c_api_classes() { } /* + * Reads the builtin Variant API to a list + */ +List<ClassAPI> generate_c_builtin_api_types() { + List<ClassAPI> api; + + // Special class for the utility methods. + { + ClassAPI utility_api; + utility_api.class_name = "Utilities"; + utility_api.is_instantiable = false; + + List<StringName> utility_functions; + Variant::get_utility_function_list(&utility_functions); + for (const List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { + const StringName &function_name = E->get(); + + MethodAPI function_api; + function_api.method_name = function_name; + function_api.has_varargs = Variant::is_utility_function_vararg(function_name); + function_api.argument_count = function_api.has_varargs ? 0 : Variant::get_utility_function_argument_count(function_name); + function_api.is_const = Variant::get_utility_function_type(function_name) == Variant::UTILITY_FUNC_TYPE_MATH; + + for (int i = 0; i < function_api.argument_count; i++) { + function_api.argument_names.push_back(Variant::get_utility_function_argument_name(function_name, i)); + Variant::Type arg_type = Variant::get_utility_function_argument_type(function_name, i); + function_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type)); + } + + if (Variant::has_utility_function_return_value(function_name)) { + Variant::Type ret_type = Variant::get_utility_function_return_type(function_name); + function_api.return_type = ret_type == Variant::NIL ? "Variant" : Variant::get_type_name(ret_type); + } else { + function_api.return_type = "void"; + } + + utility_api.methods.push_back(function_api); + } + + api.push_back(utility_api); + } + + for (int t = 0; t < Variant::VARIANT_MAX; t++) { + Variant::Type type = (Variant::Type)t; + + ClassAPI class_api; + class_api.class_name = Variant::get_type_name(type); + class_api.is_instantiable = true; + class_api.has_indexing = Variant::has_indexing(type); + class_api.indexed_type = Variant::get_type_name(Variant::get_indexed_element_type(type)); + class_api.is_keyed = Variant::is_keyed(type); + // Types that are passed by reference. + switch (type) { + case Variant::OBJECT: + case Variant::DICTIONARY: + case Variant::ARRAY: + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + case Variant::PACKED_STRING_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: + case Variant::PACKED_COLOR_ARRAY: + class_api.is_reference = true; + break; + default: + class_api.is_reference = false; + break; + } + + // Methods. + + List<StringName> methods; + Variant::get_builtin_method_list(type, &methods); + for (const List<StringName>::Element *E = methods.front(); E; E = E->next()) { + const StringName &method_name = E->get(); + + MethodAPI method_api; + + method_api.method_name = method_name; + method_api.argument_count = Variant::get_builtin_method_argument_count(type, method_name); + method_api.has_varargs = Variant::is_builtin_method_vararg(type, method_name); + method_api.is_const = Variant::is_builtin_method_const(type, method_name); + + for (int i = 0; i < method_api.argument_count; i++) { + method_api.argument_names.push_back(Variant::get_builtin_method_argument_name(type, method_name, i)); + Variant::Type arg_type = Variant::get_builtin_method_argument_type(type, method_name, i); + method_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type)); + } + + Vector<Variant> default_arguments = Variant::get_builtin_method_default_arguments(type, method_name); + + int default_start = method_api.argument_names.size() - default_arguments.size(); + + for (int i = 0; i < default_arguments.size(); i++) { + method_api.default_arguments[default_start + i] = default_arguments[i]; + } + + if (Variant::has_builtin_method_return_value(type, method_name)) { + Variant::Type ret_type = Variant::get_builtin_method_return_type(type, method_name); + method_api.return_type = ret_type == Variant::NIL ? "Variant" : Variant::get_type_name(ret_type); + } else { + method_api.return_type = "void"; + } + + class_api.methods.push_back(method_api); + } + + // Constructors. + + for (int c = 0; c < Variant::get_constructor_count(type); c++) { + MethodAPI constructor_api; + + constructor_api.method_name = Variant::get_type_name(type); + constructor_api.argument_count = Variant::get_constructor_argument_count(type, c); + constructor_api.return_type = Variant::get_type_name(type); + + for (int i = 0; i < constructor_api.argument_count; i++) { + constructor_api.argument_names.push_back(Variant::get_constructor_argument_name(type, c, i)); + Variant::Type arg_type = Variant::get_constructor_argument_type(type, c, i); + constructor_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type)); + } + + class_api.constructors.push_back(constructor_api); + } + + // Constants. + + List<StringName> constants; + Variant::get_constants_for_type(type, &constants); + for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) { + const StringName &constant_name = E->get(); + ConstantAPI constant_api; + + constant_api.constant_name = constant_name; + constant_api.builtin_constant_value = Variant::get_constant_value(type, constant_name); + constant_api.builtin_constant_type = Variant::get_type_name(constant_api.builtin_constant_value.get_type()); + + class_api.constants.push_back(constant_api); + } + + // Members. + + List<StringName> members; + Variant::get_member_list(type, &members); + for (const List<StringName>::Element *E = members.front(); E; E = E->next()) { + const StringName &member_name = E->get(); + + PropertyAPI member_api; + member_api.name = member_name; + Variant::Type member_type = Variant::get_member_type(type, member_name); + member_api.type = member_type == Variant::NIL ? "Variant" : Variant::get_type_name(member_type); + + class_api.properties.push_back(member_api); + } + + // Operators. + + for (int op = 0; op < Variant::OP_MAX; op++) { + Variant::Operator oper = (Variant::Operator)op; + + for (int ot = 0; ot < Variant::VARIANT_MAX; ot++) { + Variant::Type other_type = (Variant::Type)ot; + + if (!Variant::get_validated_operator_evaluator(oper, type, other_type)) { + continue; + } + + OperatorAPI oper_api; + oper_api.name = Variant::get_operator_name(oper); + oper_api.oper = oper; + oper_api.other_type = Variant::get_type_name(other_type); + oper_api.return_type = Variant::get_type_name(Variant::get_operator_return_type(oper, type, other_type)); + + class_api.operators.push_back(oper_api); + } + } + + api.push_back(class_api); + } + + return api; +} + +/* * Generates the JSON source from the API in p_api */ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { @@ -421,9 +649,8 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { source.push_back(String("\t\t\"api_type\": \"") + (api.api_type == ClassDB::API_CORE ? "core" : (api.api_type == ClassDB::API_EDITOR ? "tools" : "none")) + "\",\n"); source.push_back(String("\t\t\"singleton\": ") + (api.is_singleton ? "true" : "false") + ",\n"); source.push_back("\t\t\"singleton_name\": \"" + api.singleton_name + "\",\n"); - source.push_back(String("\t\t\"instanciable\": ") + (api.is_instanciable ? "true" : "false") + ",\n"); + source.push_back(String("\t\t\"instantiable\": ") + (api.is_instantiable ? "true" : "false") + ",\n"); source.push_back(String("\t\t\"is_reference\": ") + (api.is_reference ? "true" : "false") + ",\n"); - // @Unclear source.push_back("\t\t\"constants\": {\n"); for (List<ConstantAPI>::Element *e = api.constants.front(); e; e = e->next()) { @@ -452,6 +679,7 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { source.push_back("\t\t\t\t\t{\n"); source.push_back("\t\t\t\t\t\t\"name\": \"" + e->get().argument_names[i] + "\",\n"); source.push_back("\t\t\t\t\t\t\"type\": \"" + e->get().argument_types[i] + "\",\n"); + source.push_back(String("\t\t\t\t\t\t\"has_default_value\": ") + (e->get().default_arguments.has(i) ? "true" : "false") + ",\n"); source.push_back("\t\t\t\t\t\t\"default_value\": \"" + (e->get().default_arguments.has(i) ? (String)e->get().default_arguments[i] : "") + "\"\n"); source.push_back(String("\t\t\t\t\t}") + ((i < e->get().argument_names.size() - 1) ? "," : "") + "\n"); } @@ -507,6 +735,165 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { return source; } +static int indent_level = 0; + +static void append_indented(StringBuilder &p_source, const String &p_text) { + for (int i = 0; i < indent_level; i++) { + p_source.append("\t"); + } + p_source.append(p_text); + p_source.append("\n"); +} + +static void append_indented(StringBuilder &p_source, const char *p_text) { + for (int i = 0; i < indent_level; i++) { + p_source.append("\t"); + } + p_source.append(p_text); + p_source.append("\n"); +} + +static void write_builtin_method(StringBuilder &p_source, const MethodAPI &p_method) { + append_indented(p_source, vformat(R"("name": "%s",)", p_method.method_name)); + append_indented(p_source, vformat(R"("return_type": "%s",)", p_method.return_type)); + append_indented(p_source, vformat(R"("is_const": %s,)", p_method.is_const ? "true" : "false")); + append_indented(p_source, vformat(R"("has_varargs": %s,)", p_method.has_varargs ? "true" : "false")); + + append_indented(p_source, R"("arguments": [)"); + indent_level++; + for (int i = 0; i < p_method.argument_count; i++) { + append_indented(p_source, "{"); + indent_level++; + + append_indented(p_source, vformat(R"("name": "%s",)", p_method.argument_names[i])); + append_indented(p_source, vformat(R"("type": "%s",)", p_method.argument_types[i])); + append_indented(p_source, vformat(R"("has_default_value": %s,)", p_method.default_arguments.has(i) ? "true" : "false")); + append_indented(p_source, vformat(R"("default_value": "%s")", p_method.default_arguments.has(i) ? p_method.default_arguments[i].operator String() : "")); + + indent_level--; + append_indented(p_source, i < p_method.argument_count - 1 ? "}," : "}"); + } + indent_level--; + append_indented(p_source, "]"); +} + +static List<String> generate_c_builtin_api_json(const List<ClassAPI> &p_api) { + StringBuilder source; + + source.append("[\n"); + + indent_level = 1; + + for (const List<ClassAPI>::Element *C = p_api.front(); C; C = C->next()) { + const ClassAPI &class_api = C->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", class_api.class_name)); + append_indented(source, vformat(R"("is_instantiable": %s,)", class_api.is_instantiable ? "true" : "false")); + append_indented(source, vformat(R"("is_reference": %s,)", class_api.is_reference ? "true" : "false")); + append_indented(source, vformat(R"("has_indexing": %s,)", class_api.has_indexing ? "true" : "false")); + append_indented(source, vformat(R"("indexed_type": "%s",)", class_api.has_indexing && class_api.indexed_type == "Nil" ? "Variant" : class_api.indexed_type)); + append_indented(source, vformat(R"("is_keyed": %s,)", class_api.is_keyed ? "true" : "false")); + + // Constructors. + append_indented(source, R"("constructors": [)"); + indent_level++; + for (const List<MethodAPI>::Element *E = class_api.constructors.front(); E; E = E->next()) { + const MethodAPI &constructor = E->get(); + append_indented(source, "{"); + indent_level++; + + write_builtin_method(source, constructor); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Constants. + append_indented(source, R"("constants": [)"); + indent_level++; + for (const List<ConstantAPI>::Element *E = class_api.constants.front(); E; E = E->next()) { + const ConstantAPI &constant = E->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", constant.constant_name)); + append_indented(source, vformat(R"("type": "%s",)", constant.builtin_constant_type)); + append_indented(source, vformat(R"("value": "%s")", constant.builtin_constant_value.operator String())); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Methods. + append_indented(source, R"("methods": [)"); + indent_level++; + for (const List<MethodAPI>::Element *E = class_api.methods.front(); E; E = E->next()) { + const MethodAPI &method = E->get(); + append_indented(source, "{"); + indent_level++; + + write_builtin_method(source, method); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Members. + append_indented(source, R"("members": [)"); + indent_level++; + for (const List<PropertyAPI>::Element *E = class_api.properties.front(); E; E = E->next()) { + const PropertyAPI &member = E->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", member.name)); + append_indented(source, vformat(R"("type": "%s")", member.type)); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Operators. + append_indented(source, R"("operators": [)"); + indent_level++; + for (const List<OperatorAPI>::Element *E = class_api.operators.front(); E; E = E->next()) { + const OperatorAPI &oper = E->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", oper.name)); + append_indented(source, vformat(R"("operator": %d,)", oper.oper)); + append_indented(source, vformat(R"("other_type": "%s",)", oper.other_type)); + append_indented(source, vformat(R"("return_type": "%s")", oper.return_type)); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "]"); + + indent_level--; + append_indented(source, C->next() ? "}," : "}"); + } + + indent_level--; + source.append("]\n"); + + List<String> result; + result.push_back(source.as_string()); + return result; +} + #endif /* @@ -525,3 +912,19 @@ Error generate_c_api(const String &p_path) { return save_file(p_path, json_source); #endif } +/* + * Saves the builtin Godot API to a JSON file located at + * p_path + */ +Error generate_c_builtin_api(const String &p_path) { +#ifndef TOOLS_ENABLED + return ERR_BUG; +#else + + List<ClassAPI> api = generate_c_builtin_api_types(); + + List<String> json_source = generate_c_builtin_api_json(api); + + return save_file(p_path, json_source); +#endif +} diff --git a/modules/gdnative/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h index edbb1d1f23..611abb2a2d 100644 --- a/modules/gdnative/nativescript/api_generator.h +++ b/modules/gdnative/nativescript/api_generator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 */ @@ -31,9 +31,10 @@ #ifndef API_GENERATOR_H #define API_GENERATOR_H +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" Error generate_c_api(const String &p_path); +Error generate_c_builtin_api(const String &p_path); #endif // API_GENERATOR_H diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index 1aea8ad160..b2abf8b8ae 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 */ @@ -30,11 +30,11 @@ #include "nativescript/godot_nativescript.h" -#include "core/class_db.h" -#include "core/error_macros.h" -#include "core/global_constants.h" -#include "core/project_settings.h" -#include "core/variant.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" +#include "core/error/error_macros.h" +#include "core/object/class_db.h" +#include "core/variant/variant.h" #include "gdnative/gdnative.h" #include <stdint.h> @@ -51,7 +51,7 @@ extern "C" void _native_script_hook() { // Script API -void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func) { +void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char *p_name, const char *p_base, godot_nativescript_instance_create_func p_create_func, godot_nativescript_instance_destroy_func p_destroy_func) { String *s = (String *)p_gdnative_handle; Map<StringName, NativeScriptDesc> *classes = &NSL->library_classes[*s]; @@ -83,7 +83,7 @@ void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char classes->insert(p_name, desc); } -void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func) { +void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const char *p_name, const char *p_base, godot_nativescript_instance_create_func p_create_func, godot_nativescript_instance_destroy_func p_destroy_func) { String *s = (String *)p_gdnative_handle; Map<StringName, NativeScriptDesc> *classes = &NSL->library_classes[*s]; @@ -116,7 +116,7 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const classes->insert(p_name, desc); } -void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const char *p_name, const char *p_function_name, godot_method_attributes p_attr, godot_instance_method p_method) { +void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const char *p_name, const char *p_function_name, godot_nativescript_method_attributes p_attr, godot_nativescript_instance_method p_method) { String *s = (String *)p_gdnative_handle; Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name); @@ -135,7 +135,7 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha E->get().methods.insert(p_function_name, method); } -void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const char *p_name, const char *p_path, godot_property_attributes *p_attr, godot_property_set_func p_set_func, godot_property_get_func p_get_func) { +void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const char *p_name, const char *p_path, godot_nativescript_property_attributes *p_attr, godot_nativescript_property_set_func p_set_func, godot_nativescript_property_get_func p_get_func) { String *s = (String *)p_gdnative_handle; Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name); @@ -221,7 +221,7 @@ void GDAPI *godot_nativescript_get_userdata(godot_object *p_instance) { * */ -void GDAPI godot_nativescript_set_method_argument_information(void *p_gdnative_handle, const char *p_name, const char *p_function_name, int p_num_args, const godot_method_arg *p_args) { +void GDAPI godot_nativescript_set_method_argument_information(void *p_gdnative_handle, const char *p_name, const char *p_function_name, int p_num_args, const godot_nativescript_method_argument *p_args) { String *s = (String *)p_gdnative_handle; Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name); @@ -235,7 +235,7 @@ void GDAPI godot_nativescript_set_method_argument_information(void *p_gdnative_h List<PropertyInfo> args; for (int i = 0; i < p_num_args; i++) { - godot_method_arg arg = p_args[i]; + godot_nativescript_method_argument arg = p_args[i]; String name = *(String *)&arg.name; String hint_string = *(String *)&arg.hint_string; @@ -329,7 +329,7 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object) return nullptr; } -int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_instance_binding_functions p_binding_functions) { +int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_nativescript_instance_binding_functions p_binding_functions) { return NativeScriptLanguage::get_singleton()->register_binding_functions(p_binding_functions); } diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index f3dfd0b68e..1bdbb0b03b 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 */ @@ -34,12 +34,12 @@ #include "gdnative/gdnative.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "core/core_string_names.h" -#include "core/global_constants.h" #include "core/io/file_access_encrypted.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/main/scene_tree.h" #include "scene/resources/resource_format_text.h" @@ -717,7 +717,7 @@ String NativeScript::get_property_documentation(const StringName &p_path) const } Variant NativeScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - if (lib_path.empty() || class_name.empty() || library.is_null()) { + if (lib_path.is_empty() || class_name.is_empty() || library.is_null()) { r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; return Variant(); } @@ -991,7 +991,8 @@ void NativeScriptInstance::notification(int p_notification) { Variant value = p_notification; const Variant *args[1] = { &value }; - call_multilevel("_notification", args, 1); + Callable::CallError error; + call("_notification", args, 1, error); } String NativeScriptInstance::to_string(bool *r_valid) { @@ -1087,31 +1088,6 @@ ScriptLanguage *NativeScriptInstance::get_language() { return NativeScriptLanguage::get_singleton(); } -void NativeScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) { - NativeScriptDesc *script_data = GET_SCRIPT_DESC(); - - while (script_data) { - Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method); - if (E) { - godot_variant res = E->get().method.method((godot_object *)owner, - E->get().method.method_data, - userdata, - p_argcount, - (godot_variant **)p_args); - godot_variant_destroy(&res); - } - script_data = script_data->base_data; - } -} - -void NativeScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) { - NativeScriptDesc *script_data = GET_SCRIPT_DESC(); - - if (script_data) { - _ml_call_reversed(script_data, p_method, p_args, p_argcount); - } -} - NativeScriptInstance::~NativeScriptInstance() { NativeScriptDesc *script_data = GET_SCRIPT_DESC(); @@ -1220,13 +1196,6 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::singleton = this; -#ifndef NO_THREADS - has_objects_to_register = false; -#endif - -#ifdef DEBUG_ENABLED - profiling = false; -#endif _init_call_type = "nativescript_init"; _init_call_name = "nativescript_init"; @@ -1281,6 +1250,15 @@ void NativeScriptLanguage::init() { } exit(0); } + + E = args.find("--gdnative-generate-json-builtin-api"); + + if (E && E->next()) { + if (generate_c_builtin_api(E->next()->get()) != OK) { + ERR_PRINT("Failed to generate C builtin API\n"); + } + exit(0); + } #endif #ifdef TOOLS_ENABLED @@ -1498,7 +1476,7 @@ void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p #endif } -int NativeScriptLanguage::register_binding_functions(godot_instance_binding_functions p_binding_functions) { +int NativeScriptLanguage::register_binding_functions(godot_nativescript_instance_binding_functions p_binding_functions) { // find index int idx = -1; @@ -1692,7 +1670,7 @@ void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeSc MutexLock lock(mutex); libs_to_init.insert(lib); scripts_to_register.insert(script); - has_objects_to_register = true; + has_objects_to_register.set(); } #endif @@ -1748,6 +1726,12 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) { S->get().erase(script); if (S->get().size() == 0) { library_script_users.erase(S); + + Map<String, Ref<GDNative>>::Element *G = library_gdnatives.find(script->lib_path); + if (G && G->get()->get_library()->is_reloadable()) { + G->get()->terminate(); + library_gdnatives.erase(G); + } } } #ifndef NO_THREADS @@ -1775,7 +1759,7 @@ void NativeScriptLanguage::call_libraries_cb(const StringName &name) { void NativeScriptLanguage::frame() { #ifndef NO_THREADS - if (has_objects_to_register) { + if (has_objects_to_register.is_set()) { MutexLock lock(mutex); for (Set<Ref<GDNativeLibrary>>::Element *L = libs_to_init.front(); L; L = L->next()) { init_library(L->get()); @@ -1785,7 +1769,7 @@ void NativeScriptLanguage::frame() { register_script(S->get()); } scripts_to_register.clear(); - has_objects_to_register = false; + has_objects_to_register.clear(); } #endif @@ -1824,7 +1808,7 @@ bool NativeScriptLanguage::handles_global_class_type(const String &p_type) const } String NativeScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const { - if (!p_path.empty()) { + if (!p_path.is_empty()) { Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript"); if (script.is_valid()) { if (r_base_type) { @@ -1853,7 +1837,7 @@ void NativeReloadNode::_notification(int p_what) { #ifdef TOOLS_ENABLED switch (p_what) { - case NOTIFICATION_WM_FOCUS_OUT: { + case NOTIFICATION_APPLICATION_FOCUS_OUT: { if (unloaded) { break; } @@ -1887,7 +1871,7 @@ void NativeReloadNode::_notification(int p_what) { } break; - case NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_APPLICATION_FOCUS_IN: { if (!unloaded) { break; } @@ -1956,7 +1940,7 @@ void NativeReloadNode::_notification(int p_what) { #endif } -RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_no_cache) { return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error); } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 1aca142889..d6ba2bbec1 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 */ @@ -31,15 +31,17 @@ #ifndef NATIVE_SCRIPT_H #define NATIVE_SCRIPT_H +#include "core/doc_data.h" +#include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/oa_hash_map.h" -#include "core/ordered_hash_map.h" +#include "core/object/script_language.h" #include "core/os/mutex.h" #include "core/os/thread_safe.h" -#include "core/resource.h" -#include "core/script_language.h" -#include "core/self_list.h" +#include "core/templates/oa_hash_map.h" +#include "core/templates/ordered_hash_map.h" +#include "core/templates/safe_refcount.h" +#include "core/templates/self_list.h" #include "scene/main/node.h" #include "modules/gdnative/gdnative.h" @@ -48,19 +50,19 @@ struct NativeScriptDesc { struct Method { - godot_instance_method method; + godot_nativescript_instance_method method; MethodInfo info; - int rpc_mode; - uint16_t rpc_method_id; + int rpc_mode = 0; + uint16_t rpc_method_id = 0; String documentation; }; struct Property { - godot_property_set_func setter; - godot_property_get_func getter; + godot_nativescript_property_set_func setter; + godot_nativescript_property_get_func getter; PropertyInfo info; Variant default_value; - int rset_mode; + int rset_mode = 0; uint16_t rset_property_id; String documentation; }; @@ -77,19 +79,19 @@ struct NativeScriptDesc { Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals StringName base; StringName base_native_type; - NativeScriptDesc *base_data; - godot_instance_create_func create_func; - godot_instance_destroy_func destroy_func; + NativeScriptDesc *base_data = nullptr; + godot_nativescript_instance_create_func create_func; + godot_nativescript_instance_destroy_func destroy_func; String documentation; const void *type_tag = nullptr; - bool is_tool; + bool is_tool = false; inline NativeScriptDesc() { - zeromem(&create_func, sizeof(godot_instance_create_func)); - zeromem(&destroy_func, sizeof(godot_instance_destroy_func)); + zeromem(&create_func, sizeof(godot_nativescript_instance_create_func)); + zeromem(&destroy_func, sizeof(godot_nativescript_instance_destroy_func)); } }; @@ -99,7 +101,7 @@ class NativeScript : public Script { #ifdef TOOLS_ENABLED Set<PlaceHolderScriptInstance *> placeholders; void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); - virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); + virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override; #endif friend class NativeScriptInstance; @@ -125,7 +127,7 @@ protected: public: inline NativeScriptDesc *get_script_desc() const; - bool inherits_script(const Ref<Script> &p_script) const; + bool inherits_script(const Ref<Script> &p_script) const override; void set_class_name(String p_class_name); String get_class_name() const; @@ -138,48 +140,55 @@ public: void set_script_class_icon_path(String p_icon_path); String get_script_class_icon_path() const; - virtual bool can_instance() const; + virtual bool can_instance() const override; - virtual Ref<Script> get_base_script() const; //for script inheritance + virtual Ref<Script> get_base_script() const override; //for script inheritance - virtual StringName get_instance_base_type() const; // this may not work in all scripts, will return empty if so - virtual ScriptInstance *instance_create(Object *p_this); - virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this); - virtual bool instance_has(const Object *p_this) const; + virtual StringName get_instance_base_type() const override; // this may not work in all scripts, will return empty if so + virtual ScriptInstance *instance_create(Object *p_this) override; + virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override; + virtual bool instance_has(const Object *p_this) const override; - virtual bool has_source_code() const; - virtual String get_source_code() const; - virtual void set_source_code(const String &p_code); - virtual Error reload(bool p_keep_state = false); + virtual bool has_source_code() const override; + virtual String get_source_code() const override; + virtual void set_source_code(const String &p_code) override; + virtual Error reload(bool p_keep_state = false) override; - virtual bool has_method(const StringName &p_method) const; - virtual MethodInfo get_method_info(const StringName &p_method) const; +#ifdef TOOLS_ENABLED + virtual const Vector<DocData::ClassDoc> &get_documentation() const override { + static Vector<DocData::ClassDoc> docs; + return docs; + } +#endif // TOOLS_ENABLED - virtual bool is_tool() const; - virtual bool is_valid() const; + virtual bool has_method(const StringName &p_method) const override; + virtual MethodInfo get_method_info(const StringName &p_method) const override; - virtual ScriptLanguage *get_language() const; + virtual bool is_tool() const override; + virtual bool is_valid() const override; - virtual bool has_script_signal(const StringName &p_signal) const; - virtual void get_script_signal_list(List<MethodInfo> *r_signals) const; + virtual ScriptLanguage *get_language() const override; - virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const; + virtual bool has_script_signal(const StringName &p_signal) const override; + virtual void get_script_signal_list(List<MethodInfo> *r_signals) const override; - virtual void update_exports(); //editor tool - virtual void get_script_method_list(List<MethodInfo> *p_list) const; - virtual void get_script_property_list(List<PropertyInfo> *p_list) const; + virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const override; - virtual Vector<ScriptNetData> get_rpc_methods() const; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + virtual void update_exports() override; //editor tool + virtual void get_script_method_list(List<MethodInfo> *p_list) const override; + virtual void get_script_property_list(List<PropertyInfo> *p_list) const override; - virtual Vector<ScriptNetData> get_rset_properties() const; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const; - virtual StringName get_rset_property(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual Vector<ScriptNetData> get_rpc_methods() const override; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const override; + virtual StringName get_rpc_method(uint16_t p_id) const override; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const override; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; + + virtual Vector<ScriptNetData> get_rset_properties() const override; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const override; + virtual StringName get_rset_property(uint16_t p_id) const override; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const override; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; String get_class_documentation() const; String get_method_documentation(const StringName &p_method) const; @@ -231,9 +240,6 @@ public: virtual ScriptLanguage *get_language(); - virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); - virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount); - virtual void refcount_incremented(); virtual bool refcount_decremented(); @@ -249,7 +255,7 @@ class NativeScriptLanguage : public ScriptLanguage { private: static NativeScriptLanguage *singleton; - int lang_idx; + int lang_idx = 0; void _unload_stuff(bool p_reload = false); @@ -257,7 +263,7 @@ private: #ifndef NO_THREADS Set<Ref<GDNativeLibrary>> libs_to_init; Set<NativeScript *> scripts_to_register; - volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed + SafeFlag has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed void defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script); #endif @@ -267,26 +273,26 @@ private: void call_libraries_cb(const StringName &name); - Vector<Pair<bool, godot_instance_binding_functions>> binding_functions; + Vector<Pair<bool, godot_nativescript_instance_binding_functions>> binding_functions; Set<Vector<void *> *> binding_instances; Map<int, HashMap<StringName, const void *>> global_type_tags; struct ProfileData { StringName signature; - uint64_t call_count; - uint64_t self_time; - uint64_t total_time; - uint64_t frame_call_count; - uint64_t frame_self_time; - uint64_t frame_total_time; - uint64_t last_frame_call_count; - uint64_t last_frame_self_time; - uint64_t last_frame_total_time; + uint64_t call_count = 0; + uint64_t self_time = 0; + uint64_t total_time = 0; + uint64_t frame_call_count = 0; + uint64_t frame_self_time = 0; + uint64_t frame_total_time = 0; + uint64_t last_frame_call_count = 0; + uint64_t last_frame_self_time = 0; + uint64_t last_frame_total_time = 0; }; Map<StringName, ProfileData> profile_data; - bool profiling; + bool profiling = false; public: // These two maps must only be touched on the main thread @@ -360,7 +366,7 @@ public: virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max); virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max); - int register_binding_functions(godot_instance_binding_functions p_binding_functions); + int register_binding_functions(godot_nativescript_instance_binding_functions p_binding_functions); void unregister_binding_functions(int p_idx); void *get_instance_binding_data(int p_idx, Object *p_object); @@ -397,7 +403,7 @@ public: class ResourceFormatLoaderNativeScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp index ac8c7ab2fd..0353ab2092 100644 --- a/modules/gdnative/nativescript/register_types.cpp +++ b/modules/gdnative/nativescript/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 */ diff --git a/modules/gdnative/nativescript/register_types.h b/modules/gdnative/nativescript/register_types.h index 088bf38dd5..d12ac9eda3 100644 --- a/modules/gdnative/nativescript/register_types.h +++ b/modules/gdnative/nativescript/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 */ |