summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub48
-rw-r--r--core/array.cpp2
-rw-r--r--core/class_db.cpp182
-rw-r--r--core/color.cpp53
-rw-r--r--core/color.h4
-rw-r--r--core/compressed_translation.cpp12
-rw-r--r--core/core_builders.py236
-rw-r--r--core/cowdata.h332
-rw-r--r--core/io/file_access_encrypted.cpp12
-rw-r--r--core/io/file_access_memory.cpp2
-rw-r--r--core/io/file_access_network.cpp10
-rw-r--r--core/io/http_client.cpp2
-rw-r--r--core/io/multiplayer_api.cpp38
-rw-r--r--core/io/packet_peer.cpp8
-rw-r--r--core/io/pck_packer.cpp2
-rw-r--r--core/io/resource_format_binary.cpp4
-rw-r--r--core/io/resource_loader.cpp2
-rw-r--r--core/io/stream_peer.cpp2
-rw-r--r--core/io/stream_peer_ssl.cpp2
-rw-r--r--core/make_binders.py9
-rw-r--r--core/math/bsp_tree.cpp22
-rw-r--r--core/math/delaunay.h6
-rw-r--r--core/math/geometry.cpp22
-rw-r--r--core/math/geometry.h4
-rw-r--r--core/math/matrix3.cpp9
-rw-r--r--core/math/matrix3.h6
-rw-r--r--core/math/quick_hull.cpp8
-rw-r--r--core/math/transform.cpp9
-rw-r--r--core/math/triangulate.cpp6
-rw-r--r--core/method_bind.h2
-rw-r--r--core/method_ptrcall.h12
-rw-r--r--core/node_path.cpp2
-rw-r--r--core/object.cpp8
-rw-r--r--core/os/file_access.cpp8
-rw-r--r--core/os/input_event.cpp8
-rw-r--r--core/os/input_event.h1
-rw-r--r--core/os/threaded_array_processor.h2
-rw-r--r--core/packed_data_container.cpp18
-rw-r--r--core/project_settings.cpp6
-rw-r--r--core/ring_buffer.h6
-rw-r--r--core/script_debugger_local.cpp4
-rw-r--r--core/script_debugger_remote.cpp8
-rw-r--r--core/string_buffer.h2
-rw-r--r--core/typedefs.h6
-rw-r--r--core/undo_redo.cpp26
-rw-r--r--core/ustring.cpp28
-rw-r--r--core/ustring.h51
-rw-r--r--core/variant.cpp22
-rw-r--r--core/variant_call.cpp14
-rw-r--r--core/vector.h382
-rw-r--r--core/vmap.h49
-rw-r--r--core/vset.h2
52 files changed, 1075 insertions, 646 deletions
diff --git a/core/SCsub b/core/SCsub
index c508ecc37e..c8e2e10b9f 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -2,7 +2,9 @@
Import('env')
-import methods
+import core_builders
+import make_binders
+from platform_methods import run_in_subprocess
env.core_sources = []
@@ -21,7 +23,7 @@ gd_cpp += gd_inc
gd_cpp += "void ProjectSettings::register_global_defaults() {\n" + gd_call + "\n}\n"
with open("global_defaults.gen.cpp", "w") as f:
- f.write(gd_cpp)
+ f.write(gd_cpp)
# Generate AES256 script encryption key
@@ -48,26 +50,27 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
print("Invalid AES256 encryption key, not 64 bits hex: " + e)
+# NOTE: It is safe to generate this file here, since this is still executed serially
with open("script_encryption_key.gen.cpp", "w") as f:
- f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
+ f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
# Add required thirdparty code. Header paths are hardcoded, we don't need to append
# to the include path (saves a few chars on the compiler invocation for touchy MSVC...)
thirdparty_dir = "#thirdparty/misc/"
thirdparty_sources = [
- # C sources
- "base64.c",
- "fastlz.c",
- "sha256.c",
- "smaz.c",
-
- # C++ sources
- "aes256.cpp",
- "hq2x.cpp",
- "md5.cpp",
- "pcg.cpp",
- "triangulator.cpp",
+ # C sources
+ "base64.c",
+ "fastlz.c",
+ "sha256.c",
+ "smaz.c",
+
+ # C++ sources
+ "aes256.cpp",
+ "hq2x.cpp",
+ "md5.cpp",
+ "pcg.cpp",
+ "triangulator.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env.add_source_files(env.core_sources, thirdparty_sources)
@@ -76,9 +79,9 @@ env.add_source_files(env.core_sources, thirdparty_sources)
# However, our version has some custom modifications, so it won't compile with the system one
thirdparty_minizip_dir = "#thirdparty/minizip/"
thirdparty_minizip_sources = [
- "ioapi.c",
- "unzip.c",
- "zip.c",
+ "ioapi.c",
+ "unzip.c",
+ "zip.c",
]
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
env.add_source_files(env.core_sources, thirdparty_minizip_sources)
@@ -92,20 +95,19 @@ env.add_source_files(env.core_sources, "*.cpp")
# Make binders
-import make_binders
-env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run)
+env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run))
# Authors
env.Depends('#core/authors.gen.h', "../AUTHORS.md")
-env.CommandNoCache('#core/authors.gen.h', "../AUTHORS.md", methods.make_authors_header)
+env.CommandNoCache('#core/authors.gen.h', "../AUTHORS.md", run_in_subprocess(core_builders.make_authors_header))
# Donors
env.Depends('#core/donors.gen.h', "../DONORS.md")
-env.CommandNoCache('#core/donors.gen.h', "../DONORS.md", methods.make_donors_header)
+env.CommandNoCache('#core/donors.gen.h', "../DONORS.md", run_in_subprocess(core_builders.make_donors_header))
# License
env.Depends('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"])
-env.CommandNoCache('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], methods.make_license_header)
+env.CommandNoCache('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(core_builders.make_license_header))
# Chain load SCsubs
SConscript('os/SCsub')
diff --git a/core/array.cpp b/core/array.cpp
index 9e3250fd47..96e64294ed 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -72,7 +72,7 @@ void Array::_unref() const {
Variant &Array::operator[](int p_idx) {
- return _p->array[p_idx];
+ return _p->array.write[p_idx];
}
const Variant &Array::operator[](int p_idx) const {
diff --git a/core/class_db.cpp b/core/class_db.cpp
index f97eaf6099..03b214aa41 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -58,8 +58,8 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(2);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
return md;
}
@@ -68,9 +68,9 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(3);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
return md;
}
@@ -79,10 +79,10 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(4);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
return md;
}
@@ -91,11 +91,11 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(5);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
return md;
}
@@ -104,12 +104,12 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(6);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
return md;
}
@@ -118,13 +118,13 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(7);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
- md.args[6] = StaticCString::create(p_arg7);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
+ md.args.write[6] = StaticCString::create(p_arg7);
return md;
}
@@ -133,14 +133,14 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(8);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
- md.args[6] = StaticCString::create(p_arg7);
- md.args[7] = StaticCString::create(p_arg8);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
+ md.args.write[6] = StaticCString::create(p_arg7);
+ md.args.write[7] = StaticCString::create(p_arg8);
return md;
}
@@ -149,15 +149,15 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(9);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
- md.args[6] = StaticCString::create(p_arg7);
- md.args[7] = StaticCString::create(p_arg8);
- md.args[8] = StaticCString::create(p_arg9);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
+ md.args.write[6] = StaticCString::create(p_arg7);
+ md.args.write[7] = StaticCString::create(p_arg8);
+ md.args.write[8] = StaticCString::create(p_arg9);
return md;
}
@@ -166,16 +166,16 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(10);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
- md.args[6] = StaticCString::create(p_arg7);
- md.args[7] = StaticCString::create(p_arg8);
- md.args[8] = StaticCString::create(p_arg9);
- md.args[9] = StaticCString::create(p_arg10);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
+ md.args.write[6] = StaticCString::create(p_arg7);
+ md.args.write[7] = StaticCString::create(p_arg8);
+ md.args.write[8] = StaticCString::create(p_arg9);
+ md.args.write[9] = StaticCString::create(p_arg10);
return md;
}
@@ -184,17 +184,17 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(11);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
- md.args[6] = StaticCString::create(p_arg7);
- md.args[7] = StaticCString::create(p_arg8);
- md.args[8] = StaticCString::create(p_arg9);
- md.args[9] = StaticCString::create(p_arg10);
- md.args[10] = StaticCString::create(p_arg11);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
+ md.args.write[6] = StaticCString::create(p_arg7);
+ md.args.write[7] = StaticCString::create(p_arg8);
+ md.args.write[8] = StaticCString::create(p_arg9);
+ md.args.write[9] = StaticCString::create(p_arg10);
+ md.args.write[10] = StaticCString::create(p_arg11);
return md;
}
@@ -203,18 +203,18 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(12);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
- md.args[6] = StaticCString::create(p_arg7);
- md.args[7] = StaticCString::create(p_arg8);
- md.args[8] = StaticCString::create(p_arg9);
- md.args[9] = StaticCString::create(p_arg10);
- md.args[10] = StaticCString::create(p_arg11);
- md.args[11] = StaticCString::create(p_arg12);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
+ md.args.write[6] = StaticCString::create(p_arg7);
+ md.args.write[7] = StaticCString::create(p_arg8);
+ md.args.write[8] = StaticCString::create(p_arg9);
+ md.args.write[9] = StaticCString::create(p_arg10);
+ md.args.write[10] = StaticCString::create(p_arg11);
+ md.args.write[11] = StaticCString::create(p_arg12);
return md;
}
@@ -223,19 +223,19 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(13);
- md.args[0] = StaticCString::create(p_arg1);
- md.args[1] = StaticCString::create(p_arg2);
- md.args[2] = StaticCString::create(p_arg3);
- md.args[3] = StaticCString::create(p_arg4);
- md.args[4] = StaticCString::create(p_arg5);
- md.args[5] = StaticCString::create(p_arg6);
- md.args[6] = StaticCString::create(p_arg7);
- md.args[7] = StaticCString::create(p_arg8);
- md.args[8] = StaticCString::create(p_arg9);
- md.args[9] = StaticCString::create(p_arg10);
- md.args[10] = StaticCString::create(p_arg11);
- md.args[11] = StaticCString::create(p_arg12);
- md.args[12] = StaticCString::create(p_arg13);
+ md.args.write[0] = StaticCString::create(p_arg1);
+ md.args.write[1] = StaticCString::create(p_arg2);
+ md.args.write[2] = StaticCString::create(p_arg3);
+ md.args.write[3] = StaticCString::create(p_arg4);
+ md.args.write[4] = StaticCString::create(p_arg5);
+ md.args.write[5] = StaticCString::create(p_arg6);
+ md.args.write[6] = StaticCString::create(p_arg7);
+ md.args.write[7] = StaticCString::create(p_arg8);
+ md.args.write[8] = StaticCString::create(p_arg9);
+ md.args.write[9] = StaticCString::create(p_arg10);
+ md.args.write[10] = StaticCString::create(p_arg11);
+ md.args.write[11] = StaticCString::create(p_arg12);
+ md.args.write[12] = StaticCString::create(p_arg13);
return md;
}
@@ -1246,7 +1246,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
defvals.resize(p_defcount);
for (int i = 0; i < p_defcount; i++) {
- defvals[i] = *p_defs[p_defcount - i - 1];
+ defvals.write[i] = *p_defs[p_defcount - i - 1];
}
p_bind->set_default_arguments(defvals);
diff --git a/core/color.cpp b/core/color.cpp
index 88e57ec6e2..fcfcf20355 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -49,6 +49,7 @@ uint32_t Color::to_argb32() const {
}
uint32_t Color::to_abgr32() const {
+
uint32_t c = (uint8_t)Math::round(a * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
@@ -73,6 +74,45 @@ uint32_t Color::to_rgba32() const {
return c;
}
+uint64_t Color::to_abgr64() const {
+
+ uint64_t c = (uint16_t)Math::round(a * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(b * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(g * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(r * 65535);
+
+ return c;
+}
+
+uint64_t Color::to_argb64() const {
+
+ uint64_t c = (uint16_t)Math::round(a * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(r * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(g * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(b * 65535);
+
+ return c;
+}
+
+uint64_t Color::to_rgba64() const {
+
+ uint64_t c = (uint16_t)Math::round(r * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(g * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(b * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(a * 65535);
+
+ return c;
+}
+
float Color::get_h() const {
float min = MIN(r, g);
@@ -200,6 +240,19 @@ Color Color::hex(uint32_t p_hex) {
return Color(r, g, b, a);
}
+Color Color::hex64(uint64_t p_hex) {
+
+ float a = (p_hex & 0xFFFF) / 65535.0;
+ p_hex >>= 16;
+ float b = (p_hex & 0xFFFF) / 65535.0;
+ p_hex >>= 16;
+ float g = (p_hex & 0xFFFF) / 65535.0;
+ p_hex >>= 16;
+ float r = (p_hex & 0xFFFF) / 65535.0;
+
+ return Color(r, g, b, a);
+}
+
static float _parse_col(const String &p_str, int p_ofs) {
int ig = 0;
diff --git a/core/color.h b/core/color.h
index a2015a34d6..c0516e55fe 100644
--- a/core/color.h
+++ b/core/color.h
@@ -55,6 +55,9 @@ struct Color {
uint32_t to_rgba32() const;
uint32_t to_argb32() const;
uint32_t to_abgr32() const;
+ uint64_t to_rgba64() const;
+ uint64_t to_argb64() const;
+ uint64_t to_abgr64() const;
float gray() const;
float get_h() const;
float get_s() const;
@@ -186,6 +189,7 @@ struct Color {
}
static Color hex(uint32_t p_hex);
+ static Color hex64(uint64_t p_hex);
static Color html(const String &p_color);
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp
index 266d793af7..5c1fd26e2a 100644
--- a/core/compressed_translation.cpp
+++ b/core/compressed_translation.cpp
@@ -73,7 +73,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
Pair<int, CharString> p;
p.first = idx;
p.second = cs;
- buckets[h % size].push_back(p);
+ buckets.write[h % size].push_back(p);
//compress string
CharString src_s = p_from->get_message(E->get()).operator String().utf8();
@@ -100,7 +100,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
ps.compressed[0] = 0;
}
- compressed[idx] = ps;
+ compressed.write[idx] = ps;
total_compression_size += ps.compressed.size();
total_string_size += src_s.size();
idx++;
@@ -111,8 +111,8 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
for (int i = 0; i < size; i++) {
- Vector<Pair<int, CharString> > &b = buckets[i];
- Map<uint32_t, int> &t = table[i];
+ const Vector<Pair<int, CharString> > &b = buckets[i];
+ Map<uint32_t, int> &t = table.write[i];
if (b.size() == 0)
continue;
@@ -136,7 +136,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
}
}
- hfunc_table[i] = d;
+ hfunc_table.write[i] = d;
bucket_table_size += 2 + b.size() * 4;
}
@@ -157,7 +157,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
for (int i = 0; i < size; i++) {
- Map<uint32_t, int> &t = table[i];
+ const Map<uint32_t, int> &t = table[i];
if (t.size() == 0) {
htw[i] = 0xFFFFFFFF; //nothing
continue;
diff --git a/core/core_builders.py b/core/core_builders.py
new file mode 100644
index 0000000000..90e505aab9
--- /dev/null
+++ b/core/core_builders.py
@@ -0,0 +1,236 @@
+"""Functions used to generate source files during build time
+
+All such functions are invoked in a subprocess on Windows to prevent build flakiness.
+
+"""
+from platform_methods import subprocess_main
+from compat import iteritems, itervalues, open_utf8, escape_string
+
+
+def make_authors_header(target, source, env):
+ sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"]
+ sections_id = ["AUTHORS_FOUNDERS", "AUTHORS_LEAD_DEVELOPERS", "AUTHORS_PROJECT_MANAGERS", "AUTHORS_DEVELOPERS"]
+
+ src = source[0]
+ dst = target[0]
+ f = open_utf8(src, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_AUTHORS_H\n")
+ g.write("#define _EDITOR_AUTHORS_H\n")
+
+ reading = False
+
+ def close_section():
+ g.write("\t0\n")
+ g.write("};\n")
+
+ for line in f:
+ if reading:
+ if line.startswith(" "):
+ g.write("\t\"" + escape_string(line.strip()) + "\",\n")
+ continue
+ if line.startswith("## "):
+ if reading:
+ close_section()
+ reading = False
+ for section, section_id in zip(sections, sections_id):
+ if line.strip().endswith(section):
+ current_section = escape_string(section_id)
+ reading = True
+ g.write("const char *const " + current_section + "[] = {\n")
+ break
+
+ if reading:
+ close_section()
+
+ g.write("#endif\n")
+
+ g.close()
+ f.close()
+
+
+def make_donors_header(target, source, env):
+ sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors",
+ "Gold donors", "Silver donors", "Bronze donors"]
+ sections_id = ["DONORS_SPONSOR_PLAT", "DONORS_SPONSOR_GOLD", "DONORS_SPONSOR_MINI",
+ "DONORS_GOLD", "DONORS_SILVER", "DONORS_BRONZE"]
+
+ src = source[0]
+ dst = target[0]
+ f = open_utf8(src, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_DONORS_H\n")
+ g.write("#define _EDITOR_DONORS_H\n")
+
+ reading = False
+
+ def close_section():
+ g.write("\t0\n")
+ g.write("};\n")
+
+ for line in f:
+ if reading >= 0:
+ if line.startswith(" "):
+ g.write("\t\"" + escape_string(line.strip()) + "\",\n")
+ continue
+ if line.startswith("## "):
+ if reading:
+ close_section()
+ reading = False
+ for section, section_id in zip(sections, sections_id):
+ if line.strip().endswith(section):
+ current_section = escape_string(section_id)
+ reading = True
+ g.write("const char *const " + current_section + "[] = {\n")
+ break
+
+ if reading:
+ close_section()
+
+ g.write("#endif\n")
+
+ g.close()
+ f.close()
+
+
+def make_license_header(target, source, env):
+ src_copyright = source[0]
+ src_license = source[1]
+ dst = target[0]
+
+ class LicenseReader:
+ def __init__(self, license_file):
+ self._license_file = license_file
+ self.line_num = 0
+ self.current = self.next_line()
+
+ def next_line(self):
+ line = self._license_file.readline()
+ self.line_num += 1
+ while line.startswith("#"):
+ line = self._license_file.readline()
+ self.line_num += 1
+ self.current = line
+ return line
+
+ def next_tag(self):
+ if not ':' in self.current:
+ return ('', [])
+ tag, line = self.current.split(":", 1)
+ lines = [line.strip()]
+ while self.next_line() and self.current.startswith(" "):
+ lines.append(self.current.strip())
+ return (tag, lines)
+
+ from collections import OrderedDict
+ projects = OrderedDict()
+ license_list = []
+
+ with open_utf8(src_copyright, "r") as copyright_file:
+ reader = LicenseReader(copyright_file)
+ part = {}
+ while reader.current:
+ tag, content = reader.next_tag()
+ if tag in ("Files", "Copyright", "License"):
+ part[tag] = content[:]
+ elif tag == "Comment":
+ # attach part to named project
+ projects[content[0]] = projects.get(content[0], []) + [part]
+
+ if not tag or not reader.current:
+ # end of a paragraph start a new part
+ if "License" in part and not "Files" in part:
+ # no Files tag in this one, so assume standalone license
+ license_list.append(part["License"])
+ part = {}
+ reader.next_line()
+
+ data_list = []
+ for project in itervalues(projects):
+ for part in project:
+ part["file_index"] = len(data_list)
+ data_list += part["Files"]
+ part["copyright_index"] = len(data_list)
+ data_list += part["Copyright"]
+
+ with open_utf8(dst, "w") as f:
+
+ f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ f.write("#ifndef _EDITOR_LICENSE_H\n")
+ f.write("#define _EDITOR_LICENSE_H\n")
+ f.write("const char *const GODOT_LICENSE_TEXT =")
+
+ with open_utf8(src_license, "r") as license_file:
+ for line in license_file:
+ escaped_string = escape_string(line.strip())
+ f.write("\n\t\t\"" + escaped_string + "\\n\"")
+ f.write(";\n\n")
+
+ f.write("struct ComponentCopyrightPart {\n"
+ "\tconst char *license;\n"
+ "\tconst char *const *files;\n"
+ "\tconst char *const *copyright_statements;\n"
+ "\tint file_count;\n"
+ "\tint copyright_count;\n"
+ "};\n\n")
+
+ f.write("struct ComponentCopyright {\n"
+ "\tconst char *name;\n"
+ "\tconst ComponentCopyrightPart *parts;\n"
+ "\tint part_count;\n"
+ "};\n\n")
+
+ f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n")
+ for line in data_list:
+ f.write("\t\"" + escape_string(line) + "\",\n")
+ f.write("};\n\n")
+
+ f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n")
+ part_index = 0
+ part_indexes = {}
+ for project_name, project in iteritems(projects):
+ part_indexes[project_name] = part_index
+ for part in project:
+ f.write("\t{ \"" + escape_string(part["License"][0]) + "\", "
+ + "&COPYRIGHT_INFO_DATA[" + str(part["file_index"]) + "], "
+ + "&COPYRIGHT_INFO_DATA[" + str(part["copyright_index"]) + "], "
+ + str(len(part["Files"])) + ", "
+ + str(len(part["Copyright"])) + " },\n")
+ part_index += 1
+ f.write("};\n\n")
+
+ f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n")
+
+ f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n")
+ for project_name, project in iteritems(projects):
+ f.write("\t{ \"" + escape_string(project_name) + "\", "
+ + "&COPYRIGHT_PROJECT_PARTS[" + str(part_indexes[project_name]) + "], "
+ + str(len(project)) + " },\n")
+ f.write("};\n\n")
+
+ f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n")
+
+ f.write("const char *const LICENSE_NAMES[] = {\n")
+ for l in license_list:
+ f.write("\t\"" + escape_string(l[0]) + "\",\n")
+ f.write("};\n\n")
+
+ f.write("const char *const LICENSE_BODIES[] = {\n\n")
+ for l in license_list:
+ for line in l[1:]:
+ if line == ".":
+ f.write("\t\"\\n\"\n")
+ else:
+ f.write("\t\"" + escape_string(line) + "\\n\"\n")
+ f.write("\t\"\",\n\n")
+ f.write("};\n\n")
+
+ f.write("#endif\n")
+
+
+if __name__ == '__main__':
+ subprocess_main(globals())
diff --git a/core/cowdata.h b/core/cowdata.h
new file mode 100644
index 0000000000..66e7d1c343
--- /dev/null
+++ b/core/cowdata.h
@@ -0,0 +1,332 @@
+/*************************************************************************/
+/* cowdata.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 COWDATA_H_
+#define COWDATA_H_
+
+#include "os/memory.h"
+#include "safe_refcount.h"
+
+template <class T>
+class Vector;
+class String;
+class CharString;
+template <class T, class V>
+class VMap;
+
+template <class T>
+class CowData {
+ template <class TV>
+ friend class Vector;
+ friend class String;
+ friend class CharString;
+ template <class TV, class VV>
+ friend class VMap;
+
+private:
+ mutable T *_ptr;
+
+ // internal helpers
+
+ _FORCE_INLINE_ uint32_t *_get_refcount() const {
+
+ if (!_ptr)
+ return NULL;
+
+ return reinterpret_cast<uint32_t *>(_ptr) - 2;
+ }
+
+ _FORCE_INLINE_ uint32_t *_get_size() const {
+
+ if (!_ptr)
+ return NULL;
+
+ return reinterpret_cast<uint32_t *>(_ptr) - 1;
+ }
+
+ _FORCE_INLINE_ T *_get_data() const {
+
+ if (!_ptr)
+ return NULL;
+ return reinterpret_cast<T *>(_ptr);
+ }
+
+ _FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
+ //return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
+ return next_power_of_2(p_elements * sizeof(T));
+ }
+
+ _FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
+#if defined(_add_overflow) && defined(_mul_overflow)
+ size_t o;
+ size_t p;
+ if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
+ *out = next_power_of_2(o);
+ if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
+ return true;
+#else
+ // Speed is more important than correctness here, do the operations unchecked
+ // and hope the best
+ *out = _get_alloc_size(p_elements);
+ return true;
+#endif
+ }
+
+ void _unref(void *p_data);
+ void _ref(const CowData &p_from);
+ void _copy_on_write();
+
+public:
+ void operator=(const CowData<T> &p_from) { _ref(p_from); }
+
+ _FORCE_INLINE_ T *ptrw() {
+ _copy_on_write();
+ return (T *)_get_data();
+ }
+
+ _FORCE_INLINE_ const T *ptr() const {
+ return _get_data();
+ }
+
+ _FORCE_INLINE_ int size() const {
+ uint32_t *size = (uint32_t *)_get_size();
+ if (size)
+ return *size;
+ else
+ return 0;
+ }
+
+ _FORCE_INLINE_ void clear() { resize(0); }
+ _FORCE_INLINE_ bool empty() const { return _ptr == 0; }
+
+ _FORCE_INLINE_ void set(int p_index, const T &p_elem) {
+
+ CRASH_BAD_INDEX(p_index, size());
+ _copy_on_write();
+ _get_data()[p_index] = p_elem;
+ }
+
+ _FORCE_INLINE_ T &get_m(int p_index) {
+
+ CRASH_BAD_INDEX(p_index, size());
+ _copy_on_write();
+ return _get_data()[p_index];
+ }
+
+ _FORCE_INLINE_ const T &get(int p_index) const {
+
+ CRASH_BAD_INDEX(p_index, size());
+
+ return _get_data()[p_index];
+ }
+
+ Error resize(int p_size);
+
+ _FORCE_INLINE_ void remove(int p_index) {
+
+ ERR_FAIL_INDEX(p_index, size());
+ T *p = ptrw();
+ int len = size();
+ for (int i = p_index; i < len - 1; i++) {
+
+ p[i] = p[i + 1];
+ };
+
+ resize(len - 1);
+ };
+
+ Error insert(int p_pos, const T &p_val) {
+
+ ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
+ resize(size() + 1);
+ for (int i = (size() - 1); i > p_pos; i--)
+ set(i, get(i - 1));
+ set(p_pos, p_val);
+
+ return OK;
+ };
+
+ _FORCE_INLINE_ CowData();
+ _FORCE_INLINE_ ~CowData();
+ _FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
+};
+
+template <class T>
+void CowData<T>::_unref(void *p_data) {
+
+ if (!p_data)
+ return;
+
+ uint32_t *refc = _get_refcount();
+
+ if (atomic_decrement(refc) > 0)
+ return; // still in use
+ // clean up
+
+ uint32_t *count = _get_size();
+ T *data = (T *)(count + 1);
+
+ for (uint32_t i = 0; i < *count; ++i) {
+ // call destructors
+ data[i].~T();
+ }
+
+ // free mem
+ Memory::free_static((uint8_t *)p_data, true);
+}
+
+template <class T>
+void CowData<T>::_copy_on_write() {
+
+ if (!_ptr)
+ return;
+
+ uint32_t *refc = _get_refcount();
+
+ if (unlikely(*refc > 1)) {
+ /* in use by more than me */
+ uint32_t current_size = *_get_size();
+
+ uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
+
+ *(mem_new - 2) = 1; //refcount
+ *(mem_new - 1) = current_size; //size
+
+ T *_data = (T *)(mem_new);
+
+ // initialize new elements
+ for (uint32_t i = 0; i < current_size; i++) {
+
+ memnew_placement(&_data[i], T(_get_data()[i]));
+ }
+
+ _unref(_ptr);
+ _ptr = _data;
+ }
+}
+
+template <class T>
+Error CowData<T>::resize(int p_size) {
+
+ ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
+
+ if (p_size == size())
+ return OK;
+
+ if (p_size == 0) {
+ // wants to clean up
+ _unref(_ptr);
+ _ptr = NULL;
+ return OK;
+ }
+
+ // possibly changing size, copy on write
+ _copy_on_write();
+
+ size_t alloc_size;
+ ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
+
+ if (p_size > size()) {
+
+ if (size() == 0) {
+ // alloc from scratch
+ uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
+ ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
+ *(ptr - 1) = 0; //size, currently none
+ *(ptr - 2) = 1; //refcount
+
+ _ptr = (T *)ptr;
+
+ } else {
+ void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
+ ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
+ _ptr = (T *)(_ptrnew);
+ }
+
+ // construct the newly created elements
+ T *elems = _get_data();
+
+ for (int i = *_get_size(); i < p_size; i++) {
+
+ memnew_placement(&elems[i], T);
+ }
+
+ *_get_size() = p_size;
+
+ } else if (p_size < size()) {
+
+ // deinitialize no longer needed elements
+ for (uint32_t i = p_size; i < *_get_size(); i++) {
+
+ T *t = &_get_data()[i];
+ t->~T();
+ }
+
+ void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
+ ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
+
+ _ptr = (T *)(_ptrnew);
+
+ *_get_size() = p_size;
+ }
+
+ return OK;
+}
+
+template <class T>
+void CowData<T>::_ref(const CowData &p_from) {
+
+ if (_ptr == p_from._ptr)
+ return; // self assign, do nothing.
+
+ _unref(_ptr);
+ _ptr = NULL;
+
+ if (!p_from._ptr)
+ return; //nothing to do
+
+ if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
+ _ptr = p_from._ptr;
+ }
+}
+
+template <class T>
+CowData<T>::CowData() {
+
+ _ptr = NULL;
+}
+
+template <class T>
+CowData<T>::~CowData() {
+
+ _unref(_ptr);
+}
+
+#endif /* COW_H_ */
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 221f457b78..bb7a444ccc 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -89,7 +89,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
for (size_t i = 0; i < ds; i += 16) {
- aes256_decrypt_ecb(&ctx, &data[i]);
+ aes256_decrypt_ecb(&ctx, &data.write[i]);
}
aes256_done(&ctx);
@@ -117,7 +117,7 @@ Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const Str
key.resize(32);
for (int i = 0; i < 32; i++) {
- key[i] = cs[i];
+ key.write[i] = cs[i];
}
return open_and_parse(p_base, key, p_mode);
@@ -148,7 +148,7 @@ void FileAccessEncrypted::close() {
compressed.resize(len);
zeromem(compressed.ptrw(), len);
for (int i = 0; i < data.size(); i++) {
- compressed[i] = data[i];
+ compressed.write[i] = data[i];
}
aes256_context ctx;
@@ -156,7 +156,7 @@ void FileAccessEncrypted::close() {
for (size_t i = 0; i < len; i += 16) {
- aes256_encrypt_ecb(&ctx, &compressed[i]);
+ aes256_encrypt_ecb(&ctx, &compressed.write[i]);
}
aes256_done(&ctx);
@@ -263,7 +263,7 @@ void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
data.resize(pos + p_length);
for (int i = 0; i < p_length; i++) {
- data[pos + i] = p_src[i];
+ data.write[pos + i] = p_src[i];
}
pos += p_length;
}
@@ -280,7 +280,7 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!writing);
if (pos < data.size()) {
- data[pos] = p_dest;
+ data.write[pos] = p_dest;
pos++;
} else if (pos == data.size()) {
data.push_back(p_dest);
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 1aa1e4a595..c4eb2848b1 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -92,7 +92,7 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
Map<String, Vector<uint8_t> >::Element *E = files->find(name);
ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
- data = &(E->get()[0]);
+ data = E->get().ptrw();
length = E->get().size();
pos = 0;
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index 21e3a4172b..e0a2dbf507 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -258,8 +258,8 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
}
buffer_mutex->lock();
- pages[page].buffer = p_block;
- pages[page].queued = false;
+ pages.write[page].buffer = p_block;
+ pages.write[page].queued = false;
buffer_mutex->unlock();
if (waiting_on_page == page) {
@@ -389,7 +389,7 @@ void FileAccessNetwork::_queue_page(int p_page) const {
br.offset = size_t(p_page) * page_size;
br.size = page_size;
nc->block_requests.push_back(br);
- pages[p_page].queued = true;
+ pages.write[p_page].queued = true;
nc->blockrequest_mutex->unlock();
DEBUG_PRINT("QUEUE PAGE POST");
nc->sem->post();
@@ -433,12 +433,12 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
_queue_page(page + j);
}
- buff = pages[page].buffer.ptrw();
+ buff = pages.write[page].buffer.ptrw();
//queue pages
buffer_mutex->unlock();
}
- buff = pages[page].buffer.ptrw();
+ buff = pages.write[page].buffer.ptrw();
last_page_buff = buff;
last_page = page;
}
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index f1620f1493..2425bb6d69 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -552,7 +552,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
} else {
int rec = 0;
- err = _get_http_data(&chunk[chunk.size() - chunk_left], chunk_left, rec);
+ err = _get_http_data(&chunk.write[chunk.size() - chunk_left], chunk_left, rec);
if (rec == 0) {
break;
}
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index ffd3ecaed0..8e67f1c97a 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -282,10 +282,10 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
ERR_FAIL_COND(p_offset >= p_packet_len);
int vlen;
- Error err = decode_variant(args[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
+ Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
ERR_FAIL_COND(err != OK);
//args[i]=p_packet[3+i];
- argp[i] = &args[i];
+ argp.write[i] = &args[i];
p_offset += vlen;
}
@@ -354,8 +354,8 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
Vector<uint8_t> packet;
packet.resize(1 + len);
- packet[0] = NETWORK_COMMAND_CONFIRM_PATH;
- encode_cstring(pname.get_data(), &packet[1]);
+ packet.write[0] = NETWORK_COMMAND_CONFIRM_PATH;
+ encode_cstring(pname.get_data(), &packet.write[1]);
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->set_target_peer(p_from);
@@ -415,9 +415,9 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
Vector<uint8_t> packet;
packet.resize(1 + 4 + len);
- packet[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
- encode_uint32(psc->id, &packet[1]);
- encode_cstring(pname.get_data(), &packet[5]);
+ packet.write[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
+ encode_uint32(psc->id, &packet.write[1]);
+ encode_cstring(pname.get_data(), &packet.write[5]);
network_peer->set_target_peer(E->get()); //to all of you
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
@@ -482,19 +482,19 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
//encode type
MAKE_ROOM(1);
- packet_cache[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
+ packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
ofs += 1;
//encode ID
MAKE_ROOM(ofs + 4);
- encode_uint32(psc->id, &(packet_cache[ofs]));
+ encode_uint32(psc->id, &(packet_cache.write[ofs]));
ofs += 4;
//encode function name
CharString name = String(p_name).utf8();
int len = encode_cstring(name.get_data(), NULL);
MAKE_ROOM(ofs + len);
- encode_cstring(name.get_data(), &(packet_cache[ofs]));
+ encode_cstring(name.get_data(), &(packet_cache.write[ofs]));
ofs += len;
if (p_set) {
@@ -502,19 +502,19 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
Error err = encode_variant(*p_arg[0], NULL, len);
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
- encode_variant(*p_arg[0], &(packet_cache[ofs]), len);
+ encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len);
ofs += len;
} else {
//call arguments
MAKE_ROOM(ofs + 1);
- packet_cache[ofs] = p_argcount;
+ packet_cache.write[ofs] = p_argcount;
ofs += 1;
for (int i = 0; i < p_argcount; i++) {
Error err = encode_variant(*p_arg[i], NULL, len);
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
- encode_variant(*p_arg[i], &(packet_cache[ofs]), len);
+ encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
ofs += len;
}
}
@@ -537,7 +537,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
CharString pname = String(from_path).utf8();
int path_len = encode_cstring(pname.get_data(), NULL);
MAKE_ROOM(ofs + path_len);
- encode_cstring(pname.get_data(), &(packet_cache[ofs]));
+ encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
@@ -554,11 +554,11 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
if (F->get() == true) {
//this one confirmed path, so use id
- encode_uint32(psc->id, &(packet_cache[1]));
+ encode_uint32(psc->id, &(packet_cache.write[1]));
network_peer->put_packet(packet_cache.ptr(), ofs);
} else {
//this one did not confirm path yet, so use entire path (sorry!)
- encode_uint32(0x80000000 | ofs, &(packet_cache[1])); //offset to path and flag
+ encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); //offset to path and flag
network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
}
}
@@ -712,8 +712,8 @@ Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, Networked
MAKE_ROOM(p_data.size() + 1);
PoolVector<uint8_t>::Read r = p_data.read();
- packet_cache[0] = NETWORK_COMMAND_RAW;
- memcpy(&packet_cache[1], &r[0], p_data.size());
+ packet_cache.write[0] = NETWORK_COMMAND_RAW;
+ memcpy(&packet_cache.write[1], &r[0], p_data.size());
network_peer->set_target_peer(p_to);
network_peer->set_transfer_mode(p_mode);
@@ -773,7 +773,7 @@ Vector<int> MultiplayerAPI::get_network_connected_peers() const {
void MultiplayerAPI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node);
- ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
+ ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
ClassDB::bind_method(D_METHOD("has_network_peer"), &MultiplayerAPI::has_network_peer);
ClassDB::bind_method(D_METHOD("get_network_peer"), &MultiplayerAPI::get_network_peer);
ClassDB::bind_method(D_METHOD("get_network_unique_id"), &MultiplayerAPI::get_network_unique_id);
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index b777a9f960..dc4997dfc2 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -173,7 +173,7 @@ Error PacketPeerStream::_poll_buffer() const {
int read = 0;
ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE);
- Error err = peer->get_partial_data(&input_buffer[0], ring_buffer.space_left(), read);
+ Error err = peer->get_partial_data(input_buffer.ptrw(), ring_buffer.space_left(), read);
if (err)
return err;
if (read == 0)
@@ -226,7 +226,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size)
ERR_FAIL_COND_V(input_buffer.size() < len, ERR_UNAVAILABLE);
ring_buffer.read(lbuf, 4); //get rid of first 4 bytes
- ring_buffer.read(&input_buffer[0], len); // read packet
+ ring_buffer.read(input_buffer.ptrw(), len); // read packet
*r_buffer = &input_buffer[0];
r_buffer_size = len;
@@ -247,8 +247,8 @@ Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER);
- encode_uint32(p_buffer_size, &output_buffer[0]);
- uint8_t *dst = &output_buffer[4];
+ encode_uint32(p_buffer_size, output_buffer.ptrw());
+ uint8_t *dst = &output_buffer.write[4];
for (int i = 0; i < p_buffer_size; i++)
dst[i] = p_buffer[i];
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index b6377662de..2fd73db27d 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -120,7 +120,7 @@ Error PCKPacker::flush(bool p_verbose) {
for (int i = 0; i < files.size(); i++) {
file->store_pascal_string(files[i].path);
- files[i].offset_offset = file->get_position();
+ files.write[i].offset_offset = file->get_position();
file->store_64(0); // offset
file->store_64(files[i].size); // size
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 0c626c197b..02c2c6ce1a 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -894,7 +894,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
for (uint32_t i = 0; i < string_table_size; i++) {
StringName s = get_unicode_string();
- string_map[i] = s;
+ string_map.write[i] = s;
}
print_bl("strings: " + itos(string_table_size));
@@ -1834,7 +1834,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
save_order.resize(external_resources.size());
for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
- save_order[E->get()] = E->key();
+ save_order.write[E->get()] = E->key();
}
for (int i = 0; i < save_order.size(); i++) {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 1351030d1e..c44d2597a7 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -556,7 +556,7 @@ void ResourceLoader::load_translation_remaps() {
Vector<String> lang_remaps;
lang_remaps.resize(langs.size());
for (int i = 0; i < langs.size(); i++) {
- lang_remaps[i] = langs[i];
+ lang_remaps.write[i] = langs[i];
}
translation_remaps[String(E->get())] = lang_remaps;
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index 927b9f6366..3e0ee088c2 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -331,7 +331,7 @@ String StreamPeer::get_string(int p_bytes) {
ERR_FAIL_COND_V(err != OK, String());
err = get_data((uint8_t *)&buf[0], p_bytes);
ERR_FAIL_COND_V(err != OK, String());
- buf[p_bytes] = 0;
+ buf.write[p_bytes] = 0;
return buf.ptr();
}
String StreamPeer::get_utf8_string(int p_bytes) {
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index c71af6b641..e7e9662d24 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -92,7 +92,7 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() {
void StreamPeerSSL::_bind_methods() {
ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
- ClassDB::bind_method(D_METHOD("accept_stream"), &StreamPeerSSL::accept_stream);
+ ClassDB::bind_method(D_METHOD("accept_stream", "base"), &StreamPeerSSL::accept_stream);
ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()));
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerSSL::get_status);
ClassDB::bind_method(D_METHOD("disconnect_from_stream"), &StreamPeerSSL::disconnect_from_stream);
diff --git a/core/make_binders.py b/core/make_binders.py
index 6a7602cd5d..f1a10829a3 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -1,4 +1,5 @@
# -*- coding: ibm850 -*-
+from platform_methods import subprocess_main
template_typed = """
@@ -265,8 +266,12 @@ def run(target, source, env):
else:
text += t
- with open(target[0].path, "w") as f:
+ with open(target[0], "w") as f:
f.write(text)
- with open(target[1].path, "w") as f:
+ with open(target[1], "w") as f:
f.write(text_ext)
+
+
+if __name__ == '__main__':
+ subprocess_main(globals())
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index 2e184f7a88..24096de551 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -449,10 +449,10 @@ BSP_Tree::operator Variant() const {
for (int i = 0; i < planes.size(); i++) {
- plane_values[i * 4 + 0] = planes[i].normal.x;
- plane_values[i * 4 + 1] = planes[i].normal.y;
- plane_values[i * 4 + 2] = planes[i].normal.z;
- plane_values[i * 4 + 3] = planes[i].d;
+ plane_values.write[i * 4 + 0] = planes[i].normal.x;
+ plane_values.write[i * 4 + 1] = planes[i].normal.y;
+ plane_values.write[i * 4 + 2] = planes[i].normal.z;
+ plane_values.write[i * 4 + 3] = planes[i].d;
}
d["planes"] = plane_values;
@@ -498,10 +498,10 @@ BSP_Tree::BSP_Tree(const Variant &p_variant) {
PoolVector<real_t>::Read r = src_planes.read();
for (int i = 0; i < plane_count / 4; i++) {
- planes[i].normal.x = r[i * 4 + 0];
- planes[i].normal.y = r[i * 4 + 1];
- planes[i].normal.z = r[i * 4 + 2];
- planes[i].d = r[i * 4 + 3];
+ planes.write[i].normal.x = r[i * 4 + 0];
+ planes.write[i].normal.y = r[i * 4 + 1];
+ planes.write[i].normal.z = r[i * 4 + 2];
+ planes.write[i].d = r[i * 4 + 3];
}
}
@@ -520,9 +520,9 @@ BSP_Tree::BSP_Tree(const Variant &p_variant) {
for (int i = 0; i < nodes.size(); i++) {
- nodes[i].over = r[i * 3 + 0];
- nodes[i].under = r[i * 3 + 1];
- nodes[i].plane = r[i * 3 + 2];
+ nodes.write[i].over = r[i * 3 + 0];
+ nodes.write[i].under = r[i * 3 + 1];
+ nodes.write[i].plane = r[i * 3 + 2];
}
}
diff --git a/core/math/delaunay.h b/core/math/delaunay.h
index 09aebc773f..13fbc0c6ae 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay.h
@@ -92,7 +92,7 @@ public:
for (int j = 0; j < triangles.size(); j++) {
if (circum_circle_contains(points, triangles[j], i)) {
- triangles[j].bad = true;
+ triangles.write[j].bad = true;
polygon.push_back(Edge(triangles[j].points[0], triangles[j].points[1]));
polygon.push_back(Edge(triangles[j].points[1], triangles[j].points[2]));
polygon.push_back(Edge(triangles[j].points[2], triangles[j].points[0]));
@@ -109,8 +109,8 @@ public:
for (int j = 0; j < polygon.size(); j++) {
for (int k = j + 1; k < polygon.size(); k++) {
if (edge_compare(points, polygon[j], polygon[k])) {
- polygon[j].bad = true;
- polygon[k].bad = true;
+ polygon.write[j].bad = true;
+ polygon.write[k].bad = true;
}
}
}
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 24f077a4ca..7ab28daf20 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -56,7 +56,7 @@ void Geometry::MeshData::optimize_vertices() {
vtx_remap[idx] = ni;
}
- faces[i].indices[j] = vtx_remap[idx];
+ faces.write[i].indices.write[j] = vtx_remap[idx];
}
}
@@ -74,8 +74,8 @@ void Geometry::MeshData::optimize_vertices() {
vtx_remap[b] = ni;
}
- edges[i].a = vtx_remap[a];
- edges[i].b = vtx_remap[b];
+ edges.write[i].a = vtx_remap[a];
+ edges.write[i].b = vtx_remap[b];
}
Vector<Vector3> new_vertices;
@@ -84,7 +84,7 @@ void Geometry::MeshData::optimize_vertices() {
for (int i = 0; i < vertices.size(); i++) {
if (vtx_remap.has(i))
- new_vertices[vtx_remap[i]] = vertices[i];
+ new_vertices.write[vtx_remap[i]] = vertices[i];
}
vertices = new_vertices;
}
@@ -1014,8 +1014,8 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
Vector<_AtlasWorkRect> wrects;
wrects.resize(p_rects.size());
for (int i = 0; i < p_rects.size(); i++) {
- wrects[i].s = p_rects[i];
- wrects[i].idx = i;
+ wrects.write[i].s = p_rects[i];
+ wrects.write[i].idx = i;
}
wrects.sort();
int widest = wrects[0].s.width;
@@ -1033,7 +1033,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
Vector<int> hmax;
hmax.resize(w);
for (int j = 0; j < w; j++)
- hmax[j] = 0;
+ hmax.write[j] = 0;
//place them
int ofs = 0;
@@ -1052,8 +1052,8 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
from_y = hmax[ofs + k];
}
- wrects[j].p.x = ofs;
- wrects[j].p.y = from_y;
+ wrects.write[j].p.x = ofs;
+ wrects.write[j].p.y = from_y;
int end_h = from_y + wrects[j].s.height;
int end_w = ofs + wrects[j].s.width;
if (ofs == 0)
@@ -1061,7 +1061,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
for (int k = 0; k < wrects[j].s.width; k++) {
- hmax[ofs + k] = end_h;
+ hmax.write[ofs + k] = end_h;
}
if (end_h > max_h)
@@ -1101,7 +1101,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
for (int i = 0; i < p_rects.size(); i++) {
- r_result[results[best].result[i].idx] = results[best].result[i].p;
+ r_result.write[results[best].result[i].idx] = results[best].result[i].p;
}
r_size = Size2(results[best].max_w, results[best].max_h);
diff --git a/core/math/geometry.h b/core/math/geometry.h
index be998aef0b..186a05fb37 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -890,14 +890,14 @@ public:
for (int i = 0; i < n; ++i) {
while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
k--;
- H[k++] = P[i];
+ H.write[k++] = P[i];
}
// Build upper hull
for (int i = n - 2, t = k + 1; i >= 0; i--) {
while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
k--;
- H[k++] = P[i];
+ H.write[k++] = P[i];
}
H.resize(k);
diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp
index 2371f49561..7db41756ed 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/matrix3.cpp
@@ -242,18 +242,11 @@ void Basis::scale_local(const Vector3 &p_scale) {
Basis Basis::scaled_local(const Vector3 &p_scale) const {
Basis b;
- b.set_scale(p_scale);
+ b.set_diagonal(p_scale);
return (*this) * b;
}
-void Basis::set_scale(const Vector3 &p_scale) {
-
- set_axis(0, get_axis(0).normalized() * p_scale.x);
- set_axis(1, get_axis(1).normalized() * p_scale.y);
- set_axis(2, get_axis(2).normalized() * p_scale.z);
-}
-
Vector3 Basis::get_scale_abs() const {
return Vector3(
diff --git a/core/math/matrix3.h b/core/math/matrix3.h
index cd1b51baa6..9ff1a97dc9 100644
--- a/core/math/matrix3.h
+++ b/core/math/matrix3.h
@@ -112,7 +112,6 @@ public:
void scale_local(const Vector3 &p_scale);
Basis scaled_local(const Vector3 &p_scale) const;
- void set_scale(const Vector3 &p_scale);
Vector3 get_scale() const;
Vector3 get_scale_abs() const;
Vector3 get_scale_local() const;
@@ -232,10 +231,13 @@ public:
operator Quat() const { return get_quat(); }
Basis(const Quat &p_quat) { set_quat(p_quat); };
+ Basis(const Quat &p_quat, const Vector3 &p_scale) { set_quat_scale(p_quat, p_scale); }
+
Basis(const Vector3 &p_euler) { set_euler(p_euler); }
+ Basis(const Vector3 &p_euler, const Vector3 &p_scale) { set_euler_scale(p_euler, p_scale); }
+
Basis(const Vector3 &p_axis, real_t p_phi) { set_axis_angle(p_axis, p_phi); }
Basis(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_phi, p_scale); }
- Basis(const Quat &p_quat, const Vector3 &p_scale) { set_quat_scale(p_quat, p_scale); }
_FORCE_INLINE_ Basis(const Vector3 &row0, const Vector3 &row1, const Vector3 &row2) {
elements[0] = row0;
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index fc90417413..cb923d264e 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -61,10 +61,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001));
if (valid_cache.has(sp)) {
- valid_points[i] = false;
+ valid_points.write[i] = false;
//print_line("INVALIDATED: "+itos(i));
} else {
- valid_points[i] = true;
+ valid_points.write[i] = true;
valid_cache.insert(sp);
}
}
@@ -452,7 +452,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
int idx = 0;
for (List<Geometry::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) {
- r_mesh.faces[idx++] = E->get();
+ r_mesh.faces.write[idx++] = E->get();
}
r_mesh.edges.resize(ret_edges.size());
idx = 0;
@@ -461,7 +461,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Geometry::MeshData::Edge e;
e.a = E->key().vertices[0];
e.b = E->key().vertices[1];
- r_mesh.edges[idx++] = e;
+ r_mesh.edges.write[idx++] = e;
}
r_mesh.vertices = p_points;
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index d1e190f4b9..976e0f174e 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -127,12 +127,11 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c)
Quat dst_rot = p_transform.basis.get_rotation_quat();
Vector3 dst_loc = p_transform.origin;
- Transform dst; //this could be made faster by using a single function in Basis..
- dst.basis = src_rot.slerp(dst_rot, p_c).normalized();
- dst.basis.set_scale(src_scale.linear_interpolate(dst_scale, p_c));
- dst.origin = src_loc.linear_interpolate(dst_loc, p_c);
+ Transform interp;
+ interp.basis.set_quat_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.linear_interpolate(dst_scale, p_c));
+ interp.origin = src_loc.linear_interpolate(dst_loc, p_c);
- return dst;
+ return interp;
}
void Transform::scale(const Vector3 &p_scale) {
diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp
index 563ba7268f..0edc0ea039 100644
--- a/core/math/triangulate.cpp
+++ b/core/math/triangulate.cpp
@@ -128,10 +128,10 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
if (0.0 < get_area(contour))
for (int v = 0; v < n; v++)
- V[v] = v;
+ V.write[v] = v;
else
for (int v = 0; v < n; v++)
- V[v] = (n - 1) - v;
+ V.write[v] = (n - 1) - v;
bool relaxed = false;
@@ -182,7 +182,7 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
/* remove v from remaining polygon */
for (s = v, t = v + 1; t < nv; s++, t++)
- V[s] = V[t];
+ V.write[s] = V[t];
nv--;
diff --git a/core/method_bind.h b/core/method_bind.h
index 41b500c401..7ee687ee40 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -354,7 +354,7 @@ public:
for (int i = 0; i < p_info.arguments.size(); i++) {
at[i + 1] = p_info.arguments[i].type;
- names[i] = p_info.arguments[i].name;
+ names.write[i] = p_info.arguments[i].name;
}
set_argument_names(names);
diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h
index 677e8e1fb2..2f6dcb3178 100644
--- a/core/method_ptrcall.h
+++ b/core/method_ptrcall.h
@@ -180,7 +180,7 @@ struct PtrToArg<const T *> {
{ \
PoolVector<m_type>::Read r = dvs->read(); \
for (int i = 0; i < len; i++) { \
- ret[i] = r[i]; \
+ ret.write[i] = r[i]; \
} \
} \
return ret; \
@@ -207,7 +207,7 @@ struct PtrToArg<const T *> {
{ \
PoolVector<m_type>::Read r = dvs->read(); \
for (int i = 0; i < len; i++) { \
- ret[i] = r[i]; \
+ ret.write[i] = r[i]; \
} \
} \
return ret; \
@@ -225,7 +225,7 @@ struct PtrToArg<const T *> {
{ \
PoolVector<m_type>::Read r = dvs->read(); \
for (int i = 0; i < len; i++) { \
- ret[i] = r[i]; \
+ ret.write[i] = r[i]; \
} \
} \
return ret; \
@@ -252,7 +252,7 @@ struct PtrToArg<const T *> {
{ \
PoolVector<m_type>::Read r = dvs->read(); \
for (int i = 0; i < len; i++) { \
- ret[i] = r[i]; \
+ ret.write[i] = r[i]; \
} \
} \
return ret; \
@@ -277,7 +277,7 @@ MAKE_VECARG_ALT(String, StringName);
int len = arr->size(); \
ret.resize(len); \
for (int i = 0; i < len; i++) { \
- ret[i] = (*arr)[i]; \
+ ret.write[i] = (*arr)[i]; \
} \
return ret; \
} \
@@ -298,7 +298,7 @@ MAKE_VECARG_ALT(String, StringName);
int len = arr->size(); \
ret.resize(len); \
for (int i = 0; i < len; i++) { \
- ret[i] = (*arr)[i]; \
+ ret.write[i] = (*arr)[i]; \
} \
return ret; \
} \
diff --git a/core/node_path.cpp b/core/node_path.cpp
index 487d5ee8c6..7d4116fa1e 100644
--- a/core/node_path.cpp
+++ b/core/node_path.cpp
@@ -427,7 +427,7 @@ NodePath::NodePath(const String &p_path) {
String name = path.substr(from, i - from);
ERR_FAIL_INDEX(slice, data->path.size());
- data->path[slice++] = name;
+ data->path.write[slice++] = name;
}
from = i + 1;
last_is_slash = true;
diff --git a/core/object.cpp b/core/object.cpp
index d86c60a3b8..8c9d3557f8 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -818,8 +818,8 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
argptrs.resize(p_args.size());
for (int i = 0; i < p_args.size(); i++) {
- args[i] = p_args[i];
- argptrs[i] = &args[i];
+ args.write[i] = p_args[i];
+ argptrs.write[i] = &args[i];
}
Variant::CallError ce;
@@ -1182,10 +1182,10 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
bind_mem.resize(p_argcount + c.binds.size());
for (int j = 0; j < p_argcount; j++) {
- bind_mem[j] = p_args[j];
+ bind_mem.write[j] = p_args[j];
}
for (int j = 0; j < c.binds.size(); j++) {
- bind_mem[p_argcount + j] = &c.binds[j];
+ bind_mem.write[p_argcount + j] = &c.binds[j];
}
args = (const Variant **)bind_mem.ptr();
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 033b4b12b9..3eac4428da 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -262,15 +262,15 @@ String FileAccess::get_token() const {
while (!eof_reached()) {
if (c <= ' ') {
- if (!token.empty())
+ if (token.length())
break;
} else {
- token.push_back(c);
+ token += c;
}
c = get_8();
}
- token.push_back(0);
+ token += '0';
return String::utf8(token.get_data());
}
@@ -293,7 +293,7 @@ class CharBuffer {
for (int i = 0; i < written; i++) {
- vector[i] = stack_buffer[i];
+ vector.write[i] = stack_buffer[i];
}
}
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index e94ccb4f48..12c6ef7d3b 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -949,6 +949,14 @@ bool InputEventAction::is_pressed() const {
return pressed;
}
+bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
+ Ref<InputEventKey> event = p_event;
+ if (event.is_null())
+ return false;
+
+ return event->is_action(action);
+}
+
bool InputEventAction::is_action(const StringName &p_action) const {
return action == p_action;
diff --git a/core/os/input_event.h b/core/os/input_event.h
index 04126fee77..07df81488b 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -480,6 +480,7 @@ public:
virtual bool is_action(const StringName &p_action) const;
+ virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h
index e0fb589767..3ff7db2a44 100644
--- a/core/os/threaded_array_processor.h
+++ b/core/os/threaded_array_processor.h
@@ -80,7 +80,7 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us
threads.resize(OS::get_singleton()->get_processor_count());
for (int i = 0; i < threads.size(); i++) {
- threads[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U> >, &data);
+ threads.write[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U> >, &data);
}
for (int i = 0; i < threads.size(); i++) {
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index eaccdba9bf..45e060fa4a 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -251,7 +251,7 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
int len;
encode_variant(p_data, NULL, len);
tmpdata.resize(tmpdata.size() + len);
- encode_variant(p_data, &tmpdata[pos], len);
+ encode_variant(p_data, &tmpdata.write[pos], len);
return pos;
} break;
@@ -268,8 +268,8 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
uint32_t pos = tmpdata.size();
int len = d.size();
tmpdata.resize(tmpdata.size() + len * 12 + 8);
- encode_uint32(TYPE_DICT, &tmpdata[pos + 0]);
- encode_uint32(len, &tmpdata[pos + 4]);
+ encode_uint32(TYPE_DICT, &tmpdata.write[pos + 0]);
+ encode_uint32(len, &tmpdata.write[pos + 4]);
List<Variant> keys;
d.get_key_list(&keys);
@@ -288,11 +288,11 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
int idx = 0;
for (List<DictKey>::Element *E = sortk.front(); E; E = E->next()) {
- encode_uint32(E->get().hash, &tmpdata[pos + 8 + idx * 12 + 0]);
+ encode_uint32(E->get().hash, &tmpdata.write[pos + 8 + idx * 12 + 0]);
uint32_t ofs = _pack(E->get().key, tmpdata, string_cache);
- encode_uint32(ofs, &tmpdata[pos + 8 + idx * 12 + 4]);
+ encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 4]);
ofs = _pack(d[E->get().key], tmpdata, string_cache);
- encode_uint32(ofs, &tmpdata[pos + 8 + idx * 12 + 8]);
+ encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 8]);
idx++;
}
@@ -306,13 +306,13 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
uint32_t pos = tmpdata.size();
int len = a.size();
tmpdata.resize(tmpdata.size() + len * 4 + 8);
- encode_uint32(TYPE_ARRAY, &tmpdata[pos + 0]);
- encode_uint32(len, &tmpdata[pos + 4]);
+ encode_uint32(TYPE_ARRAY, &tmpdata.write[pos + 0]);
+ encode_uint32(len, &tmpdata.write[pos + 4]);
for (int i = 0; i < len; i++) {
uint32_t ofs = _pack(a[i], tmpdata, string_cache);
- encode_uint32(ofs, &tmpdata[pos + 8 + i * 4]);
+ encode_uint32(ofs, &tmpdata.write[pos + 8 + i * 4]);
}
return pos;
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 60e8933751..146b4870e8 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -627,7 +627,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
Vector<uint8_t> buff;
buff.resize(len);
- err = encode_variant(p_custom_features, &buff[0], len);
+ err = encode_variant(p_custom_features, buff.ptrw(), len);
if (err != OK) {
memdelete(file);
ERR_FAIL_V(err);
@@ -664,7 +664,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
Vector<uint8_t> buff;
buff.resize(len);
- err = encode_variant(value, &buff[0], len);
+ err = encode_variant(value, buff.ptrw(), len);
if (err != OK)
memdelete(file);
ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
@@ -959,7 +959,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("application/config/name", "");
GLOBAL_DEF("application/run/main_scene", "");
- custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "tscn,scn,res");
+ custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res");
GLOBAL_DEF("application/run/disable_stdout", false);
GLOBAL_DEF("application/run/disable_stderr", false);
GLOBAL_DEF("application/config/use_custom_user_dir", false);
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index de4757612a..00628a4ab3 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -137,7 +137,7 @@ public:
Error write(const T &p_v) {
ERR_FAIL_COND_V(space_left() < 1, FAILED);
- data[inc(write_pos, 1)] = p_v;
+ data.write[inc(write_pos, 1)] = p_v;
return OK;
};
@@ -156,7 +156,7 @@ public:
int total = end - pos;
for (int i = 0; i < total; i++) {
- data[pos + i] = p_buf[src++];
+ data.write[pos + i] = p_buf[src++];
};
to_write -= total;
pos = 0;
@@ -196,7 +196,7 @@ public:
data.resize(1 << p_power);
if (old_size < new_size && read_pos > write_pos) {
for (int i = 0; i < write_pos; i++) {
- data[(old_size + i) & mask] = data[i];
+ data.write[(old_size + i) & mask] = data[i];
};
write_pos = (old_size + write_pos) & mask;
} else {
diff --git a/core/script_debugger_local.cpp b/core/script_debugger_local.cpp
index 55d7270473..6949b5802b 100644
--- a/core/script_debugger_local.cpp
+++ b/core/script_debugger_local.cpp
@@ -325,7 +325,7 @@ void ScriptDebuggerLocal::idle_poll() {
int ofs = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo[ofs], pinfo.size() - ofs);
+ ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo.write[ofs], pinfo.size() - ofs);
}
SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;
@@ -377,7 +377,7 @@ void ScriptDebuggerLocal::profiling_end() {
int ofs = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo[ofs], pinfo.size() - ofs);
+ ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo.write[ofs], pinfo.size() - ofs);
}
SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 3955f222f9..c5daaeea47 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -783,13 +783,13 @@ void ScriptDebuggerRemote::_send_profiling_data(bool p_for_frame) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
if (p_for_frame)
- ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info[ofs], profile_info.size() - ofs);
+ ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info.write[ofs], profile_info.size() - ofs);
else
- ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info[ofs], profile_info.size() - ofs);
+ ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info.write[ofs], profile_info.size() - ofs);
}
for (int i = 0; i < ofs; i++) {
- profile_info_ptrs[i] = &profile_info[i];
+ profile_info_ptrs.write[i] = &profile_info.write[i];
}
SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa;
@@ -1054,7 +1054,7 @@ void ScriptDebuggerRemote::add_profiling_frame_data(const StringName &p_name, co
if (idx == -1) {
profile_frame_data.push_back(fd);
} else {
- profile_frame_data[idx] = fd;
+ profile_frame_data.write[idx] = fd;
}
}
diff --git a/core/string_buffer.h b/core/string_buffer.h
index 7e9b151bea..5d3be0ecf1 100644
--- a/core/string_buffer.h
+++ b/core/string_buffer.h
@@ -42,7 +42,7 @@ class StringBuffer {
int string_length;
_FORCE_INLINE_ CharType *current_buffer_ptr() {
- return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptrw();
+ return static_cast<String &>(buffer).empty() ? short_buffer : buffer.ptrw();
}
public:
diff --git a/core/typedefs.h b/core/typedefs.h
index 71771ea4e6..57afa3bdb4 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -58,12 +58,8 @@
#endif
#ifndef _FORCE_INLINE_
-#ifdef DEBUG_ENABLED
-#define _FORCE_INLINE_ inline
-#else
#define _FORCE_INLINE_ _ALWAYS_INLINE_
#endif
-#endif
//custom, gcc-safe offsetof, because gcc complains a lot.
template <class T>
@@ -267,7 +263,7 @@ static inline uint64_t BSWAP64(uint64_t x) {
template <class T>
struct Comparator {
- inline bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
+ _ALWAYS_INLINE_ bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
};
void _global_lock();
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index b9a2fdd0ac..3d90608dd7 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -39,7 +39,7 @@ void UndoRedo::_discard_redo() {
for (int i = current_action + 1; i < actions.size(); i++) {
- for (List<Operation>::Element *E = actions[i].do_ops.front(); E; E = E->next()) {
+ for (List<Operation>::Element *E = actions.write[i].do_ops.front(); E; E = E->next()) {
if (E->get().type == Operation::TYPE_REFERENCE) {
@@ -70,7 +70,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
if (p_mode == MERGE_ENDS) {
// Clear all do ops from last action, and delete all object references
- List<Operation>::Element *E = actions[current_action + 1].do_ops.front();
+ List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
while (E) {
@@ -83,11 +83,11 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
}
E = E->next();
- actions[current_action + 1].do_ops.pop_front();
+ actions.write[current_action + 1].do_ops.pop_front();
}
}
- actions[actions.size() - 1].last_tick = ticks;
+ actions.write[actions.size() - 1].last_tick = ticks;
merge_mode = p_mode;
@@ -122,7 +122,7 @@ void UndoRedo::add_do_method(Object *p_object, const String &p_method, VARIANT_A
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
do_op.args[i] = *argptr[i];
}
- actions[current_action + 1].do_ops.push_back(do_op);
+ actions.write[current_action + 1].do_ops.push_back(do_op);
}
void UndoRedo::add_undo_method(Object *p_object, const String &p_method, VARIANT_ARG_DECLARE) {
@@ -147,7 +147,7 @@ void UndoRedo::add_undo_method(Object *p_object, const String &p_method, VARIANT
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
undo_op.args[i] = *argptr[i];
}
- actions[current_action + 1].undo_ops.push_back(undo_op);
+ actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
void UndoRedo::add_do_property(Object *p_object, const String &p_property, const Variant &p_value) {
@@ -162,7 +162,7 @@ void UndoRedo::add_do_property(Object *p_object, const String &p_property, const
do_op.type = Operation::TYPE_PROPERTY;
do_op.name = p_property;
do_op.args[0] = p_value;
- actions[current_action + 1].do_ops.push_back(do_op);
+ actions.write[current_action + 1].do_ops.push_back(do_op);
}
void UndoRedo::add_undo_property(Object *p_object, const String &p_property, const Variant &p_value) {
@@ -182,7 +182,7 @@ void UndoRedo::add_undo_property(Object *p_object, const String &p_property, con
undo_op.type = Operation::TYPE_PROPERTY;
undo_op.name = p_property;
undo_op.args[0] = p_value;
- actions[current_action + 1].undo_ops.push_back(undo_op);
+ actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
void UndoRedo::add_do_reference(Object *p_object) {
@@ -195,7 +195,7 @@ void UndoRedo::add_do_reference(Object *p_object) {
do_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
do_op.type = Operation::TYPE_REFERENCE;
- actions[current_action + 1].do_ops.push_back(do_op);
+ actions.write[current_action + 1].do_ops.push_back(do_op);
}
void UndoRedo::add_undo_reference(Object *p_object) {
@@ -213,7 +213,7 @@ void UndoRedo::add_undo_reference(Object *p_object) {
undo_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
undo_op.type = Operation::TYPE_REFERENCE;
- actions[current_action + 1].undo_ops.push_back(undo_op);
+ actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
void UndoRedo::_pop_history_tail() {
@@ -223,7 +223,7 @@ void UndoRedo::_pop_history_tail() {
if (!actions.size())
return;
- for (List<Operation>::Element *E = actions[0].undo_ops.front(); E; E = E->next()) {
+ for (List<Operation>::Element *E = actions.write[0].undo_ops.front(); E; E = E->next()) {
if (E->get().type == Operation::TYPE_REFERENCE) {
@@ -307,7 +307,7 @@ bool UndoRedo::redo() {
return false; //nothing to redo
current_action++;
- _process_operation_list(actions[current_action].do_ops.front());
+ _process_operation_list(actions.write[current_action].do_ops.front());
version++;
return true;
@@ -318,7 +318,7 @@ bool UndoRedo::undo() {
ERR_FAIL_COND_V(action_level > 0, false);
if (current_action < 0)
return false; //nothing to redo
- _process_operation_list(actions[current_action].undo_ops.front());
+ _process_operation_list(actions.write[current_action].undo_ops.front());
current_action--;
version--;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 5f3858cb17..84613610a9 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -102,6 +102,15 @@ bool CharString::operator<(const CharString &p_right) const {
return is_str_less(get_data(), p_right.get_data());
}
+CharString &CharString::operator+=(char p_char) {
+
+ resize(size() ? size() + 1 : 2);
+ set(length(), 0);
+ set(length() - 1, p_char);
+
+ return *this;
+}
+
const char *CharString::get_data() const {
if (size())
@@ -1578,6 +1587,7 @@ String::String(const char *p_str) {
copy_from(p_str);
}
+
String::String(const CharType *p_str, int p_clip_to_len) {
copy_from(p_str, p_clip_to_len);
@@ -2197,7 +2207,7 @@ Vector<uint8_t> String::md5_buffer() const {
Vector<uint8_t> ret;
ret.resize(16);
for (int i = 0; i < 16; i++) {
- ret[i] = ctx.digest[i];
+ ret.write[i] = ctx.digest[i];
};
return ret;
@@ -2214,7 +2224,7 @@ Vector<uint8_t> String::sha256_buffer() const {
Vector<uint8_t> ret;
ret.resize(32);
for (int i = 0; i < 32; i++) {
- ret[i] = hash[i];
+ ret.write[i] = hash[i];
}
return ret;
@@ -2673,7 +2683,7 @@ Vector<String> String::bigrams() const {
}
b.resize(n_pairs);
for (int i = 0; i < n_pairs; i++) {
- b[i] = substr(i, 2);
+ b.write[i] = substr(i, 2);
}
return b;
}
@@ -3032,14 +3042,14 @@ String String::strip_escapes() const {
return substr(beg, end - beg);
}
-String String::lstrip(const Vector<CharType> &p_chars) const {
+String String::lstrip(const String &p_chars) const {
int len = length();
int beg;
for (beg = 0; beg < len; beg++) {
- if (p_chars.find(operator[](beg)) == -1)
+ if (p_chars.find(&ptr()[beg]) == -1)
break;
}
@@ -3049,14 +3059,14 @@ String String::lstrip(const Vector<CharType> &p_chars) const {
return substr(beg, len - beg);
}
-String String::rstrip(const Vector<CharType> &p_chars) const {
+String String::rstrip(const String &p_chars) const {
int len = length();
int end;
for (end = len - 1; end >= 0; end--) {
- if (p_chars.find(operator[](end)) == -1)
+ if (p_chars.find(&ptr()[end]) == -1)
break;
}
@@ -3868,10 +3878,10 @@ String String::percent_decode() const {
c += d;
i += 2;
}
- pe.push_back(c);
+ pe += c;
}
- pe.push_back(0);
+ pe += '0';
return String::utf8(pe.ptr());
}
diff --git a/core/ustring.h b/core/ustring.h
index 001d111d64..3b4405833c 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -32,6 +32,7 @@
#define RSTRING_H
#include "array.h"
+#include "cowdata.h"
#include "typedefs.h"
#include "vector.h"
@@ -39,9 +40,27 @@
@author red <red@killy>
*/
-class CharString : public Vector<char> {
+class CharString {
+
+ CowData<char> _cowdata;
+
public:
+ _FORCE_INLINE_ char *ptrw() { return _cowdata.ptrw(); }
+ _FORCE_INLINE_ const char *ptr() const { return _cowdata.ptr(); }
+ _FORCE_INLINE_ int size() const { return _cowdata.size(); }
+ Error resize(int p_size) { return _cowdata.resize(p_size); }
+
+ _FORCE_INLINE_ char get(int p_index) { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ const char get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ void set(int p_index, const char &p_elem) { _cowdata.set(p_index, p_elem); }
+ _FORCE_INLINE_ char &operator[](int p_index) { return _cowdata.get_m(p_index); }
+ _FORCE_INLINE_ const char &operator[](int p_index) const { return _cowdata.get(p_index); }
+
+ _FORCE_INLINE_ CharString() {}
+ _FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
+
bool operator<(const CharString &p_right) const;
+ CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
const char *get_data() const;
operator const char *() { return get_data(); };
@@ -60,7 +79,9 @@ struct StrRange {
}
};
-class String : public Vector<CharType> {
+class String {
+
+ CowData<CharType> _cowdata;
void copy_from(const char *p_cstr);
void copy_from(const CharType *p_cstr, int p_clip_to = -1);
@@ -74,6 +95,21 @@ public:
npos = -1 ///<for "some" compatibility with std::string (npos is a huge value in std::string)
};
+ _FORCE_INLINE_ CharType *ptrw() { return _cowdata.ptrw(); }
+ _FORCE_INLINE_ const CharType *ptr() const { return _cowdata.ptr(); }
+
+ void remove(int p_index) { _cowdata.remove(p_index); }
+
+ _FORCE_INLINE_ void clear() { resize(0); }
+
+ _FORCE_INLINE_ CharType get(int p_index) { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ const CharType get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ void set(int p_index, const CharType &p_elem) { _cowdata.set(p_index, p_elem); }
+ _FORCE_INLINE_ int size() const { return _cowdata.size(); }
+ Error resize(int p_size) { return _cowdata.resize(p_size); }
+ _FORCE_INLINE_ CharType &operator[](int p_index) { return _cowdata.get_m(p_index); }
+ _FORCE_INLINE_ const CharType &operator[](int p_index) const { return _cowdata.get(p_index); }
+
bool operator==(const String &p_str) const;
bool operator!=(const String &p_str) const;
String operator+(const String &p_str) const;
@@ -192,8 +228,8 @@ public:
String dedent() const;
String strip_edges(bool left = true, bool right = true) const;
String strip_escapes() const;
- String lstrip(const Vector<CharType> &p_chars) const;
- String rstrip(const Vector<CharType> &p_chars) const;
+ String lstrip(const String &p_chars) const;
+ String rstrip(const String &p_chars) const;
String get_extension() const;
String get_basename() const;
String plus_file(const String &p_file) const;
@@ -254,9 +290,10 @@ public:
* The constructors must not depend on other overloads
*/
/* String(CharType p_char);*/
- inline String() {}
- inline String(const String &p_str) :
- Vector(p_str) {}
+
+ _FORCE_INLINE_ String() {}
+ _FORCE_INLINE_ String(const String &p_str) { _cowdata._ref(p_str._cowdata); }
+
String(const char *p_str);
String(const CharType *p_str, int p_clip_to_len = -1);
String(const StrRange &p_range);
diff --git a/core/variant.cpp b/core/variant.cpp
index c48aa57652..e4be5520bc 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -1878,7 +1878,7 @@ Variant::operator Vector<RID>() const {
Vector<RID> rids;
rids.resize(va.size());
for (int i = 0; i < rids.size(); i++)
- rids[i] = va[i];
+ rids.write[i] = va[i];
return rids;
}
@@ -1891,7 +1891,7 @@ Variant::operator Vector<Vector2>() const {
return Vector<Vector2>();
to.resize(len);
PoolVector<Vector2>::Read r = from.read();
- Vector2 *w = &to[0];
+ Vector2 *w = to.ptrw();
for (int i = 0; i < len; i++) {
w[i] = r[i];
@@ -1945,7 +1945,7 @@ Variant::operator Vector<Plane>() const {
planes.resize(va_size);
for (int i = 0; i < va_size; i++)
- planes[i] = va[i];
+ planes.write[i] = va[i];
return planes;
}
@@ -1958,7 +1958,7 @@ Variant::operator Vector<Variant>() const {
to.resize(len);
for (int i = 0; i < len; i++) {
- to[i] = from[i];
+ to.write[i] = from[i];
}
return to;
}
@@ -1971,7 +1971,7 @@ Variant::operator Vector<uint8_t>() const {
to.resize(len);
for (int i = 0; i < len; i++) {
- to[i] = from[i];
+ to.write[i] = from[i];
}
return to;
}
@@ -1983,7 +1983,7 @@ Variant::operator Vector<int>() const {
to.resize(len);
for (int i = 0; i < len; i++) {
- to[i] = from[i];
+ to.write[i] = from[i];
}
return to;
}
@@ -1995,7 +1995,7 @@ Variant::operator Vector<real_t>() const {
to.resize(len);
for (int i = 0; i < len; i++) {
- to[i] = from[i];
+ to.write[i] = from[i];
}
return to;
}
@@ -2008,7 +2008,7 @@ Variant::operator Vector<String>() const {
to.resize(len);
for (int i = 0; i < len; i++) {
- to[i] = from[i];
+ to.write[i] = from[i];
}
return to;
}
@@ -2020,7 +2020,7 @@ Variant::operator Vector<StringName>() const {
to.resize(len);
for (int i = 0; i < len; i++) {
- to[i] = from[i];
+ to.write[i] = from[i];
}
return to;
}
@@ -2034,7 +2034,7 @@ Variant::operator Vector<Vector3>() const {
return Vector<Vector3>();
to.resize(len);
PoolVector<Vector3>::Read r = from.read();
- Vector3 *w = &to[0];
+ Vector3 *w = to.ptrw();
for (int i = 0; i < len; i++) {
w[i] = r[i];
@@ -2050,7 +2050,7 @@ Variant::operator Vector<Color>() const {
return Vector<Color>();
to.resize(len);
PoolVector<Color>::Read r = from.read();
- Color *w = &to[0];
+ Color *w = to.ptrw();
for (int i = 0; i < len; i++) {
w[i] = r[i];
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index e6f36ecbf1..20a2929dc0 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -64,7 +64,7 @@ struct _VariantCall {
if (arg_count == 0)
return true;
- Variant::Type *tptr = &arg_types[0];
+ const Variant::Type *tptr = &arg_types[0];
for (int i = 0; i < arg_count; i++) {
@@ -446,8 +446,12 @@ struct _VariantCall {
VCALL_LOCALMEM1(Quat, set_euler);
VCALL_LOCALMEM2(Quat, set_axis_angle);
- VCALL_LOCALMEM0R(Color, to_rgba32);
VCALL_LOCALMEM0R(Color, to_argb32);
+ VCALL_LOCALMEM0R(Color, to_abgr32);
+ VCALL_LOCALMEM0R(Color, to_rgba32);
+ VCALL_LOCALMEM0R(Color, to_argb64);
+ VCALL_LOCALMEM0R(Color, to_abgr64);
+ VCALL_LOCALMEM0R(Color, to_rgba64);
VCALL_LOCALMEM0R(Color, gray);
VCALL_LOCALMEM0R(Color, inverted);
VCALL_LOCALMEM0R(Color, contrasted);
@@ -1613,8 +1617,12 @@ void register_variant_methods() {
ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray());
ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", REAL, "angle", varray());
- ADDFUNC0R(COLOR, INT, Color, to_rgba32, varray());
ADDFUNC0R(COLOR, INT, Color, to_argb32, varray());
+ ADDFUNC0R(COLOR, INT, Color, to_abgr32, varray());
+ ADDFUNC0R(COLOR, INT, Color, to_rgba32, varray());
+ ADDFUNC0R(COLOR, INT, Color, to_argb64, varray());
+ ADDFUNC0R(COLOR, INT, Color, to_abgr64, varray());
+ ADDFUNC0R(COLOR, INT, Color, to_rgba64, varray());
ADDFUNC0R(COLOR, REAL, Color, gray, varray());
ADDFUNC0R(COLOR, COLOR, Color, inverted, varray());
ADDFUNC0R(COLOR, COLOR, Color, contrasted, varray());
diff --git a/core/vector.h b/core/vector.h
index c026448ddd..7e3da34be0 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -36,131 +36,69 @@
* @author Juan Linietsky
* Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use PoolVector for large arrays.
*/
+#include "cowdata.h"
#include "error_macros.h"
#include "os/memory.h"
-#include "safe_refcount.h"
#include "sort.h"
template <class T>
-class Vector {
-
- mutable T *_ptr;
-
- // internal helpers
-
- _FORCE_INLINE_ uint32_t *_get_refcount() const {
-
- if (!_ptr)
- return NULL;
+class VectorWriteProxy {
+ friend class Vector<T>;
+ Vector<T> &_parent;
- return reinterpret_cast<uint32_t *>(_ptr) - 2;
- }
-
- _FORCE_INLINE_ uint32_t *_get_size() const {
-
- if (!_ptr)
- return NULL;
-
- return reinterpret_cast<uint32_t *>(_ptr) - 1;
- }
- _FORCE_INLINE_ T *_get_data() const {
+ _FORCE_INLINE_ VectorWriteProxy(Vector<T> &parent) :
+ _parent(parent){};
+ VectorWriteProxy(const VectorWriteProxy<T> &p_other);
- if (!_ptr)
- return NULL;
- return reinterpret_cast<T *>(_ptr);
- }
-
- _FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
- //return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
- return next_power_of_2(p_elements * sizeof(T));
- }
+public:
+ _FORCE_INLINE_ T &operator[](int p_index) {
+ CRASH_BAD_INDEX(p_index, _parent.size());
- _FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
-#if defined(_add_overflow) && defined(_mul_overflow)
- size_t o;
- size_t p;
- if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
- *out = next_power_of_2(o);
- if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
- return true;
-#else
- // Speed is more important than correctness here, do the operations unchecked
- // and hope the best
- *out = _get_alloc_size(p_elements);
- return true;
-#endif
+ return _parent.ptrw()[p_index];
}
+};
- void _unref(void *p_data);
+template <class T>
+class Vector {
+ friend class VectorWriteProxy<T>;
- void _copy_from(const Vector &p_from);
- void _copy_on_write();
+ CowData<T> _cowdata;
public:
- _FORCE_INLINE_ T *ptrw() {
- if (!_ptr) return NULL;
- _copy_on_write();
- return (T *)_get_data();
- }
- _FORCE_INLINE_ const T *ptr() const {
- if (!_ptr) return NULL;
- return _get_data();
- }
-
- _FORCE_INLINE_ void clear() { resize(0); }
+ VectorWriteProxy<T> write;
- _FORCE_INLINE_ int size() const {
- uint32_t *size = (uint32_t *)_get_size();
- if (size)
- return *size;
- else
- return 0;
- }
- _FORCE_INLINE_ bool empty() const { return _ptr == 0; }
- Error resize(int p_size);
bool push_back(const T &p_elem);
- void remove(int p_index);
+ void remove(int p_index) { _cowdata.remove(p_index); }
void erase(const T &p_val) {
int idx = find(p_val);
if (idx >= 0) remove(idx);
};
void invert();
- template <class T_val>
- int find(const T_val &p_val, int p_from = 0) const;
-
- void set(int p_index, const T &p_elem);
- T get(int p_index) const;
-
- inline T &operator[](int p_index) {
-
- CRASH_BAD_INDEX(p_index, size());
-
- _copy_on_write(); // wants to write, so copy on write.
-
- return _get_data()[p_index];
- }
-
- inline const T &operator[](int p_index) const {
-
- CRASH_BAD_INDEX(p_index, size());
-
- // no cow needed, since it's reading
- return _get_data()[p_index];
- }
+ _FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
+ _FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
+ _FORCE_INLINE_ void clear() { resize(0); }
+ _FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
- Error insert(int p_pos, const T &p_val);
+ _FORCE_INLINE_ T get(int p_index) { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ const T get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); }
+ _FORCE_INLINE_ int size() const { return _cowdata.size(); }
+ Error resize(int p_size) { return _cowdata.resize(p_size); }
+ _FORCE_INLINE_ const T &operator[](int p_index) const { return _cowdata.get(p_index); }
+ Error insert(int p_pos, const T &p_val) { return _cowdata.insert(p_pos, p_val); }
void append_array(const Vector<T> &p_other);
template <class C>
void sort_custom() {
- int len = size();
+ int len = _cowdata.size();
if (len == 0)
return;
- T *data = &operator[](0);
+
+ T *data = ptrw();
SortArray<T, C> sorter;
sorter.sort(data, len);
}
@@ -172,7 +110,7 @@ public:
void ordered_insert(const T &p_val) {
int i;
- for (i = 0; i < size(); i++) {
+ for (i = 0; i < _cowdata.size(); i++) {
if (p_val < operator[](i)) {
break;
@@ -181,235 +119,42 @@ public:
insert(i, p_val);
}
- void operator=(const Vector &p_from);
- Vector(const Vector &p_from);
-
- _FORCE_INLINE_ Vector();
- _FORCE_INLINE_ ~Vector();
-};
+ int find(const T &p_val, int p_from = 0) const {
+ int ret = -1;
+ if (p_from < 0 || size() == 0)
+ return ret;
-template <class T>
-void Vector<T>::_unref(void *p_data) {
+ for (int i = p_from; i < size(); i++) {
- if (!p_data)
- return;
-
- uint32_t *refc = _get_refcount();
-
- if (atomic_decrement(refc) > 0)
- return; // still in use
- // clean up
-
- uint32_t *count = _get_size();
- T *data = (T *)(count + 1);
-
- for (uint32_t i = 0; i < *count; i++) {
- // call destructors
- data[i].~T();
- }
-
- // free mem
- Memory::free_static((uint8_t *)p_data, true);
-}
-
-template <class T>
-void Vector<T>::_copy_on_write() {
-
- if (!_ptr)
- return;
-
- uint32_t *refc = _get_refcount();
-
- if (*refc > 1) {
- /* in use by more than me */
- uint32_t current_size = *_get_size();
-
- uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
-
- *(mem_new - 2) = 1; //refcount
- *(mem_new - 1) = current_size; //size
-
- T *_data = (T *)(mem_new);
-
- // initialize new elements
- for (uint32_t i = 0; i < current_size; i++) {
-
- memnew_placement(&_data[i], T(_get_data()[i]));
- }
-
- _unref(_ptr);
- _ptr = _data;
- }
-}
-
-template <class T>
-template <class T_val>
-int Vector<T>::find(const T_val &p_val, int p_from) const {
-
- int ret = -1;
- if (p_from < 0 || size() == 0)
- return ret;
-
- for (int i = p_from; i < size(); i++) {
-
- if (operator[](i) == p_val) {
- ret = i;
- break;
+ if (ptr()[i] == p_val) {
+ ret = i;
+ break;
+ };
};
- };
-
- return ret;
-}
-
-template <class T>
-Error Vector<T>::resize(int p_size) {
-
- ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
-
- if (p_size == size())
- return OK;
- if (p_size == 0) {
- // wants to clean up
- _unref(_ptr);
- _ptr = NULL;
- return OK;
+ return ret;
}
- // possibly changing size, copy on write
- _copy_on_write();
-
- size_t alloc_size;
- ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
-
- if (p_size > size()) {
-
- if (size() == 0) {
- // alloc from scratch
- uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
- ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
- *(ptr - 1) = 0; //size, currently none
- *(ptr - 2) = 1; //refcount
-
- _ptr = (T *)ptr;
-
- } else {
- void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
- ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
- _ptr = (T *)(_ptrnew);
- }
-
- // construct the newly created elements
- T *elems = _get_data();
-
- for (int i = *_get_size(); i < p_size; i++) {
-
- memnew_placement(&elems[i], T);
- }
-
- *_get_size() = p_size;
-
- } else if (p_size < size()) {
-
- // deinitialize no longer needed elements
- for (uint32_t i = p_size; i < *_get_size(); i++) {
-
- T *t = &_get_data()[i];
- t->~T();
- }
-
- void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
- ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
-
- _ptr = (T *)(_ptrnew);
-
- *_get_size() = p_size;
+ _FORCE_INLINE_ Vector() :
+ write(VectorWriteProxy<T>(*this)) {}
+ _FORCE_INLINE_ Vector(const Vector &p_from) :
+ write(VectorWriteProxy<T>(*this)) { _cowdata._ref(p_from._cowdata); }
+ inline Vector &operator=(const Vector &p_from) {
+ _cowdata._ref(p_from._cowdata);
+ return *this;
}
-
- return OK;
-}
+};
template <class T>
void Vector<T>::invert() {
for (int i = 0; i < size() / 2; i++) {
-
- SWAP(operator[](i), operator[](size() - i - 1));
- }
-}
-
-template <class T>
-void Vector<T>::set(int p_index, const T &p_elem) {
-
- operator[](p_index) = p_elem;
-}
-
-template <class T>
-T Vector<T>::get(int p_index) const {
-
- return operator[](p_index);
-}
-
-template <class T>
-bool Vector<T>::push_back(const T &p_elem) {
-
- Error err = resize(size() + 1);
- ERR_FAIL_COND_V(err, true)
- set(size() - 1, p_elem);
-
- return false;
-}
-
-template <class T>
-void Vector<T>::remove(int p_index) {
-
- ERR_FAIL_INDEX(p_index, size());
- T *p = ptrw();
- int len = size();
- for (int i = p_index; i < len - 1; i++) {
-
- p[i] = p[i + 1];
- };
-
- resize(len - 1);
-};
-
-template <class T>
-void Vector<T>::_copy_from(const Vector &p_from) {
-
- if (_ptr == p_from._ptr)
- return; // self assign, do nothing.
-
- _unref(_ptr);
- _ptr = NULL;
-
- if (!p_from._ptr)
- return; //nothing to do
-
- if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
- _ptr = p_from._ptr;
+ T *p = ptrw();
+ SWAP(p[i], p[size() - i - 1]);
}
}
template <class T>
-void Vector<T>::operator=(const Vector &p_from) {
-
- _copy_from(p_from);
-}
-
-template <class T>
-Error Vector<T>::insert(int p_pos, const T &p_val) {
-
- ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
- resize(size() + 1);
- for (int i = (size() - 1); i > p_pos; i--)
- set(i, get(i - 1));
- set(p_pos, p_val);
-
- return OK;
-}
-
-template <class T>
void Vector<T>::append_array(const Vector<T> &p_other) {
const int ds = p_other.size();
if (ds == 0)
@@ -417,26 +162,17 @@ void Vector<T>::append_array(const Vector<T> &p_other) {
const int bs = size();
resize(bs + ds);
for (int i = 0; i < ds; ++i)
- operator[](bs + i) = p_other[i];
-}
-
-template <class T>
-Vector<T>::Vector(const Vector &p_from) {
-
- _ptr = NULL;
- _copy_from(p_from);
+ ptrw()[bs + i] = p_other[i];
}
template <class T>
-Vector<T>::Vector() {
-
- _ptr = NULL;
-}
+bool Vector<T>::push_back(const T &p_elem) {
-template <class T>
-Vector<T>::~Vector() {
+ Error err = resize(size() + 1);
+ ERR_FAIL_COND_V(err, true)
+ set(size() - 1, p_elem);
- _unref(_ptr);
+ return false;
}
#endif
diff --git a/core/vmap.h b/core/vmap.h
index 8636c02997..ce0ddc4ec6 100644
--- a/core/vmap.h
+++ b/core/vmap.h
@@ -31,8 +31,8 @@
#ifndef VMAP_H
#define VMAP_H
+#include "cowdata.h"
#include "typedefs.h"
-#include "vector.h"
template <class T, class V>
class VMap {
@@ -51,17 +51,17 @@ class VMap {
}
};
- Vector<_Pair> _data;
+ CowData<_Pair> _cowdata;
_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
r_exact = false;
- if (_data.empty())
+ if (_cowdata.empty())
return 0;
int low = 0;
- int high = _data.size() - 1;
- const _Pair *a = &_data[0];
+ int high = _cowdata.size() - 1;
+ const _Pair *a = _cowdata.ptr();
int middle = 0;
#if DEBUG_ENABLED
@@ -89,13 +89,13 @@ class VMap {
_FORCE_INLINE_ int _find_exact(const T &p_val) const {
- if (_data.empty())
+ if (_cowdata.empty())
return -1;
int low = 0;
- int high = _data.size() - 1;
+ int high = _cowdata.size() - 1;
int middle;
- const _Pair *a = &_data[0];
+ const _Pair *a = _cowdata.ptr();
while (low <= high) {
middle = (low + high) / 2;
@@ -118,10 +118,10 @@ public:
bool exact;
int pos = _find(p_key, exact);
if (exact) {
- _data[pos].value = p_val;
+ _cowdata.get_m(pos).value = p_val;
return pos;
}
- _data.insert(pos, _Pair(p_key, p_val));
+ _cowdata.insert(pos, _Pair(p_key, p_val));
return pos;
}
@@ -135,7 +135,7 @@ public:
int pos = _find_exact(p_val);
if (pos < 0)
return;
- _data.remove(pos);
+ _cowdata.remove(pos);
}
int find(const T &p_val) const {
@@ -149,37 +149,37 @@ public:
return _find(p_val, exact);
}
- _FORCE_INLINE_ int size() const { return _data.size(); }
- _FORCE_INLINE_ bool empty() const { return _data.empty(); }
+ _FORCE_INLINE_ int size() const { return _cowdata.size(); }
+ _FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
const _Pair *get_array() const {
- return _data.ptr();
+ return _cowdata.ptr();
}
_Pair *get_array() {
- return _data.ptr();
+ return _cowdata.ptrw();
}
const V &getv(int p_index) const {
- return _data[p_index].value;
+ return _cowdata.get(p_index).value;
}
V &getv(int p_index) {
- return _data[p_index].value;
+ return _cowdata.get_m(p_index).value;
}
const T &getk(int p_index) const {
- return _data[p_index].key;
+ return _cowdata.get(p_index).key;
}
T &getk(int p_index) {
- return _data[p_index].key;
+ return _cowdata.get_m(p_index).key;
}
inline const V &operator[](const T &p_key) const {
@@ -188,7 +188,7 @@ public:
CRASH_COND(pos < 0);
- return _data[pos].value;
+ return _cowdata.get(pos).value;
}
inline V &operator[](const T &p_key) {
@@ -199,7 +199,14 @@ public:
pos = insert(p_key, val);
}
- return _data[pos].value;
+ return _cowdata.get_m(pos).value;
+ }
+
+ _FORCE_INLINE_ VMap(){};
+ _FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); }
+ inline VMap &operator=(const VMap &p_from) {
+ _cowdata._ref(p_from._cowdata);
+ return *this;
}
};
#endif // VMAP_H
diff --git a/core/vset.h b/core/vset.h
index 449943b4a1..7f4d8e7f62 100644
--- a/core/vset.h
+++ b/core/vset.h
@@ -133,7 +133,7 @@ public:
inline T &operator[](int p_index) {
- return _data[p_index];
+ return _data.write[p_index];
}
inline const T &operator[](int p_index) const {