Browse Source

Merge branch 'master' into arcore_support

Marc 5 years ago
parent
commit
e5334579db
10 changed files with 307 additions and 187 deletions
  1. 156 0
      .gitignore
  2. 5 5
      README.md
  3. 20 17
      SConstruct
  4. 45 9
      binding_generator.py
  5. 3 1
      include/core/Defs.hpp
  6. 18 13
      include/core/Godot.hpp
  7. 3 0
      include/core/String.hpp
  8. 9 2
      include/core/Vector2.hpp
  9. 9 2
      include/core/Vector3.hpp
  10. 39 138
      src/core/String.cpp

+ 156 - 0
.gitignore

@@ -16,3 +16,159 @@ bin
 *.creator.user
 *.files
 *.includes
+
+# Gprof output
+gmon.out
+
+# Vim temp files
+*.swo
+*.swp
+
+# Qt project files
+*.config
+*.creator
+*.creator.*
+*.files
+*.includes
+*.cflags
+*.cxxflags
+
+# Eclipse CDT files
+.cproject
+.settings/
+
+# Geany/geany-plugins files
+*.geany
+.geanyprj
+
+# Misc
+.DS_Store
+logs/
+
+# for projects that use SCons for building: http://http://www.scons.org/
+.sconf_temp
+.sconsign.dblite
+*.pyc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.opendb
+*.VC.VC.opendb
+enc_temp_folder/
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# CodeLite project files
+*.project
+*.workspace
+.codelite/
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+__pycache__/
+
+# KDE
+.directory
+
+#Kdevelop project files
+*.kdev4
+
+# xCode
+xcuserdata
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# =========================
+# Windows detritus
+# =========================
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+logo.h
+*.autosave
+
+# https://github.com/github/gitignore/blob/master/Global/Tags.gitignore
+# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
+TAGS
+!TAGS/
+tags
+*.tags
+!tags/
+gtags.files
+GTAGS
+GRTAGS
+GPATH
+cscope.files
+cscope.out
+cscope.in.out
+cscope.po.out
+godot.creator.*
+
+# Visual Studio 2017 and Visual Studio Code workspace folder
+/.vs
+/.vscode
+
+# Visual Studio Code workspace file
+*.code-workspace
+
+# Scons progress indicator
+.scons_node_count
+
+# ccls cache (https://github.com/MaskRay/ccls)
+.ccls-cache/
+
+# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
+compile_commands.json

+ 5 - 5
README.md

@@ -221,8 +221,8 @@ Once you've compiled the GDNative C++ bindings (see above), you can compile the
 
 ```bash
 cd SimpleLibrary
-clang -fPIC -o src/init.os -c src/init.cpp -g -O3 -std=c++14 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot_headers
-clang -o bin/libtest.so -shared src/init.os -Lgodot-cpp/bin -l<name of the godot-cpp>
+clang++ -fPIC -o src/init.o -c src/init.cpp -g -O3 -std=c++14 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot_headers
+clang++ -o bin/libtest.so -shared src/init.o -Lgodot-cpp/bin -l<name of the godot-cpp>
 ```
 
 You'll need to replace `<name of the godot-cpp>` with the file that was created in [**Compiling the cpp bindings library**](#compiling-the-cpp-bindings-library).
@@ -256,11 +256,11 @@ submit a pull request :slightly_smiling_face:
 
 ```bash
 cd SimpleLibrary
-aarch64-linux-android29-clang -fPIC -o src/init.os -c src/init.cpp -g -O3 -std=c++14 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot_headers
-aarch64-linux-android29-clang -o bin/libtest.so -shared src/init.os -Lgodot-cpp/bin -l<name of the godot-cpp>
+aarch64-linux-android29-clang++ -fPIC -o src/init.o -c src/init.cpp -g -O3 -std=c++14 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot_headers
+aarch64-linux-android29-clang++ -o bin/libtest.so -shared src/init.o -Lgodot-cpp/bin -l<name of the godot-cpp>
 ```
 
-You'll need to replace `<name of the godot-cpp>` with the file that was created in [**Compiling the cpp bindings library**](#compiling-the-cpp-bindings-library). The command above targets `arm64v8`. To target `armv7`, use `armv7a-linux-androideabi29-clang` instead of `aarch64-linux-android29-clang`.
+You'll need to replace `<name of the godot-cpp>` with the file that was created in [**Compiling the cpp bindings library**](#compiling-the-cpp-bindings-library). The command above targets `arm64v8`. To target `armv7`, use `armv7a-linux-androideabi29-clang++` instead of `aarch64-linux-android29-clang++`.
 
 This creates the file `libtest.so` in your `SimpleLibrary/bin` directory.
 

+ 20 - 17
SConstruct

@@ -68,6 +68,17 @@ else:
         'platform=<platform>'
     )
 
+env = Environment(ENV = os.environ)
+
+is64 = sys.maxsize > 2**32
+if (
+    env['TARGET_ARCH'] == 'amd64' or
+    env['TARGET_ARCH'] == 'emt64' or
+    env['TARGET_ARCH'] == 'x86_64' or
+    env['TARGET_ARCH'] == 'arm64-v8a'
+):
+    is64 = True
+
 opts = Variables([], ARGUMENTS)
 opts.Add(EnumVariable(
     'platform',
@@ -79,8 +90,8 @@ opts.Add(EnumVariable(
 opts.Add(EnumVariable(
     'bits',
     'Target platform bits',
-    'default',
-    ('default', '32', '64')
+    '64' if is64 else '32',
+    ('32', '64')
 ))
 opts.Add(BoolVariable(
     'use_llvm',
@@ -144,23 +155,15 @@ opts.Add(
     'Path to your Android NDK installation. By default, uses ANDROID_NDK_ROOT from your defined environment variables.',
     os.environ.get("ANDROID_NDK_ROOT", None)
 )
+opts.Add(BoolVariable(
+	'generate_template_get_node',
+	"Generate a template version of the Node class's get_node.",
+	True
+))
 
-env = Environment(ENV = os.environ)
 opts.Update(env)
 Help(opts.GenerateHelpText(env))
 
-is64 = sys.maxsize > 2**32
-if (
-    env['TARGET_ARCH'] == 'amd64' or
-    env['TARGET_ARCH'] == 'emt64' or
-    env['TARGET_ARCH'] == 'x86_64' or
-    env['TARGET_ARCH'] == 'arm64-v8a'
-):
-    is64 = True
-
-if env['bits'] == 'default':
-    env['bits'] = '64' if is64 else '32'
-
 # This makes sure to keep the session environment variables on Windows.
 # This way, you can run SCons in a Visual Studio 2017 prompt and it will find
 # all the required tools
@@ -356,13 +359,13 @@ json_api_file = ''
 if 'custom_api_file' in env:
     json_api_file = env['custom_api_file']
 else:
-    json_api_file = os.path.join(os.getcwd(), 'godot_headers', 'api.json')
+    json_api_file = os.path.join(os.getcwd(), env['headers_dir'], 'api.json')
 
 if env['generate_bindings']:
     # Actually create the bindings here
     import binding_generator
 
-    binding_generator.generate_bindings(json_api_file)
+    binding_generator.generate_bindings(json_api_file, env['generate_template_get_node'])
 
 # Sources to compile
 sources = []

+ 45 - 9
binding_generator.py

@@ -4,9 +4,16 @@ import json
 
 # comment.
 
+# Convenience function for using template get_node
+def correct_method_name(method_list):
+    for method in method_list:
+        if method["name"] == "get_node":
+            method["name"] = "get_node_internal"
+
+
 classes = []
 
-def generate_bindings(path):
+def generate_bindings(path, use_template_get_node):
 
     global classes
     classes = json.load(open(path))
@@ -16,10 +23,12 @@ def generate_bindings(path):
     for c in classes:
         # print c['name']
         used_classes = get_used_classes(c)
+        if use_template_get_node and c["name"] == "Node":
+            correct_method_name(c["methods"])
 
-        header = generate_class_header(used_classes, c)
+        header = generate_class_header(used_classes, c, use_template_get_node)
 
-        impl = generate_class_implementation(icalls, used_classes, c)
+        impl = generate_class_implementation(icalls, used_classes, c, use_template_get_node)
 
         header_file = open("include/gen/" + strip_name(c["name"]) + ".hpp", "w+")
         header_file.write(header)
@@ -62,7 +71,7 @@ def make_gdnative_type(t, ref_allowed):
         return strip_name(t) + " "
 
 
-def generate_class_header(used_classes, c):
+def generate_class_header(used_classes, c, use_template_get_node):
 
     source = []
     source.append("#ifndef GODOT_CPP_" + strip_name(c["name"]).upper() + "_HPP")
@@ -146,10 +155,14 @@ def generate_class_header(used_classes, c):
 
     source.append("\t};")
     source.append("\tstatic ___method_bindings ___mb;")
+    source.append("\tstatic void *_detail_class_tag;")
     source.append("")
     source.append("public:")
     source.append("\tstatic void ___init_method_bindings();")
 
+    # class id from core engine for casting
+    source.append("\tinline static size_t ___get_id() { return (size_t)_detail_class_tag; }")
+
     source.append("")
 
 
@@ -203,7 +216,6 @@ def generate_class_header(used_classes, c):
         source.append("")
 
     for method in c["methods"]:
-
         method_signature = ""
 
         # TODO decide what to do about virtual methods
@@ -281,10 +293,26 @@ def generate_class_header(used_classes, c):
         source.append("\t" + method_signature + ";")
 
     source.append(vararg_templates)
-    source.append("};")
-    source.append("")
 
+    if use_template_get_node and class_name == "Node":
+        # Extra definition for template get_node that calls the renamed get_node_internal; has a default template parameter for backwards compatibility.
+        source.append("\ttemplate <class T = Node>")
+        source.append("\tT *get_node(const NodePath path) const {")
+        source.append("\t\treturn Object::cast_to<T>(get_node_internal(path));")
+        source.append("\t}")
 
+        source.append("};")
+        source.append("")
+
+        # ...And a specialized version so we don't unnecessarily cast when using the default.
+        source.append("template <>")
+        source.append("inline Node *Node::get_node<Node>(const NodePath path) const {")
+        source.append("\treturn get_node_internal(path);")
+        source.append("}")
+        source.append("")
+    else:
+        source.append("};")
+        source.append("")
 
     source.append("}")
     source.append("")
@@ -298,7 +326,7 @@ def generate_class_header(used_classes, c):
 
 
 
-def generate_class_implementation(icalls, used_classes, c):
+def generate_class_implementation(icalls, used_classes, c, use_template_get_node):
     class_name = strip_name(c["name"])
 
     ref_allowed = class_name != "Object" and class_name != "Reference"
@@ -355,10 +383,18 @@ def generate_class_implementation(icalls, used_classes, c):
     source.append(class_name + "::___method_bindings " + class_name + "::___mb = {};")
     source.append("")
 
+    source.append("void *" + class_name + "::_detail_class_tag = nullptr;")
+    source.append("")
+
     source.append("void " + class_name + "::___init_method_bindings() {")
 
     for method in c["methods"]:
-        source.append("\t___mb.mb_" + method["name"] + " = godot::api->godot_method_bind_get_method(\"" + c["name"] + "\", \"" + method["name"] + "\");")
+        source.append("\t___mb.mb_" + method["name"] + " = godot::api->godot_method_bind_get_method(\"" + c["name"] + "\", \"" + ("get_node" if use_template_get_node and method["name"] == "get_node_internal" else method["name"]) + "\");")
+
+    source.append("\tgodot_string_name class_name;")
+    source.append("\tgodot::api->godot_string_name_new_data(&class_name, \"" + c["name"] + "\");")
+    source.append("\t_detail_class_tag = godot::core_1_2_api->godot_get_class_tag(&class_name);")
+    source.append("\tgodot::api->godot_string_name_destroy(&class_name);")
 
     source.append("}")
     source.append("")

+ 3 - 1
include/core/Defs.hpp

@@ -62,8 +62,10 @@ enum class Error {
 #include <GodotGlobal.hpp>
 
 // alloca() is non-standard. When using MSVC, it's in malloc.h.
-#if defined(__linux__) || defined(__APPLE__) || defined(__MINGW32__)
+#if defined(__linux__) || defined(__APPLE__)
 #include <alloca.h>
+#else
+#include <malloc.h>
 #endif
 
 typedef float real_t;

+ 18 - 13
include/core/Godot.hpp

@@ -100,7 +100,7 @@ public:
 		return godot::detail::create_custom_class_instance<Name>();                         \
 	}                                                                                       \
 	inline static size_t ___get_id() { return typeid(Name).hash_code(); }                   \
-	inline static size_t ___get_base_id() { return typeid(Base).hash_code(); }              \
+	inline static size_t ___get_base_id() { return Base::___get_id(); }                     \
 	inline static const char *___get_base_type_name() { return Base::___get_class_name(); } \
 	inline static godot::Object *___get_from_variant(godot::Variant a) {                    \
 		return (godot::Object *)godot::detail::get_custom_class_instance<Name>(             \
@@ -513,23 +513,28 @@ T *Object::cast_to(const Object *obj) {
 	if (!obj)
 		return nullptr;
 
-	size_t have_tag = (size_t)godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner);
-
-	if (have_tag) {
-		if (!godot::_TagDB::is_type_known((size_t)have_tag)) {
-			have_tag = 0;
+	if (T::___CLASS_IS_SCRIPT) {
+		size_t have_tag = (size_t)godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner);
+		if (have_tag) {
+			if (!godot::_TagDB::is_type_known((size_t)have_tag)) {
+				have_tag = 0;
+			}
 		}
-	}
 
-	if (!have_tag) {
-		have_tag = obj->_type_tag;
-	}
+		if (!have_tag) {
+			have_tag = obj->_type_tag;
+		}
 
-	if (godot::_TagDB::is_type_compatible(typeid(T).hash_code(), have_tag)) {
-		return (T::___CLASS_IS_SCRIPT) ? detail::get_custom_class_instance<T>(obj) : (T *)obj;
+		if (godot::_TagDB::is_type_compatible(T::___get_id(), have_tag)) {
+			return detail::get_custom_class_instance<T>(obj);
+		}
 	} else {
-		return nullptr;
+		if (godot::core_1_2_api->godot_object_cast_to(obj->_owner, (void *)T::___get_id())) {
+			return (T *)obj;
+		}
 	}
+
+	return nullptr;
 }
 #endif
 

+ 3 - 0
include/core/String.hpp

@@ -29,6 +29,9 @@ public:
 class String {
 	godot_string _godot_string;
 
+	String(godot_string contents) :
+			_godot_string(contents) {}
+
 public:
 	String();
 	String(const char *contents);

+ 9 - 2
include/core/Vector2.hpp

@@ -178,6 +178,13 @@ struct Vector2 {
 
 	Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
 
+	Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const {
+		Vector2 v = *this;
+		Vector2 vd = p_to - v;
+		real_t len = vd.length();
+		return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
+	}
+
 	inline Vector2 slide(const Vector2 &p_vec) const {
 		return p_vec - *this * this->dot(p_vec);
 	}
@@ -186,8 +193,8 @@ struct Vector2 {
 		return -reflect(p_normal);
 	}
 
-	inline Vector2 reflect(const Vector2 &p_vec) const {
-		return p_vec - *this * this->dot(p_vec) * 2.0;
+	inline Vector2 reflect(const Vector2 &p_normal) const {
+		return -(*this - p_normal * this->dot(p_normal) * 2.0);
 	}
 
 	inline real_t angle() const {

+ 9 - 2
include/core/Vector3.hpp

@@ -167,6 +167,13 @@ struct Vector3 {
 
 	Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const;
 
+	Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const {
+		Vector3 v = *this;
+		Vector3 vd = p_to - v;
+		real_t len = vd.length();
+		return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
+	}
+
 	Vector3 bounce(const Vector3 &p_normal) const {
 		return -reflect(p_normal);
 	}
@@ -244,8 +251,8 @@ struct Vector3 {
 		return v;
 	}
 
-	inline Vector3 reflect(const Vector3 &by) const {
-		return by - *this * this->dot(by) * 2.f;
+	inline Vector3 reflect(const Vector3 &p_normal) const {
+		return -(*this - p_normal * this->dot(p_normal) * 2.0);
 	}
 
 	inline Vector3 rotated(const Vector3 &axis, const real_t phi) const {

+ 39 - 138
src/core/String.cpp

@@ -25,52 +25,31 @@ const char *godot::CharString::get_data() const {
 }
 
 String String::num(double p_num, int p_decimals) {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_num_with_decimals(p_num, p_decimals);
-
-	return new_string;
+	return String(godot::api->godot_string_num_with_decimals(p_num, p_decimals));
 }
 
 String String::num_scientific(double p_num) {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_num_scientific(p_num);
-
-	return new_string;
+	return String(godot::api->godot_string_num_scientific(p_num));
 }
 
 String String::num_real(double p_num) {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_num_real(p_num);
-
-	return new_string;
+	return String(godot::api->godot_string_num_real(p_num));
 }
 
 String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_num_int64_capitalized(p_num, base, capitalize_hex);
-
-	return new_string;
+	return String(godot::api->godot_string_num_int64_capitalized(p_num, base, capitalize_hex));
 }
 
 String String::chr(godot_char_type p_char) {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_chr(p_char);
-
-	return new_string;
+	return String(godot::api->godot_string_chr(p_char));
 }
 
 String String::md5(const uint8_t *p_md5) {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_md5(p_md5);
-
-	return new_string;
+	return String(godot::api->godot_string_md5(p_md5));
 }
 
 String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_hex_encode_buffer(p_buffer, p_len);
-
-	return new_string;
+	return String(godot::api->godot_string_hex_encode_buffer(p_buffer, p_len));
 }
 
 godot::String::String() {
@@ -124,18 +103,16 @@ bool String::operator!=(const String &s) const {
 }
 
 String String::operator+(const String &s) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string));
 }
 
 void String::operator+=(const String &s) {
-	_godot_string = godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string);
+	*this = String(godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string));
 }
 
 void String::operator+=(const wchar_t c) {
-	// @Todo
+	String _to_be_added = String(c);
+	*this = String(godot::api->godot_string_operator_plus(&_godot_string, &_to_be_added._godot_string));
 }
 
 bool String::operator<(const String &s) const {
@@ -223,24 +200,15 @@ PoolStringArray String::bigrams() const {
 }
 
 String String::c_escape() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_c_escape(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_c_escape(&_godot_string));
 }
 
 String String::c_unescape() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_c_unescape(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_c_unescape(&_godot_string));
 }
 
 String String::capitalize() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_capitalize(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_capitalize(&_godot_string));
 }
 
 bool String::empty() const {
@@ -268,41 +236,31 @@ int String::findn(String p_what, int p_from) const {
 }
 
 String String::format(Variant values) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_format(&_godot_string, (godot_variant *)&values);
-
-	return new_string;
+	return String(godot::api->godot_string_format(&_godot_string, (godot_variant *)&values));
 }
 
 String String::format(Variant values, String placeholder) const {
-	String new_string;
 	godot_char_string contents = godot::api->godot_string_utf8(&placeholder._godot_string);
-	new_string._godot_string = godot::api->godot_string_format_with_custom_placeholder(&_godot_string, (godot_variant *)&values, godot::api->godot_char_string_get_data(&contents));
+	String new_string(godot::api->godot_string_format_with_custom_placeholder(&_godot_string, (godot_variant *)&values, godot::api->godot_char_string_get_data(&contents)));
 	godot::api->godot_char_string_destroy(&contents);
 
 	return new_string;
 }
 
 String String::get_base_dir() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_get_base_dir(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_get_base_dir(&_godot_string));
 }
 
 String String::get_basename() const {
-	godot_string new_string = godot::api->godot_string_get_basename(&_godot_string);
-	return *(String *)&new_string;
+	return String(godot::api->godot_string_get_basename(&_godot_string));
 }
 
 String String::get_extension() const {
-	godot_string new_string = godot::api->godot_string_get_extension(&_godot_string);
-	return *(String *)&new_string;
+	return String(godot::api->godot_string_get_extension(&_godot_string));
 }
 
 String String::get_file() const {
-	godot_string new_string = godot::api->godot_string_get_file(&_godot_string);
-	return *(String *)&new_string;
+	return String(godot::api->godot_string_get_file(&_godot_string));
 }
 
 int String::hash() const {
@@ -314,10 +272,7 @@ int String::hex_to_int() const {
 }
 
 String String::insert(int position, String what) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_insert(&_godot_string, position, what._godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_insert(&_godot_string, position, what._godot_string));
 }
 
 bool String::is_abs_path() const {
@@ -357,17 +312,11 @@ bool String::is_valid_ip_address() const {
 }
 
 String String::json_escape() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_json_escape(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_json_escape(&_godot_string));
 }
 
 String String::left(int position) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_left(&_godot_string, position);
-
-	return new_string;
+	return String(godot::api->godot_string_left(&_godot_string, position));
 }
 
 bool String::match(String expr) const {
@@ -384,10 +333,7 @@ PoolByteArray String::md5_buffer() const {
 }
 
 String String::md5_text() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_md5_text(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_md5_text(&_godot_string));
 }
 
 int String::ord_at(int at) const {
@@ -395,52 +341,31 @@ int String::ord_at(int at) const {
 }
 
 String String::pad_decimals(int digits) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_pad_decimals(&_godot_string, digits);
-
-	return new_string;
+	return String(godot::api->godot_string_pad_decimals(&_godot_string, digits));
 }
 
 String String::pad_zeros(int digits) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_pad_zeros(&_godot_string, digits);
-
-	return new_string;
+	return String(godot::api->godot_string_pad_zeros(&_godot_string, digits));
 }
 
 String String::percent_decode() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_percent_decode(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_percent_decode(&_godot_string));
 }
 
 String String::percent_encode() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_percent_encode(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_percent_encode(&_godot_string));
 }
 
 String String::plus_file(String file) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_plus_file(&_godot_string, &file._godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_plus_file(&_godot_string, &file._godot_string));
 }
 
 String String::replace(String p_key, String p_with) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_replace(&_godot_string, p_key._godot_string, p_with._godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_replace(&_godot_string, p_key._godot_string, p_with._godot_string));
 }
 
 String String::replacen(String what, String forwhat) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_replacen(&_godot_string, what._godot_string, forwhat._godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_replacen(&_godot_string, what._godot_string, forwhat._godot_string));
 }
 
 int String::rfind(String p_what, int p_from) const {
@@ -452,10 +377,7 @@ int String::rfindn(String p_what, int p_from) const {
 }
 
 String String::right(int position) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_right(&_godot_string, position);
-
-	return new_string;
+	return String(godot::api->godot_string_right(&_godot_string, position));
 }
 
 PoolByteArray String::sha256_buffer() const {
@@ -465,10 +387,7 @@ PoolByteArray String::sha256_buffer() const {
 }
 
 String String::sha256_text() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_sha256_text(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_sha256_text(&_godot_string));
 }
 
 float String::similarity(String text) const {
@@ -494,17 +413,11 @@ PoolRealArray String::split_floats(String divisor, bool allow_empty) const {
 }
 
 String String::strip_edges(bool left, bool right) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_strip_edges(&_godot_string, left, right);
-
-	return new_string;
+	return String(godot::api->godot_string_strip_edges(&_godot_string, left, right));
 }
 
 String String::substr(int from, int len) const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_substr(&_godot_string, from, len);
-
-	return new_string;
+	return String(godot::api->godot_string_substr(&_godot_string, from, len));
 }
 
 float String::to_float() const {
@@ -516,31 +429,19 @@ int64_t String::to_int() const {
 }
 
 String String::to_lower() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_to_lower(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_to_lower(&_godot_string));
 }
 
 String String::to_upper() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_to_upper(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_to_upper(&_godot_string));
 }
 
 String String::xml_escape() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_xml_escape(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_xml_escape(&_godot_string));
 }
 
 String String::xml_unescape() const {
-	String new_string;
-	new_string._godot_string = godot::api->godot_string_xml_unescape(&_godot_string);
-
-	return new_string;
+	return String(godot::api->godot_string_xml_unescape(&_godot_string));
 }
 
 signed char String::casecmp_to(String p_str) const {