diff options
1045 files changed, 22340 insertions, 14641 deletions
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 3ce3765efc..f4b571fc08 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=android verbose=yes warnings=all werror=yes --jobs=2 + SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes --jobs=2 SCONS_CACHE_LIMIT: 4096 jobs: diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml index 80db5d68ce..fa965a45f1 100644 --- a/.github/workflows/ios_builds.yml +++ b/.github/workflows/ios_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=iphone verbose=yes warnings=all werror=yes --jobs=2 + SCONSFLAGS: platform=iphone verbose=yes warnings=extra werror=yes --jobs=2 SCONS_CACHE_LIMIT: 4096 jobs: diff --git a/.github/workflows/javascript_builds.disabled b/.github/workflows/javascript_builds.disabled index 8ed77726cc..015a1f314c 100644 --- a/.github/workflows/javascript_builds.disabled +++ b/.github/workflows/javascript_builds.disabled @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=javascript verbose=yes warnings=all werror=yes --jobs=2 + SCONSFLAGS: platform=javascript verbose=yes warnings=extra werror=yes --jobs=2 SCONS_CACHE_LIMIT: 4096 EM_VERSION: 1.39.20 EM_CACHE_FOLDER: 'emsdk-cache' diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index b81c06e54d..b7b40eccbd 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=linuxbsd verbose=yes warnings=all werror=yes --jobs=2 + SCONSFLAGS: platform=linuxbsd verbose=yes warnings=extra werror=yes --jobs=2 SCONS_CACHE_LIMIT: 4096 jobs: diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 5f9ad24ac7..401cfadc30 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=osx verbose=yes warnings=all werror=yes --jobs=2 + SCONSFLAGS: platform=osx verbose=yes warnings=extra werror=yes --jobs=2 SCONS_CACHE_LIMIT: 4096 jobs: diff --git a/core/SCsub b/core/SCsub index b9f06d12ae..78a4395619 100644 --- a/core/SCsub +++ b/core/SCsub @@ -34,7 +34,7 @@ if "SCRIPT_AES256_ENCRYPTION_KEY" in os.environ: # 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 "core/project_settings.h"\nuint8_t script_encryption_key[32]={' + txt + "};\n") + f.write('#include "core/config/project_settings.h"\nuint8_t script_encryption_key[32]={' + txt + "};\n") # Add required thirdparty code. @@ -174,7 +174,12 @@ SConscript("crypto/SCsub") SConscript("io/SCsub") SConscript("debugger/SCsub") SConscript("input/SCsub") -SConscript("bind/SCsub") +SConscript("variant/SCsub") +SConscript("object/SCsub") +SConscript("templates/SCsub") +SConscript("string/SCsub") +SConscript("config/SCsub") +SConscript("error/SCsub") # Build it all as a library diff --git a/core/bind/SCsub b/core/bind/SCsub deleted file mode 100644 index 19a6549225..0000000000 --- a/core/bind/SCsub +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -env.add_source_files(env.core_sources, "*.cpp") diff --git a/core/color_names.inc b/core/color_names.inc deleted file mode 100644 index 2b50d88b02..0000000000 --- a/core/color_names.inc +++ /dev/null @@ -1,155 +0,0 @@ -// Names from https://en.wikipedia.org/wiki/X11_color_names -#include "core/map.h" - -static Map<String, Color> _named_colors; -static void _populate_named_colors() { - if (!_named_colors.empty()) { - return; - } - _named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00)); - _named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84)); - _named_colors.insert("aqua", Color(0.00, 1.00, 1.00)); - _named_colors.insert("aquamarine", Color(0.50, 1.00, 0.83)); - _named_colors.insert("azure", Color(0.94, 1.00, 1.00)); - _named_colors.insert("beige", Color(0.96, 0.96, 0.86)); - _named_colors.insert("bisque", Color(1.00, 0.89, 0.77)); - _named_colors.insert("black", Color(0.00, 0.00, 0.00)); - _named_colors.insert("blanchedalmond", Color(1.00, 0.92, 0.80)); - _named_colors.insert("blue", Color(0.00, 0.00, 1.00)); - _named_colors.insert("blueviolet", Color(0.54, 0.17, 0.89)); - _named_colors.insert("brown", Color(0.65, 0.16, 0.16)); - _named_colors.insert("burlywood", Color(0.87, 0.72, 0.53)); - _named_colors.insert("cadetblue", Color(0.37, 0.62, 0.63)); - _named_colors.insert("chartreuse", Color(0.50, 1.00, 0.00)); - _named_colors.insert("chocolate", Color(0.82, 0.41, 0.12)); - _named_colors.insert("coral", Color(1.00, 0.50, 0.31)); - _named_colors.insert("cornflower", Color(0.39, 0.58, 0.93)); - _named_colors.insert("cornsilk", Color(1.00, 0.97, 0.86)); - _named_colors.insert("crimson", Color(0.86, 0.08, 0.24)); - _named_colors.insert("cyan", Color(0.00, 1.00, 1.00)); - _named_colors.insert("darkblue", Color(0.00, 0.00, 0.55)); - _named_colors.insert("darkcyan", Color(0.00, 0.55, 0.55)); - _named_colors.insert("darkgoldenrod", Color(0.72, 0.53, 0.04)); - _named_colors.insert("darkgray", Color(0.66, 0.66, 0.66)); - _named_colors.insert("darkgreen", Color(0.00, 0.39, 0.00)); - _named_colors.insert("darkkhaki", Color(0.74, 0.72, 0.42)); - _named_colors.insert("darkmagenta", Color(0.55, 0.00, 0.55)); - _named_colors.insert("darkolivegreen", Color(0.33, 0.42, 0.18)); - _named_colors.insert("darkorange", Color(1.00, 0.55, 0.00)); - _named_colors.insert("darkorchid", Color(0.60, 0.20, 0.80)); - _named_colors.insert("darkred", Color(0.55, 0.00, 0.00)); - _named_colors.insert("darksalmon", Color(0.91, 0.59, 0.48)); - _named_colors.insert("darkseagreen", Color(0.56, 0.74, 0.56)); - _named_colors.insert("darkslateblue", Color(0.28, 0.24, 0.55)); - _named_colors.insert("darkslategray", Color(0.18, 0.31, 0.31)); - _named_colors.insert("darkturquoise", Color(0.00, 0.81, 0.82)); - _named_colors.insert("darkviolet", Color(0.58, 0.00, 0.83)); - _named_colors.insert("deeppink", Color(1.00, 0.08, 0.58)); - _named_colors.insert("deepskyblue", Color(0.00, 0.75, 1.00)); - _named_colors.insert("dimgray", Color(0.41, 0.41, 0.41)); - _named_colors.insert("dodgerblue", Color(0.12, 0.56, 1.00)); - _named_colors.insert("firebrick", Color(0.70, 0.13, 0.13)); - _named_colors.insert("floralwhite", Color(1.00, 0.98, 0.94)); - _named_colors.insert("forestgreen", Color(0.13, 0.55, 0.13)); - _named_colors.insert("fuchsia", Color(1.00, 0.00, 1.00)); - _named_colors.insert("gainsboro", Color(0.86, 0.86, 0.86)); - _named_colors.insert("ghostwhite", Color(0.97, 0.97, 1.00)); - _named_colors.insert("gold", Color(1.00, 0.84, 0.00)); - _named_colors.insert("goldenrod", Color(0.85, 0.65, 0.13)); - _named_colors.insert("gray", Color(0.75, 0.75, 0.75)); - _named_colors.insert("webgray", Color(0.50, 0.50, 0.50)); - _named_colors.insert("green", Color(0.00, 1.00, 0.00)); - _named_colors.insert("webgreen", Color(0.00, 0.50, 0.00)); - _named_colors.insert("greenyellow", Color(0.68, 1.00, 0.18)); - _named_colors.insert("honeydew", Color(0.94, 1.00, 0.94)); - _named_colors.insert("hotpink", Color(1.00, 0.41, 0.71)); - _named_colors.insert("indianred", Color(0.80, 0.36, 0.36)); - _named_colors.insert("indigo", Color(0.29, 0.00, 0.51)); - _named_colors.insert("ivory", Color(1.00, 1.00, 0.94)); - _named_colors.insert("khaki", Color(0.94, 0.90, 0.55)); - _named_colors.insert("lavender", Color(0.90, 0.90, 0.98)); - _named_colors.insert("lavenderblush", Color(1.00, 0.94, 0.96)); - _named_colors.insert("lawngreen", Color(0.49, 0.99, 0.00)); - _named_colors.insert("lemonchiffon", Color(1.00, 0.98, 0.80)); - _named_colors.insert("lightblue", Color(0.68, 0.85, 0.90)); - _named_colors.insert("lightcoral", Color(0.94, 0.50, 0.50)); - _named_colors.insert("lightcyan", Color(0.88, 1.00, 1.00)); - _named_colors.insert("lightgoldenrod", Color(0.98, 0.98, 0.82)); - _named_colors.insert("lightgray", Color(0.83, 0.83, 0.83)); - _named_colors.insert("lightgreen", Color(0.56, 0.93, 0.56)); - _named_colors.insert("lightpink", Color(1.00, 0.71, 0.76)); - _named_colors.insert("lightsalmon", Color(1.00, 0.63, 0.48)); - _named_colors.insert("lightseagreen", Color(0.13, 0.70, 0.67)); - _named_colors.insert("lightskyblue", Color(0.53, 0.81, 0.98)); - _named_colors.insert("lightslategray", Color(0.47, 0.53, 0.60)); - _named_colors.insert("lightsteelblue", Color(0.69, 0.77, 0.87)); - _named_colors.insert("lightyellow", Color(1.00, 1.00, 0.88)); - _named_colors.insert("lime", Color(0.00, 1.00, 0.00)); - _named_colors.insert("limegreen", Color(0.20, 0.80, 0.20)); - _named_colors.insert("linen", Color(0.98, 0.94, 0.90)); - _named_colors.insert("magenta", Color(1.00, 0.00, 1.00)); - _named_colors.insert("maroon", Color(0.69, 0.19, 0.38)); - _named_colors.insert("webmaroon", Color(0.50, 0.00, 0.00)); - _named_colors.insert("mediumaquamarine", Color(0.40, 0.80, 0.67)); - _named_colors.insert("mediumblue", Color(0.00, 0.00, 0.80)); - _named_colors.insert("mediumorchid", Color(0.73, 0.33, 0.83)); - _named_colors.insert("mediumpurple", Color(0.58, 0.44, 0.86)); - _named_colors.insert("mediumseagreen", Color(0.24, 0.70, 0.44)); - _named_colors.insert("mediumslateblue", Color(0.48, 0.41, 0.93)); - _named_colors.insert("mediumspringgreen", Color(0.00, 0.98, 0.60)); - _named_colors.insert("mediumturquoise", Color(0.28, 0.82, 0.80)); - _named_colors.insert("mediumvioletred", Color(0.78, 0.08, 0.52)); - _named_colors.insert("midnightblue", Color(0.10, 0.10, 0.44)); - _named_colors.insert("mintcream", Color(0.96, 1.00, 0.98)); - _named_colors.insert("mistyrose", Color(1.00, 0.89, 0.88)); - _named_colors.insert("moccasin", Color(1.00, 0.89, 0.71)); - _named_colors.insert("navajowhite", Color(1.00, 0.87, 0.68)); - _named_colors.insert("navyblue", Color(0.00, 0.00, 0.50)); - _named_colors.insert("oldlace", Color(0.99, 0.96, 0.90)); - _named_colors.insert("olive", Color(0.50, 0.50, 0.00)); - _named_colors.insert("olivedrab", Color(0.42, 0.56, 0.14)); - _named_colors.insert("orange", Color(1.00, 0.65, 0.00)); - _named_colors.insert("orangered", Color(1.00, 0.27, 0.00)); - _named_colors.insert("orchid", Color(0.85, 0.44, 0.84)); - _named_colors.insert("palegoldenrod", Color(0.93, 0.91, 0.67)); - _named_colors.insert("palegreen", Color(0.60, 0.98, 0.60)); - _named_colors.insert("paleturquoise", Color(0.69, 0.93, 0.93)); - _named_colors.insert("palevioletred", Color(0.86, 0.44, 0.58)); - _named_colors.insert("papayawhip", Color(1.00, 0.94, 0.84)); - _named_colors.insert("peachpuff", Color(1.00, 0.85, 0.73)); - _named_colors.insert("peru", Color(0.80, 0.52, 0.25)); - _named_colors.insert("pink", Color(1.00, 0.75, 0.80)); - _named_colors.insert("plum", Color(0.87, 0.63, 0.87)); - _named_colors.insert("powderblue", Color(0.69, 0.88, 0.90)); - _named_colors.insert("purple", Color(0.63, 0.13, 0.94)); - _named_colors.insert("webpurple", Color(0.50, 0.00, 0.50)); - _named_colors.insert("rebeccapurple", Color(0.40, 0.20, 0.60)); - _named_colors.insert("red", Color(1.00, 0.00, 0.00)); - _named_colors.insert("rosybrown", Color(0.74, 0.56, 0.56)); - _named_colors.insert("royalblue", Color(0.25, 0.41, 0.88)); - _named_colors.insert("saddlebrown", Color(0.55, 0.27, 0.07)); - _named_colors.insert("salmon", Color(0.98, 0.50, 0.45)); - _named_colors.insert("sandybrown", Color(0.96, 0.64, 0.38)); - _named_colors.insert("seagreen", Color(0.18, 0.55, 0.34)); - _named_colors.insert("seashell", Color(1.00, 0.96, 0.93)); - _named_colors.insert("sienna", Color(0.63, 0.32, 0.18)); - _named_colors.insert("silver", Color(0.75, 0.75, 0.75)); - _named_colors.insert("skyblue", Color(0.53, 0.81, 0.92)); - _named_colors.insert("slateblue", Color(0.42, 0.35, 0.80)); - _named_colors.insert("slategray", Color(0.44, 0.50, 0.56)); - _named_colors.insert("snow", Color(1.00, 0.98, 0.98)); - _named_colors.insert("springgreen", Color(0.00, 1.00, 0.50)); - _named_colors.insert("steelblue", Color(0.27, 0.51, 0.71)); - _named_colors.insert("tan", Color(0.82, 0.71, 0.55)); - _named_colors.insert("teal", Color(0.00, 0.50, 0.50)); - _named_colors.insert("thistle", Color(0.85, 0.75, 0.85)); - _named_colors.insert("tomato", Color(1.00, 0.39, 0.28)); - _named_colors.insert("turquoise", Color(0.25, 0.88, 0.82)); - _named_colors.insert("transparent", Color(1.00, 1.00, 1.00, 0.00)); - _named_colors.insert("violet", Color(0.93, 0.51, 0.93)); - _named_colors.insert("wheat", Color(0.96, 0.87, 0.70)); - _named_colors.insert("white", Color(1.00, 1.00, 1.00)); - _named_colors.insert("whitesmoke", Color(0.96, 0.96, 0.96)); - _named_colors.insert("yellow", Color(1.00, 1.00, 0.00)); - _named_colors.insert("yellowgreen", Color(0.60, 0.80, 0.20)); -} diff --git a/core/config/SCsub b/core/config/SCsub new file mode 100644 index 0000000000..bf70285490 --- /dev/null +++ b/core/config/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import("env") + +env_config = env.Clone() + +env_config.add_source_files(env.core_sources, "*.cpp") diff --git a/core/engine.cpp b/core/config/engine.cpp index b0037ffb37..b0037ffb37 100644 --- a/core/engine.cpp +++ b/core/config/engine.cpp diff --git a/core/engine.h b/core/config/engine.h index b581c58ec5..1d3d963b39 100644 --- a/core/engine.h +++ b/core/config/engine.h @@ -31,10 +31,10 @@ #ifndef ENGINE_H #define ENGINE_H -#include "core/list.h" #include "core/os/main_loop.h" -#include "core/ustring.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/list.h" +#include "core/templates/vector.h" class Engine { public: diff --git a/core/project_settings.cpp b/core/config/project_settings.cpp index 3829474626..aa954ed300 100644 --- a/core/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -30,7 +30,7 @@ #include "project_settings.h" -#include "core/bind/core_bind.h" +#include "core/core_bind.h" #include "core/core_string_names.h" #include "core/io/file_access_network.h" #include "core/io/file_access_pack.h" @@ -39,7 +39,7 @@ #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" #include <zlib.h> diff --git a/core/project_settings.h b/core/config/project_settings.h index 9a1d9cee97..a8c9adc587 100644 --- a/core/project_settings.h +++ b/core/config/project_settings.h @@ -31,9 +31,9 @@ #ifndef PROJECT_SETTINGS_H #define PROJECT_SETTINGS_H -#include "core/class_db.h" +#include "core/object/class_db.h" #include "core/os/thread_safe.h" -#include "core/set.h" +#include "core/templates/set.h" class ProjectSettings : public Object { GDCLASS(ProjectSettings, Object); diff --git a/core/bind/core_bind.cpp b/core/core_bind.cpp index baf5d4b928..f3bdea1eec 100644 --- a/core/bind/core_bind.cpp +++ b/core/core_bind.cpp @@ -30,6 +30,7 @@ #include "core_bind.h" +#include "core/config/project_settings.h" #include "core/crypto/crypto_core.h" #include "core/debugger/engine_debugger.h" #include "core/io/file_access_compressed.h" @@ -40,7 +41,6 @@ #include "core/math/geometry_3d.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/project_settings.h" /** * Time constants borrowed from loc_time.h diff --git a/core/bind/core_bind.h b/core/core_bind.h index e75e740cd5..7794750387 100644 --- a/core/bind/core_bind.h +++ b/core/core_bind.h @@ -31,8 +31,8 @@ #ifndef CORE_BIND_H #define CORE_BIND_H -#include "core/image.h" #include "core/io/compression.h" +#include "core/io/image.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/dir_access.h" diff --git a/core/core_constants.cpp b/core/core_constants.cpp new file mode 100644 index 0000000000..4229436e84 --- /dev/null +++ b/core/core_constants.cpp @@ -0,0 +1,690 @@ +/*************************************************************************/ +/* core_constants.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "core_constants.h" + +#include "core/input/input_event.h" +#include "core/object/class_db.h" +#include "core/os/keyboard.h" +#include "core/variant/variant.h" + +struct _CoreConstant { +#ifdef DEBUG_METHODS_ENABLED + StringName enum_name; + bool ignore_value_in_docs; +#endif + const char *name; + int value; + + _CoreConstant() {} + +#ifdef DEBUG_METHODS_ENABLED + _CoreConstant(const StringName &p_enum_name, const char *p_name, int p_value, bool p_ignore_value_in_docs = false) : + enum_name(p_enum_name), + ignore_value_in_docs(p_ignore_value_in_docs), + name(p_name), + value(p_value) { + } +#else + _CoreConstant(const char *p_name, int p_value) : + name(p_name), + value(p_value) { + } +#endif +}; + +static Vector<_CoreConstant> _global_constants; + +#ifdef DEBUG_METHODS_ENABLED + +#define BIND_CORE_CONSTANT(m_constant) \ + _global_constants.push_back(_CoreConstant(StringName(), #m_constant, m_constant)); + +#define BIND_CORE_ENUM_CONSTANT(m_constant) \ + _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant)); + +#define BIND_CORE_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \ + _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), m_custom_name, m_constant)); + +#define BIND_CORE_CONSTANT_NO_VAL(m_constant) \ + _global_constants.push_back(_CoreConstant(StringName(), #m_constant, m_constant, true)); + +#define BIND_CORE_ENUM_CONSTANT_NO_VAL(m_constant) \ + _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant, true)); + +#define BIND_CORE_ENUM_CONSTANT_CUSTOM_NO_VAL(m_custom_name, m_constant) \ + _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), m_custom_name, m_constant, true)); + +#else + +#define BIND_CORE_CONSTANT(m_constant) \ + _global_constants.push_back(_CoreConstant(#m_constant, m_constant)); + +#define BIND_CORE_ENUM_CONSTANT(m_constant) \ + _global_constants.push_back(_CoreConstant(#m_constant, m_constant)); + +#define BIND_CORE_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \ + _global_constants.push_back(_CoreConstant(m_custom_name, m_constant)); + +#define BIND_CORE_CONSTANT_NO_VAL(m_constant) \ + _global_constants.push_back(_CoreConstant(#m_constant, m_constant)); + +#define BIND_CORE_ENUM_CONSTANT_NO_VAL(m_constant) \ + _global_constants.push_back(_CoreConstant(#m_constant, m_constant)); + +#define BIND_CORE_ENUM_CONSTANT_CUSTOM_NO_VAL(m_custom_name, m_constant) \ + _global_constants.push_back(_CoreConstant(m_custom_name, m_constant)); + +#endif + +VARIANT_ENUM_CAST(KeyList); +VARIANT_ENUM_CAST(KeyModifierMask); +VARIANT_ENUM_CAST(ButtonList); +VARIANT_ENUM_CAST(JoyButtonList); +VARIANT_ENUM_CAST(JoyAxisList); +VARIANT_ENUM_CAST(MidiMessageList); + +void register_global_constants() { + BIND_CORE_ENUM_CONSTANT(MARGIN_LEFT); + BIND_CORE_ENUM_CONSTANT(MARGIN_TOP); + BIND_CORE_ENUM_CONSTANT(MARGIN_RIGHT); + BIND_CORE_ENUM_CONSTANT(MARGIN_BOTTOM); + + BIND_CORE_ENUM_CONSTANT(CORNER_TOP_LEFT); + BIND_CORE_ENUM_CONSTANT(CORNER_TOP_RIGHT); + BIND_CORE_ENUM_CONSTANT(CORNER_BOTTOM_RIGHT); + BIND_CORE_ENUM_CONSTANT(CORNER_BOTTOM_LEFT); + + BIND_CORE_ENUM_CONSTANT(VERTICAL); + BIND_CORE_ENUM_CONSTANT(HORIZONTAL); + + BIND_CORE_ENUM_CONSTANT(HALIGN_LEFT); + BIND_CORE_ENUM_CONSTANT(HALIGN_CENTER); + BIND_CORE_ENUM_CONSTANT(HALIGN_RIGHT); + + BIND_CORE_ENUM_CONSTANT(VALIGN_TOP); + BIND_CORE_ENUM_CONSTANT(VALIGN_CENTER); + BIND_CORE_ENUM_CONSTANT(VALIGN_BOTTOM); + + // huge list of keys + BIND_CORE_CONSTANT(SPKEY); + + BIND_CORE_ENUM_CONSTANT(KEY_ESCAPE); + BIND_CORE_ENUM_CONSTANT(KEY_TAB); + BIND_CORE_ENUM_CONSTANT(KEY_BACKTAB); + BIND_CORE_ENUM_CONSTANT(KEY_BACKSPACE); + BIND_CORE_ENUM_CONSTANT(KEY_ENTER); + BIND_CORE_ENUM_CONSTANT(KEY_KP_ENTER); + BIND_CORE_ENUM_CONSTANT(KEY_INSERT); + BIND_CORE_ENUM_CONSTANT(KEY_DELETE); + BIND_CORE_ENUM_CONSTANT(KEY_PAUSE); + BIND_CORE_ENUM_CONSTANT(KEY_PRINT); + BIND_CORE_ENUM_CONSTANT(KEY_SYSREQ); + BIND_CORE_ENUM_CONSTANT(KEY_CLEAR); + BIND_CORE_ENUM_CONSTANT(KEY_HOME); + BIND_CORE_ENUM_CONSTANT(KEY_END); + BIND_CORE_ENUM_CONSTANT(KEY_LEFT); + BIND_CORE_ENUM_CONSTANT(KEY_UP); + BIND_CORE_ENUM_CONSTANT(KEY_RIGHT); + BIND_CORE_ENUM_CONSTANT(KEY_DOWN); + BIND_CORE_ENUM_CONSTANT(KEY_PAGEUP); + BIND_CORE_ENUM_CONSTANT(KEY_PAGEDOWN); + BIND_CORE_ENUM_CONSTANT(KEY_SHIFT); + BIND_CORE_ENUM_CONSTANT(KEY_CONTROL); + BIND_CORE_ENUM_CONSTANT(KEY_META); + BIND_CORE_ENUM_CONSTANT(KEY_ALT); + BIND_CORE_ENUM_CONSTANT(KEY_CAPSLOCK); + BIND_CORE_ENUM_CONSTANT(KEY_NUMLOCK); + BIND_CORE_ENUM_CONSTANT(KEY_SCROLLLOCK); + BIND_CORE_ENUM_CONSTANT(KEY_F1); + BIND_CORE_ENUM_CONSTANT(KEY_F2); + BIND_CORE_ENUM_CONSTANT(KEY_F3); + BIND_CORE_ENUM_CONSTANT(KEY_F4); + BIND_CORE_ENUM_CONSTANT(KEY_F5); + BIND_CORE_ENUM_CONSTANT(KEY_F6); + BIND_CORE_ENUM_CONSTANT(KEY_F7); + BIND_CORE_ENUM_CONSTANT(KEY_F8); + BIND_CORE_ENUM_CONSTANT(KEY_F9); + BIND_CORE_ENUM_CONSTANT(KEY_F10); + BIND_CORE_ENUM_CONSTANT(KEY_F11); + BIND_CORE_ENUM_CONSTANT(KEY_F12); + BIND_CORE_ENUM_CONSTANT(KEY_F13); + BIND_CORE_ENUM_CONSTANT(KEY_F14); + BIND_CORE_ENUM_CONSTANT(KEY_F15); + BIND_CORE_ENUM_CONSTANT(KEY_F16); + BIND_CORE_ENUM_CONSTANT(KEY_KP_MULTIPLY); + BIND_CORE_ENUM_CONSTANT(KEY_KP_DIVIDE); + BIND_CORE_ENUM_CONSTANT(KEY_KP_SUBTRACT); + BIND_CORE_ENUM_CONSTANT(KEY_KP_PERIOD); + BIND_CORE_ENUM_CONSTANT(KEY_KP_ADD); + BIND_CORE_ENUM_CONSTANT(KEY_KP_0); + BIND_CORE_ENUM_CONSTANT(KEY_KP_1); + BIND_CORE_ENUM_CONSTANT(KEY_KP_2); + BIND_CORE_ENUM_CONSTANT(KEY_KP_3); + BIND_CORE_ENUM_CONSTANT(KEY_KP_4); + BIND_CORE_ENUM_CONSTANT(KEY_KP_5); + BIND_CORE_ENUM_CONSTANT(KEY_KP_6); + BIND_CORE_ENUM_CONSTANT(KEY_KP_7); + BIND_CORE_ENUM_CONSTANT(KEY_KP_8); + BIND_CORE_ENUM_CONSTANT(KEY_KP_9); + BIND_CORE_ENUM_CONSTANT(KEY_SUPER_L); + BIND_CORE_ENUM_CONSTANT(KEY_SUPER_R); + BIND_CORE_ENUM_CONSTANT(KEY_MENU); + BIND_CORE_ENUM_CONSTANT(KEY_HYPER_L); + BIND_CORE_ENUM_CONSTANT(KEY_HYPER_R); + BIND_CORE_ENUM_CONSTANT(KEY_HELP); + BIND_CORE_ENUM_CONSTANT(KEY_DIRECTION_L); + BIND_CORE_ENUM_CONSTANT(KEY_DIRECTION_R); + BIND_CORE_ENUM_CONSTANT(KEY_BACK); + BIND_CORE_ENUM_CONSTANT(KEY_FORWARD); + BIND_CORE_ENUM_CONSTANT(KEY_STOP); + BIND_CORE_ENUM_CONSTANT(KEY_REFRESH); + BIND_CORE_ENUM_CONSTANT(KEY_VOLUMEDOWN); + BIND_CORE_ENUM_CONSTANT(KEY_VOLUMEMUTE); + BIND_CORE_ENUM_CONSTANT(KEY_VOLUMEUP); + BIND_CORE_ENUM_CONSTANT(KEY_BASSBOOST); + BIND_CORE_ENUM_CONSTANT(KEY_BASSUP); + BIND_CORE_ENUM_CONSTANT(KEY_BASSDOWN); + BIND_CORE_ENUM_CONSTANT(KEY_TREBLEUP); + BIND_CORE_ENUM_CONSTANT(KEY_TREBLEDOWN); + BIND_CORE_ENUM_CONSTANT(KEY_MEDIAPLAY); + BIND_CORE_ENUM_CONSTANT(KEY_MEDIASTOP); + BIND_CORE_ENUM_CONSTANT(KEY_MEDIAPREVIOUS); + BIND_CORE_ENUM_CONSTANT(KEY_MEDIANEXT); + BIND_CORE_ENUM_CONSTANT(KEY_MEDIARECORD); + BIND_CORE_ENUM_CONSTANT(KEY_HOMEPAGE); + BIND_CORE_ENUM_CONSTANT(KEY_FAVORITES); + BIND_CORE_ENUM_CONSTANT(KEY_SEARCH); + BIND_CORE_ENUM_CONSTANT(KEY_STANDBY); + BIND_CORE_ENUM_CONSTANT(KEY_OPENURL); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHMAIL); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHMEDIA); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH0); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH1); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH2); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH3); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH4); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH5); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH6); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH7); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH8); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH9); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHA); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHB); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHC); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHD); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHE); + BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHF); + + BIND_CORE_ENUM_CONSTANT(KEY_UNKNOWN); + BIND_CORE_ENUM_CONSTANT(KEY_SPACE); + BIND_CORE_ENUM_CONSTANT(KEY_EXCLAM); + BIND_CORE_ENUM_CONSTANT(KEY_QUOTEDBL); + BIND_CORE_ENUM_CONSTANT(KEY_NUMBERSIGN); + BIND_CORE_ENUM_CONSTANT(KEY_DOLLAR); + BIND_CORE_ENUM_CONSTANT(KEY_PERCENT); + BIND_CORE_ENUM_CONSTANT(KEY_AMPERSAND); + BIND_CORE_ENUM_CONSTANT(KEY_APOSTROPHE); + BIND_CORE_ENUM_CONSTANT(KEY_PARENLEFT); + BIND_CORE_ENUM_CONSTANT(KEY_PARENRIGHT); + BIND_CORE_ENUM_CONSTANT(KEY_ASTERISK); + BIND_CORE_ENUM_CONSTANT(KEY_PLUS); + BIND_CORE_ENUM_CONSTANT(KEY_COMMA); + BIND_CORE_ENUM_CONSTANT(KEY_MINUS); + BIND_CORE_ENUM_CONSTANT(KEY_PERIOD); + BIND_CORE_ENUM_CONSTANT(KEY_SLASH); + BIND_CORE_ENUM_CONSTANT(KEY_0); + BIND_CORE_ENUM_CONSTANT(KEY_1); + BIND_CORE_ENUM_CONSTANT(KEY_2); + BIND_CORE_ENUM_CONSTANT(KEY_3); + BIND_CORE_ENUM_CONSTANT(KEY_4); + BIND_CORE_ENUM_CONSTANT(KEY_5); + BIND_CORE_ENUM_CONSTANT(KEY_6); + BIND_CORE_ENUM_CONSTANT(KEY_7); + BIND_CORE_ENUM_CONSTANT(KEY_8); + BIND_CORE_ENUM_CONSTANT(KEY_9); + BIND_CORE_ENUM_CONSTANT(KEY_COLON); + BIND_CORE_ENUM_CONSTANT(KEY_SEMICOLON); + BIND_CORE_ENUM_CONSTANT(KEY_LESS); + BIND_CORE_ENUM_CONSTANT(KEY_EQUAL); + BIND_CORE_ENUM_CONSTANT(KEY_GREATER); + BIND_CORE_ENUM_CONSTANT(KEY_QUESTION); + BIND_CORE_ENUM_CONSTANT(KEY_AT); + BIND_CORE_ENUM_CONSTANT(KEY_A); + BIND_CORE_ENUM_CONSTANT(KEY_B); + BIND_CORE_ENUM_CONSTANT(KEY_C); + BIND_CORE_ENUM_CONSTANT(KEY_D); + BIND_CORE_ENUM_CONSTANT(KEY_E); + BIND_CORE_ENUM_CONSTANT(KEY_F); + BIND_CORE_ENUM_CONSTANT(KEY_G); + BIND_CORE_ENUM_CONSTANT(KEY_H); + BIND_CORE_ENUM_CONSTANT(KEY_I); + BIND_CORE_ENUM_CONSTANT(KEY_J); + BIND_CORE_ENUM_CONSTANT(KEY_K); + BIND_CORE_ENUM_CONSTANT(KEY_L); + BIND_CORE_ENUM_CONSTANT(KEY_M); + BIND_CORE_ENUM_CONSTANT(KEY_N); + BIND_CORE_ENUM_CONSTANT(KEY_O); + BIND_CORE_ENUM_CONSTANT(KEY_P); + BIND_CORE_ENUM_CONSTANT(KEY_Q); + BIND_CORE_ENUM_CONSTANT(KEY_R); + BIND_CORE_ENUM_CONSTANT(KEY_S); + BIND_CORE_ENUM_CONSTANT(KEY_T); + BIND_CORE_ENUM_CONSTANT(KEY_U); + BIND_CORE_ENUM_CONSTANT(KEY_V); + BIND_CORE_ENUM_CONSTANT(KEY_W); + BIND_CORE_ENUM_CONSTANT(KEY_X); + BIND_CORE_ENUM_CONSTANT(KEY_Y); + BIND_CORE_ENUM_CONSTANT(KEY_Z); + BIND_CORE_ENUM_CONSTANT(KEY_BRACKETLEFT); + BIND_CORE_ENUM_CONSTANT(KEY_BACKSLASH); + BIND_CORE_ENUM_CONSTANT(KEY_BRACKETRIGHT); + BIND_CORE_ENUM_CONSTANT(KEY_ASCIICIRCUM); + BIND_CORE_ENUM_CONSTANT(KEY_UNDERSCORE); + BIND_CORE_ENUM_CONSTANT(KEY_QUOTELEFT); + BIND_CORE_ENUM_CONSTANT(KEY_BRACELEFT); + BIND_CORE_ENUM_CONSTANT(KEY_BAR); + BIND_CORE_ENUM_CONSTANT(KEY_BRACERIGHT); + BIND_CORE_ENUM_CONSTANT(KEY_ASCIITILDE); + BIND_CORE_ENUM_CONSTANT(KEY_NOBREAKSPACE); + BIND_CORE_ENUM_CONSTANT(KEY_EXCLAMDOWN); + BIND_CORE_ENUM_CONSTANT(KEY_CENT); + BIND_CORE_ENUM_CONSTANT(KEY_STERLING); + BIND_CORE_ENUM_CONSTANT(KEY_CURRENCY); + BIND_CORE_ENUM_CONSTANT(KEY_YEN); + BIND_CORE_ENUM_CONSTANT(KEY_BROKENBAR); + BIND_CORE_ENUM_CONSTANT(KEY_SECTION); + BIND_CORE_ENUM_CONSTANT(KEY_DIAERESIS); + BIND_CORE_ENUM_CONSTANT(KEY_COPYRIGHT); + BIND_CORE_ENUM_CONSTANT(KEY_ORDFEMININE); + BIND_CORE_ENUM_CONSTANT(KEY_GUILLEMOTLEFT); + BIND_CORE_ENUM_CONSTANT(KEY_NOTSIGN); + BIND_CORE_ENUM_CONSTANT(KEY_HYPHEN); + BIND_CORE_ENUM_CONSTANT(KEY_REGISTERED); + BIND_CORE_ENUM_CONSTANT(KEY_MACRON); + BIND_CORE_ENUM_CONSTANT(KEY_DEGREE); + BIND_CORE_ENUM_CONSTANT(KEY_PLUSMINUS); + BIND_CORE_ENUM_CONSTANT(KEY_TWOSUPERIOR); + BIND_CORE_ENUM_CONSTANT(KEY_THREESUPERIOR); + BIND_CORE_ENUM_CONSTANT(KEY_ACUTE); + BIND_CORE_ENUM_CONSTANT(KEY_MU); + BIND_CORE_ENUM_CONSTANT(KEY_PARAGRAPH); + BIND_CORE_ENUM_CONSTANT(KEY_PERIODCENTERED); + BIND_CORE_ENUM_CONSTANT(KEY_CEDILLA); + BIND_CORE_ENUM_CONSTANT(KEY_ONESUPERIOR); + BIND_CORE_ENUM_CONSTANT(KEY_MASCULINE); + BIND_CORE_ENUM_CONSTANT(KEY_GUILLEMOTRIGHT); + BIND_CORE_ENUM_CONSTANT(KEY_ONEQUARTER); + BIND_CORE_ENUM_CONSTANT(KEY_ONEHALF); + BIND_CORE_ENUM_CONSTANT(KEY_THREEQUARTERS); + BIND_CORE_ENUM_CONSTANT(KEY_QUESTIONDOWN); + BIND_CORE_ENUM_CONSTANT(KEY_AGRAVE); + BIND_CORE_ENUM_CONSTANT(KEY_AACUTE); + BIND_CORE_ENUM_CONSTANT(KEY_ACIRCUMFLEX); + BIND_CORE_ENUM_CONSTANT(KEY_ATILDE); + BIND_CORE_ENUM_CONSTANT(KEY_ADIAERESIS); + BIND_CORE_ENUM_CONSTANT(KEY_ARING); + BIND_CORE_ENUM_CONSTANT(KEY_AE); + BIND_CORE_ENUM_CONSTANT(KEY_CCEDILLA); + BIND_CORE_ENUM_CONSTANT(KEY_EGRAVE); + BIND_CORE_ENUM_CONSTANT(KEY_EACUTE); + BIND_CORE_ENUM_CONSTANT(KEY_ECIRCUMFLEX); + BIND_CORE_ENUM_CONSTANT(KEY_EDIAERESIS); + BIND_CORE_ENUM_CONSTANT(KEY_IGRAVE); + BIND_CORE_ENUM_CONSTANT(KEY_IACUTE); + BIND_CORE_ENUM_CONSTANT(KEY_ICIRCUMFLEX); + BIND_CORE_ENUM_CONSTANT(KEY_IDIAERESIS); + BIND_CORE_ENUM_CONSTANT(KEY_ETH); + BIND_CORE_ENUM_CONSTANT(KEY_NTILDE); + BIND_CORE_ENUM_CONSTANT(KEY_OGRAVE); + BIND_CORE_ENUM_CONSTANT(KEY_OACUTE); + BIND_CORE_ENUM_CONSTANT(KEY_OCIRCUMFLEX); + BIND_CORE_ENUM_CONSTANT(KEY_OTILDE); + BIND_CORE_ENUM_CONSTANT(KEY_ODIAERESIS); + BIND_CORE_ENUM_CONSTANT(KEY_MULTIPLY); + BIND_CORE_ENUM_CONSTANT(KEY_OOBLIQUE); + BIND_CORE_ENUM_CONSTANT(KEY_UGRAVE); + BIND_CORE_ENUM_CONSTANT(KEY_UACUTE); + BIND_CORE_ENUM_CONSTANT(KEY_UCIRCUMFLEX); + BIND_CORE_ENUM_CONSTANT(KEY_UDIAERESIS); + BIND_CORE_ENUM_CONSTANT(KEY_YACUTE); + BIND_CORE_ENUM_CONSTANT(KEY_THORN); + BIND_CORE_ENUM_CONSTANT(KEY_SSHARP); + + BIND_CORE_ENUM_CONSTANT(KEY_DIVISION); + BIND_CORE_ENUM_CONSTANT(KEY_YDIAERESIS); + + BIND_CORE_ENUM_CONSTANT(KEY_CODE_MASK); + BIND_CORE_ENUM_CONSTANT(KEY_MODIFIER_MASK); + + BIND_CORE_ENUM_CONSTANT(KEY_MASK_SHIFT); + BIND_CORE_ENUM_CONSTANT(KEY_MASK_ALT); + BIND_CORE_ENUM_CONSTANT(KEY_MASK_META); + BIND_CORE_ENUM_CONSTANT(KEY_MASK_CTRL); + BIND_CORE_ENUM_CONSTANT_NO_VAL(KEY_MASK_CMD); + BIND_CORE_ENUM_CONSTANT(KEY_MASK_KPAD); + BIND_CORE_ENUM_CONSTANT(KEY_MASK_GROUP_SWITCH); + + // mouse + BIND_CORE_ENUM_CONSTANT(BUTTON_LEFT); + BIND_CORE_ENUM_CONSTANT(BUTTON_RIGHT); + BIND_CORE_ENUM_CONSTANT(BUTTON_MIDDLE); + BIND_CORE_ENUM_CONSTANT(BUTTON_XBUTTON1); + BIND_CORE_ENUM_CONSTANT(BUTTON_XBUTTON2); + BIND_CORE_ENUM_CONSTANT(BUTTON_WHEEL_UP); + BIND_CORE_ENUM_CONSTANT(BUTTON_WHEEL_DOWN); + BIND_CORE_ENUM_CONSTANT(BUTTON_WHEEL_LEFT); + BIND_CORE_ENUM_CONSTANT(BUTTON_WHEEL_RIGHT); + BIND_CORE_ENUM_CONSTANT(BUTTON_MASK_LEFT); + BIND_CORE_ENUM_CONSTANT(BUTTON_MASK_RIGHT); + BIND_CORE_ENUM_CONSTANT(BUTTON_MASK_MIDDLE); + BIND_CORE_ENUM_CONSTANT(BUTTON_MASK_XBUTTON1); + BIND_CORE_ENUM_CONSTANT(BUTTON_MASK_XBUTTON2); + + // Joypad buttons + BIND_CORE_ENUM_CONSTANT(JOY_INVALID_BUTTON); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_A); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_B); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_X); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_Y); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_BACK); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_GUIDE); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_START); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_LEFT_STICK); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_RIGHT_STICK); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_LEFT_SHOULDER); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_RIGHT_SHOULDER); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_UP); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT); + BIND_CORE_ENUM_CONSTANT(JOY_SDL_BUTTONS); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_X); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_CROSS); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_CIRCLE); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_SQUARE); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_TRIANGLE); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_SELECT); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_START); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_PS); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_L1); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_R1); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_L3); + BIND_CORE_ENUM_CONSTANT(JOY_SONY_R3); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_A); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_B); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_X); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_Y); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_BACK); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_START); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_HOME); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_LS); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_RS); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_LB); + BIND_CORE_ENUM_CONSTANT(JOY_XBOX_RB); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MAX); + + // Joypad axes + BIND_CORE_ENUM_CONSTANT(JOY_INVALID_AXIS); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_LEFT_X); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_LEFT_Y); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_RIGHT_X); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_RIGHT_Y); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_TRIGGER_LEFT); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_TRIGGER_RIGHT); + BIND_CORE_ENUM_CONSTANT(JOY_SDL_AXES); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_0_X); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_0_Y); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_1_X); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_1_Y); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_2_X); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_2_Y); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_3_X); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_3_Y); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_4_X); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_4_Y); + BIND_CORE_ENUM_CONSTANT(JOY_AXIS_MAX); + + // midi + BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_OFF); + BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_ON); + BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_AFTERTOUCH); + BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_CONTROL_CHANGE); + BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_PROGRAM_CHANGE); + BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_CHANNEL_PRESSURE); + BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_PITCH_BEND); + + // error list + + BIND_CORE_ENUM_CONSTANT(OK); // (0) + BIND_CORE_ENUM_CONSTANT(FAILED); + BIND_CORE_ENUM_CONSTANT(ERR_UNAVAILABLE); + BIND_CORE_ENUM_CONSTANT(ERR_UNCONFIGURED); + BIND_CORE_ENUM_CONSTANT(ERR_UNAUTHORIZED); + BIND_CORE_ENUM_CONSTANT(ERR_PARAMETER_RANGE_ERROR); // (5) + BIND_CORE_ENUM_CONSTANT(ERR_OUT_OF_MEMORY); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_NOT_FOUND); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_BAD_DRIVE); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_BAD_PATH); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_NO_PERMISSION); // (10) + BIND_CORE_ENUM_CONSTANT(ERR_FILE_ALREADY_IN_USE); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_CANT_OPEN); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_CANT_WRITE); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_CANT_READ); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_UNRECOGNIZED); // (15) + BIND_CORE_ENUM_CONSTANT(ERR_FILE_CORRUPT); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_MISSING_DEPENDENCIES); + BIND_CORE_ENUM_CONSTANT(ERR_FILE_EOF); + BIND_CORE_ENUM_CONSTANT(ERR_CANT_OPEN); + BIND_CORE_ENUM_CONSTANT(ERR_CANT_CREATE); // (20) + BIND_CORE_ENUM_CONSTANT(ERR_QUERY_FAILED); + BIND_CORE_ENUM_CONSTANT(ERR_ALREADY_IN_USE); + BIND_CORE_ENUM_CONSTANT(ERR_LOCKED); + BIND_CORE_ENUM_CONSTANT(ERR_TIMEOUT); + BIND_CORE_ENUM_CONSTANT(ERR_CANT_CONNECT); // (25) + BIND_CORE_ENUM_CONSTANT(ERR_CANT_RESOLVE); + BIND_CORE_ENUM_CONSTANT(ERR_CONNECTION_ERROR); + BIND_CORE_ENUM_CONSTANT(ERR_CANT_ACQUIRE_RESOURCE); + BIND_CORE_ENUM_CONSTANT(ERR_CANT_FORK); + BIND_CORE_ENUM_CONSTANT(ERR_INVALID_DATA); // (30) + BIND_CORE_ENUM_CONSTANT(ERR_INVALID_PARAMETER); + BIND_CORE_ENUM_CONSTANT(ERR_ALREADY_EXISTS); + BIND_CORE_ENUM_CONSTANT(ERR_DOES_NOT_EXIST); + BIND_CORE_ENUM_CONSTANT(ERR_DATABASE_CANT_READ); + BIND_CORE_ENUM_CONSTANT(ERR_DATABASE_CANT_WRITE); // (35) + BIND_CORE_ENUM_CONSTANT(ERR_COMPILATION_FAILED); + BIND_CORE_ENUM_CONSTANT(ERR_METHOD_NOT_FOUND); + BIND_CORE_ENUM_CONSTANT(ERR_LINK_FAILED); + BIND_CORE_ENUM_CONSTANT(ERR_SCRIPT_FAILED); + BIND_CORE_ENUM_CONSTANT(ERR_CYCLIC_LINK); // (40) + BIND_CORE_ENUM_CONSTANT(ERR_INVALID_DECLARATION); + BIND_CORE_ENUM_CONSTANT(ERR_DUPLICATE_SYMBOL); + BIND_CORE_ENUM_CONSTANT(ERR_PARSE_ERROR); + BIND_CORE_ENUM_CONSTANT(ERR_BUSY); + BIND_CORE_ENUM_CONSTANT(ERR_SKIP); // (45) + BIND_CORE_ENUM_CONSTANT(ERR_HELP); + BIND_CORE_ENUM_CONSTANT(ERR_BUG); + BIND_CORE_ENUM_CONSTANT(ERR_PRINTER_ON_FIRE); + + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NONE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_RANGE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_RANGE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LENGTH); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_KEY_ACCEL); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FLAGS); + + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_RENDER); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_PHYSICS); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_RENDER); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_PHYSICS); + + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FILE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_DIR); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_FILE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_DIR); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_RESOURCE_TYPE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MULTILINE_TEXT); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PLACEHOLDER_TEXT); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_COLOR_NO_ALPHA); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSY); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS); + + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_STORAGE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NETWORK); + + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_HELPER); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKABLE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKED); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_GROUP); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE); + + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT_INTL); + BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NOEDITOR); + + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_NORMAL); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_EDITOR); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_NOSCRIPT); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_CONST); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_REVERSE); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_FROM_SCRIPT); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT); + + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT", Variant::INT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_REAL", Variant::FLOAT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING", Variant::STRING); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2", Variant::VECTOR2); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2I", Variant::VECTOR2I); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RECT2", Variant::RECT2); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RECT2I", Variant::RECT2I); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3", Variant::VECTOR3); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3I", Variant::VECTOR3I); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_QUAT", Variant::QUAT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM", Variant::TRANSFORM); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_NAME", Variant::STRING_NAME); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RID", Variant::RID); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_OBJECT", Variant::OBJECT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_CALLABLE", Variant::CALLABLE); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_SIGNAL", Variant::SIGNAL); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_ARRAY", Variant::ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RAW_ARRAY", Variant::PACKED_BYTE_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT32_ARRAY", Variant::PACKED_INT32_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT64_ARRAY", Variant::PACKED_INT64_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_ARRAY", Variant::PACKED_STRING_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_MAX", Variant::VARIANT_MAX); + + //comparison + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_EQUAL", Variant::OP_EQUAL); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_NOT_EQUAL", Variant::OP_NOT_EQUAL); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_LESS", Variant::OP_LESS); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_LESS_EQUAL", Variant::OP_LESS_EQUAL); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_GREATER", Variant::OP_GREATER); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_GREATER_EQUAL", Variant::OP_GREATER_EQUAL); + //mathematic + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_ADD", Variant::OP_ADD); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SUBTRACT", Variant::OP_SUBTRACT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_MULTIPLY", Variant::OP_MULTIPLY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_DIVIDE", Variant::OP_DIVIDE); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_NEGATE", Variant::OP_NEGATE); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_POSITIVE", Variant::OP_POSITIVE); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_MODULE", Variant::OP_MODULE); + //bitwise + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SHIFT_LEFT", Variant::OP_SHIFT_LEFT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SHIFT_RIGHT", Variant::OP_SHIFT_RIGHT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_AND", Variant::OP_BIT_AND); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_OR", Variant::OP_BIT_OR); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_XOR", Variant::OP_BIT_XOR); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_NEGATE", Variant::OP_BIT_NEGATE); + //logic + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_AND", Variant::OP_AND); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_OR", Variant::OP_OR); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_XOR", Variant::OP_XOR); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_NOT", Variant::OP_NOT); + //containment + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_IN", Variant::OP_IN); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_MAX", Variant::OP_MAX); +} + +void unregister_global_constants() { + _global_constants.clear(); +} + +int CoreConstants::get_global_constant_count() { + return _global_constants.size(); +} + +#ifdef DEBUG_METHODS_ENABLED +StringName CoreConstants::get_global_constant_enum(int p_idx) { + return _global_constants[p_idx].enum_name; +} + +bool CoreConstants::get_ignore_value_in_docs(int p_idx) { + return _global_constants[p_idx].ignore_value_in_docs; +} +#else +StringName CoreConstants::get_global_constant_enum(int p_idx) { + return StringName(); +} + +bool CoreConstants::get_ignore_value_in_docs(int p_idx) { + return false; +} +#endif + +const char *CoreConstants::get_global_constant_name(int p_idx) { + return _global_constants[p_idx].name; +} + +int CoreConstants::get_global_constant_value(int p_idx) { + return _global_constants[p_idx].value; +} diff --git a/core/global_constants.h b/core/core_constants.h index 989633a6fa..6cddd9daec 100644 --- a/core/global_constants.h +++ b/core/core_constants.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* global_constants.h */ +/* core_constants.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GLOBAL_CONSTANTS_H -#define GLOBAL_CONSTANTS_H +#ifndef CORE_CONSTANTS_H +#define CORE_CONSTANTS_H -#include "core/string_name.h" +#include "core/string/string_name.h" -class GlobalConstants { +class CoreConstants { public: static int get_global_constant_count(); static StringName get_global_constant_enum(int p_idx); diff --git a/core/core_string_names.h b/core/core_string_names.h index 43597ef301..c0bdc33d28 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -31,7 +31,7 @@ #ifndef CORE_STRING_NAMES_H #define CORE_STRING_NAMES_H -#include "core/string_name.h" +#include "core/string/string_name.h" class CoreStringNames { friend void register_core_types(); diff --git a/core/crypto/aes_context.h b/core/crypto/aes_context.h index 006ecee2ad..c23c504a72 100644 --- a/core/crypto/aes_context.h +++ b/core/crypto/aes_context.h @@ -32,7 +32,7 @@ #define AES_CONTEXT_H #include "core/crypto/crypto_core.h" -#include "core/reference.h" +#include "core/object/reference.h" class AESContext : public Reference { GDCLASS(AESContext, Reference); diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index 29d02e11df..d12108bca0 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -30,7 +30,7 @@ #include "crypto.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/io/certs_compressed.gen.h" #include "core/io/compression.h" diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 916f7798eb..8325f043bf 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -32,10 +32,10 @@ #define CRYPTO_H #include "core/crypto/hashing_context.h" +#include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/reference.h" -#include "core/resource.h" +#include "core/object/reference.h" class CryptoKey : public Resource { GDCLASS(CryptoKey, Resource); diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h index 9ab2871caa..57ba469f8d 100644 --- a/core/crypto/crypto_core.h +++ b/core/crypto/crypto_core.h @@ -31,7 +31,7 @@ #ifndef CRYPTO_CORE_H #define CRYPTO_CORE_H -#include "core/reference.h" +#include "core/object/reference.h" class CryptoCore { public: diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h index f9454fa891..40d075afa9 100644 --- a/core/crypto/hashing_context.h +++ b/core/crypto/hashing_context.h @@ -31,7 +31,7 @@ #ifndef HASHING_CONTEXT_H #define HASHING_CONTEXT_H -#include "core/reference.h" +#include "core/object/reference.h" class HashingContext : public Reference { GDCLASS(HashingContext, Reference); diff --git a/core/debugger/debugger_marshalls.h b/core/debugger/debugger_marshalls.h index 7b7f4ac4b5..f5a1a891bf 100644 --- a/core/debugger/debugger_marshalls.h +++ b/core/debugger/debugger_marshalls.h @@ -31,7 +31,7 @@ #ifndef DEBUGGER_MARSHARLLS_H #define DEBUGGER_MARSHARLLS_H -#include "core/script_language.h" +#include "core/object/script_language.h" #include "servers/rendering_server.h" struct DebuggerMarshalls { diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h index 8d5ebb2394..10f04bf97a 100644 --- a/core/debugger/engine_debugger.h +++ b/core/debugger/engine_debugger.h @@ -31,12 +31,12 @@ #ifndef ENGINE_DEBUGGER_H #define ENGINE_DEBUGGER_H -#include "core/array.h" -#include "core/map.h" -#include "core/string_name.h" -#include "core/ustring.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/templates/map.h" +#include "core/templates/vector.h" +#include "core/variant/array.h" +#include "core/variant/variant.h" class RemoteDebuggerPeer; class ScriptDebugger; diff --git a/core/debugger/local_debugger.h b/core/debugger/local_debugger.h index d342da6d44..dbdeec173b 100644 --- a/core/debugger/local_debugger.h +++ b/core/debugger/local_debugger.h @@ -32,8 +32,8 @@ #define LOCAL_DEBUGGER_H #include "core/debugger/engine_debugger.h" -#include "core/list.h" -#include "core/script_language.h" +#include "core/object/script_language.h" +#include "core/templates/list.h" class LocalDebugger : public EngineDebugger { private: diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index 9d55e1312e..ff89517497 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -30,13 +30,13 @@ #include "remote_debugger.h" +#include "core/config/project_settings.h" #include "core/debugger/debugger_marshalls.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" #include "core/input/input.h" +#include "core/object/script_language.h" #include "core/os/os.h" -#include "core/project_settings.h" -#include "core/script_language.h" #include "scene/main/node.h" #include "servers/display_server.h" diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h index 320ee15996..37cc8af2a5 100644 --- a/core/debugger/remote_debugger.h +++ b/core/debugger/remote_debugger.h @@ -31,13 +31,13 @@ #ifndef REMOTE_DEBUGGER_H #define REMOTE_DEBUGGER_H -#include "core/array.h" -#include "core/class_db.h" #include "core/debugger/debugger_marshalls.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/remote_debugger_peer.h" -#include "core/string_name.h" -#include "core/ustring.h" +#include "core/object/class_db.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/variant/array.h" class RemoteDebugger : public EngineDebugger { public: diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp index 0ce0042f50..338c637014 100644 --- a/core/debugger/remote_debugger_peer.cpp +++ b/core/debugger/remote_debugger_peer.cpp @@ -30,9 +30,9 @@ #include "remote_debugger_peer.h" +#include "core/config/project_settings.h" #include "core/io/marshalls.h" #include "core/os/os.h" -#include "core/project_settings.h" bool RemoteDebuggerPeerTCP::is_peer_connected() { return connected; diff --git a/core/debugger/remote_debugger_peer.h b/core/debugger/remote_debugger_peer.h index 3a75a2a02b..79b88f5549 100644 --- a/core/debugger/remote_debugger_peer.h +++ b/core/debugger/remote_debugger_peer.h @@ -32,10 +32,10 @@ #define REMOTE_DEBUGGER_PEER_H #include "core/io/stream_peer_tcp.h" +#include "core/object/reference.h" #include "core/os/mutex.h" #include "core/os/thread.h" -#include "core/reference.h" -#include "core/ustring.h" +#include "core/string/ustring.h" class RemoteDebuggerPeer : public Reference { protected: diff --git a/core/debugger/script_debugger.h b/core/debugger/script_debugger.h index 0068691825..7f2f2becc2 100644 --- a/core/debugger/script_debugger.h +++ b/core/debugger/script_debugger.h @@ -31,11 +31,11 @@ #ifndef SCRIPT_DEBUGGER_H #define SCRIPT_DEBUGGER_H -#include "core/map.h" -#include "core/script_language.h" -#include "core/set.h" -#include "core/string_name.h" -#include "core/vector.h" +#include "core/object/script_language.h" +#include "core/string/string_name.h" +#include "core/templates/map.h" +#include "core/templates/set.h" +#include "core/templates/vector.h" class ScriptDebugger { typedef ScriptLanguage::StackInfo StackInfo; diff --git a/core/error/SCsub b/core/error/SCsub new file mode 100644 index 0000000000..dfd6248a94 --- /dev/null +++ b/core/error/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import("env") + +env_error = env.Clone() + +env_error.add_source_files(env.core_sources, "*.cpp") diff --git a/core/error_list.h b/core/error/error_list.h index a0218cf045..a0218cf045 100644 --- a/core/error_list.h +++ b/core/error/error_list.h diff --git a/core/error_macros.cpp b/core/error/error_macros.cpp index 2fae939965..80879dd25d 100644 --- a/core/error_macros.cpp +++ b/core/error/error_macros.cpp @@ -31,8 +31,8 @@ #include "error_macros.h" #include "core/io/logger.h" -#include "core/ustring.h" -#include "os/os.h" +#include "core/os/os.h" +#include "core/string/ustring.h" static ErrorHandlerList *error_handler_list = nullptr; diff --git a/core/error_macros.h b/core/error/error_macros.h index 6353961b04..6353961b04 100644 --- a/core/error_macros.h +++ b/core/error/error_macros.h diff --git a/core/func_ref.cpp b/core/func_ref.cpp deleted file mode 100644 index 7e062f16d0..0000000000 --- a/core/func_ref.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ -/* func_ref.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "func_ref.h" - -Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - if (id.is_null()) { - r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return Variant(); - } - Object *obj = ObjectDB::get_instance(id); - - if (!obj) { - r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return Variant(); - } - - return obj->call(function, p_args, p_argcount, r_error); -} - -Variant FuncRef::call_funcv(const Array &p_args) { - ERR_FAIL_COND_V(id.is_null(), Variant()); - - Object *obj = ObjectDB::get_instance(id); - - ERR_FAIL_COND_V(!obj, Variant()); - - return obj->callv(function, p_args); -} - -void FuncRef::set_instance(Object *p_obj) { - ERR_FAIL_NULL(p_obj); - id = p_obj->get_instance_id(); -} - -void FuncRef::set_function(const StringName &p_func) { - function = p_func; -} - -StringName FuncRef::get_function() { - return function; -} - -bool FuncRef::is_valid() const { - if (id.is_null()) { - return false; - } - - Object *obj = ObjectDB::get_instance(id); - if (!obj) { - return false; - } - - return obj->has_method(function); -} - -void FuncRef::_bind_methods() { - { - MethodInfo mi; - mi.name = "call_func"; - Vector<Variant> defargs; - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_func", &FuncRef::call_func, mi, defargs); - } - - ClassDB::bind_method(D_METHOD("call_funcv", "arg_array"), &FuncRef::call_funcv); - - ClassDB::bind_method(D_METHOD("set_instance", "instance"), &FuncRef::set_instance); - ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid); - - ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function); - ClassDB::bind_method(D_METHOD("get_function"), &FuncRef::get_function); - - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "function"), "set_function", "get_function"); -} diff --git a/core/global_constants.cpp b/core/global_constants.cpp deleted file mode 100644 index 064c302341..0000000000 --- a/core/global_constants.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/*************************************************************************/ -/* global_constants.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "global_constants.h" - -#include "core/class_db.h" -#include "core/input/input_event.h" -#include "core/os/keyboard.h" -#include "core/variant.h" - -struct _GlobalConstant { -#ifdef DEBUG_METHODS_ENABLED - StringName enum_name; - bool ignore_value_in_docs; -#endif - const char *name; - int value; - - _GlobalConstant() {} - -#ifdef DEBUG_METHODS_ENABLED - _GlobalConstant(const StringName &p_enum_name, const char *p_name, int p_value, bool p_ignore_value_in_docs = false) : - enum_name(p_enum_name), - ignore_value_in_docs(p_ignore_value_in_docs), - name(p_name), - value(p_value) { - } -#else - _GlobalConstant(const char *p_name, int p_value) : - name(p_name), - value(p_value) { - } -#endif -}; - -static Vector<_GlobalConstant> _global_constants; - -#ifdef DEBUG_METHODS_ENABLED - -#define BIND_GLOBAL_CONSTANT(m_constant) \ - _global_constants.push_back(_GlobalConstant(StringName(), #m_constant, m_constant)); - -#define BIND_GLOBAL_ENUM_CONSTANT(m_constant) \ - _global_constants.push_back(_GlobalConstant(__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant)); - -#define BIND_GLOBAL_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \ - _global_constants.push_back(_GlobalConstant(__constant_get_enum_name(m_constant, #m_constant), m_custom_name, m_constant)); - -#define BIND_GLOBAL_CONSTANT_NO_VAL(m_constant) \ - _global_constants.push_back(_GlobalConstant(StringName(), #m_constant, m_constant, true)); - -#define BIND_GLOBAL_ENUM_CONSTANT_NO_VAL(m_constant) \ - _global_constants.push_back(_GlobalConstant(__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant, true)); - -#define BIND_GLOBAL_ENUM_CONSTANT_CUSTOM_NO_VAL(m_custom_name, m_constant) \ - _global_constants.push_back(_GlobalConstant(__constant_get_enum_name(m_constant, #m_constant), m_custom_name, m_constant, true)); - -#else - -#define BIND_GLOBAL_CONSTANT(m_constant) \ - _global_constants.push_back(_GlobalConstant(#m_constant, m_constant)); - -#define BIND_GLOBAL_ENUM_CONSTANT(m_constant) \ - _global_constants.push_back(_GlobalConstant(#m_constant, m_constant)); - -#define BIND_GLOBAL_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \ - _global_constants.push_back(_GlobalConstant(m_custom_name, m_constant)); - -#define BIND_GLOBAL_CONSTANT_NO_VAL(m_constant) \ - _global_constants.push_back(_GlobalConstant(#m_constant, m_constant)); - -#define BIND_GLOBAL_ENUM_CONSTANT_NO_VAL(m_constant) \ - _global_constants.push_back(_GlobalConstant(#m_constant, m_constant)); - -#define BIND_GLOBAL_ENUM_CONSTANT_CUSTOM_NO_VAL(m_custom_name, m_constant) \ - _global_constants.push_back(_GlobalConstant(m_custom_name, m_constant)); - -#endif - -VARIANT_ENUM_CAST(KeyList); -VARIANT_ENUM_CAST(KeyModifierMask); -VARIANT_ENUM_CAST(ButtonList); -VARIANT_ENUM_CAST(JoyButtonList); -VARIANT_ENUM_CAST(JoyAxisList); -VARIANT_ENUM_CAST(MidiMessageList); - -void register_global_constants() { - BIND_GLOBAL_ENUM_CONSTANT(MARGIN_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(MARGIN_TOP); - BIND_GLOBAL_ENUM_CONSTANT(MARGIN_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(MARGIN_BOTTOM); - - BIND_GLOBAL_ENUM_CONSTANT(CORNER_TOP_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(CORNER_TOP_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(CORNER_BOTTOM_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(CORNER_BOTTOM_LEFT); - - BIND_GLOBAL_ENUM_CONSTANT(VERTICAL); - BIND_GLOBAL_ENUM_CONSTANT(HORIZONTAL); - - BIND_GLOBAL_ENUM_CONSTANT(HALIGN_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(HALIGN_CENTER); - BIND_GLOBAL_ENUM_CONSTANT(HALIGN_RIGHT); - - BIND_GLOBAL_ENUM_CONSTANT(VALIGN_TOP); - BIND_GLOBAL_ENUM_CONSTANT(VALIGN_CENTER); - BIND_GLOBAL_ENUM_CONSTANT(VALIGN_BOTTOM); - - // huge list of keys - BIND_GLOBAL_CONSTANT(SPKEY); - - BIND_GLOBAL_ENUM_CONSTANT(KEY_ESCAPE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_TAB); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BACKTAB); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BACKSPACE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ENTER); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_ENTER); - BIND_GLOBAL_ENUM_CONSTANT(KEY_INSERT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_DELETE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PAUSE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PRINT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SYSREQ); - BIND_GLOBAL_ENUM_CONSTANT(KEY_CLEAR); - BIND_GLOBAL_ENUM_CONSTANT(KEY_HOME); - BIND_GLOBAL_ENUM_CONSTANT(KEY_END); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_UP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_DOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PAGEUP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PAGEDOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SHIFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_CONTROL); - BIND_GLOBAL_ENUM_CONSTANT(KEY_META); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ALT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_CAPSLOCK); - BIND_GLOBAL_ENUM_CONSTANT(KEY_NUMLOCK); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SCROLLLOCK); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F1); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F2); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F3); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F4); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F5); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F6); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F7); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F8); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F9); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F10); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F11); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F12); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F13); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F14); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F15); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F16); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_MULTIPLY); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_DIVIDE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_SUBTRACT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_PERIOD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_ADD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_0); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_1); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_2); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_3); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_4); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_5); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_6); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_7); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_8); - BIND_GLOBAL_ENUM_CONSTANT(KEY_KP_9); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SUPER_L); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SUPER_R); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MENU); - BIND_GLOBAL_ENUM_CONSTANT(KEY_HYPER_L); - BIND_GLOBAL_ENUM_CONSTANT(KEY_HYPER_R); - BIND_GLOBAL_ENUM_CONSTANT(KEY_HELP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_DIRECTION_L); - BIND_GLOBAL_ENUM_CONSTANT(KEY_DIRECTION_R); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BACK); - BIND_GLOBAL_ENUM_CONSTANT(KEY_FORWARD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_STOP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_REFRESH); - BIND_GLOBAL_ENUM_CONSTANT(KEY_VOLUMEDOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_VOLUMEMUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_VOLUMEUP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BASSBOOST); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BASSUP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BASSDOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_TREBLEUP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_TREBLEDOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MEDIAPLAY); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MEDIASTOP); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MEDIAPREVIOUS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MEDIANEXT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MEDIARECORD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_HOMEPAGE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_FAVORITES); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SEARCH); - BIND_GLOBAL_ENUM_CONSTANT(KEY_STANDBY); - BIND_GLOBAL_ENUM_CONSTANT(KEY_OPENURL); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHMAIL); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHMEDIA); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH0); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH1); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH2); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH3); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH4); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH5); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH6); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH7); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH8); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCH9); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHA); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHB); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHC); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LAUNCHF); - - BIND_GLOBAL_ENUM_CONSTANT(KEY_UNKNOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SPACE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_EXCLAM); - BIND_GLOBAL_ENUM_CONSTANT(KEY_QUOTEDBL); - BIND_GLOBAL_ENUM_CONSTANT(KEY_NUMBERSIGN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_DOLLAR); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PERCENT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_AMPERSAND); - BIND_GLOBAL_ENUM_CONSTANT(KEY_APOSTROPHE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PARENLEFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PARENRIGHT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ASTERISK); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PLUS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_COMMA); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MINUS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PERIOD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SLASH); - BIND_GLOBAL_ENUM_CONSTANT(KEY_0); - BIND_GLOBAL_ENUM_CONSTANT(KEY_1); - BIND_GLOBAL_ENUM_CONSTANT(KEY_2); - BIND_GLOBAL_ENUM_CONSTANT(KEY_3); - BIND_GLOBAL_ENUM_CONSTANT(KEY_4); - BIND_GLOBAL_ENUM_CONSTANT(KEY_5); - BIND_GLOBAL_ENUM_CONSTANT(KEY_6); - BIND_GLOBAL_ENUM_CONSTANT(KEY_7); - BIND_GLOBAL_ENUM_CONSTANT(KEY_8); - BIND_GLOBAL_ENUM_CONSTANT(KEY_9); - BIND_GLOBAL_ENUM_CONSTANT(KEY_COLON); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SEMICOLON); - BIND_GLOBAL_ENUM_CONSTANT(KEY_LESS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_EQUAL); - BIND_GLOBAL_ENUM_CONSTANT(KEY_GREATER); - BIND_GLOBAL_ENUM_CONSTANT(KEY_QUESTION); - BIND_GLOBAL_ENUM_CONSTANT(KEY_AT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_A); - BIND_GLOBAL_ENUM_CONSTANT(KEY_B); - BIND_GLOBAL_ENUM_CONSTANT(KEY_C); - BIND_GLOBAL_ENUM_CONSTANT(KEY_D); - BIND_GLOBAL_ENUM_CONSTANT(KEY_E); - BIND_GLOBAL_ENUM_CONSTANT(KEY_F); - BIND_GLOBAL_ENUM_CONSTANT(KEY_G); - BIND_GLOBAL_ENUM_CONSTANT(KEY_H); - BIND_GLOBAL_ENUM_CONSTANT(KEY_I); - BIND_GLOBAL_ENUM_CONSTANT(KEY_J); - BIND_GLOBAL_ENUM_CONSTANT(KEY_K); - BIND_GLOBAL_ENUM_CONSTANT(KEY_L); - BIND_GLOBAL_ENUM_CONSTANT(KEY_M); - BIND_GLOBAL_ENUM_CONSTANT(KEY_N); - BIND_GLOBAL_ENUM_CONSTANT(KEY_O); - BIND_GLOBAL_ENUM_CONSTANT(KEY_P); - BIND_GLOBAL_ENUM_CONSTANT(KEY_Q); - BIND_GLOBAL_ENUM_CONSTANT(KEY_R); - BIND_GLOBAL_ENUM_CONSTANT(KEY_S); - BIND_GLOBAL_ENUM_CONSTANT(KEY_T); - BIND_GLOBAL_ENUM_CONSTANT(KEY_U); - BIND_GLOBAL_ENUM_CONSTANT(KEY_V); - BIND_GLOBAL_ENUM_CONSTANT(KEY_W); - BIND_GLOBAL_ENUM_CONSTANT(KEY_X); - BIND_GLOBAL_ENUM_CONSTANT(KEY_Y); - BIND_GLOBAL_ENUM_CONSTANT(KEY_Z); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BRACKETLEFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BACKSLASH); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BRACKETRIGHT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ASCIICIRCUM); - BIND_GLOBAL_ENUM_CONSTANT(KEY_UNDERSCORE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_QUOTELEFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BRACELEFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BAR); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BRACERIGHT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ASCIITILDE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_NOBREAKSPACE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_EXCLAMDOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_CENT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_STERLING); - BIND_GLOBAL_ENUM_CONSTANT(KEY_CURRENCY); - BIND_GLOBAL_ENUM_CONSTANT(KEY_YEN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_BROKENBAR); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SECTION); - BIND_GLOBAL_ENUM_CONSTANT(KEY_DIAERESIS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_COPYRIGHT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ORDFEMININE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_GUILLEMOTLEFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_NOTSIGN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_HYPHEN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_REGISTERED); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MACRON); - BIND_GLOBAL_ENUM_CONSTANT(KEY_DEGREE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PLUSMINUS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_TWOSUPERIOR); - BIND_GLOBAL_ENUM_CONSTANT(KEY_THREESUPERIOR); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ACUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MU); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PARAGRAPH); - BIND_GLOBAL_ENUM_CONSTANT(KEY_PERIODCENTERED); - BIND_GLOBAL_ENUM_CONSTANT(KEY_CEDILLA); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ONESUPERIOR); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MASCULINE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_GUILLEMOTRIGHT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ONEQUARTER); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ONEHALF); - BIND_GLOBAL_ENUM_CONSTANT(KEY_THREEQUARTERS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_QUESTIONDOWN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_AGRAVE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_AACUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ACIRCUMFLEX); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ATILDE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ADIAERESIS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ARING); - BIND_GLOBAL_ENUM_CONSTANT(KEY_AE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_CCEDILLA); - BIND_GLOBAL_ENUM_CONSTANT(KEY_EGRAVE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_EACUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ECIRCUMFLEX); - BIND_GLOBAL_ENUM_CONSTANT(KEY_EDIAERESIS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_IGRAVE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_IACUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ICIRCUMFLEX); - BIND_GLOBAL_ENUM_CONSTANT(KEY_IDIAERESIS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ETH); - BIND_GLOBAL_ENUM_CONSTANT(KEY_NTILDE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_OGRAVE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_OACUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_OCIRCUMFLEX); - BIND_GLOBAL_ENUM_CONSTANT(KEY_OTILDE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_ODIAERESIS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MULTIPLY); - BIND_GLOBAL_ENUM_CONSTANT(KEY_OOBLIQUE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_UGRAVE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_UACUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_UCIRCUMFLEX); - BIND_GLOBAL_ENUM_CONSTANT(KEY_UDIAERESIS); - BIND_GLOBAL_ENUM_CONSTANT(KEY_YACUTE); - BIND_GLOBAL_ENUM_CONSTANT(KEY_THORN); - BIND_GLOBAL_ENUM_CONSTANT(KEY_SSHARP); - - BIND_GLOBAL_ENUM_CONSTANT(KEY_DIVISION); - BIND_GLOBAL_ENUM_CONSTANT(KEY_YDIAERESIS); - - BIND_GLOBAL_ENUM_CONSTANT(KEY_CODE_MASK); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MODIFIER_MASK); - - BIND_GLOBAL_ENUM_CONSTANT(KEY_MASK_SHIFT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MASK_ALT); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MASK_META); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MASK_CTRL); - BIND_GLOBAL_ENUM_CONSTANT_NO_VAL(KEY_MASK_CMD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MASK_KPAD); - BIND_GLOBAL_ENUM_CONSTANT(KEY_MASK_GROUP_SWITCH); - - // mouse - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MIDDLE); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_XBUTTON1); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_XBUTTON2); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_WHEEL_UP); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_WHEEL_DOWN); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_WHEEL_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_WHEEL_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_MIDDLE); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_XBUTTON1); - BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_XBUTTON2); - - // Joypad buttons - BIND_GLOBAL_ENUM_CONSTANT(JOY_INVALID_BUTTON); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_A); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_B); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_BACK); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_GUIDE); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_START); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_LEFT_STICK); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_RIGHT_STICK); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_LEFT_SHOULDER); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_RIGHT_SHOULDER); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_UP); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SDL_BUTTONS); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_CROSS); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_CIRCLE); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_SQUARE); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_TRIANGLE); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_SELECT); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_START); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_PS); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_L1); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_R1); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_L3); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_R3); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_A); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_B); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_BACK); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_START); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_HOME); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_LS); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_RS); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_LB); - BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_RB); - BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_MAX); - - // Joypad axes - BIND_GLOBAL_ENUM_CONSTANT(JOY_INVALID_AXIS); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_LEFT_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_LEFT_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_RIGHT_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_RIGHT_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_TRIGGER_LEFT); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_TRIGGER_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT(JOY_SDL_AXES); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_0_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_0_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_1_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_1_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_2_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_2_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_3_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_3_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_4_X); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_4_Y); - BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_MAX); - - // midi - BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_OFF); - BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_ON); - BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_AFTERTOUCH); - BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_CONTROL_CHANGE); - BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_PROGRAM_CHANGE); - BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_CHANNEL_PRESSURE); - BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_PITCH_BEND); - - // error list - - BIND_GLOBAL_ENUM_CONSTANT(OK); // (0) - BIND_GLOBAL_ENUM_CONSTANT(FAILED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_UNAVAILABLE); - BIND_GLOBAL_ENUM_CONSTANT(ERR_UNCONFIGURED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_UNAUTHORIZED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_PARAMETER_RANGE_ERROR); // (5) - BIND_GLOBAL_ENUM_CONSTANT(ERR_OUT_OF_MEMORY); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_NOT_FOUND); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_BAD_DRIVE); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_BAD_PATH); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_NO_PERMISSION); // (10) - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_ALREADY_IN_USE); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CANT_OPEN); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CANT_WRITE); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CANT_READ); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_UNRECOGNIZED); // (15) - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CORRUPT); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_MISSING_DEPENDENCIES); - BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_EOF); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_OPEN); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_CREATE); // (20) - BIND_GLOBAL_ENUM_CONSTANT(ERR_QUERY_FAILED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_ALREADY_IN_USE); - BIND_GLOBAL_ENUM_CONSTANT(ERR_LOCKED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_TIMEOUT); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_CONNECT); // (25) - BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_RESOLVE); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CONNECTION_ERROR); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_ACQUIRE_RESOURCE); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_FORK); - BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_DATA); // (30) - BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_PARAMETER); - BIND_GLOBAL_ENUM_CONSTANT(ERR_ALREADY_EXISTS); - BIND_GLOBAL_ENUM_CONSTANT(ERR_DOES_NOT_EXIST); - BIND_GLOBAL_ENUM_CONSTANT(ERR_DATABASE_CANT_READ); - BIND_GLOBAL_ENUM_CONSTANT(ERR_DATABASE_CANT_WRITE); // (35) - BIND_GLOBAL_ENUM_CONSTANT(ERR_COMPILATION_FAILED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_METHOD_NOT_FOUND); - BIND_GLOBAL_ENUM_CONSTANT(ERR_LINK_FAILED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_SCRIPT_FAILED); - BIND_GLOBAL_ENUM_CONSTANT(ERR_CYCLIC_LINK); // (40) - BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_DECLARATION); - BIND_GLOBAL_ENUM_CONSTANT(ERR_DUPLICATE_SYMBOL); - BIND_GLOBAL_ENUM_CONSTANT(ERR_PARSE_ERROR); - BIND_GLOBAL_ENUM_CONSTANT(ERR_BUSY); - BIND_GLOBAL_ENUM_CONSTANT(ERR_SKIP); // (45) - BIND_GLOBAL_ENUM_CONSTANT(ERR_HELP); - BIND_GLOBAL_ENUM_CONSTANT(ERR_BUG); - BIND_GLOBAL_ENUM_CONSTANT(ERR_PRINTER_ON_FIRE); - - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_NONE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_RANGE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_EXP_RANGE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_ENUM); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_LENGTH); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_KEY_ACCEL); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_FLAGS); - - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_RENDER); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_PHYSICS); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_RENDER); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_PHYSICS); - - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_FILE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_DIR); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_FILE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_DIR); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_RESOURCE_TYPE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_MULTILINE_TEXT); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_PLACEHOLDER_TEXT); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_COLOR_NO_ALPHA); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSY); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS); - - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORAGE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NETWORK); - - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_HELPER); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CHECKABLE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CHECKED); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_GROUP); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE); - - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT_INTL); - BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NOEDITOR); - - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAG_NORMAL); - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAG_EDITOR); - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAG_NOSCRIPT); - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAG_CONST); - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAG_REVERSE); - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL); - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAG_FROM_SCRIPT); - BIND_GLOBAL_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT); - - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_INT", Variant::INT); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_REAL", Variant::FLOAT); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_STRING", Variant::STRING); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2", Variant::VECTOR2); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2I", Variant::VECTOR2I); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RECT2", Variant::RECT2); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RECT2I", Variant::RECT2I); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3", Variant::VECTOR3); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3I", Variant::VECTOR3I); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_QUAT", Variant::QUAT); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM", Variant::TRANSFORM); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_STRING_NAME", Variant::STRING_NAME); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RID", Variant::_RID); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_OBJECT", Variant::OBJECT); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_CALLABLE", Variant::CALLABLE); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_SIGNAL", Variant::SIGNAL); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_ARRAY", Variant::ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RAW_ARRAY", Variant::PACKED_BYTE_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_INT32_ARRAY", Variant::PACKED_INT32_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_INT64_ARRAY", Variant::PACKED_INT64_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_STRING_ARRAY", Variant::PACKED_STRING_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_MAX", Variant::VARIANT_MAX); - - //comparison - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_EQUAL", Variant::OP_EQUAL); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_NOT_EQUAL", Variant::OP_NOT_EQUAL); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_LESS", Variant::OP_LESS); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_LESS_EQUAL", Variant::OP_LESS_EQUAL); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_GREATER", Variant::OP_GREATER); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_GREATER_EQUAL", Variant::OP_GREATER_EQUAL); - //mathematic - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_ADD", Variant::OP_ADD); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_SUBTRACT", Variant::OP_SUBTRACT); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_MULTIPLY", Variant::OP_MULTIPLY); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_DIVIDE", Variant::OP_DIVIDE); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_NEGATE", Variant::OP_NEGATE); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_POSITIVE", Variant::OP_POSITIVE); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_MODULE", Variant::OP_MODULE); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_STRING_CONCAT", Variant::OP_STRING_CONCAT); - //bitwise - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_SHIFT_LEFT", Variant::OP_SHIFT_LEFT); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_SHIFT_RIGHT", Variant::OP_SHIFT_RIGHT); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_BIT_AND", Variant::OP_BIT_AND); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_BIT_OR", Variant::OP_BIT_OR); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_BIT_XOR", Variant::OP_BIT_XOR); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_BIT_NEGATE", Variant::OP_BIT_NEGATE); - //logic - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_AND", Variant::OP_AND); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_OR", Variant::OP_OR); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_XOR", Variant::OP_XOR); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_NOT", Variant::OP_NOT); - //containment - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_IN", Variant::OP_IN); - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_MAX", Variant::OP_MAX); -} - -void unregister_global_constants() { - _global_constants.clear(); -} - -int GlobalConstants::get_global_constant_count() { - return _global_constants.size(); -} - -#ifdef DEBUG_METHODS_ENABLED -StringName GlobalConstants::get_global_constant_enum(int p_idx) { - return _global_constants[p_idx].enum_name; -} - -bool GlobalConstants::get_ignore_value_in_docs(int p_idx) { - return _global_constants[p_idx].ignore_value_in_docs; -} -#else -StringName GlobalConstants::get_global_constant_enum(int p_idx) { - return StringName(); -} - -bool GlobalConstants::get_ignore_value_in_docs(int p_idx) { - return false; -} -#endif - -const char *GlobalConstants::get_global_constant_name(int p_idx) { - return _global_constants[p_idx].name; -} - -int GlobalConstants::get_global_constant_value(int p_idx) { - return _global_constants[p_idx].value; -} diff --git a/core/input/input.cpp b/core/input/input.cpp index b0b1d20222..ee66bf94cb 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -30,10 +30,10 @@ #include "input.h" +#include "core/config/project_settings.h" #include "core/input/default_controller_mappings.h" #include "core/input/input_map.h" #include "core/os/os.h" -#include "core/project_settings.h" #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" diff --git a/core/input/input.h b/core/input/input.h index 60e378d72c..98bbff6441 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -32,7 +32,7 @@ #define INPUT_H #include "core/input/input_event.h" -#include "core/object.h" +#include "core/object/object.h" #include "core/os/thread_safe.h" class Input : public Object { diff --git a/core/input/input_event.h b/core/input/input_event.h index 815ba5ae80..8b58cf08c2 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -31,11 +31,11 @@ #ifndef INPUT_EVENT_H #define INPUT_EVENT_H +#include "core/io/resource.h" #include "core/math/transform_2d.h" #include "core/os/copymem.h" -#include "core/resource.h" +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" /** * Input Event classes. These are used in the main loop. diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 6319ffc8f1..ba1de3c58d 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -30,8 +30,8 @@ #include "input_map.h" +#include "core/config/project_settings.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" InputMap *InputMap::singleton = nullptr; diff --git a/core/input/input_map.h b/core/input/input_map.h index 755df26984..35c65d0881 100644 --- a/core/input/input_map.h +++ b/core/input/input_map.h @@ -31,8 +31,8 @@ #ifndef INPUT_MAP_H #define INPUT_MAP_H -#include "core/class_db.h" #include "core/input/input_event.h" +#include "core/object/class_db.h" class InputMap : public Object { GDCLASS(InputMap, Object); diff --git a/core/int_types.h b/core/int_types.h deleted file mode 100644 index 71caa2202d..0000000000 --- a/core/int_types.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ -/* int_types.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 INT_TYPES_H -#define INT_TYPES_H - -#ifdef _MSC_VER - -typedef signed __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef signed __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef signed __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - -#else - -#ifdef NO_STDINT_H -typedef unsigned char uint8_t; -typedef signed char int8_t; -typedef unsigned short uint16_t; -typedef signed short int16_t; -typedef unsigned int uint32_t; -typedef signed int int32_t; -typedef long long int64_t; -typedef unsigned long long uint64_t; -#else -#include <stdint.h> -#endif - -#endif // _MSC_VER - -#endif // INT_TYPES_H diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 7480262835..cd8793bb0a 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -30,9 +30,9 @@ #include "compression.h" +#include "core/config/project_settings.h" #include "core/io/zip_io.h" #include "core/os/copymem.h" -#include "core/project_settings.h" #include "thirdparty/misc/fastlz.h" diff --git a/core/io/compression.h b/core/io/compression.h index c103fa8eae..864869788a 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -31,8 +31,8 @@ #ifndef COMPRESSION_H #define COMPRESSION_H +#include "core/templates/vector.h" #include "core/typedefs.h" -#include "core/vector.h" class Compression { public: diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 1af9142317..8be39178db 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -32,7 +32,7 @@ #include "core/io/file_access_encrypted.h" #include "core/os/keyboard.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" PackedStringArray ConfigFile::_get_sections() const { List<String> s; diff --git a/core/io/config_file.h b/core/io/config_file.h index ae06960f02..1dc4492ca8 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -31,10 +31,10 @@ #ifndef CONFIG_FILE_H #define CONFIG_FILE_H -#include "core/ordered_hash_map.h" +#include "core/object/reference.h" #include "core/os/file_access.h" -#include "core/reference.h" -#include "core/variant_parser.h" +#include "core/templates/ordered_hash_map.h" +#include "core/variant/variant_parser.h" class ConfigFile : public Reference { GDCLASS(ConfigFile, Reference); diff --git a/core/io/dtls_server.cpp b/core/io/dtls_server.cpp index e43b1f5385..1930f40c47 100644 --- a/core/io/dtls_server.cpp +++ b/core/io/dtls_server.cpp @@ -30,8 +30,8 @@ #include "dtls_server.h" +#include "core/config/project_settings.h" #include "core/os/file_access.h" -#include "core/project_settings.h" DTLSServer *(*DTLSServer::_create)() = nullptr; bool DTLSServer::available = false; diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp index 6208f3a4d1..714f3b6099 100644 --- a/core/io/file_access_buffered.cpp +++ b/core/io/file_access_buffered.cpp @@ -30,7 +30,7 @@ #include "file_access_buffered.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" Error FileAccessBuffered::set_error(Error p_error) const { return (last_error = p_error); diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h index 99d5ce903d..7fd99b6373 100644 --- a/core/io/file_access_buffered.h +++ b/core/io/file_access_buffered.h @@ -33,7 +33,7 @@ #include "core/os/file_access.h" -#include "core/ustring.h" +#include "core/string/ustring.h" class FileAccessBuffered : public FileAccess { public: diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 7817ccb773..4424192af2 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -30,7 +30,7 @@ #include "file_access_compressed.h" -#include "core/print_string.h" +#include "core/string/print_string.h" void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) { magic = p_magic.ascii().get_data(); diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index eb684f457e..2ac24d5169 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -32,8 +32,8 @@ #include "core/crypto/crypto_core.h" #include "core/os/copymem.h" -#include "core/print_string.h" -#include "core/variant.h" +#include "core/string/print_string.h" +#include "core/variant/variant.h" #include <stdio.h> diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index a65ff92a89..79cba63765 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -30,10 +30,10 @@ #include "file_access_memory.h" -#include "core/map.h" +#include "core/config/project_settings.h" #include "core/os/copymem.h" #include "core/os/dir_access.h" -#include "core/project_settings.h" +#include "core/templates/map.h" static Map<String, Vector<uint8_t>> *files = nullptr; diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 6890740d90..1e9266f118 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -30,10 +30,10 @@ #include "file_access_network.h" +#include "core/config/project_settings.h" #include "core/io/ip.h" #include "core/io/marshalls.h" #include "core/os/os.h" -#include "core/project_settings.h" //#define DEBUG_PRINT(m_p) print_line(m_p) //#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n",m_what,OS::get_singleton()->get_ticks_usec()); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 8fdbb650d4..a025ca5730 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -31,7 +31,7 @@ #include "file_access_pack.h" #include "core/io/file_access_encrypted.h" -#include "core/script_language.h" +#include "core/object/script_language.h" #include "core/version.h" #include <stdio.h> @@ -442,8 +442,14 @@ String DirAccessPack::get_drive(int p_drive) { return ""; } -Error DirAccessPack::change_dir(String p_dir) { +PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) { String nd = p_dir.replace("\\", "/"); + + // Special handling since simplify_path() will forbid it + if (p_dir == "..") { + return current->parent; + } + bool absolute = false; if (nd.begins_with("res://")) { nd = nd.replace_first("res://", ""); @@ -483,13 +489,21 @@ Error DirAccessPack::change_dir(String p_dir) { pd = pd->subdirs[p]; } else { - return ERR_INVALID_PARAMETER; + return nullptr; } } - current = pd; + return pd; +} - return OK; +Error DirAccessPack::change_dir(String p_dir) { + PackedData::PackedDir *pd = _find_dir(p_dir); + if (pd) { + current = pd; + return OK; + } else { + return ERR_INVALID_PARAMETER; + } } String DirAccessPack::get_current_dir(bool p_include_drive) { @@ -507,13 +521,17 @@ String DirAccessPack::get_current_dir(bool p_include_drive) { bool DirAccessPack::file_exists(String p_file) { p_file = fix_path(p_file); - return current->files.has(p_file); + PackedData::PackedDir *pd = _find_dir(p_file.get_base_dir()); + if (!pd) { + return false; + } + return pd->files.has(p_file.get_file()); } bool DirAccessPack::dir_exists(String p_dir) { p_dir = fix_path(p_dir); - return current->subdirs.has(p_dir); + return _find_dir(p_dir) != nullptr; } Error DirAccessPack::make_dir(String p_dir) { diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index d934b0deb5..c13626a5aa 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -31,11 +31,11 @@ #ifndef FILE_ACCESS_PACK_H #define FILE_ACCESS_PACK_H -#include "core/list.h" -#include "core/map.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" -#include "core/print_string.h" +#include "core/string/print_string.h" +#include "core/templates/list.h" +#include "core/templates/map.h" // Godot's packed file magic header ("GDPC" in ASCII). #define PACK_HEADER_MAGIC 0x43504447 @@ -122,6 +122,9 @@ public: _FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path); + _FORCE_INLINE_ DirAccess *try_open_directory(const String &p_path); + _FORCE_INLINE_ bool has_directory(const String &p_path); + PackedData(); ~PackedData(); }; @@ -199,6 +202,16 @@ bool PackedData::has_path(const String &p_path) { return files.has(PathMD5(p_path.md5_buffer())); } +bool PackedData::has_directory(const String &p_path) { + DirAccess *da = try_open_directory(p_path); + if (da) { + memdelete(da); + return true; + } else { + return false; + } +} + class DirAccessPack : public DirAccess { PackedData::PackedDir *current; @@ -206,6 +219,8 @@ class DirAccessPack : public DirAccess { List<String> list_files; bool cdir = false; + PackedData::PackedDir *_find_dir(String p_dir); + public: virtual Error list_dir_begin(); virtual String get_next(); @@ -235,4 +250,13 @@ public: ~DirAccessPack() {} }; +DirAccess *PackedData::try_open_directory(const String &p_path) { + DirAccess *da = memnew(DirAccessPack()); + if (da->change_dir(p_path) != OK) { + memdelete(da); + da = nullptr; + } + return da; +} + #endif // FILE_ACCESS_PACK_H diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index c251b3c424..eff07c60e2 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -34,7 +34,7 @@ #ifdef MINIZIP_ENABLED #include "core/io/file_access_pack.h" -#include "core/map.h" +#include "core/templates/map.h" #include "thirdparty/minizip/unzip.h" diff --git a/core/io/http_client.h b/core/io/http_client.h index 1dc1f3d76a..ece7e1924b 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -34,7 +34,7 @@ #include "core/io/ip.h" #include "core/io/stream_peer.h" #include "core/io/stream_peer_tcp.h" -#include "core/reference.h" +#include "core/object/reference.h" class HTTPClient : public Reference { GDCLASS(HTTPClient, Reference); @@ -182,7 +182,8 @@ private: int response_num = 0; Vector<String> response_headers; - int read_chunk_size = 4096; + // 64 KiB by default (favors fast download speeds at the cost of memory usage). + int read_chunk_size = 65536; Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received); diff --git a/core/image.cpp b/core/io/image.cpp index b8a443eed2..005fd481e8 100644 --- a/core/image.cpp +++ b/core/io/image.cpp @@ -30,13 +30,13 @@ #include "image.h" -#include "core/error_macros.h" -#include "core/hash_map.h" +#include "core/error/error_macros.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/math/math_funcs.h" #include "core/os/copymem.h" -#include "core/print_string.h" +#include "core/string/print_string.h" +#include "core/templates/hash_map.h" #include <stdio.h> @@ -2711,6 +2711,7 @@ ImageMemLoadFunc Image::_png_mem_loader_func = nullptr; ImageMemLoadFunc Image::_jpg_mem_loader_func = nullptr; ImageMemLoadFunc Image::_webp_mem_loader_func = nullptr; ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; void (*Image::_image_compress_bc_func)(Image *, float, Image::UsedChannels) = nullptr; void (*Image::_image_compress_bptc_func)(Image *, float, Image::UsedChannels) = nullptr; @@ -3141,6 +3142,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("load_jpg_from_buffer", "buffer"), &Image::load_jpg_from_buffer); ClassDB::bind_method(D_METHOD("load_webp_from_buffer", "buffer"), &Image::load_webp_from_buffer); ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer); + ClassDB::bind_method(D_METHOD("load_bmp_from_buffer", "buffer"), &Image::load_bmp_from_buffer); ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data"); @@ -3473,10 +3475,21 @@ Error Image::load_webp_from_buffer(const Vector<uint8_t> &p_array) { } Error Image::load_tga_from_buffer(const Vector<uint8_t> &p_array) { - ERR_FAIL_NULL_V_MSG(_tga_mem_loader_func, ERR_UNAVAILABLE, "TGA module was not installed."); + ERR_FAIL_NULL_V_MSG( + _tga_mem_loader_func, + ERR_UNAVAILABLE, + "The TGA module isn't enabled. Recompile the Godot editor or export template binary with the `module_tga_enabled=yes` SCons option."); return _load_from_buffer(p_array, _tga_mem_loader_func); } +Error Image::load_bmp_from_buffer(const Vector<uint8_t> &p_array) { + ERR_FAIL_NULL_V_MSG( + _bmp_mem_loader_func, + ERR_UNAVAILABLE, + "The BMP module isn't enabled. Recompile the Godot editor or export template binary with the `module_bmp_enabled=yes` SCons option."); + return _load_from_buffer(p_array, _bmp_mem_loader_func); +} + void Image::convert_rg_to_ra_rgba8() { ERR_FAIL_COND(format != FORMAT_RGBA8); ERR_FAIL_COND(!data.size()); diff --git a/core/image.h b/core/io/image.h index 06794c7fed..fecb90cab0 100644 --- a/core/image.h +++ b/core/io/image.h @@ -31,9 +31,9 @@ #ifndef IMAGE_H #define IMAGE_H -#include "core/color.h" +#include "core/io/resource.h" +#include "core/math/color.h" #include "core/math/rect2.h" -#include "core/resource.h" /** * @author Juan Linietsky <reduzio@gmail.com> @@ -136,6 +136,7 @@ public: static ImageMemLoadFunc _jpg_mem_loader_func; static ImageMemLoadFunc _webp_mem_loader_func; static ImageMemLoadFunc _tga_mem_loader_func; + static ImageMemLoadFunc _bmp_mem_loader_func; static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels); static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels); @@ -375,6 +376,7 @@ public: Error load_jpg_from_buffer(const Vector<uint8_t> &p_array); Error load_webp_from_buffer(const Vector<uint8_t> &p_array); Error load_tga_from_buffer(const Vector<uint8_t> &p_array); + Error load_bmp_from_buffer(const Vector<uint8_t> &p_array); void convert_rg_to_ra_rgba8(); void convert_ra_rgba8_to_rg(); diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index b1e92eb87f..f6d8668349 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -30,7 +30,7 @@ #include "image_loader.h" -#include "core/print_string.h" +#include "core/string/print_string.h" bool ImageFormatLoader::recognize(const String &p_extension) const { List<String> extensions; diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 9682f144c7..d5fb4678eb 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -31,11 +31,11 @@ #ifndef IMAGE_LOADER_H #define IMAGE_LOADER_H -#include "core/image.h" +#include "core/io/image.h" #include "core/io/resource_loader.h" -#include "core/list.h" #include "core/os/file_access.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/list.h" class ImageLoader; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 24b8ec7cc1..9f3540efad 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -30,9 +30,9 @@ #include "ip.h" -#include "core/hash_map.h" #include "core/os/semaphore.h" #include "core/os/thread.h" +#include "core/templates/hash_map.h" VARIANT_ENUM_CAST(IP::ResolverStatus); diff --git a/core/io/ip_address.h b/core/io/ip_address.h index 2f8f83503e..7a813230f5 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -31,7 +31,7 @@ #ifndef IP_ADDRESS_H #define IP_ADDRESS_H -#include "core/ustring.h" +#include "core/string/ustring.h" struct IP_Address { private: diff --git a/core/io/json.cpp b/core/io/json.cpp index 1b89d966fd..d61c2b8236 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -30,7 +30,7 @@ #include "json.h" -#include "core/print_string.h" +#include "core/string/print_string.h" const char *JSON::tk_name[TK_MAX] = { "'{'", @@ -455,3 +455,35 @@ Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int & return err; } + +Error JSONParser::parse_string(const String &p_json_string) { + return JSON::parse(p_json_string, data, err_text, err_line); +} +String JSONParser::get_error_text() const { + return err_text; +} +int JSONParser::get_error_line() const { + return err_line; +} +Variant JSONParser::get_data() const { + return data; +} + +Error JSONParser::decode_data(const Variant &p_data, const String &p_indent, bool p_sort_keys) { + string = JSON::print(p_data, p_indent, p_sort_keys); + data = p_data; + return OK; +} + +String JSONParser::get_string() const { + return string; +} + +void JSONParser::_bind_methods() { + ClassDB::bind_method(D_METHOD("parse_string", "json_string"), &JSONParser::parse_string); + ClassDB::bind_method(D_METHOD("get_error_text"), &JSONParser::get_error_text); + ClassDB::bind_method(D_METHOD("get_error_line"), &JSONParser::get_error_line); + ClassDB::bind_method(D_METHOD("get_data"), &JSONParser::get_data); + ClassDB::bind_method(D_METHOD("decode_data", "data", "indent", "sort_keys"), &JSONParser::decode_data, DEFVAL(""), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_string"), &JSONParser::get_string); +} diff --git a/core/io/json.h b/core/io/json.h index 9122228163..2854d956ec 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -31,8 +31,8 @@ #ifndef JSON_H #define JSON_H -#include "core/variant.h" - +#include "core/object/reference.h" +#include "core/variant/variant.h" class JSON { enum TokenType { TK_CURLY_BRACKET_OPEN, @@ -75,4 +75,25 @@ public: static Error parse(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line); }; +class JSONParser : public Reference { + GDCLASS(JSONParser, Reference); + + Variant data; + String string; + String err_text; + int err_line = 0; + +protected: + static void _bind_methods(); + +public: + Error parse_string(const String &p_json_string); + String get_error_text() const; + int get_error_line() const; + Variant get_data() const; + + Error decode_data(const Variant &p_data, const String &p_indent = "", bool p_sort_keys = true); + String get_string() const; +}; + #endif // JSON_H diff --git a/core/io/logger.cpp b/core/io/logger.cpp index 886e5695b1..0e6a2e2c9f 100644 --- a/core/io/logger.cpp +++ b/core/io/logger.cpp @@ -32,7 +32,7 @@ #include "core/os/dir_access.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #if defined(MINGW_ENABLED) || defined(_MSC_VER) #define sprintf sprintf_s diff --git a/core/io/logger.h b/core/io/logger.h index 277be9ed35..9eaf506c51 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -32,8 +32,8 @@ #define LOGGER_H #include "core/os/file_access.h" -#include "core/ustring.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/vector.h" #include <stdarg.h> diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index eb39b1433f..3cf4acaf39 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -30,9 +30,9 @@ #include "marshalls.h" +#include "core/object/reference.h" #include "core/os/keyboard.h" -#include "core/print_string.h" -#include "core/reference.h" +#include "core/string/print_string.h" #include <limits.h> #include <stdio.h> @@ -420,7 +420,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; - case Variant::_RID: { + case Variant::RID: { r_variant = RID(); } break; case Variant::OBJECT: { @@ -1172,7 +1172,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4 * 4; } break; - case Variant::_RID: { + case Variant::RID: { } break; case Variant::CALLABLE: { } break; diff --git a/core/io/marshalls.h b/core/io/marshalls.h index c8ed497528..6969a9b500 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -31,9 +31,9 @@ #ifndef MARSHALLS_H #define MARSHALLS_H -#include "core/reference.h" +#include "core/object/reference.h" #include "core/typedefs.h" -#include "core/variant.h" +#include "core/variant/variant.h" /** * Miscellaneous helpers for marshalling data types, and encoding diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index 06eab7796c..e0ce1c8ca4 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -32,7 +32,7 @@ #define MULTIPLAYER_API_H #include "core/io/networked_multiplayer_peer.h" -#include "core/reference.h" +#include "core/object/reference.h" class MultiplayerAPI : public Reference { GDCLASS(MultiplayerAPI, Reference); diff --git a/core/io/net_socket.h b/core/io/net_socket.h index 746945eced..67d0253985 100644 --- a/core/io/net_socket.h +++ b/core/io/net_socket.h @@ -32,7 +32,7 @@ #define NET_SOCKET_H #include "core/io/ip.h" -#include "core/reference.h" +#include "core/object/reference.h" class NetSocket : public Reference { protected: diff --git a/core/packed_data_container.cpp b/core/io/packed_data_container.cpp index e335ec0daa..fbe8fa8a28 100644 --- a/core/packed_data_container.cpp +++ b/core/io/packed_data_container.cpp @@ -39,6 +39,9 @@ Variant PackedDataContainer::getvar(const Variant &p_key, bool *r_valid) const { if (r_valid) { *r_valid = !err; } + if (err) { + return Object::getvar(p_key, r_valid); + } return ret; } @@ -243,7 +246,7 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd } break; // misc types - case Variant::_RID: + case Variant::RID: case Variant::OBJECT: { return _pack(Variant(), tmpdata, string_cache); } break; diff --git a/core/packed_data_container.h b/core/io/packed_data_container.h index 28ec9cc87c..b784abcd16 100644 --- a/core/packed_data_container.h +++ b/core/io/packed_data_container.h @@ -31,7 +31,7 @@ #ifndef PACKED_DATA_CONTAINER_H #define PACKED_DATA_CONTAINER_H -#include "core/resource.h" +#include "core/io/resource.h" class PackedDataContainer : public Resource { GDCLASS(PackedDataContainer, Resource); diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index dacd548a3e..b6cc5bf42a 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -30,8 +30,8 @@ #include "packet_peer.h" +#include "core/config/project_settings.h" #include "core/io/marshalls.h" -#include "core/project_settings.h" /* helpers / binders */ diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index fb4dc181db..f7f080aa43 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -31,9 +31,9 @@ #ifndef PACKET_PEER_H #define PACKET_PEER_H -#include "core/class_db.h" #include "core/io/stream_peer.h" -#include "core/ring_buffer.h" +#include "core/object/class_db.h" +#include "core/templates/ring_buffer.h" class PacketPeer : public Reference { GDCLASS(PacketPeer, Reference); diff --git a/core/io/packet_peer_dtls.cpp b/core/io/packet_peer_dtls.cpp index 632f86a9f6..9f6fccc993 100644 --- a/core/io/packet_peer_dtls.cpp +++ b/core/io/packet_peer_dtls.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "packet_peer_dtls.h" +#include "core/config/project_settings.h" #include "core/os/file_access.h" -#include "core/project_settings.h" PacketPeerDTLS *(*PacketPeerDTLS::_create)() = nullptr; bool PacketPeerDTLS::available = false; diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h index a6054dff2c..c1026c2499 100644 --- a/core/io/pck_packer.h +++ b/core/io/pck_packer.h @@ -31,7 +31,7 @@ #ifndef PCK_PACKER_H #define PCK_PACKER_H -#include "core/reference.h" +#include "core/object/reference.h" class FileAccess; diff --git a/core/resource.cpp b/core/io/resource.cpp index 3b589793ef..5b249f7af3 100644 --- a/core/resource.cpp +++ b/core/io/resource.cpp @@ -32,9 +32,9 @@ #include "core/core_string_names.h" #include "core/io/resource_loader.h" +#include "core/object/script_language.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/script_language.h" #include "scene/main/node.h" //only so casting works #include <stdio.h> diff --git a/core/resource.h b/core/io/resource.h index 41707f216d..6e0bd7d7f4 100644 --- a/core/resource.h +++ b/core/io/resource.h @@ -31,10 +31,10 @@ #ifndef RESOURCE_H #define RESOURCE_H -#include "core/class_db.h" -#include "core/reference.h" -#include "core/safe_refcount.h" -#include "core/self_list.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" +#include "core/templates/safe_refcount.h" +#include "core/templates/self_list.h" #define RES_BASE_EXTENSION(m_ext) \ public: \ diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 21de7835ce..c67e68e4fc 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -30,11 +30,11 @@ #include "resource_format_binary.h" -#include "core/image.h" +#include "core/config/project_settings.h" #include "core/io/file_access_compressed.h" +#include "core/io/image.h" #include "core/io/marshalls.h" #include "core/os/dir_access.h" -#include "core/project_settings.h" #include "core/version.h" //#define print_bl(m_what) print_line(m_what) @@ -1467,7 +1467,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } } break; - case Variant::_RID: { + case Variant::RID: { f->store_32(VARIANT_RID); WARN_PRINT("Can't save RIDs."); RID val = p_property; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 4d980bcf1a..c88331cf9e 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -30,9 +30,9 @@ #include "resource_importer.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const { return p_a->get_importer_name() < p_b->get_importer_name(); diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index b5c598e860..9991ee405e 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -30,13 +30,13 @@ #include "resource_loader.h" +#include "core/config/project_settings.h" #include "core/io/resource_importer.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/project_settings.h" -#include "core/translation.h" -#include "core/variant_parser.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" +#include "core/variant/variant_parser.h" #ifdef DEBUG_LOAD_THREADED #define print_lt(m_text) print_line(m_text) diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 9322b5273a..02c668f214 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -31,9 +31,9 @@ #ifndef RESOURCE_LOADER_H #define RESOURCE_LOADER_H +#include "core/io/resource.h" #include "core/os/semaphore.h" #include "core/os/thread.h" -#include "core/resource.h" class ResourceFormatLoader : public Reference { GDCLASS(ResourceFormatLoader, Reference); diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index a8da215b61..2eac2a6b4d 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -29,10 +29,10 @@ /*************************************************************************/ #include "resource_saver.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" +#include "core/object/script_language.h" #include "core/os/file_access.h" -#include "core/project_settings.h" -#include "core/script_language.h" Ref<ResourceFormatSaver> ResourceSaver::saver[MAX_SAVERS]; diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 8b4cdd86f8..2e2950af53 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -31,7 +31,7 @@ #ifndef RESOURCE_SAVER_H #define RESOURCE_SAVER_H -#include "core/resource.h" +#include "core/io/resource.h" class ResourceFormatSaver : public Reference { GDCLASS(ResourceFormatSaver, Reference); diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index 39097a57f2..8c1e918dd8 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -31,7 +31,7 @@ #ifndef STREAM_PEER_H #define STREAM_PEER_H -#include "core/reference.h" +#include "core/object/reference.h" class StreamPeer : public Reference { GDCLASS(StreamPeer, Reference); diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp index 3dc31c6769..daf36a5350 100644 --- a/core/io/stream_peer_ssl.cpp +++ b/core/io/stream_peer_ssl.cpp @@ -30,7 +30,7 @@ #include "stream_peer_ssl.h" -#include "core/engine.h" +#include "core/config/engine.h" StreamPeerSSL *(*StreamPeerSSL::_create)() = nullptr; diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index cce728c30a..aa9c409528 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -30,7 +30,7 @@ #include "stream_peer_tcp.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" Error StreamPeerTCP::_poll_connection() { ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED); diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index d8ddb213c3..34cccca540 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -31,8 +31,8 @@ #include "translation_loader_po.h" #include "core/os/file_access.h" -#include "core/translation.h" -#include "core/translation_po.h" +#include "core/string/translation.h" +#include "core/string/translation_po.h" RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { enum Status { diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index a196a37dc0..16c9f1e680 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -33,7 +33,7 @@ #include "core/io/resource_loader.h" #include "core/os/file_access.h" -#include "core/translation.h" +#include "core/string/translation.h" class TranslationLoaderPO : public ResourceFormatLoader { public: diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index fc75ac7d1e..85143c0f04 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -30,7 +30,7 @@ #include "xml_parser.h" -#include "core/print_string.h" +#include "core/string/print_string.h" //#define DEBUG_XML diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index ee2174d52c..d8cc26b4c1 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -31,10 +31,10 @@ #ifndef XML_PARSER_H #define XML_PARSER_H +#include "core/object/reference.h" #include "core/os/file_access.h" -#include "core/reference.h" -#include "core/ustring.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/vector.h" /* Based on irrXML (see their zlib license). Added mainly for compatibility with their Collada loader. diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 30f712b2c3..b4410acf7d 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -31,7 +31,7 @@ #include "a_star.h" #include "core/math/geometry_3d.h" -#include "core/script_language.h" +#include "core/object/script_language.h" #include "scene/scene_string_names.h" int AStar::get_available_point_id() const { diff --git a/core/math/a_star.h b/core/math/a_star.h index ba1c3033b8..a6fa771b30 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -31,8 +31,8 @@ #ifndef A_STAR_H #define A_STAR_H -#include "core/oa_hash_map.h" -#include "core/reference.h" +#include "core/object/reference.h" +#include "core/templates/oa_hash_map.h" /** A* pathfinding algorithm diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index e868ebc7c8..08673d0dd1 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -30,8 +30,8 @@ #include "aabb.h" -#include "core/print_string.h" -#include "core/variant.h" +#include "core/string/print_string.h" +#include "core/variant/variant.h" real_t AABB::get_area() const { return size.x * size.y * size.z; diff --git a/core/math/aabb.h b/core/math/aabb.h index 8c08754e1c..45dcbc7f7f 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -107,6 +107,14 @@ public: Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const; Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const; + _FORCE_INLINE_ void set_end(const Vector3 &p_end) { + size = p_end - position; + } + + _FORCE_INLINE_ Vector3 get_end() const { + return position + size; + } + operator String() const; _FORCE_INLINE_ AABB() {} diff --git a/core/math/basis.cpp b/core/math/basis.cpp index a712ae7e3e..c6030d9757 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -32,7 +32,7 @@ #include "core/math/math_funcs.h" #include "core/os/copymem.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #define cofac(row1, col1, row2, col2) \ (elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1]) diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index c154d57a13..5e5efb6356 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -31,7 +31,7 @@ #include "camera_matrix.h" #include "core/math/math_funcs.h" -#include "core/print_string.h" +#include "core/string/print_string.h" float CameraMatrix::determinant() const { return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] - diff --git a/core/color.cpp b/core/math/color.cpp index c61ee0e64a..2afe14bd63 100644 --- a/core/color.cpp +++ b/core/math/color.cpp @@ -30,10 +30,10 @@ #include "color.h" -#include "core/color_names.inc" -#include "core/map.h" +#include "color_names.inc" #include "core/math/math_funcs.h" -#include "core/print_string.h" +#include "core/string/print_string.h" +#include "core/templates/map.h" uint32_t Color::to_argb32() const { uint32_t c = (uint8_t)Math::round(a * 255); @@ -159,7 +159,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) { a = p_alpha; if (p_s == 0) { - // acp_hromatic (grey) + // Achromatic (grey) r = g = b = p_v; return; } @@ -217,12 +217,6 @@ void Color::invert() { b = 1.0 - b; } -void Color::contrast() { - r = Math::fmod(r + 0.5, 1.0); - g = Math::fmod(g + 0.5, 1.0); - b = Math::fmod(b + 0.5, 1.0); -} - Color Color::hex(uint32_t p_hex) { float a = (p_hex & 0xFF) / 255.0; p_hex >>= 8; @@ -284,12 +278,6 @@ Color Color::inverted() const { return c; } -Color Color::contrasted() const { - Color c = *this; - c.contrast(); - return c; -} - Color Color::html(const String &p_rgba) { String color = p_rgba; if (color.length() == 0) { @@ -367,9 +355,6 @@ bool Color::html_is_valid(const String &p_color) { } Color Color::named(const String &p_name) { - if (_named_colors.empty()) { - _populate_named_colors(); // from color_names.inc - } String name = p_name; // Normalize name name = name.replace(" ", ""); @@ -379,9 +364,31 @@ Color Color::named(const String &p_name) { name = name.replace(".", ""); name = name.to_lower(); - const Map<String, Color>::Element *color = _named_colors.find(name); - ERR_FAIL_NULL_V_MSG(color, Color(), "Invalid color name: " + p_name + "."); - return color->value(); + int idx = 0; + while (named_colors[idx].name != nullptr) { + if (name == named_colors[idx].name) { + return named_colors[idx].color; + } + idx++; + } + + ERR_FAIL_V_MSG(Color(), "Invalid color name: " + p_name + "."); + + return Color(); +} + +int Color::get_named_color_count() { + int idx = 0; + while (named_colors[idx].name != nullptr) { + idx++; + } + return idx; +} +String Color::get_named_color_name(int p_idx) { + return named_colors[p_idx].name; +} +Color Color::get_named_color(int p_idx) { + return named_colors[p_idx].color; } String _to_hex(float p_val) { @@ -482,6 +489,13 @@ Color Color::operator+(const Color &p_color) const { a + p_color.a); } +void Color::operator+=(const Color &p_color) { + r = r + p_color.r; + g = g + p_color.g; + b = b + p_color.b; + a = a + p_color.a; +} + Color Color::operator-(const Color &p_color) const { return Color( r - p_color.r, @@ -505,12 +519,12 @@ Color Color::operator*(const Color &p_color) const { a * p_color.a); } -Color Color::operator*(const real_t &rvalue) const { +Color Color::operator*(real_t p_rvalue) const { return Color( - r * rvalue, - g * rvalue, - b * rvalue, - a * rvalue); + r * p_rvalue, + g * p_rvalue, + b * p_rvalue, + a * p_rvalue); } void Color::operator*=(const Color &p_color) { @@ -520,11 +534,11 @@ void Color::operator*=(const Color &p_color) { a = a * p_color.a; } -void Color::operator*=(const real_t &rvalue) { - r = r * rvalue; - g = g * rvalue; - b = b * rvalue; - a = a * rvalue; +void Color::operator*=(real_t p_rvalue) { + r = r * p_rvalue; + g = g * p_rvalue; + b = b * p_rvalue; + a = a * p_rvalue; } Color Color::operator/(const Color &p_color) const { @@ -535,12 +549,12 @@ Color Color::operator/(const Color &p_color) const { a / p_color.a); } -Color Color::operator/(const real_t &rvalue) const { +Color Color::operator/(real_t p_rvalue) const { return Color( - r / rvalue, - g / rvalue, - b / rvalue, - a / rvalue); + r / p_rvalue, + g / p_rvalue, + b / p_rvalue, + a / p_rvalue); } void Color::operator/=(const Color &p_color) { @@ -550,17 +564,17 @@ void Color::operator/=(const Color &p_color) { a = a / p_color.a; } -void Color::operator/=(const real_t &rvalue) { - if (rvalue == 0) { +void Color::operator/=(real_t p_rvalue) { + if (p_rvalue == 0) { r = 1.0; g = 1.0; b = 1.0; a = 1.0; } else { - r = r / rvalue; - g = g / rvalue; - b = b / rvalue; - a = a / rvalue; + r = r / p_rvalue; + g = g / p_rvalue; + b = b / p_rvalue; + a = a / p_rvalue; } } diff --git a/core/color.h b/core/math/color.h index 2dbbc52905..a9be9e9035 100644 --- a/core/color.h +++ b/core/math/color.h @@ -32,7 +32,7 @@ #define COLOR_H #include "core/math/math_funcs.h" -#include "core/ustring.h" +#include "core/string/ustring.h" struct Color { union { @@ -45,9 +45,6 @@ struct Color { float components[4] = { 0, 0, 0, 1.0 }; }; - bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); } - bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); } - uint32_t to_rgba32() const; uint32_t to_argb32() const; uint32_t to_abgr32() const; @@ -59,41 +56,41 @@ struct Color { float get_v() const; void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0); - _FORCE_INLINE_ float &operator[](int idx) { - return components[idx]; + _FORCE_INLINE_ float &operator[](int p_idx) { + return components[p_idx]; } - _FORCE_INLINE_ const float &operator[](int idx) const { - return components[idx]; + _FORCE_INLINE_ const float &operator[](int p_idx) const { + return components[p_idx]; } - Color operator+(const Color &p_color) const; - _FORCE_INLINE_ void operator+=(const Color &p_color) { - r = r + p_color.r; - g = g + p_color.g; - b = b + p_color.b; - a = a + p_color.a; + bool operator==(const Color &p_color) const { + return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); } + bool operator!=(const Color &p_color) const { + return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); + } + + Color operator+(const Color &p_color) const; + void operator+=(const Color &p_color); Color operator-() const; Color operator-(const Color &p_color) const; void operator-=(const Color &p_color); Color operator*(const Color &p_color) const; - Color operator*(const real_t &rvalue) const; + Color operator*(real_t p_rvalue) const; void operator*=(const Color &p_color); - void operator*=(const real_t &rvalue); + void operator*=(real_t p_rvalue); Color operator/(const Color &p_color) const; - Color operator/(const real_t &rvalue) const; + Color operator/(real_t p_rvalue) const; void operator/=(const Color &p_color); - void operator/=(const real_t &rvalue); + void operator/=(real_t p_rvalue); bool is_equal_approx(const Color &p_color) const; void invert(); - void contrast(); Color inverted() const; - Color contrasted() const; _FORCE_INLINE_ Color lerp(const Color &p_b, float p_t) const { Color res = *this; @@ -125,10 +122,9 @@ struct Color { _FORCE_INLINE_ uint32_t to_rgbe9995() const { const float pow2to9 = 512.0f; const float B = 15.0f; - //const float Emax = 31.0f; const float N = 9.0f; - float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f); + float sharedexp = 65408.000f; // Result of: ((pow2to9 - 1.0f) / pow2to9) * powf(2.0f, 31.0f - 15.0f) float cRed = MAX(0.0f, MIN(sharedexp, r)); float cGreen = MAX(0.0f, MIN(sharedexp, g)); @@ -136,8 +132,6 @@ struct Color { float cMax = MAX(cRed, MAX(cGreen, cBlue)); - // expp = MAX(-B - 1, log2(maxc)) + 1 + B - float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B; float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f); @@ -188,6 +182,9 @@ struct Color { static Color html(const String &p_rgba); static bool html_is_valid(const String &p_color); static Color named(const String &p_name); + static int get_named_color_count(); + static String get_named_color_name(int p_idx); + static Color get_named_color(int p_idx); String to_html(bool p_alpha = true) const; Color from_hsv(float p_h, float p_s, float p_v, float p_a) const; static Color from_rgbe9995(uint32_t p_rgbe); @@ -195,12 +192,27 @@ struct Color { _FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys operator String() const; + // For the binder. + _FORCE_INLINE_ void set_r8(int32_t r8) { r = (CLAMP(r8, 0, 255) / 255.0); } + _FORCE_INLINE_ int32_t get_r8() const { return int32_t(CLAMP(r * 255.0, 0.0, 255.0)); } + _FORCE_INLINE_ void set_g8(int32_t g8) { g = (CLAMP(g8, 0, 255) / 255.0); } + _FORCE_INLINE_ int32_t get_g8() const { return int32_t(CLAMP(g * 255.0, 0.0, 255.0)); } + _FORCE_INLINE_ void set_b8(int32_t b8) { b = (CLAMP(b8, 0, 255) / 255.0); } + _FORCE_INLINE_ int32_t get_b8() const { return int32_t(CLAMP(b * 255.0, 0.0, 255.0)); } + _FORCE_INLINE_ void set_a8(int32_t a8) { a = (CLAMP(a8, 0, 255) / 255.0); } + _FORCE_INLINE_ int32_t get_a8() const { return int32_t(CLAMP(a * 255.0, 0.0, 255.0)); } + + _FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v()); } + _FORCE_INLINE_ void set_s(float p_s) { set_hsv(get_h(), p_s, get_v()); } + _FORCE_INLINE_ void set_v(float p_v) { set_hsv(get_h(), get_s(), p_v); } + _FORCE_INLINE_ Color() {} /** - * RGB / RGBA construct parameters. Alpha is optional, but defaults to 1.0 + * RGBA construct parameters. + * Alpha is not optional as otherwise we can't bind the RGB version for scripting. */ - _FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a = 1.0) { + _FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a) { r = p_r; g = p_g; b = p_b; @@ -208,6 +220,16 @@ struct Color { } /** + * RGB construct parameters. + */ + _FORCE_INLINE_ Color(float p_r, float p_g, float p_b) { + r = p_r; + g = p_g; + b = p_b; + a = 1.0; + } + + /** * Construct a Color from another Color, but with the specified alpha value. */ _FORCE_INLINE_ Color(const Color &p_c, float p_a) { @@ -234,7 +256,7 @@ bool Color::operator<(const Color &p_color) const { } } -_FORCE_INLINE_ Color operator*(const real_t &p_real, const Color &p_color) { +_FORCE_INLINE_ Color operator*(real_t p_real, const Color &p_color) { return p_color * p_real; } diff --git a/core/math/color_names.inc b/core/math/color_names.inc new file mode 100644 index 0000000000..523c7e3c59 --- /dev/null +++ b/core/math/color_names.inc @@ -0,0 +1,160 @@ +// Names from https://en.wikipedia.org/wiki/X11_color_names + +// So this in a way that does not require memory allocation +// the old way leaked memory +// this is not used as often as for more performance to make sense + +struct NamedColor { + const char *name; + Color color; +}; + +static NamedColor named_colors[] = { + { "aliceblue", Color(0.94, 0.97, 1.00) }, + { "antiquewhite", Color(0.98, 0.92, 0.84) }, + { "aqua", Color(0.00, 1.00, 1.00) }, + { "aquamarine", Color(0.50, 1.00, 0.83) }, + { "azure", Color(0.94, 1.00, 1.00) }, + { "beige", Color(0.96, 0.96, 0.86) }, + { "bisque", Color(1.00, 0.89, 0.77) }, + { "black", Color(0.00, 0.00, 0.00) }, + { "blanchedalmond", Color(1.00, 0.92, 0.80) }, + { "blue", Color(0.00, 0.00, 1.00) }, + { "blueviolet", Color(0.54, 0.17, 0.89) }, + { "brown", Color(0.65, 0.16, 0.16) }, + { "burlywood", Color(0.87, 0.72, 0.53) }, + { "cadetblue", Color(0.37, 0.62, 0.63) }, + { "chartreuse", Color(0.50, 1.00, 0.00) }, + { "chocolate", Color(0.82, 0.41, 0.12) }, + { "coral", Color(1.00, 0.50, 0.31) }, + { "cornflower", Color(0.39, 0.58, 0.93) }, + { "cornsilk", Color(1.00, 0.97, 0.86) }, + { "crimson", Color(0.86, 0.08, 0.24) }, + { "cyan", Color(0.00, 1.00, 1.00) }, + { "darkblue", Color(0.00, 0.00, 0.55) }, + { "darkcyan", Color(0.00, 0.55, 0.55) }, + { "darkgoldenrod", Color(0.72, 0.53, 0.04) }, + { "darkgray", Color(0.66, 0.66, 0.66) }, + { "darkgreen", Color(0.00, 0.39, 0.00) }, + { "darkkhaki", Color(0.74, 0.72, 0.42) }, + { "darkmagenta", Color(0.55, 0.00, 0.55) }, + { "darkolivegreen", Color(0.33, 0.42, 0.18) }, + { "darkorange", Color(1.00, 0.55, 0.00) }, + { "darkorchid", Color(0.60, 0.20, 0.80) }, + { "darkred", Color(0.55, 0.00, 0.00) }, + { "darksalmon", Color(0.91, 0.59, 0.48) }, + { "darkseagreen", Color(0.56, 0.74, 0.56) }, + { "darkslateblue", Color(0.28, 0.24, 0.55) }, + { "darkslategray", Color(0.18, 0.31, 0.31) }, + { "darkturquoise", Color(0.00, 0.81, 0.82) }, + { "darkviolet", Color(0.58, 0.00, 0.83) }, + { "deeppink", Color(1.00, 0.08, 0.58) }, + { "deepskyblue", Color(0.00, 0.75, 1.00) }, + { "dimgray", Color(0.41, 0.41, 0.41) }, + { "dodgerblue", Color(0.12, 0.56, 1.00) }, + { "firebrick", Color(0.70, 0.13, 0.13) }, + { "floralwhite", Color(1.00, 0.98, 0.94) }, + { "forestgreen", Color(0.13, 0.55, 0.13) }, + { "fuchsia", Color(1.00, 0.00, 1.00) }, + { "gainsboro", Color(0.86, 0.86, 0.86) }, + { "ghostwhite", Color(0.97, 0.97, 1.00) }, + { "gold", Color(1.00, 0.84, 0.00) }, + { "goldenrod", Color(0.85, 0.65, 0.13) }, + { "gray", Color(0.75, 0.75, 0.75) }, + { "green", Color(0.00, 1.00, 0.00) }, + { "greenyellow", Color(0.68, 1.00, 0.18) }, + { "honeydew", Color(0.94, 1.00, 0.94) }, + { "hotpink", Color(1.00, 0.41, 0.71) }, + { "indianred", Color(0.80, 0.36, 0.36) }, + { "indigo", Color(0.29, 0.00, 0.51) }, + { "ivory", Color(1.00, 1.00, 0.94) }, + { "khaki", Color(0.94, 0.90, 0.55) }, + { "lavender", Color(0.90, 0.90, 0.98) }, + { "lavenderblush", Color(1.00, 0.94, 0.96) }, + { "lawngreen", Color(0.49, 0.99, 0.00) }, + { "lemonchiffon", Color(1.00, 0.98, 0.80) }, + { "lightblue", Color(0.68, 0.85, 0.90) }, + { "lightcoral", Color(0.94, 0.50, 0.50) }, + { "lightcyan", Color(0.88, 1.00, 1.00) }, + { "lightgoldenrod", Color(0.98, 0.98, 0.82) }, + { "lightgray", Color(0.83, 0.83, 0.83) }, + { "lightgreen", Color(0.56, 0.93, 0.56) }, + { "lightpink", Color(1.00, 0.71, 0.76) }, + { "lightsalmon", Color(1.00, 0.63, 0.48) }, + { "lightseagreen", Color(0.13, 0.70, 0.67) }, + { "lightskyblue", Color(0.53, 0.81, 0.98) }, + { "lightslategray", Color(0.47, 0.53, 0.60) }, + { "lightsteelblue", Color(0.69, 0.77, 0.87) }, + { "lightyellow", Color(1.00, 1.00, 0.88) }, + { "lime", Color(0.00, 1.00, 0.00) }, + { "limegreen", Color(0.20, 0.80, 0.20) }, + { "linen", Color(0.98, 0.94, 0.90) }, + { "magenta", Color(1.00, 0.00, 1.00) }, + { "maroon", Color(0.69, 0.19, 0.38) }, + { "mediumaquamarine", Color(0.40, 0.80, 0.67) }, + { "mediumblue", Color(0.00, 0.00, 0.80) }, + { "mediumorchid", Color(0.73, 0.33, 0.83) }, + { "mediumpurple", Color(0.58, 0.44, 0.86) }, + { "mediumseagreen", Color(0.24, 0.70, 0.44) }, + { "mediumslateblue", Color(0.48, 0.41, 0.93) }, + { "mediumspringgreen", Color(0.00, 0.98, 0.60) }, + { "mediumturquoise", Color(0.28, 0.82, 0.80) }, + { "mediumvioletred", Color(0.78, 0.08, 0.52) }, + { "midnightblue", Color(0.10, 0.10, 0.44) }, + { "mintcream", Color(0.96, 1.00, 0.98) }, + { "mistyrose", Color(1.00, 0.89, 0.88) }, + { "moccasin", Color(1.00, 0.89, 0.71) }, + { "navajowhite", Color(1.00, 0.87, 0.68) }, + { "navyblue", Color(0.00, 0.00, 0.50) }, + { "oldlace", Color(0.99, 0.96, 0.90) }, + { "olive", Color(0.50, 0.50, 0.00) }, + { "olivedrab", Color(0.42, 0.56, 0.14) }, + { "orange", Color(1.00, 0.65, 0.00) }, + { "orangered", Color(1.00, 0.27, 0.00) }, + { "orchid", Color(0.85, 0.44, 0.84) }, + { "palegoldenrod", Color(0.93, 0.91, 0.67) }, + { "palegreen", Color(0.60, 0.98, 0.60) }, + { "paleturquoise", Color(0.69, 0.93, 0.93) }, + { "palevioletred", Color(0.86, 0.44, 0.58) }, + { "papayawhip", Color(1.00, 0.94, 0.84) }, + { "peachpuff", Color(1.00, 0.85, 0.73) }, + { "peru", Color(0.80, 0.52, 0.25) }, + { "pink", Color(1.00, 0.75, 0.80) }, + { "plum", Color(0.87, 0.63, 0.87) }, + { "powderblue", Color(0.69, 0.88, 0.90) }, + { "purple", Color(0.63, 0.13, 0.94) }, + { "rebeccapurple", Color(0.40, 0.20, 0.60) }, + { "red", Color(1.00, 0.00, 0.00) }, + { "rosybrown", Color(0.74, 0.56, 0.56) }, + { "royalblue", Color(0.25, 0.41, 0.88) }, + { "saddlebrown", Color(0.55, 0.27, 0.07) }, + { "salmon", Color(0.98, 0.50, 0.45) }, + { "sandybrown", Color(0.96, 0.64, 0.38) }, + { "seagreen", Color(0.18, 0.55, 0.34) }, + { "seashell", Color(1.00, 0.96, 0.93) }, + { "sienna", Color(0.63, 0.32, 0.18) }, + { "silver", Color(0.75, 0.75, 0.75) }, + { "skyblue", Color(0.53, 0.81, 0.92) }, + { "slateblue", Color(0.42, 0.35, 0.80) }, + { "slategray", Color(0.44, 0.50, 0.56) }, + { "snow", Color(1.00, 0.98, 0.98) }, + { "springgreen", Color(0.00, 1.00, 0.50) }, + { "steelblue", Color(0.27, 0.51, 0.71) }, + { "tan", Color(0.82, 0.71, 0.55) }, + { "teal", Color(0.00, 0.50, 0.50) }, + { "thistle", Color(0.85, 0.75, 0.85) }, + { "tomato", Color(1.00, 0.39, 0.28) }, + { "transparent", Color(1.00, 1.00, 1.00, 0.00) }, + { "turquoise", Color(0.25, 0.88, 0.82) }, + { "violet", Color(0.93, 0.51, 0.93) }, + { "webgray", Color(0.50, 0.50, 0.50) }, + { "webgreen", Color(0.00, 0.50, 0.00) }, + { "webmaroon", Color(0.50, 0.00, 0.00) }, + { "webpurple", Color(0.50, 0.00, 0.50) }, + { "wheat", Color(0.96, 0.87, 0.70) }, + { "white", Color(1.00, 1.00, 1.00) }, + { "whitesmoke", Color(0.96, 0.96, 0.96) }, + { "yellow", Color(1.00, 1.00, 0.00) }, + { "yellowgreen", Color(0.60, 0.80, 0.20) }, + { nullptr, Color(0.60, 0.80, 0.20) }, +}; diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 014b4c4621..ea8655cfff 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -31,15 +31,15 @@ #ifndef DELAUNAY_3D_H #define DELAUNAY_3D_H -#include "core/local_vector.h" #include "core/math/aabb.h" #include "core/math/camera_matrix.h" #include "core/math/vector3.h" -#include "core/oa_hash_map.h" #include "core/os/file_access.h" -#include "core/print_string.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/string/print_string.h" +#include "core/templates/local_vector.h" +#include "core/templates/oa_hash_map.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" #include "thirdparty/misc/r128.h" diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h index 198f46e111..51b9ce81af 100644 --- a/core/math/disjoint_set.h +++ b/core/math/disjoint_set.h @@ -31,8 +31,8 @@ #ifndef DISJOINT_SET_H #define DISJOINT_SET_H -#include "core/map.h" -#include "core/vector.h" +#include "core/templates/map.h" +#include "core/templates/vector.h" /** @author Marios Staikopoulos <marios@staik.net> diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 1040f9e0e4..d1f15caa5e 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -30,714 +30,12 @@ #include "expression.h" -#include "core/class_db.h" -#include "core/func_ref.h" #include "core/io/marshalls.h" #include "core/math/math_funcs.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" #include "core/os/os.h" -#include "core/reference.h" -#include "core/variant_parser.h" - -const char *Expression::func_name[Expression::FUNC_MAX] = { - "sin", - "cos", - "tan", - "sinh", - "cosh", - "tanh", - "asin", - "acos", - "atan", - "atan2", - "sqrt", - "fmod", - "fposmod", - "posmod", - "floor", - "ceil", - "round", - "abs", - "sign", - "pow", - "log", - "exp", - "is_nan", - "is_inf", - "ease", - "step_decimals", - "stepify", - "lerp", - "lerp_angle", - "inverse_lerp", - "range_lerp", - "smoothstep", - "move_toward", - "dectime", - "randomize", - "randi", - "randf", - "rand_range", - "seed", - "rand_seed", - "deg2rad", - "rad2deg", - "linear2db", - "db2linear", - "polar2cartesian", - "cartesian2polar", - "wrapi", - "wrapf", - "max", - "min", - "clamp", - "nearest_po2", - "weakref", - "funcref", - "convert", - "typeof", - "type_exists", - "char", - "ord", - "str", - "print", - "printerr", - "printraw", - "var2str", - "str2var", - "var2bytes", - "bytes2var", - "color_named", -}; - -Expression::BuiltinFunc Expression::find_function(const String &p_string) { - for (int i = 0; i < FUNC_MAX; i++) { - if (p_string == func_name[i]) { - return BuiltinFunc(i); - } - } - - return FUNC_MAX; -} - -String Expression::get_func_name(BuiltinFunc p_func) { - ERR_FAIL_INDEX_V(p_func, FUNC_MAX, String()); - return func_name[p_func]; -} - -int Expression::get_func_argument_count(BuiltinFunc p_func) { - switch (p_func) { - case MATH_RANDOMIZE: - case MATH_RAND: - case MATH_RANDF: - return 0; - case MATH_SIN: - case MATH_COS: - case MATH_TAN: - case MATH_SINH: - case MATH_COSH: - case MATH_TANH: - case MATH_ASIN: - case MATH_ACOS: - case MATH_ATAN: - case MATH_SQRT: - case MATH_FLOOR: - case MATH_CEIL: - case MATH_ROUND: - case MATH_ABS: - case MATH_SIGN: - case MATH_LOG: - case MATH_EXP: - case MATH_ISNAN: - case MATH_ISINF: - case MATH_STEP_DECIMALS: - case MATH_SEED: - case MATH_RANDSEED: - case MATH_DEG2RAD: - case MATH_RAD2DEG: - case MATH_LINEAR2DB: - case MATH_DB2LINEAR: - case LOGIC_NEAREST_PO2: - case OBJ_WEAKREF: - case TYPE_OF: - case TEXT_CHAR: - case TEXT_ORD: - case TEXT_STR: - case TEXT_PRINT: - case TEXT_PRINTERR: - case TEXT_PRINTRAW: - case VAR_TO_STR: - case STR_TO_VAR: - case TYPE_EXISTS: - return 1; - case VAR_TO_BYTES: - case BYTES_TO_VAR: - case MATH_ATAN2: - case MATH_FMOD: - case MATH_FPOSMOD: - case MATH_POSMOD: - case MATH_POW: - case MATH_EASE: - case MATH_STEPIFY: - case MATH_RANDOM: - case MATH_POLAR2CARTESIAN: - case MATH_CARTESIAN2POLAR: - case LOGIC_MAX: - case LOGIC_MIN: - case FUNC_FUNCREF: - case TYPE_CONVERT: - case COLORN: - return 2; - case MATH_LERP: - case MATH_LERP_ANGLE: - case MATH_INVERSE_LERP: - case MATH_SMOOTHSTEP: - case MATH_MOVE_TOWARD: - case MATH_DECTIME: - case MATH_WRAP: - case MATH_WRAPF: - case LOGIC_CLAMP: - return 3; - case MATH_RANGE_LERP: - return 5; - case FUNC_MAX: { - } - } - return 0; -} - -#define VALIDATE_ARG_NUM(m_arg) \ - if (!p_inputs[m_arg]->is_num()) { \ - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \ - r_error.argument = m_arg; \ - r_error.expected = Variant::FLOAT; \ - return; \ - } - -void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) { - r_error.error = Callable::CallError::CALL_OK; - switch (p_func) { - case MATH_SIN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::sin((double)*p_inputs[0]); - } break; - case MATH_COS: { - VALIDATE_ARG_NUM(0); - *r_return = Math::cos((double)*p_inputs[0]); - } break; - case MATH_TAN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::tan((double)*p_inputs[0]); - } break; - case MATH_SINH: { - VALIDATE_ARG_NUM(0); - *r_return = Math::sinh((double)*p_inputs[0]); - } break; - case MATH_COSH: { - VALIDATE_ARG_NUM(0); - *r_return = Math::cosh((double)*p_inputs[0]); - } break; - case MATH_TANH: { - VALIDATE_ARG_NUM(0); - *r_return = Math::tanh((double)*p_inputs[0]); - } break; - case MATH_ASIN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::asin((double)*p_inputs[0]); - } break; - case MATH_ACOS: { - VALIDATE_ARG_NUM(0); - *r_return = Math::acos((double)*p_inputs[0]); - } break; - case MATH_ATAN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::atan((double)*p_inputs[0]); - } break; - case MATH_ATAN2: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::atan2((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case MATH_SQRT: { - VALIDATE_ARG_NUM(0); - *r_return = Math::sqrt((double)*p_inputs[0]); - } break; - case MATH_FMOD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::fmod((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case MATH_FPOSMOD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case MATH_POSMOD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]); - } break; - case MATH_FLOOR: { - VALIDATE_ARG_NUM(0); - *r_return = Math::floor((double)*p_inputs[0]); - } break; - case MATH_CEIL: { - VALIDATE_ARG_NUM(0); - *r_return = Math::ceil((double)*p_inputs[0]); - } break; - case MATH_ROUND: { - VALIDATE_ARG_NUM(0); - *r_return = Math::round((double)*p_inputs[0]); - } break; - case MATH_ABS: { - if (p_inputs[0]->get_type() == Variant::INT) { - int64_t i = *p_inputs[0]; - *r_return = ABS(i); - } else if (p_inputs[0]->get_type() == Variant::FLOAT) { - real_t r = *p_inputs[0]; - *r_return = Math::abs(r); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::FLOAT; - } - } break; - case MATH_SIGN: { - if (p_inputs[0]->get_type() == Variant::INT) { - int64_t i = *p_inputs[0]; - *r_return = i < 0 ? -1 : (i > 0 ? +1 : 0); - } else if (p_inputs[0]->get_type() == Variant::FLOAT) { - real_t r = *p_inputs[0]; - *r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::FLOAT; - } - } break; - case MATH_POW: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::pow((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case MATH_LOG: { - VALIDATE_ARG_NUM(0); - *r_return = Math::log((double)*p_inputs[0]); - } break; - case MATH_EXP: { - VALIDATE_ARG_NUM(0); - *r_return = Math::exp((double)*p_inputs[0]); - } break; - case MATH_ISNAN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::is_nan((double)*p_inputs[0]); - } break; - case MATH_ISINF: { - VALIDATE_ARG_NUM(0); - *r_return = Math::is_inf((double)*p_inputs[0]); - } break; - case MATH_EASE: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case MATH_STEP_DECIMALS: { - VALIDATE_ARG_NUM(0); - *r_return = Math::step_decimals((double)*p_inputs[0]); - } break; - case MATH_STEPIFY: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::stepify((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case MATH_LERP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case MATH_LERP_ANGLE: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case MATH_INVERSE_LERP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::inverse_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case MATH_RANGE_LERP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - VALIDATE_ARG_NUM(3); - VALIDATE_ARG_NUM(4); - *r_return = Math::range_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2], (double)*p_inputs[3], (double)*p_inputs[4]); - } break; - case MATH_SMOOTHSTEP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::smoothstep((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case MATH_MOVE_TOWARD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::move_toward((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case MATH_DECTIME: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::dectime((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case MATH_RANDOMIZE: { - Math::randomize(); - - } break; - case MATH_RAND: { - *r_return = Math::rand(); - } break; - case MATH_RANDF: { - *r_return = Math::randf(); - } break; - case MATH_RANDOM: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::random((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case MATH_SEED: { - VALIDATE_ARG_NUM(0); - uint64_t seed = *p_inputs[0]; - Math::seed(seed); - - } break; - case MATH_RANDSEED: { - VALIDATE_ARG_NUM(0); - uint64_t seed = *p_inputs[0]; - int ret = Math::rand_from_seed(&seed); - Array reta; - reta.push_back(ret); - reta.push_back(seed); - *r_return = reta; - - } break; - case MATH_DEG2RAD: { - VALIDATE_ARG_NUM(0); - *r_return = Math::deg2rad((double)*p_inputs[0]); - } break; - case MATH_RAD2DEG: { - VALIDATE_ARG_NUM(0); - *r_return = Math::rad2deg((double)*p_inputs[0]); - } break; - case MATH_LINEAR2DB: { - VALIDATE_ARG_NUM(0); - *r_return = Math::linear2db((double)*p_inputs[0]); - } break; - case MATH_DB2LINEAR: { - VALIDATE_ARG_NUM(0); - *r_return = Math::db2linear((double)*p_inputs[0]); - } break; - case MATH_POLAR2CARTESIAN: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - double r = *p_inputs[0]; - double th = *p_inputs[1]; - *r_return = Vector2(r * Math::cos(th), r * Math::sin(th)); - } break; - case MATH_CARTESIAN2POLAR: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - double x = *p_inputs[0]; - double y = *p_inputs[1]; - *r_return = Vector2(Math::sqrt(x * x + y * y), Math::atan2(y, x)); - } break; - case MATH_WRAP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::wrapi((int64_t)*p_inputs[0], (int64_t)*p_inputs[1], (int64_t)*p_inputs[2]); - } break; - case MATH_WRAPF: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::wrapf((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case LOGIC_MAX: { - if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) { - int64_t a = *p_inputs[0]; - int64_t b = *p_inputs[1]; - *r_return = MAX(a, b); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - - real_t a = *p_inputs[0]; - real_t b = *p_inputs[1]; - - *r_return = MAX(a, b); - } - - } break; - case LOGIC_MIN: { - if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) { - int64_t a = *p_inputs[0]; - int64_t b = *p_inputs[1]; - *r_return = MIN(a, b); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - - real_t a = *p_inputs[0]; - real_t b = *p_inputs[1]; - - *r_return = MIN(a, b); - } - } break; - case LOGIC_CLAMP: { - if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT && p_inputs[2]->get_type() == Variant::INT) { - int64_t a = *p_inputs[0]; - int64_t b = *p_inputs[1]; - int64_t c = *p_inputs[2]; - *r_return = CLAMP(a, b, c); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - - real_t a = *p_inputs[0]; - real_t b = *p_inputs[1]; - real_t c = *p_inputs[2]; - - *r_return = CLAMP(a, b, c); - } - } break; - case LOGIC_NEAREST_PO2: { - VALIDATE_ARG_NUM(0); - int64_t num = *p_inputs[0]; - *r_return = next_power_of_2(num); - } break; - case OBJ_WEAKREF: { - if (p_inputs[0]->get_type() != Variant::OBJECT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - - return; - } - - if (p_inputs[0]->is_ref()) { - REF r = *p_inputs[0]; - if (!r.is_valid()) { - return; - } - - Ref<WeakRef> wref = memnew(WeakRef); - wref->set_ref(r); - *r_return = wref; - } else { - Object *obj = *p_inputs[0]; - if (!obj) { - return; - } - Ref<WeakRef> wref = memnew(WeakRef); - wref->set_obj(obj); - *r_return = wref; - } - - } break; - case FUNC_FUNCREF: { - if (p_inputs[0]->get_type() != Variant::OBJECT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - - return; - } - if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING; - - return; - } - - Ref<FuncRef> fr = memnew(FuncRef); - - fr->set_instance(*p_inputs[0]); - fr->set_function(*p_inputs[1]); - - *r_return = fr; - - } break; - case TYPE_CONVERT: { - VALIDATE_ARG_NUM(1); - int type = *p_inputs[1]; - if (type < 0 || type >= Variant::VARIANT_MAX) { - r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants."); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::INT; - return; - - } else { - *r_return = Variant::construct(Variant::Type(type), p_inputs, 1, r_error); - } - } break; - case TYPE_OF: { - *r_return = p_inputs[0]->get_type(); - - } break; - case TYPE_EXISTS: { - *r_return = ClassDB::class_exists(*p_inputs[0]); - - } break; - case TEXT_CHAR: { - char32_t result[2] = { *p_inputs[0], 0 }; - - *r_return = String(result); - - } break; - case TEXT_ORD: { - if (p_inputs[0]->get_type() != Variant::STRING) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - - return; - } - - String str = *p_inputs[0]; - - if (str.length() != 1) { - r_error_str = RTR("Expected a string of length 1 (a character)."); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - - return; - } - - *r_return = str.get(0); - - } break; - case TEXT_STR: { - String str = *p_inputs[0]; - - *r_return = str; - - } break; - case TEXT_PRINT: { - String str = *p_inputs[0]; - print_line(str); - - } break; - - case TEXT_PRINTERR: { - String str = *p_inputs[0]; - print_error(str); - - } break; - case TEXT_PRINTRAW: { - String str = *p_inputs[0]; - OS::get_singleton()->print("%s", str.utf8().get_data()); - - } break; - case VAR_TO_STR: { - String vars; - VariantWriter::write_to_string(*p_inputs[0], vars); - *r_return = vars; - } break; - case STR_TO_VAR: { - if (p_inputs[0]->get_type() != Variant::STRING) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - - return; - } - - VariantParser::StreamString ss; - ss.s = *p_inputs[0]; - - String errs; - int line; - Error err = VariantParser::parse(&ss, *r_return, errs, line); - - if (err != OK) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - *r_return = "Parse error at line " + itos(line) + ": " + errs; - return; - } - - } break; - case VAR_TO_BYTES: { - PackedByteArray barr; - bool full_objects = *p_inputs[1]; - int len; - Error err = encode_variant(*p_inputs[0], nullptr, len, full_objects); - if (err) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::NIL; - r_error_str = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID)."; - return; - } - - barr.resize(len); - { - uint8_t *w = barr.ptrw(); - encode_variant(*p_inputs[0], w, len, full_objects); - } - *r_return = barr; - } break; - case BYTES_TO_VAR: { - if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::PACKED_BYTE_ARRAY; - - return; - } - - PackedByteArray varr = *p_inputs[0]; - bool allow_objects = *p_inputs[1]; - Variant ret; - { - const uint8_t *r = varr.ptr(); - Error err = decode_variant(ret, r, varr.size(), nullptr, allow_objects); - if (err != OK) { - r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format."); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::PACKED_BYTE_ARRAY; - return; - } - } - - *r_return = ret; - - } break; - case COLORN: { - VALIDATE_ARG_NUM(1); - - Color color = Color::named(*p_inputs[0]); - color.a = *p_inputs[1]; - - *r_return = String(color); - - } break; - default: { - } - } -} - -//////// +#include "core/variant/variant_parser.h" static bool _is_number(char32_t c) { return (c >= '0' && c <= '9'); @@ -1112,18 +410,9 @@ Error Expression::_get_token(Token &r_token) { } else if (id == "self") { r_token.type = TK_SELF; } else { - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (id == Variant::get_type_name(Variant::Type(i))) { - r_token.type = TK_BASIC_TYPE; - r_token.value = i; - return OK; - } - } - - BuiltinFunc bifunc = find_function(id); - if (bifunc != FUNC_MAX) { + if (Variant::has_utility_function(id)) { r_token.type = TK_BUILTIN_FUNC; - r_token.value = bifunc; + r_token.value = id; return OK; } @@ -1421,6 +710,8 @@ Expression::ENode *Expression::_parse_expression() { case TK_BUILTIN_FUNC: { //builtin function + StringName func = tk.value; + _get_token(tk); if (tk.type != TK_PARENTHESIS_OPEN) { _set_error("Expected '('"); @@ -1428,7 +719,7 @@ Expression::ENode *Expression::_parse_expression() { } BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>(); - bifunc->func = BuiltinFunc(int(tk.value)); + bifunc->func = func; while (true) { int cofs = str_ofs; @@ -1456,9 +747,11 @@ Expression::ENode *Expression::_parse_expression() { } } - int expected_args = get_func_argument_count(bifunc->func); - if (bifunc->arguments.size() != expected_args) { - _set_error("Builtin func '" + get_func_name(bifunc->func) + "' expects " + itos(expected_args) + " arguments."); + if (!Variant::is_utility_function_vararg(bifunc->func)) { + int expected_args = Variant::get_utility_function_argument_count(bifunc->func); + if (expected_args != bifunc->arguments.size()) { + _set_error("Builtin func '" + String(bifunc->func) + "' expects " + itos(expected_args) + " arguments."); + } } expr = bifunc; @@ -1973,7 +1266,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: } bool valid; - r_ret = base.get_named(index->name, &valid); + r_ret = base.get_named(index->name, valid); if (!valid) { r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), Variant::get_type_name(base.get_type())); return true; @@ -2041,7 +1334,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: } Callable::CallError ce; - r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce); + Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = vformat(RTR("Invalid arguments to construct '%s'"), Variant::get_type_name(constructor->data_type)); @@ -2067,11 +1360,11 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: argp.write[i] = &arr[i]; } + r_ret = Variant(); //may not return anything Callable::CallError ce; - exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str); - + Variant::call_utility_function(bifunc->func, &r_ret, (const Variant **)argp.ptr(), argp.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { - r_error_str = "Builtin Call Failed. " + r_error_str; + r_error_str = "Builtin Call Failed. " + Variant::get_call_error_text(bifunc->func, (const Variant **)argp.ptr(), argp.size(), ce); return true; } @@ -2103,7 +1396,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: } Callable::CallError ce; - r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce); + base.call(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = vformat(RTR("On call to '%s':"), String(call->method)); diff --git a/core/math/expression.h b/core/math/expression.h index f2cfe6b1a6..d9cedb8c2c 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -31,92 +31,12 @@ #ifndef EXPRESSION_H #define EXPRESSION_H -#include "core/reference.h" +#include "core/object/reference.h" class Expression : public Reference { GDCLASS(Expression, Reference); -public: - enum BuiltinFunc { - MATH_SIN, - MATH_COS, - MATH_TAN, - MATH_SINH, - MATH_COSH, - MATH_TANH, - MATH_ASIN, - MATH_ACOS, - MATH_ATAN, - MATH_ATAN2, - MATH_SQRT, - MATH_FMOD, - MATH_FPOSMOD, - MATH_POSMOD, - MATH_FLOOR, - MATH_CEIL, - MATH_ROUND, - MATH_ABS, - MATH_SIGN, - MATH_POW, - MATH_LOG, - MATH_EXP, - MATH_ISNAN, - MATH_ISINF, - MATH_EASE, - MATH_STEP_DECIMALS, - MATH_STEPIFY, - MATH_LERP, - MATH_LERP_ANGLE, - MATH_INVERSE_LERP, - MATH_RANGE_LERP, - MATH_SMOOTHSTEP, - MATH_MOVE_TOWARD, - MATH_DECTIME, - MATH_RANDOMIZE, - MATH_RAND, - MATH_RANDF, - MATH_RANDOM, - MATH_SEED, - MATH_RANDSEED, - MATH_DEG2RAD, - MATH_RAD2DEG, - MATH_LINEAR2DB, - MATH_DB2LINEAR, - MATH_POLAR2CARTESIAN, - MATH_CARTESIAN2POLAR, - MATH_WRAP, - MATH_WRAPF, - LOGIC_MAX, - LOGIC_MIN, - LOGIC_CLAMP, - LOGIC_NEAREST_PO2, - OBJ_WEAKREF, - FUNC_FUNCREF, - TYPE_CONVERT, - TYPE_OF, - TYPE_EXISTS, - TEXT_CHAR, - TEXT_ORD, - TEXT_STR, - TEXT_PRINT, - TEXT_PRINTERR, - TEXT_PRINTRAW, - VAR_TO_STR, - STR_TO_VAR, - VAR_TO_BYTES, - BYTES_TO_VAR, - COLORN, - FUNC_MAX - }; - - static int get_func_argument_count(BuiltinFunc p_func); - static String get_func_name(BuiltinFunc p_func); - static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str); - static BuiltinFunc find_function(const String &p_string); - private: - static const char *func_name[FUNC_MAX]; - struct Input { Variant::Type type = Variant::NIL; String name; @@ -315,7 +235,7 @@ private: }; struct BuiltinFuncNode : public ENode { - BuiltinFunc func; + StringName func; Vector<ENode *> arguments; BuiltinFuncNode() { type = TYPE_BUILTIN_FUNC; diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index cfd7abfacb..12bad5768e 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -34,8 +34,8 @@ #include "core/math/delaunay_2d.h" #include "core/math/rect2.h" #include "core/math/triangulate.h" -#include "core/object.h" -#include "core/vector.h" +#include "core/object/object.h" +#include "core/templates/vector.h" class Geometry2D { Geometry2D(); diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index 2c19fe2085..56353de783 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -30,7 +30,7 @@ #include "geometry_3d.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "thirdparty/misc/clipper.hpp" #include "thirdparty/misc/triangulator.h" diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 11cac8f108..f10fbeaaaf 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -32,8 +32,8 @@ #define GEOMETRY_3D_H #include "core/math/face3.h" -#include "core/object.h" -#include "core/vector.h" +#include "core/object/object.h" +#include "core/templates/vector.h" class Geometry3D { Geometry3D(); diff --git a/core/math/math_fieldwise.h b/core/math/math_fieldwise.h index c1ee9ec8f0..e8aac0dced 100644 --- a/core/math/math_fieldwise.h +++ b/core/math/math_fieldwise.h @@ -33,7 +33,7 @@ #ifdef TOOLS_ENABLED -#include "core/variant.h" +#include "core/variant/variant.h" Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field); diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 1585c96b38..e57257b442 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -30,12 +30,10 @@ #include "math_funcs.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC); -#define PHI 0x9e3779b9 - uint32_t Math::rand_from_seed(uint64_t *seed) { RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC); uint32_t r = rng.rand(); @@ -183,3 +181,7 @@ double Math::random(double from, double to) { float Math::random(float from, float to) { return default_rand.random(from, to); } + +int Math::random(int from, int to) { + return default_rand.random(from, to); +} diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index f83ee44f4a..827637bf2b 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -289,7 +289,7 @@ public: static double random(double from, double to); static float random(float from, float to); - static real_t random(int from, int to) { return (real_t)random((real_t)from, (real_t)to); } + static int random(int from, int to); static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) { // Check for exact equality first, required to handle "infinity" values. diff --git a/core/math/octree.h b/core/math/octree.h index 5d9688d442..40201f99b1 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -31,13 +31,13 @@ #ifndef OCTREE_H #define OCTREE_H -#include "core/list.h" -#include "core/map.h" #include "core/math/aabb.h" #include "core/math/geometry_3d.h" #include "core/math/vector3.h" -#include "core/print_string.h" -#include "core/variant.h" +#include "core/string/print_string.h" +#include "core/templates/list.h" +#include "core/templates/map.h" +#include "core/variant/variant.h" typedef uint32_t OctreeElementID; diff --git a/core/math/plane.cpp b/core/math/plane.cpp index ae2021d2f6..e1ae3288ed 100644 --- a/core/math/plane.cpp +++ b/core/math/plane.cpp @@ -31,7 +31,7 @@ #include "plane.h" #include "core/math/math_funcs.h" -#include "core/variant.h" +#include "core/variant/variant.h" void Plane::set_normal(const Vector3 &p_normal) { normal = p_normal; diff --git a/core/math/quat.cpp b/core/math/quat.cpp index c10f5da494..b6a017dd41 100644 --- a/core/math/quat.cpp +++ b/core/math/quat.cpp @@ -31,7 +31,7 @@ #include "quat.h" #include "core/math/basis.h" -#include "core/print_string.h" +#include "core/string/print_string.h" // set_euler_xyz expects a vector containing the Euler angles in the format // (ax,ay,az), where ax is the angle of rotation around x axis, diff --git a/core/math/quat.h b/core/math/quat.h index 3152b7d233..f8ab537d7b 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -36,12 +36,26 @@ #include "core/math/math_defs.h" #include "core/math/math_funcs.h" -#include "core/ustring.h" +#include "core/string/ustring.h" class Quat { public: - real_t x = 0, y = 0, z = 0, w = 1; - + union { + struct { + real_t x; + real_t y; + real_t z; + real_t w; + }; + real_t components[4] = { 0, 0, 0, 1.0 }; + }; + + _FORCE_INLINE_ real_t &operator[](int idx) { + return components[idx]; + } + _FORCE_INLINE_ const real_t &operator[](int idx) const { + return components[idx]; + } _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Quat &p_quat) const; real_t length() const; @@ -91,6 +105,10 @@ public: return v + ((uv * w) + u.cross(uv)) * ((real_t)2); } + _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &v) const { + return inverse().xform(v); + } + _FORCE_INLINE_ void operator+=(const Quat &q); _FORCE_INLINE_ void operator-=(const Quat &q); _FORCE_INLINE_ void operator*=(const real_t &s); diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 8ba1ba9286..8dff13c050 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -30,7 +30,7 @@ #include "quick_hull.h" -#include "core/map.h" +#include "core/templates/map.h" uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF; diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h index cac8e58d23..80f32e191b 100644 --- a/core/math/quick_hull.h +++ b/core/math/quick_hull.h @@ -31,10 +31,10 @@ #ifndef QUICK_HULL_H #define QUICK_HULL_H -#include "core/list.h" #include "core/math/aabb.h" #include "core/math/geometry_3d.h" -#include "core/set.h" +#include "core/templates/list.h" +#include "core/templates/set.h" class QuickHull { public: diff --git a/core/math/random_number_generator.cpp b/core/math/random_number_generator.cpp index 67f4c0b14a..a124f63030 100644 --- a/core/math/random_number_generator.cpp +++ b/core/math/random_number_generator.cpp @@ -33,7 +33,6 @@ void RandomNumberGenerator::_bind_methods() { ClassDB::bind_method(D_METHOD("set_seed", "seed"), &RandomNumberGenerator::set_seed); ClassDB::bind_method(D_METHOD("get_seed"), &RandomNumberGenerator::get_seed); - ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed"); ClassDB::bind_method(D_METHOD("randi"), &RandomNumberGenerator::randi); ClassDB::bind_method(D_METHOD("randf"), &RandomNumberGenerator::randf); @@ -41,4 +40,8 @@ void RandomNumberGenerator::_bind_methods() { ClassDB::bind_method(D_METHOD("randf_range", "from", "to"), &RandomNumberGenerator::randf_range); ClassDB::bind_method(D_METHOD("randi_range", "from", "to"), &RandomNumberGenerator::randi_range); ClassDB::bind_method(D_METHOD("randomize"), &RandomNumberGenerator::randomize); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed"); + // Default value is non-deterministic, override it for doc generation purposes. + ADD_PROPERTY_DEFAULT("seed", 0); } diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h index 2e7941b345..0d0ea17205 100644 --- a/core/math/random_number_generator.h +++ b/core/math/random_number_generator.h @@ -32,7 +32,7 @@ #define RANDOM_NUMBER_GENERATOR_H #include "core/math/random_pcg.h" -#include "core/reference.h" +#include "core/object/reference.h" class RandomNumberGenerator : public Reference { GDCLASS(RandomNumberGenerator, Reference); @@ -43,7 +43,7 @@ protected: static void _bind_methods(); public: - _FORCE_INLINE_ void set_seed(uint64_t seed) { randbase.seed(seed); } + _FORCE_INLINE_ void set_seed(uint64_t p_seed) { randbase.seed(p_seed); } _FORCE_INLINE_ uint64_t get_seed() { return randbase.get_seed(); } @@ -53,24 +53,11 @@ public: _FORCE_INLINE_ real_t randf() { return randbase.randf(); } - _FORCE_INLINE_ real_t randf_range(real_t from, real_t to) { return randbase.random(from, to); } + _FORCE_INLINE_ real_t randf_range(real_t p_from, real_t p_to) { return randbase.random(p_from, p_to); } - _FORCE_INLINE_ real_t randfn(real_t mean = 0.0, real_t deviation = 1.0) { return randbase.randfn(mean, deviation); } + _FORCE_INLINE_ real_t randfn(real_t p_mean = 0.0, real_t p_deviation = 1.0) { return randbase.randfn(p_mean, p_deviation); } - _FORCE_INLINE_ int randi_range(int from, int to) { - int range; - int min; - if (to > from) { - range = to - from + 1; - min = from; - } else if (to < from) { - range = from - to + 1; - min = to; - } else { // from == to - return from; - } - return randbase.rand(range) + min; - } + _FORCE_INLINE_ int randi_range(int p_from, int p_to) { return randbase.random(p_from, p_to); } RandomNumberGenerator() {} }; diff --git a/core/math/random_pcg.cpp b/core/math/random_pcg.cpp index 02257c38d9..e0768b9403 100644 --- a/core/math/random_pcg.cpp +++ b/core/math/random_pcg.cpp @@ -49,3 +49,18 @@ double RandomPCG::random(double p_from, double p_to) { float RandomPCG::random(float p_from, float p_to) { return randf() * (p_to - p_from) + p_from; } + +int RandomPCG::random(int p_from, int p_to) { + int range; + int min; + if (p_to > p_from) { + range = p_to - p_from + 1; + min = p_from; + } else if (p_to < p_from) { + range = p_from - p_to + 1; + min = p_to; + } else { // from == to + return p_from; + } + return rand(range) + min; +} diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index dfdae53eed..fe6b1b5639 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -133,7 +133,7 @@ public: double random(double p_from, double p_to); float random(float p_from, float p_to); - real_t random(int p_from, int p_to) { return (real_t)random((real_t)p_from, (real_t)p_to); } + int random(int p_from, int p_to); }; #endif // RANDOM_PCG_H diff --git a/core/math/rect2.h b/core/math/rect2.h index 7660db71eb..b1fe865ba5 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -244,6 +244,77 @@ struct Rect2 { return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); } + Vector2 get_support(const Vector2 &p_normal) const { + Vector2 half_extents = size * 0.5; + Vector2 ofs = position + half_extents; + return Vector2( + (p_normal.x > 0) ? -half_extents.x : half_extents.x, + (p_normal.y > 0) ? -half_extents.y : half_extents.y) + + ofs; + } + + _FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const { + Vector2 center = position + size * 0.5; + int side_plus = 0; + int side_minus = 0; + Vector2 end = position + size; + + int i_f = p_point_count - 1; + for (int i = 0; i < p_point_count; i++) { + const Vector2 &a = p_points[i_f]; + const Vector2 &b = p_points[i]; + i_f = i; + + Vector2 r = (b - a); + float l = r.length(); + if (l == 0.0) { + continue; + } + + //check inside + Vector2 tg = r.tangent(); + float s = tg.dot(center) - tg.dot(a); + if (s < 0.0) { + side_plus++; + } else { + side_minus++; + } + + //check ray box + r /= l; + Vector2 ir(1.0 / r.x, 1.0 / r.y); + + // lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner + // r.org is origin of ray + Vector2 t13 = (position - a) * ir; + Vector2 t24 = (end - a) * ir; + + float tmin = MAX(MIN(t13.x, t24.x), MIN(t13.y, t24.y)); + float tmax = MIN(MAX(t13.x, t24.x), MAX(t13.y, t24.y)); + + // if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us + if (tmax < 0 || tmin > tmax || tmin >= l) { + continue; + } + + return true; + } + + if (side_plus * side_minus == 0) { + return true; //all inside + } else { + return false; + } + } + + _FORCE_INLINE_ void set_end(const Vector2 &p_end) { + size = p_end - position; + } + + _FORCE_INLINE_ Vector2 get_end() const { + return position + size; + } + operator String() const { return String(position) + ", " + String(size); } Rect2() {} @@ -305,8 +376,8 @@ struct Rect2i { new_rect.position.x = MAX(p_rect.position.x, position.x); new_rect.position.y = MAX(p_rect.position.y, position.y); - Point2 p_rect_end = p_rect.position + p_rect.size; - Point2 end = position + size; + Point2i p_rect_end = p_rect.position + p_rect.size; + Point2i end = position + size; new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x); new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y); @@ -328,7 +399,7 @@ struct Rect2i { return new_rect; } - bool has_point(const Point2 &p_point) const { + bool has_point(const Point2i &p_point) const { if (p_point.x < position.x) { return false; } @@ -413,6 +484,14 @@ struct Rect2i { return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); } + _FORCE_INLINE_ void set_end(const Vector2i &p_end) { + size = p_end - position; + } + + _FORCE_INLINE_ Vector2i get_end() const { + return position + size; + } + operator String() const { return String(position) + ", " + String(size); } operator Rect2() const { return Rect2(position, size); } @@ -423,10 +502,10 @@ struct Rect2i { size(p_r2.size) { } Rect2i(int p_x, int p_y, int p_width, int p_height) : - position(Point2(p_x, p_y)), - size(Size2(p_width, p_height)) { + position(Point2i(p_x, p_y)), + size(Size2i(p_width, p_height)) { } - Rect2i(const Point2 &p_pos, const Size2 &p_size) : + Rect2i(const Point2i &p_pos, const Size2i &p_size) : position(p_pos), size(p_size) { } diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 0274dd18af..733bb4d55e 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -32,7 +32,7 @@ #include "core/math/math_funcs.h" #include "core/os/copymem.h" -#include "core/print_string.h" +#include "core/string/print_string.h" void Transform::affine_invert() { basis.invert(); @@ -200,6 +200,13 @@ Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) : origin(p_origin) { } +Transform::Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) : + origin(p_origin) { + basis.set_axis(0, p_x); + basis.set_axis(1, p_y); + basis.set_axis(2, p_z); +} + Transform::Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) { basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz); origin = Vector3(ox, oy, oz); diff --git a/core/math/transform.h b/core/math/transform.h index 71847d36ac..c63dbcb989 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -106,9 +106,10 @@ public: operator String() const; - Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz); - Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3()); Transform() {} + Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3()); + Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin); + Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz); }; _FORCE_INLINE_ Vector3 Transform::xform(const Vector3 &p_vector) const { diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 180aeaa0af..00e561f973 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -251,7 +251,7 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t real_t dot = v1.dot(v2); - dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1] + dot = CLAMP(dot, -1.0, 1.0); Vector2 v; diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 46e97abaa7..342623939e 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -128,6 +128,12 @@ struct Transform2D { elements[2][1] = oy; } + Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) { + elements[0] = p_x; + elements[1] = p_y; + elements[2] = p_origin; + } + Transform2D(real_t p_rot, const Vector2 &p_pos); Transform2D() { elements[0][0] = 1.0; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index c9a546e385..cfe8422d80 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -30,7 +30,7 @@ #include "triangle_mesh.h" -#include "core/sort_array.h" +#include "core/templates/sort_array.h" int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) { if (p_depth > max_depth) { diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 86412cf725..d719822ec3 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -32,7 +32,7 @@ #define TRIANGLE_MESH_H #include "core/math/face3.h" -#include "core/reference.h" +#include "core/object/reference.h" class TriangleMesh : public Reference { GDCLASS(TriangleMesh, Reference); diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 233421e070..75e742a5f1 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -233,6 +233,19 @@ void Vector2i::operator/=(const int &rvalue) { y /= rvalue; } +Vector2i Vector2i::operator%(const Vector2i &p_v1) const { + return Vector2i(x % p_v1.x, y % p_v1.y); +} + +Vector2i Vector2i::operator%(const int &rvalue) const { + return Vector2i(x % rvalue, y % rvalue); +} + +void Vector2i::operator%=(const int &rvalue) { + x %= rvalue; + y %= rvalue; +} + Vector2i Vector2i::operator-() const { return Vector2i(-x, -y); } diff --git a/core/math/vector2.h b/core/math/vector2.h index c2a2656e72..8cb63b2fb5 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -32,7 +32,7 @@ #define VECTOR2_H #include "core/math/math_funcs.h" -#include "core/ustring.h" +#include "core/string/ustring.h" struct Vector2i; @@ -290,11 +290,13 @@ struct Vector2i { void operator*=(const int &rvalue); Vector2i operator/(const Vector2i &p_v1) const; - Vector2i operator/(const int &rvalue) const; - void operator/=(const int &rvalue); + Vector2i operator%(const Vector2i &p_v1) const; + Vector2i operator%(const int &rvalue) const; + void operator%=(const int &rvalue); + Vector2i operator-() const; bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } diff --git a/core/math/vector3.h b/core/math/vector3.h index 5370b297f1..ae8b9376cf 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -33,7 +33,7 @@ #include "core/math/math_funcs.h" #include "core/math/vector3i.h" -#include "core/ustring.h" +#include "core/string/ustring.h" class Basis; diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 08729ad056..1bfd6d5ab2 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -31,8 +31,8 @@ #ifndef VECTOR3I_H #define VECTOR3I_H +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" struct Vector3i { enum Axis { @@ -80,11 +80,15 @@ struct Vector3i { _FORCE_INLINE_ Vector3i operator*(const Vector3i &p_v) const; _FORCE_INLINE_ Vector3i &operator/=(const Vector3i &p_v); _FORCE_INLINE_ Vector3i operator/(const Vector3i &p_v) const; + _FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v); + _FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const; _FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar); _FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const; _FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar); _FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const; + _FORCE_INLINE_ Vector3i &operator%=(int32_t p_scalar); + _FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const; _FORCE_INLINE_ Vector3i operator-() const; @@ -159,6 +163,17 @@ Vector3i Vector3i::operator/(const Vector3i &p_v) const { return Vector3i(x / p_v.x, y / p_v.y, z / p_v.z); } +Vector3i &Vector3i::operator%=(const Vector3i &p_v) { + x %= p_v.x; + y %= p_v.y; + z %= p_v.z; + return *this; +} + +Vector3i Vector3i::operator%(const Vector3i &p_v) const { + return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z); +} + Vector3i &Vector3i::operator*=(int32_t p_scalar) { x *= p_scalar; y *= p_scalar; @@ -185,6 +200,17 @@ Vector3i Vector3i::operator/(int32_t p_scalar) const { return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar); } +Vector3i &Vector3i::operator%=(int32_t p_scalar) { + x %= p_scalar; + y %= p_scalar; + z %= p_scalar; + return *this; +} + +Vector3i Vector3i::operator%(int32_t p_scalar) const { + return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar); +} + Vector3i Vector3i::operator-() const { return Vector3i(-x, -y, -z); } diff --git a/core/object/SCsub b/core/object/SCsub new file mode 100644 index 0000000000..5d429960e5 --- /dev/null +++ b/core/object/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import("env") + +env_object = env.Clone() + +env_object.add_source_files(env.core_sources, "*.cpp") diff --git a/core/callable_method_pointer.cpp b/core/object/callable_method_pointer.cpp index 21a917cbd7..21a917cbd7 100644 --- a/core/callable_method_pointer.cpp +++ b/core/object/callable_method_pointer.cpp diff --git a/core/callable_method_pointer.h b/core/object/callable_method_pointer.h index 2007b9f338..ee6da6a8db 100644 --- a/core/callable_method_pointer.h +++ b/core/object/callable_method_pointer.h @@ -31,12 +31,12 @@ #ifndef CALLABLE_METHOD_POINTER_H #define CALLABLE_METHOD_POINTER_H -#include "core/binder_common.h" -#include "core/callable.h" -#include "core/hashfuncs.h" -#include "core/object.h" +#include "core/object/object.h" #include "core/os/copymem.h" -#include "core/simple_type.h" +#include "core/templates/hashfuncs.h" +#include "core/templates/simple_type.h" +#include "core/variant/binder_common.h" +#include "core/variant/callable.h" class CallableCustomMethodPointerBase : public CallableCustom { uint32_t *comp_ptr; diff --git a/core/class_db.cpp b/core/object/class_db.cpp index ad85cd0d62..64ebeb427e 100644 --- a/core/class_db.cpp +++ b/core/object/class_db.cpp @@ -30,7 +30,7 @@ #include "class_db.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/os/mutex.h" #include "core/version.h" @@ -242,21 +242,25 @@ HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes; HashMap<StringName, StringName> ClassDB::resource_base_extensions; HashMap<StringName, StringName> ClassDB::compat_classes; -bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) { - OBJTYPE_RLOCK; - +bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_inherits) { StringName inherits = p_class; while (inherits.operator String().length()) { if (inherits == p_inherits) { return true; } - inherits = get_parent_class(inherits); + inherits = _get_parent_class(inherits); } return false; } +bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) { + OBJTYPE_RLOCK; + + return _is_parent_class(p_class, p_inherits); +} + void ClassDB::get_class_list(List<StringName> *p_classes) { OBJTYPE_RLOCK; @@ -275,7 +279,7 @@ void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringNa const StringName *k = nullptr; while ((k = classes.next(k))) { - if (*k != p_class && is_parent_class(*k, p_class)) { + if (*k != p_class && _is_parent_class(*k, p_class)) { p_classes->push_back(*k); } } @@ -287,7 +291,7 @@ void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<S const StringName *k = nullptr; while ((k = classes.next(k))) { - if (*k != p_class && get_parent_class(*k) == p_class) { + if (*k != p_class && _get_parent_class(*k) == p_class) { p_classes->push_back(*k); } } @@ -315,14 +319,18 @@ StringName ClassDB::get_compatibility_remapped_class(const StringName &p_class) return p_class; } -StringName ClassDB::get_parent_class(const StringName &p_class) { - OBJTYPE_RLOCK; - +StringName ClassDB::_get_parent_class(const StringName &p_class) { ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_COND_V_MSG(!ti, StringName(), "Cannot get class '" + String(p_class) + "'."); return ti->inherits; } +StringName ClassDB::get_parent_class(const StringName &p_class) { + OBJTYPE_RLOCK; + + return _get_parent_class(p_class); +} + ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) { OBJTYPE_RLOCK; diff --git a/core/class_db.h b/core/object/class_db.h index 4734b06c7a..94f26da60d 100644 --- a/core/class_db.h +++ b/core/object/class_db.h @@ -31,9 +31,9 @@ #ifndef CLASS_DB_H #define CLASS_DB_H -#include "core/method_bind.h" -#include "core/object.h" -#include "core/print_string.h" +#include "core/object/method_bind.h" +#include "core/object/object.h" +#include "core/string/print_string.h" /** To bind more then 6 parameters include this: * @@ -41,7 +41,7 @@ // Makes callable_mp readily available in all classes connecting signals. // Needs to come after method_bind and object have been included. -#include "core/callable_method_pointer.h" +#include "core/object/callable_method_pointer.h" #define DEFVAL(m_defval) (m_defval) @@ -164,6 +164,11 @@ public: static HashMap<StringName, HashMap<StringName, Variant>> default_values; static Set<StringName> default_values_cached; +private: + // Non-locking variants of get_parent_class and is_parent_class. + static StringName _get_parent_class(const StringName &p_class); + static bool _is_parent_class(const StringName &p_class, const StringName &p_inherits); + public: // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! template <class T> diff --git a/core/message_queue.cpp b/core/object/message_queue.cpp index 6dcf24e7ed..f0d6786853 100644 --- a/core/message_queue.cpp +++ b/core/object/message_queue.cpp @@ -30,9 +30,9 @@ #include "message_queue.h" +#include "core/config/project_settings.h" #include "core/core_string_names.h" -#include "core/project_settings.h" -#include "core/script_language.h" +#include "core/object/script_language.h" MessageQueue *MessageQueue::singleton = nullptr; diff --git a/core/message_queue.h b/core/object/message_queue.h index 5d39ceee03..2901ab196a 100644 --- a/core/message_queue.h +++ b/core/object/message_queue.h @@ -31,7 +31,7 @@ #ifndef MESSAGE_QUEUE_H #define MESSAGE_QUEUE_H -#include "core/class_db.h" +#include "core/object/class_db.h" #include "core/os/thread_safe.h" class MessageQueue { diff --git a/core/method_bind.cpp b/core/object/method_bind.cpp index 3244c63292..e6652ac09f 100644 --- a/core/method_bind.cpp +++ b/core/object/method_bind.cpp @@ -30,7 +30,7 @@ // object.h needs to be the first include *before* method_bind.h // FIXME: Find out why and fix potential cyclical dependencies. -#include "core/object.h" +#include "core/object/object.h" #include "method_bind.h" diff --git a/core/method_bind.h b/core/object/method_bind.h index d43186257b..ab4ba90b94 100644 --- a/core/method_bind.h +++ b/core/object/method_bind.h @@ -31,7 +31,7 @@ #ifndef METHOD_BIND_H #define METHOD_BIND_H -#include "core/binder_common.h" +#include "core/variant/binder_common.h" enum MethodFlags { diff --git a/core/object.cpp b/core/object/object.cpp index 0d9e5c5116..c3f49856ca 100644 --- a/core/object.cpp +++ b/core/object/object.cpp @@ -30,14 +30,14 @@ #include "object.h" -#include "core/class_db.h" #include "core/core_string_names.h" -#include "core/message_queue.h" +#include "core/io/resource.h" +#include "core/object/class_db.h" +#include "core/object/message_queue.h" +#include "core/object/script_language.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/resource.h" -#include "core/script_language.h" -#include "core/translation.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" #ifdef DEBUG_ENABLED @@ -421,17 +421,6 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid return; } - { - bool valid; - setvar(p_name, p_value, &valid); - if (valid) { - if (r_valid) { - *r_valid = true; - } - return; - } - } - #ifdef TOOLS_ENABLED if (script_instance) { bool valid; @@ -496,18 +485,6 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { return ret; } - //if nothing else, use getvar - { - bool valid; - ret = getvar(p_name, &valid); - if (valid) { - if (r_valid) { - *r_valid = true; - } - return ret; - } - } - #ifdef TOOLS_ENABLED if (script_instance) { bool valid; @@ -555,9 +532,12 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val } for (int i = 1; i < p_names.size() - 1; i++) { - value_stack.push_back(value_stack.back()->get().get_named(p_names[i], r_valid)); + value_stack.push_back(value_stack.back()->get().get_named(p_names[i], valid)); + if (r_valid) { + *r_valid = valid; + } - if (!*r_valid) { + if (!valid) { value_stack.clear(); return; } @@ -566,10 +546,13 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val value_stack.push_back(p_value); // p_names[p_names.size() - 1] for (int i = p_names.size() - 1; i > 0; i--) { - value_stack.back()->prev()->get().set_named(p_names[i], value_stack.back()->get(), r_valid); + value_stack.back()->prev()->get().set_named(p_names[i], value_stack.back()->get(), valid); value_stack.pop_back(); - if (!*r_valid) { + if (r_valid) { + *r_valid = valid; + } + if (!valid) { value_stack.clear(); return; } @@ -592,7 +575,7 @@ Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) co Variant current_value = get(p_names[0], &valid); for (int i = 1; i < p_names.size(); i++) { - current_value = current_value.get_named(p_names[i], &valid); + current_value = current_value.get_named(p_names[i], valid); if (!valid) { break; @@ -698,6 +681,10 @@ Variant Object::getvar(const Variant &p_key, bool *r_valid) const { if (r_valid) { *r_valid = false; } + + if (p_key.get_type() == Variant::STRING_NAME || p_key.get_type() == Variant::STRING) { + return get(p_key, r_valid); + } return Variant(); } @@ -705,6 +692,9 @@ void Object::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid) if (r_valid) { *r_valid = false; } + if (p_key.get_type() == Variant::STRING_NAME || p_key.get_type() == Variant::STRING) { + return set(p_key, p_value, r_valid); + } } Variant Object::callv(const StringName &p_method, const Array &p_args) { @@ -1700,7 +1690,8 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName> } Callable::CallError ce; - Variant check = Variant::construct(t, nullptr, 0, ce); + Variant check; + Variant::construct(t, check, nullptr, 0, ce); for (int i = 1; i < p_path.size(); i++) { if (check.get_type() == Variant::OBJECT || check.get_type() == Variant::DICTIONARY || check.get_type() == Variant::ARRAY) { @@ -1711,7 +1702,7 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName> return Variant::NIL; } - check = check.get_named(p_path[i], &valid); + check = check.get_named(p_path[i], valid); if (!valid) { if (r_valid) { diff --git a/core/object.h b/core/object/object.h index 765fb63c6e..c79745cf74 100644 --- a/core/object.h +++ b/core/object/object.h @@ -31,16 +31,16 @@ #ifndef OBJECT_H #define OBJECT_H -#include "core/callable_bind.h" -#include "core/hash_map.h" -#include "core/list.h" -#include "core/map.h" -#include "core/object_id.h" +#include "core/object/object_id.h" #include "core/os/rw_lock.h" -#include "core/set.h" -#include "core/spin_lock.h" -#include "core/variant.h" -#include "core/vmap.h" +#include "core/os/spin_lock.h" +#include "core/templates/hash_map.h" +#include "core/templates/list.h" +#include "core/templates/map.h" +#include "core/templates/set.h" +#include "core/templates/vmap.h" +#include "core/variant/callable_bind.h" +#include "core/variant/variant.h" #define VARIANT_ARG_LIST const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant() #define VARIANT_ARG_PASS p_arg1, p_arg2, p_arg3, p_arg4, p_arg5 diff --git a/core/object_id.h b/core/object/object_id.h index 63b0c27af8..63b0c27af8 100644 --- a/core/object_id.h +++ b/core/object/object_id.h diff --git a/core/reference.cpp b/core/object/reference.cpp index d1dba0d9bf..ce95d83dfc 100644 --- a/core/reference.cpp +++ b/core/object/reference.cpp @@ -30,7 +30,7 @@ #include "reference.h" -#include "core/script_language.h" +#include "core/object/script_language.h" bool Reference::init_ref() { if (reference()) { diff --git a/core/reference.h b/core/object/reference.h index 868894aad4..575f1cd914 100644 --- a/core/reference.h +++ b/core/object/reference.h @@ -31,8 +31,8 @@ #ifndef REFERENCE_H #define REFERENCE_H -#include "core/class_db.h" -#include "core/safe_refcount.h" +#include "core/object/class_db.h" +#include "core/templates/safe_refcount.h" class Reference : public Object { GDCLASS(Reference, Object); diff --git a/core/script_language.cpp b/core/object/script_language.cpp index d535c54dea..17ac75e19f 100644 --- a/core/script_language.cpp +++ b/core/object/script_language.cpp @@ -30,10 +30,10 @@ #include "script_language.h" +#include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" -#include "core/project_settings.h" #include <stdint.h> diff --git a/core/script_language.h b/core/object/script_language.h index a94c128932..447216f14f 100644 --- a/core/script_language.h +++ b/core/object/script_language.h @@ -32,9 +32,9 @@ #define SCRIPT_LANGUAGE_H #include "core/io/multiplayer_api.h" -#include "core/map.h" -#include "core/pair.h" -#include "core/resource.h" +#include "core/io/resource.h" +#include "core/templates/map.h" +#include "core/templates/pair.h" class ScriptLanguage; diff --git a/core/undo_redo.cpp b/core/object/undo_redo.cpp index 1dcbb0cd6b..1dcbb0cd6b 100644 --- a/core/undo_redo.cpp +++ b/core/object/undo_redo.cpp diff --git a/core/undo_redo.h b/core/object/undo_redo.h index 68a553efd4..68d78e0d7d 100644 --- a/core/undo_redo.h +++ b/core/object/undo_redo.h @@ -31,8 +31,8 @@ #ifndef UNDO_REDO_H #define UNDO_REDO_H -#include "core/class_db.h" -#include "core/resource.h" +#include "core/io/resource.h" +#include "core/object/class_db.h" class UndoRedo : public Object { GDCLASS(UndoRedo, Object); diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 5e1cb8ea29..30b1b51b53 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -30,10 +30,10 @@ #include "dir_access.h" +#include "core/config/project_settings.h" #include "core/os/file_access.h" #include "core/os/memory.h" #include "core/os/os.h" -#include "core/project_settings.h" String DirAccess::_get_root_path() const { switch (_access_type) { diff --git a/core/os/dir_access.h b/core/os/dir_access.h index 6bce9a4c12..0f4fa9b250 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -31,8 +31,8 @@ #ifndef DIR_ACCESS_H #define DIR_ACCESS_H +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" //@ TODO, excellent candidate for THREAD_SAFE MACRO, should go through all these and add THREAD_SAFE where it applies class DirAccess { diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index 9dbb2952f7..fd3c6f8806 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -30,11 +30,11 @@ #include "file_access.h" +#include "core/config/project_settings.h" #include "core/crypto/crypto_core.h" #include "core/io/file_access_pack.h" #include "core/io/marshalls.h" #include "core/os/os.h" -#include "core/project_settings.h" FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { nullptr, nullptr }; @@ -51,7 +51,7 @@ FileAccess *FileAccess::create(AccessType p_access) { } bool FileAccess::exists(const String &p_name) { - if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_name)) { return true; } @@ -456,7 +456,7 @@ void FileAccess::store_double(double p_dest) { } uint64_t FileAccess::get_modified_time(const String &p_file) { - if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { return 0; } @@ -469,7 +469,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) { } uint32_t FileAccess::get_unix_permissions(const String &p_file) { - if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { return 0; } @@ -482,6 +482,10 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) { } Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { + return ERR_UNAVAILABLE; + } + FileAccess *fa = create_for_path(p_file); ERR_FAIL_COND_V_MSG(!fa, ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); diff --git a/core/os/file_access.h b/core/os/file_access.h index 48b9ee4269..39b977a4d9 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -33,8 +33,8 @@ #include "core/math/math_defs.h" #include "core/os/memory.h" +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" /** * Multi-Platform abstraction for accessing to files. diff --git a/core/os/keyboard.h b/core/os/keyboard.h index 5d11e6a378..92664aff8f 100644 --- a/core/os/keyboard.h +++ b/core/os/keyboard.h @@ -31,7 +31,7 @@ #ifndef KEYBOARD_H #define KEYBOARD_H -#include "core/ustring.h" +#include "core/string/ustring.h" /* Special Key: diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index 434f6fa300..d29bcd011f 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -30,14 +30,9 @@ #include "main_loop.h" -#include "core/script_language.h" +#include "core/object/script_language.h" void MainLoop::_bind_methods() { - ClassDB::bind_method(D_METHOD("init"), &MainLoop::init); - ClassDB::bind_method(D_METHOD("iteration", "delta"), &MainLoop::iteration); - ClassDB::bind_method(D_METHOD("idle", "delta"), &MainLoop::idle); - ClassDB::bind_method(D_METHOD("finish"), &MainLoop::finish); - BIND_VMETHOD(MethodInfo("_initialize")); BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::FLOAT, "delta"))); diff --git a/core/os/main_loop.h b/core/os/main_loop.h index 2c34cf193c..8c46ad9b6a 100644 --- a/core/os/main_loop.h +++ b/core/os/main_loop.h @@ -32,8 +32,8 @@ #define MAIN_LOOP_H #include "core/input/input_event.h" -#include "core/reference.h" -#include "core/script_language.h" +#include "core/object/reference.h" +#include "core/object/script_language.h" class MainLoop : public Object { GDCLASS(MainLoop, Object); diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 8457c52092..f2723d13f6 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -30,9 +30,9 @@ #include "memory.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/copymem.h" -#include "core/safe_refcount.h" +#include "core/templates/safe_refcount.h" #include <stdio.h> #include <stdlib.h> diff --git a/core/os/memory.h b/core/os/memory.h index 46ffb4124b..dee08d4de4 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -31,8 +31,8 @@ #ifndef MEMORY_H #define MEMORY_H -#include "core/error_macros.h" -#include "core/safe_refcount.h" +#include "core/error/error_macros.h" +#include "core/templates/safe_refcount.h" #include <stddef.h> diff --git a/core/os/midi_driver.h b/core/os/midi_driver.h index bc922e1fcf..f487b31d4c 100644 --- a/core/os/midi_driver.h +++ b/core/os/midi_driver.h @@ -32,7 +32,7 @@ #define MIDI_DRIVER_H #include "core/typedefs.h" -#include "core/variant.h" +#include "core/variant/variant.h" /** * Multi-Platform abstraction for accessing to MIDI. diff --git a/core/os/mutex.h b/core/os/mutex.h index d42cbed821..778bdaba09 100644 --- a/core/os/mutex.h +++ b/core/os/mutex.h @@ -31,7 +31,7 @@ #ifndef MUTEX_H #define MUTEX_H -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/typedefs.h" #if !defined(NO_THREADS) diff --git a/core/os/os.cpp b/core/os/os.cpp index 3a398316bd..552bf043bf 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -30,11 +30,11 @@ #include "os.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/midi_driver.h" -#include "core/project_settings.h" #include "core/version_generated.gen.h" #include "servers/audio_server.h" diff --git a/core/os/os.h b/core/os/os.h index 4c1d930107..a1e75b5ee9 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -31,13 +31,13 @@ #ifndef OS_H #define OS_H -#include "core/engine.h" -#include "core/image.h" +#include "core/config/engine.h" +#include "core/io/image.h" #include "core/io/logger.h" -#include "core/list.h" #include "core/os/main_loop.h" -#include "core/ustring.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/list.h" +#include "core/templates/vector.h" #include <stdarg.h> diff --git a/core/pool_allocator.cpp b/core/os/pool_allocator.cpp index b222c20a00..52536ff45d 100644 --- a/core/pool_allocator.cpp +++ b/core/os/pool_allocator.cpp @@ -30,11 +30,11 @@ #include "pool_allocator.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/copymem.h" #include "core/os/memory.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <assert.h> diff --git a/core/pool_allocator.h b/core/os/pool_allocator.h index 7d77af6266..7d77af6266 100644 --- a/core/pool_allocator.h +++ b/core/os/pool_allocator.h diff --git a/core/os/rw_lock.cpp b/core/os/rw_lock.cpp index a668fe2b4c..669f05c6b0 100644 --- a/core/os/rw_lock.cpp +++ b/core/os/rw_lock.cpp @@ -30,7 +30,7 @@ #include "rw_lock.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include <stddef.h> diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h index 1035072cce..1190102a83 100644 --- a/core/os/rw_lock.h +++ b/core/os/rw_lock.h @@ -31,7 +31,7 @@ #ifndef RW_LOCK_H #define RW_LOCK_H -#include "core/error_list.h" +#include "core/error/error_list.h" class RWLock { protected: diff --git a/core/os/semaphore.h b/core/os/semaphore.h index 077e04704b..b170cada3a 100644 --- a/core/os/semaphore.h +++ b/core/os/semaphore.h @@ -31,7 +31,7 @@ #ifndef SEMAPHORE_H #define SEMAPHORE_H -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/typedefs.h" #if !defined(NO_THREADS) diff --git a/core/spin_lock.h b/core/os/spin_lock.h index 1bb810bb29..1bb810bb29 100644 --- a/core/spin_lock.h +++ b/core/os/spin_lock.h diff --git a/core/os/thread.h b/core/os/thread.h index f761d4ca43..d68476e683 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -31,8 +31,8 @@ #ifndef THREAD_H #define THREAD_H +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" typedef void (*ThreadCreateCallback)(void *p_userdata); diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h index d27399e4cc..ed141a5339 100644 --- a/core/os/threaded_array_processor.h +++ b/core/os/threaded_array_processor.h @@ -35,7 +35,7 @@ #include "core/os/os.h" #include "core/os/thread.h" #include "core/os/thread_safe.h" -#include "core/safe_refcount.h" +#include "core/templates/safe_refcount.h" template <class C, class U> struct ThreadArrayProcessData { diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index a2b3f75bea..7e32f215e7 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -30,24 +30,24 @@ #include "register_core_types.h" -#include "core/bind/core_bind.h" -#include "core/class_db.h" -#include "core/compressed_translation.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/core_bind.h" #include "core/core_string_names.h" #include "core/crypto/aes_context.h" #include "core/crypto/crypto.h" #include "core/crypto/hashing_context.h" -#include "core/engine.h" -#include "core/func_ref.h" #include "core/input/input.h" #include "core/input/input_map.h" #include "core/io/config_file.h" #include "core/io/dtls_server.h" #include "core/io/http_client.h" #include "core/io/image_loader.h" +#include "core/io/json.h" #include "core/io/marshalls.h" #include "core/io/multiplayer_api.h" #include "core/io/networked_multiplayer_peer.h" +#include "core/io/packed_data_container.h" #include "core/io/packet_peer.h" #include "core/io/packet_peer_dtls.h" #include "core/io/packet_peer_udp.h" @@ -65,11 +65,11 @@ #include "core/math/geometry_3d.h" #include "core/math/random_number_generator.h" #include "core/math/triangle_mesh.h" +#include "core/object/class_db.h" +#include "core/object/undo_redo.h" #include "core/os/main_loop.h" -#include "core/packed_data_container.h" -#include "core/project_settings.h" -#include "core/translation.h" -#include "core/undo_redo.h" +#include "core/string/compressed_translation.h" +#include "core/string/translation.h" static Ref<ResourceFormatSaverBinary> resource_saver_binary; static Ref<ResourceFormatLoaderBinary> resource_loader_binary; @@ -97,8 +97,6 @@ extern Mutex _global_mutex; extern void register_global_constants(); extern void unregister_global_constants(); -extern void register_variant_methods(); -extern void unregister_variant_methods(); void register_core_types() { //consistency check @@ -111,7 +109,8 @@ void register_core_types() { ResourceLoader::initialize(); register_global_constants(); - register_variant_methods(); + + Variant::register_types(); CoreStringNames::create(); @@ -155,7 +154,6 @@ void register_core_types() { ClassDB::register_class<InputEventPanGesture>(); ClassDB::register_class<InputEventMIDI>(); - ClassDB::register_class<FuncRef>(); ClassDB::register_virtual_class<StreamPeer>(); ClassDB::register_class<StreamPeerBuffer>(); ClassDB::register_class<StreamPeerTCP>(); @@ -200,6 +198,7 @@ void register_core_types() { ClassDB::register_class<_Semaphore>(); ClassDB::register_class<XMLParser>(); + ClassDB::register_class<JSONParser>(); ClassDB::register_class<ConfigFile>(); @@ -319,7 +318,8 @@ void unregister_core_types() { ClassDB::cleanup_defaults(); ObjectDB::cleanup(); - unregister_variant_methods(); + Variant::unregister_types(); + unregister_global_constants(); ClassDB::cleanup(); diff --git a/core/string/SCsub b/core/string/SCsub new file mode 100644 index 0000000000..3217166f18 --- /dev/null +++ b/core/string/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import("env") + +env_string = env.Clone() + +env_string.add_source_files(env.core_sources, "*.cpp") diff --git a/core/compressed_translation.cpp b/core/string/compressed_translation.cpp index a92275565d..bdb296a79b 100644 --- a/core/compressed_translation.cpp +++ b/core/string/compressed_translation.cpp @@ -30,7 +30,7 @@ #include "compressed_translation.h" -#include "core/pair.h" +#include "core/templates/pair.h" extern "C" { #include "thirdparty/misc/smaz.h" diff --git a/core/compressed_translation.h b/core/string/compressed_translation.h index c8b3cd2330..efb3535362 100644 --- a/core/compressed_translation.h +++ b/core/string/compressed_translation.h @@ -31,7 +31,7 @@ #ifndef COMPRESSED_TRANSLATION_H #define COMPRESSED_TRANSLATION_H -#include "core/translation.h" +#include "core/string/translation.h" class PHashTranslation : public Translation { GDCLASS(PHashTranslation, Translation); diff --git a/core/node_path.cpp b/core/string/node_path.cpp index 2a51dca74a..4d152d9258 100644 --- a/core/node_path.cpp +++ b/core/string/node_path.cpp @@ -30,7 +30,7 @@ #include "node_path.h" -#include "core/print_string.h" +#include "core/string/print_string.h" void NodePath::_update_hash_cache() const { uint32_t h = data->absolute ? 1 : 0; diff --git a/core/node_path.h b/core/string/node_path.h index 7c06bf01ce..b4513ddb3c 100644 --- a/core/node_path.h +++ b/core/string/node_path.h @@ -31,8 +31,8 @@ #ifndef NODE_PATH_H #define NODE_PATH_H -#include "core/string_name.h" -#include "core/ustring.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" class NodePath { struct Data { diff --git a/core/print_string.cpp b/core/string/print_string.cpp index 54de229471..54de229471 100644 --- a/core/print_string.cpp +++ b/core/string/print_string.cpp diff --git a/core/print_string.h b/core/string/print_string.h index 4d03f4a6de..3e8f244cc5 100644 --- a/core/print_string.h +++ b/core/string/print_string.h @@ -31,7 +31,7 @@ #ifndef PRINT_STRING_H #define PRINT_STRING_H -#include "core/ustring.h" +#include "core/string/ustring.h" extern void (*_print_func)(String); diff --git a/core/string_buffer.h b/core/string/string_buffer.h index a685720851..1317b538d4 100644 --- a/core/string_buffer.h +++ b/core/string/string_buffer.h @@ -31,7 +31,7 @@ #ifndef STRING_BUFFER_H #define STRING_BUFFER_H -#include "core/ustring.h" +#include "core/string/ustring.h" template <int SHORT_BUFFER_SIZE = 64> class StringBuffer { diff --git a/core/string_builder.cpp b/core/string/string_builder.cpp index dec299ffa3..dec299ffa3 100644 --- a/core/string_builder.cpp +++ b/core/string/string_builder.cpp diff --git a/core/string_builder.h b/core/string/string_builder.h index 2a37d14218..c732f1b9ea 100644 --- a/core/string_builder.h +++ b/core/string/string_builder.h @@ -31,8 +31,8 @@ #ifndef STRING_BUILDER_H #define STRING_BUILDER_H -#include "core/ustring.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/vector.h" class StringBuilder { uint32_t string_length = 0; diff --git a/core/string_name.cpp b/core/string/string_name.cpp index 6260e3ce8c..34afdaee38 100644 --- a/core/string_name.cpp +++ b/core/string/string_name.cpp @@ -31,7 +31,7 @@ #include "string_name.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" StaticCString StaticCString::create(const char *p_ptr) { StaticCString scs; @@ -377,3 +377,17 @@ StringName StringName::search(const String &p_name) { StringName::~StringName() { unref(); } + +bool operator==(const String &p_name, const StringName &p_string_name) { + return p_name == p_string_name.operator String(); +} +bool operator!=(const String &p_name, const StringName &p_string_name) { + return p_name != p_string_name.operator String(); +} + +bool operator==(const char *p_name, const StringName &p_string_name) { + return p_name == p_string_name.operator String(); +} +bool operator!=(const char *p_name, const StringName &p_string_name) { + return p_name != p_string_name.operator String(); +} diff --git a/core/string_name.h b/core/string/string_name.h index 4f90479bda..e6b46506c3 100644 --- a/core/string_name.h +++ b/core/string/string_name.h @@ -32,8 +32,8 @@ #define STRING_NAME_H #include "core/os/mutex.h" -#include "core/safe_refcount.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/safe_refcount.h" class Main; @@ -155,6 +155,11 @@ public: ~StringName(); }; +bool operator==(const String &p_name, const StringName &p_string_name); +bool operator!=(const String &p_name, const StringName &p_string_name); +bool operator==(const char *p_name, const StringName &p_string_name); +bool operator!=(const char *p_name, const StringName &p_string_name); + StringName _scs_create(const char *p_chr); #endif // STRING_NAME_H diff --git a/core/translation.cpp b/core/string/translation.cpp index 8c8ca06740..df8a26e5ce 100644 --- a/core/translation.cpp +++ b/core/string/translation.cpp @@ -30,9 +30,9 @@ #include "translation.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/os/os.h" -#include "core/project_settings.h" // ISO 639-1 language codes, with the addition of glibc locales with their // regional identifiers. This list must match the language names (in English) diff --git a/core/translation.h b/core/string/translation.h index cba25a434f..8d34f7997e 100644 --- a/core/translation.h +++ b/core/string/translation.h @@ -31,7 +31,7 @@ #ifndef TRANSLATION_H #define TRANSLATION_H -#include "core/resource.h" +#include "core/io/resource.h" class Translation : public Resource { GDCLASS(Translation, Resource); diff --git a/core/translation_po.cpp b/core/string/translation_po.cpp index 203f29026b..203f29026b 100644 --- a/core/translation_po.cpp +++ b/core/string/translation_po.cpp diff --git a/core/translation_po.h b/core/string/translation_po.h index 88830210ef..c8a47bec5a 100644 --- a/core/translation_po.h +++ b/core/string/translation_po.h @@ -34,7 +34,7 @@ //#define DEBUG_TRANSLATION_PO #include "core/math/expression.h" -#include "core/translation.h" +#include "core/string/translation.h" class TranslationPO : public Translation { GDCLASS(TranslationPO, Translation); diff --git a/core/ucaps.h b/core/string/ucaps.h index 79b346acba..79b346acba 100644 --- a/core/ucaps.h +++ b/core/string/ucaps.h diff --git a/core/ustring.cpp b/core/string/ustring.cpp index 27dab8db6e..b5758bddf3 100644 --- a/core/ustring.cpp +++ b/core/string/ustring.cpp @@ -30,14 +30,14 @@ #include "ustring.h" -#include "core/color.h" #include "core/crypto/crypto_core.h" +#include "core/math/color.h" #include "core/math/math_funcs.h" #include "core/os/memory.h" -#include "core/print_string.h" -#include "core/translation.h" -#include "core/ucaps.h" -#include "core/variant.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" +#include "core/string/ucaps.h" +#include "core/variant/variant.h" #include <cstdint> @@ -637,6 +637,20 @@ bool operator==(const wchar_t *p_chr, const String &p_str) { #endif } +bool operator!=(const char *p_chr, const String &p_str) { + return !(p_str == p_chr); +} + +bool operator!=(const wchar_t *p_chr, const String &p_str) { +#ifdef WINDOWS_ENABLED + // wchar_t is 16-bit + return !(p_str == String::utf16((const char16_t *)p_chr)); +#else + // wchar_t is 32-bi + return !(p_str == String((const char32_t *)p_chr)); +#endif +} + bool String::operator!=(const char *p_str) const { return (!(*this == p_str)); } @@ -654,7 +668,14 @@ bool String::operator!=(const String &p_str) const { } bool String::operator<=(const String &p_str) const { - return (*this < p_str) || (*this == p_str); + return !(p_str < *this); +} + +bool String::operator>(const String &p_str) const { + return p_str < *this; +} +bool String::operator>=(const String &p_str) const { + return !(*this < p_str); } bool String::operator<(const char *p_str) const { @@ -4455,7 +4476,9 @@ String String::sprintf(const Array &values, bool *error) const { bool left_justified = false; bool show_sign = false; - *error = true; + if (error) { + *error = true; + } for (; *self; self++) { const char32_t c = *self; @@ -4716,7 +4739,9 @@ String String::sprintf(const Array &values, bool *error) const { return "not all arguments converted during string formatting"; } - *error = false; + if (error) { + *error = false; + } return formatted; } diff --git a/core/ustring.h b/core/string/ustring.h index bf9c06b9ca..b46733ab66 100644 --- a/core/ustring.h +++ b/core/string/ustring.h @@ -31,10 +31,10 @@ #ifndef USTRING_H #define USTRING_H -#include "core/array.h" -#include "core/cowdata.h" +#include "core/templates/cowdata.h" +#include "core/templates/vector.h" #include "core/typedefs.h" -#include "core/vector.h" +#include "core/variant/array.h" /*************************************************************************/ /* CharProxy */ @@ -254,6 +254,8 @@ public: bool operator<(const String &p_str) const; bool operator<=(const String &p_str) const; + bool operator>(const String &p_str) const; + bool operator>=(const String &p_str) const; signed char casecmp_to(const String &p_str) const; signed char nocasecmp_to(const String &p_str) const; @@ -431,10 +433,10 @@ public: /** * The constructors must not depend on other overloads */ - /* String(char32_t p_char);*/ _FORCE_INLINE_ String() {} _FORCE_INLINE_ String(const String &p_str) { _cowdata._ref(p_str._cowdata); } + String &operator=(const String &p_str) { _cowdata._ref(p_str._cowdata); return *this; @@ -456,6 +458,8 @@ public: bool operator==(const char *p_chr, const String &p_str); bool operator==(const wchar_t *p_chr, const String &p_str); +bool operator!=(const char *p_chr, const String &p_str); +bool operator!=(const wchar_t *p_chr, const String &p_str); String operator+(const char *p_chr, const String &p_str); String operator+(const wchar_t *p_chr, const String &p_str); @@ -532,4 +536,24 @@ String RTRN(const String &p_text, const String &p_text_plural, int p_n, const St bool is_symbol(char32_t c); bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end); +_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) { +} + +_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr, const String &p_str) { + arr.push_back(p_str); +} + +template <class... P> +_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr, const String &p_str, P... p_args) { + arr.push_back(p_str); + sarray_add_str(arr, p_args...); +} + +template <class... P> +_FORCE_INLINE_ Vector<String> sarray(P... p_args) { + Vector<String> arr; + sarray_add_str(arr, p_args...); + return arr; +} + #endif // USTRING_H diff --git a/core/templates/SCsub b/core/templates/SCsub new file mode 100644 index 0000000000..8c4c843a33 --- /dev/null +++ b/core/templates/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import("env") + +env_templates = env.Clone() + +env_templates.add_source_files(env.core_sources, "*.cpp") diff --git a/core/command_queue_mt.cpp b/core/templates/command_queue_mt.cpp index a55eed5d3c..a94853a21c 100644 --- a/core/command_queue_mt.cpp +++ b/core/templates/command_queue_mt.cpp @@ -30,8 +30,8 @@ #include "command_queue_mt.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" void CommandQueueMT::lock() { mutex.lock(); diff --git a/core/command_queue_mt.h b/core/templates/command_queue_mt.h index 0e5bc7f369..ac38d330de 100644 --- a/core/command_queue_mt.h +++ b/core/templates/command_queue_mt.h @@ -34,7 +34,7 @@ #include "core/os/memory.h" #include "core/os/mutex.h" #include "core/os/semaphore.h" -#include "core/simple_type.h" +#include "core/templates/simple_type.h" #include "core/typedefs.h" #define COMMA(N) _COMMA_##N diff --git a/core/cowdata.h b/core/templates/cowdata.h index 79676e6d80..d5eb08286d 100644 --- a/core/cowdata.h +++ b/core/templates/cowdata.h @@ -31,9 +31,9 @@ #ifndef COWDATA_H #define COWDATA_H -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/memory.h" -#include "core/safe_refcount.h" +#include "core/templates/safe_refcount.h" #include <string.h> diff --git a/core/hash_map.h b/core/templates/hash_map.h index 10fc931e7a..f6b889015a 100644 --- a/core/hash_map.h +++ b/core/templates/hash_map.h @@ -31,12 +31,12 @@ #ifndef HASH_MAP_H #define HASH_MAP_H -#include "core/error_macros.h" -#include "core/hashfuncs.h" -#include "core/list.h" +#include "core/error/error_macros.h" #include "core/math/math_funcs.h" #include "core/os/memory.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/hashfuncs.h" +#include "core/templates/list.h" /** * @class HashMap diff --git a/core/hashfuncs.h b/core/templates/hashfuncs.h index f4048843fc..86bb1b5228 100644 --- a/core/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -33,12 +33,12 @@ #include "core/math/math_defs.h" #include "core/math/math_funcs.h" -#include "core/node_path.h" -#include "core/object_id.h" -#include "core/rid.h" -#include "core/string_name.h" +#include "core/object/object_id.h" +#include "core/string/node_path.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/templates/rid.h" #include "core/typedefs.h" -#include "core/ustring.h" /** * Hashing functions */ diff --git a/core/list.h b/core/templates/list.h index 1cef3c484d..d745066e4c 100644 --- a/core/list.h +++ b/core/templates/list.h @@ -31,9 +31,9 @@ #ifndef LIST_H #define LIST_H -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/memory.h" -#include "core/sort_array.h" +#include "core/templates/sort_array.h" /** * Generic Templatized Linked List Implementation. diff --git a/core/local_vector.h b/core/templates/local_vector.h index b0dbd22b29..4ef040dc77 100644 --- a/core/local_vector.h +++ b/core/templates/local_vector.h @@ -31,11 +31,11 @@ #ifndef LOCAL_VECTOR_H #define LOCAL_VECTOR_H -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/copymem.h" #include "core/os/memory.h" -#include "core/sort_array.h" -#include "core/vector.h" +#include "core/templates/sort_array.h" +#include "core/templates/vector.h" template <class T, class U = uint32_t, bool force_trivial = false> class LocalVector { diff --git a/core/map.h b/core/templates/map.h index fd4f500556..c454d69256 100644 --- a/core/map.h +++ b/core/templates/map.h @@ -31,8 +31,8 @@ #ifndef MAP_H #define MAP_H -#include "core/error_macros.h" -#include "core/set.h" +#include "core/error/error_macros.h" +#include "core/templates/set.h" // based on the very nice implementation of rb-trees by: // https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html diff --git a/core/oa_hash_map.h b/core/templates/oa_hash_map.h index 6061366ab3..d9d632b4ce 100644 --- a/core/oa_hash_map.h +++ b/core/templates/oa_hash_map.h @@ -31,10 +31,10 @@ #ifndef OA_HASH_MAP_H #define OA_HASH_MAP_H -#include "core/hashfuncs.h" #include "core/math/math_funcs.h" #include "core/os/copymem.h" #include "core/os/memory.h" +#include "core/templates/hashfuncs.h" /** * A HashMap implementation that uses open addressing with Robin Hood hashing. diff --git a/core/ordered_hash_map.h b/core/templates/ordered_hash_map.h index e6a6340a2f..9398868b01 100644 --- a/core/ordered_hash_map.h +++ b/core/templates/ordered_hash_map.h @@ -31,9 +31,9 @@ #ifndef ORDERED_HASH_MAP_H #define ORDERED_HASH_MAP_H -#include "core/hash_map.h" -#include "core/list.h" -#include "core/pair.h" +#include "core/templates/hash_map.h" +#include "core/templates/list.h" +#include "core/templates/pair.h" /** * A hash map which allows to iterate elements in insertion order. diff --git a/core/pair.h b/core/templates/pair.h index 89ea2b9fd9..89ea2b9fd9 100644 --- a/core/pair.h +++ b/core/templates/pair.h diff --git a/core/rid.h b/core/templates/rid.h index 4b65f3fb6a..a475d166d5 100644 --- a/core/rid.h +++ b/core/templates/rid.h @@ -52,6 +52,9 @@ public: _FORCE_INLINE_ bool operator>(const RID &p_rid) const { return _id > p_rid._id; } + _FORCE_INLINE_ bool operator>=(const RID &p_rid) const { + return _id >= p_rid._id; + } _FORCE_INLINE_ bool operator!=(const RID &p_rid) const { return _id != p_rid._id; } diff --git a/core/rid_owner.cpp b/core/templates/rid_owner.cpp index a5065f29f8..a5065f29f8 100644 --- a/core/rid_owner.cpp +++ b/core/templates/rid_owner.cpp diff --git a/core/rid_owner.h b/core/templates/rid_owner.h index 30f1e41733..d1bcb92010 100644 --- a/core/rid_owner.h +++ b/core/templates/rid_owner.h @@ -31,14 +31,14 @@ #ifndef RID_OWNER_H #define RID_OWNER_H -#include "core/list.h" -#include "core/oa_hash_map.h" #include "core/os/memory.h" -#include "core/print_string.h" -#include "core/rid.h" -#include "core/safe_refcount.h" -#include "core/set.h" -#include "core/spin_lock.h" +#include "core/os/spin_lock.h" +#include "core/string/print_string.h" +#include "core/templates/list.h" +#include "core/templates/oa_hash_map.h" +#include "core/templates/rid.h" +#include "core/templates/safe_refcount.h" +#include "core/templates/set.h" #include <stdio.h> #include <typeinfo> diff --git a/core/ring_buffer.h b/core/templates/ring_buffer.h index 6b71d12cf3..12ec047fb6 100644 --- a/core/ring_buffer.h +++ b/core/templates/ring_buffer.h @@ -31,7 +31,7 @@ #ifndef RING_BUFFER_H #define RING_BUFFER_H -#include "core/vector.h" +#include "core/templates/vector.h" template <typename T> class RingBuffer { diff --git a/core/safe_refcount.cpp b/core/templates/safe_refcount.cpp index d5ee778ef7..d5ee778ef7 100644 --- a/core/safe_refcount.cpp +++ b/core/templates/safe_refcount.cpp diff --git a/core/safe_refcount.h b/core/templates/safe_refcount.h index dc4e62354a..dc4e62354a 100644 --- a/core/safe_refcount.h +++ b/core/templates/safe_refcount.h diff --git a/core/self_list.h b/core/templates/self_list.h index 3104bcb714..2a037d109c 100644 --- a/core/self_list.h +++ b/core/templates/self_list.h @@ -31,7 +31,7 @@ #ifndef SELF_LIST_H #define SELF_LIST_H -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/typedefs.h" template <class T> diff --git a/core/set.h b/core/templates/set.h index 1bc0a3f41e..1bc0a3f41e 100644 --- a/core/set.h +++ b/core/templates/set.h diff --git a/core/simple_type.h b/core/templates/simple_type.h index 841ab9f384..841ab9f384 100644 --- a/core/simple_type.h +++ b/core/templates/simple_type.h diff --git a/core/sort_array.h b/core/templates/sort_array.h index 93cc6f727d..a4326ac565 100644 --- a/core/sort_array.h +++ b/core/templates/sort_array.h @@ -31,7 +31,7 @@ #ifndef SORT_ARRAY_H #define SORT_ARRAY_H -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/typedefs.h" #define ERR_BAD_COMPARE(cond) \ diff --git a/core/thread_work_pool.cpp b/core/templates/thread_work_pool.cpp index 3a95e83ffc..3a95e83ffc 100644 --- a/core/thread_work_pool.cpp +++ b/core/templates/thread_work_pool.cpp diff --git a/core/thread_work_pool.h b/core/templates/thread_work_pool.h index 661060aa3f..661060aa3f 100644 --- a/core/thread_work_pool.h +++ b/core/templates/thread_work_pool.h diff --git a/core/vector.h b/core/templates/vector.h index 5a61f0eae3..9d45f7c30a 100644 --- a/core/vector.h +++ b/core/templates/vector.h @@ -37,11 +37,11 @@ * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays. */ -#include "core/cowdata.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/copymem.h" #include "core/os/memory.h" -#include "core/sort_array.h" +#include "core/templates/cowdata.h" +#include "core/templates/sort_array.h" template <class T> class VectorWriteProxy { @@ -157,6 +157,32 @@ public: return slice; } + bool operator==(const Vector<T> &p_arr) const { + int s = size(); + if (s != p_arr.size()) { + return false; + } + for (int i = 0; i < s; i++) { + if (operator[](i) != p_arr[i]) { + return false; + } + } + return true; + } + + bool operator!=(const Vector<T> &p_arr) const { + int s = size(); + if (s != p_arr.size()) { + return true; + } + for (int i = 0; i < s; i++) { + if (operator[](i) != p_arr[i]) { + return true; + } + } + return false; + } + _FORCE_INLINE_ Vector() {} _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); } diff --git a/core/vmap.h b/core/templates/vmap.h index c91ea9b3c9..8d2a3d2a9c 100644 --- a/core/vmap.h +++ b/core/templates/vmap.h @@ -31,7 +31,7 @@ #ifndef VMAP_H #define VMAP_H -#include "core/cowdata.h" +#include "core/templates/cowdata.h" #include "core/typedefs.h" template <class T, class V> diff --git a/core/vset.h b/core/templates/vset.h index 034b8fe851..4c0b8717b6 100644 --- a/core/vset.h +++ b/core/templates/vset.h @@ -31,8 +31,8 @@ #ifndef VSET_H #define VSET_H +#include "core/templates/vector.h" #include "core/typedefs.h" -#include "core/vector.h" template <class T> class VSet { diff --git a/core/typedefs.h b/core/typedefs.h index 2472e5fcd9..d7ee5ee40e 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -41,8 +41,8 @@ #include "platform_config.h" // Should be available everywhere. -#include "core/error_list.h" -#include "core/int_types.h" +#include "core/error/error_list.h" +#include <cstdint> // Turn argument to string constant: // https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing @@ -193,6 +193,20 @@ static inline unsigned int nearest_shift(unsigned int p_number) { return 0; } +// constexpr function to find the floored log2 of a number +template <typename T> +constexpr T floor_log2(T x) { + return x < 2 ? x : 1 + floor_log2(x >> 1); +} + +// Get the number of bits needed to represent the number. +// IE, if you pass in 8, you will get 4. +// If you want to know how many bits are needed to store 8 values however, pass in (8 - 1). +template <typename T> +constexpr T get_num_bits(T x) { + return floor_log2(x); +} + // Swap 16, 32 and 64 bits value for endianness. #if defined(__GNUC__) #define BSWAP16(x) __builtin_bswap16(x) diff --git a/core/variant/SCsub b/core/variant/SCsub new file mode 100644 index 0000000000..7f4c8b7788 --- /dev/null +++ b/core/variant/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import("env") + +env_variant = env.Clone() + +env_variant.add_source_files(env.core_sources, "*.cpp") diff --git a/core/array.cpp b/core/variant/array.cpp index c6e90d71ec..79bc01b89c 100644 --- a/core/array.cpp +++ b/core/variant/array.cpp @@ -31,11 +31,11 @@ #include "array.h" #include "container_type_validate.h" -#include "core/class_db.h" -#include "core/hashfuncs.h" -#include "core/script_language.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/object/class_db.h" +#include "core/object/script_language.h" +#include "core/templates/hashfuncs.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" class ArrayPrivate { public: @@ -98,6 +98,37 @@ bool Array::operator==(const Array &p_array) const { return _p == p_array._p; } +bool Array::operator!=(const Array &p_array) const { + return !operator==(p_array); +} + +bool Array::operator<(const Array &p_array) const { + int a_len = size(); + int b_len = p_array.size(); + + int min_cmp = MIN(a_len, b_len); + + for (int i = 0; i < min_cmp; i++) { + if (operator[](i) < p_array[i]) { + return true; + } else if (p_array[i] < operator[](i)) { + return false; + } + } + + return a_len < b_len; +} + +bool Array::operator<=(const Array &p_array) const { + return !operator>(p_array); +} +bool Array::operator>(const Array &p_array) const { + return p_array < *this; +} +bool Array::operator>=(const Array &p_array) const { + return !operator<(p_array); +} + uint32_t Array::hash() const { uint32_t h = hash_djb2_one_32(0); @@ -134,7 +165,7 @@ void Array::_assign(const Array &p_array) { } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) { Variant *ptr = &src_val; Callable::CallError ce; - new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true); + Variant::construct(_p->typed.type, new_array.write[i], (const Variant **)&ptr, 1, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); } @@ -161,6 +192,11 @@ void Array::push_back(const Variant &p_value) { _p->array.push_back(p_value); } +void Array::append_array(const Array &p_array) { + ERR_FAIL_COND(!_p->typed.validate(p_array, "append_array")); + _p->array.append_array(p_array._p->array); +} + Error Array::resize(int p_new_size) { return _p->array.resize(p_new_size); } diff --git a/core/array.h b/core/variant/array.h index 34367088e4..e01ac13168 100644 --- a/core/array.h +++ b/core/variant/array.h @@ -61,12 +61,14 @@ public: void clear(); bool operator==(const Array &p_array) const; + bool operator!=(const Array &p_array) const; uint32_t hash() const; void operator=(const Array &p_array); void push_back(const Variant &p_value); _FORCE_INLINE_ void append(const Variant &p_value) { push_back(p_value); } //for python compatibility + void append_array(const Array &p_array); Error resize(int p_new_size); void insert(int p_pos, const Variant &p_value); @@ -98,6 +100,11 @@ public: Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const; + bool operator<(const Array &p_array) const; + bool operator<=(const Array &p_array) const; + bool operator>(const Array &p_array) const; + bool operator>=(const Array &p_array) const; + Variant min() const; Variant max() const; diff --git a/core/binder_common.h b/core/variant/binder_common.h index 0fbfa56230..2e38ce5b06 100644 --- a/core/binder_common.h +++ b/core/variant/binder_common.h @@ -31,14 +31,14 @@ #ifndef BINDER_COMMON_H #define BINDER_COMMON_H -#include "core/list.h" -#include "core/method_ptrcall.h" -#include "core/object.h" -#include "core/simple_type.h" -#include "core/type_info.h" +#include "core/object/object.h" +#include "core/templates/list.h" +#include "core/templates/simple_type.h" #include "core/typedefs.h" -#include "core/variant.h" -#include "core/variant_internal.h" +#include "core/variant/method_ptrcall.h" +#include "core/variant/type_info.h" +#include "core/variant/variant.h" +#include "core/variant/variant_internal.h" #include <stdio.h> @@ -650,6 +650,39 @@ void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *, (void)p_args; } +template <class T, class R, class... P> +void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &default_values, Callable::CallError &r_error) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = &default_values[i - p_argcount + (dvs - missing)]; + } + } + + call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + #if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/core/callable.cpp b/core/variant/callable.cpp index c368565687..e504fd05e3 100644 --- a/core/callable.cpp +++ b/core/variant/callable.cpp @@ -31,10 +31,10 @@ #include "callable.h" #include "callable_bind.h" -#include "core/script_language.h" -#include "message_queue.h" -#include "object.h" -#include "reference.h" +#include "core/object/message_queue.h" +#include "core/object/object.h" +#include "core/object/reference.h" +#include "core/object/script_language.h" void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const { MessageQueue::get_singleton()->push_callable(*this, p_arguments, p_argcount); diff --git a/core/callable.h b/core/variant/callable.h index 936272a681..40621fbde3 100644 --- a/core/callable.h +++ b/core/variant/callable.h @@ -31,9 +31,9 @@ #ifndef CALLABLE_H #define CALLABLE_H -#include "core/list.h" -#include "core/object_id.h" -#include "core/string_name.h" +#include "core/object/object_id.h" +#include "core/string/string_name.h" +#include "core/templates/list.h" class Object; class Variant; diff --git a/core/callable_bind.cpp b/core/variant/callable_bind.cpp index da08d3ccbd..da08d3ccbd 100644 --- a/core/callable_bind.cpp +++ b/core/variant/callable_bind.cpp diff --git a/core/callable_bind.h b/core/variant/callable_bind.h index 21b9228be3..fc5659e412 100644 --- a/core/callable_bind.h +++ b/core/variant/callable_bind.h @@ -31,8 +31,8 @@ #ifndef CALLABLE_BIND_H #define CALLABLE_BIND_H -#include "core/callable.h" -#include "core/variant.h" +#include "core/variant/callable.h" +#include "core/variant/variant.h" class CallableCustomBind : public CallableCustom { Callable callable; diff --git a/core/container_type_validate.h b/core/variant/container_type_validate.h index 8a361aa0ef..4d3a5f683b 100644 --- a/core/container_type_validate.h +++ b/core/variant/container_type_validate.h @@ -31,8 +31,8 @@ #ifndef CONTAINER_TYPE_VALIDATE_H #define CONTAINER_TYPE_VALIDATE_H -#include "core/script_language.h" -#include "core/variant.h" +#include "core/object/script_language.h" +#include "core/variant/variant.h" struct ContainerTypeValidate { Variant::Type type = Variant::NIL; diff --git a/core/dictionary.cpp b/core/variant/dictionary.cpp index 052e1bdae1..2bc1f7a86d 100644 --- a/core/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -30,9 +30,9 @@ #include "dictionary.h" -#include "core/ordered_hash_map.h" -#include "core/safe_refcount.h" -#include "core/variant.h" +#include "core/templates/ordered_hash_map.h" +#include "core/templates/safe_refcount.h" +#include "core/variant/variant.h" struct DictionaryPrivate { SafeRefCount refcount; diff --git a/core/dictionary.h b/core/variant/dictionary.h index a01d96ba01..bbe94122ad 100644 --- a/core/dictionary.h +++ b/core/variant/dictionary.h @@ -31,9 +31,9 @@ #ifndef DICTIONARY_H #define DICTIONARY_H -#include "core/array.h" -#include "core/list.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/list.h" +#include "core/variant/array.h" class Variant; diff --git a/core/method_ptrcall.h b/core/variant/method_ptrcall.h index 022ed2a5d6..936de145f8 100644 --- a/core/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -32,9 +32,9 @@ #define METHOD_PTRCALL_H #include "core/math/transform_2d.h" -#include "core/object_id.h" +#include "core/object/object_id.h" #include "core/typedefs.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef PTRCALL_ENABLED diff --git a/core/type_info.h b/core/variant/type_info.h index b9ae88d97c..ce7c2bfe14 100644 --- a/core/type_info.h +++ b/core/variant/type_info.h @@ -153,7 +153,7 @@ MAKE_TYPE_INFO(Transform, Variant::TRANSFORM) MAKE_TYPE_INFO(Color, Variant::COLOR) MAKE_TYPE_INFO(StringName, Variant::STRING_NAME) MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH) -MAKE_TYPE_INFO(RID, Variant::_RID) +MAKE_TYPE_INFO(RID, Variant::RID) MAKE_TYPE_INFO(Callable, Variant::CALLABLE) MAKE_TYPE_INFO(Signal, Variant::SIGNAL) MAKE_TYPE_INFO(Dictionary, Variant::DICTIONARY) diff --git a/core/typed_array.h b/core/variant/typed_array.h index 86f26d7550..ff42cb687e 100644 --- a/core/typed_array.h +++ b/core/variant/typed_array.h @@ -31,9 +31,9 @@ #ifndef TYPED_ARRAY_H #define TYPED_ARRAY_H -#include "core/array.h" -#include "core/method_ptrcall.h" -#include "core/variant.h" +#include "core/variant/array.h" +#include "core/variant/method_ptrcall.h" +#include "core/variant/variant.h" template <class T> class TypedArray : public Array { @@ -105,7 +105,7 @@ MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM) MAKE_TYPED_ARRAY(Color, Variant::COLOR) MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME) MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH) -MAKE_TYPED_ARRAY(RID, Variant::_RID) +MAKE_TYPED_ARRAY(RID, Variant::RID) MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE) MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL) MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY) @@ -207,7 +207,7 @@ MAKE_TYPED_ARRAY_INFO(Transform, Variant::TRANSFORM) MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR) MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME) MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH) -MAKE_TYPED_ARRAY_INFO(RID, Variant::_RID) +MAKE_TYPED_ARRAY_INFO(RID, Variant::RID) MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE) MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL) MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY) diff --git a/core/variant.cpp b/core/variant/variant.cpp index 181ced0f32..741d05c139 100644 --- a/core/variant.cpp +++ b/core/variant/variant.cpp @@ -33,10 +33,10 @@ #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" #include "core/io/marshalls.h" +#include "core/io/resource.h" #include "core/math/math_funcs.h" -#include "core/print_string.h" -#include "core/resource.h" -#include "core/variant_parser.h" +#include "core/string/print_string.h" +#include "core/variant/variant_parser.h" #include "scene/gui/control.h" #include "scene/main/node.h" @@ -109,7 +109,7 @@ String Variant::get_type_name(Variant::Type p_type) { return "Color"; } break; - case _RID: { + case RID: { return "RID"; } break; case OBJECT: { @@ -342,7 +342,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { } break; - case _RID: { + case RID: { static const Type valid[] = { OBJECT, NIL @@ -649,7 +649,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type } break; - case _RID: { + case RID: { static const Type valid[] = { OBJECT, NIL @@ -891,8 +891,8 @@ bool Variant::is_zero() const { return *reinterpret_cast<const Color *>(_data._mem) == Color(); } break; - case _RID: { - return *reinterpret_cast<const RID *>(_data._mem) == RID(); + case RID: { + return *reinterpret_cast<const ::RID *>(_data._mem) == ::RID(); } break; case OBJECT: { return _get_obj().obj == nullptr; @@ -1109,8 +1109,8 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._mem, Color(*reinterpret_cast<const Color *>(p_variant._data._mem))); } break; - case _RID: { - memnew_placement(_data._mem, RID(*reinterpret_cast<const RID *>(p_variant._data._mem))); + case RID: { + memnew_placement(_data._mem, ::RID(*reinterpret_cast<const ::RID *>(p_variant._data._mem))); } break; case OBJECT: { memnew_placement(_data._mem, ObjData); @@ -1266,7 +1266,7 @@ void Variant::zero() { } } -void Variant::clear() { +void Variant::_clear_internal() { switch (type) { case STRING: { reinterpret_cast<String *>(_data._mem)->~String(); @@ -1311,9 +1311,11 @@ void Variant::clear() { _get_obj().obj = nullptr; _get_obj().id = ObjectID(); } break; - case _RID: { + case RID: { // not much need probably - reinterpret_cast<RID *>(_data._mem)->~RID(); + // Can't seem to use destructor + scoping operator, so hack. + typedef ::RID RID_Class; + reinterpret_cast<RID_Class *>(_data._mem)->~RID_Class(); } break; case CALLABLE: { reinterpret_cast<Callable *>(_data._mem)->~Callable(); @@ -1358,8 +1360,6 @@ void Variant::clear() { default: { } /* not needed */ } - - type = NIL; } Variant::operator signed int() const { @@ -1849,8 +1849,8 @@ String Variant::stringify(List<const void *> &stack) const { const Signal &s = *reinterpret_cast<const Signal *>(_data._mem); return s; } break; - case _RID: { - const RID &s = *reinterpret_cast<const RID *>(_data._mem); + case RID: { + const ::RID &s = *reinterpret_cast<const ::RID *>(_data._mem); return "RID(" + itos(s.get_id()) + ")"; } break; default: { @@ -2041,25 +2041,25 @@ Variant::operator NodePath() const { } } -Variant::operator RID() const { - if (type == _RID) { - return *reinterpret_cast<const RID *>(_data._mem); +Variant::operator ::RID() const { + if (type == RID) { + return *reinterpret_cast<const ::RID *>(_data._mem); } else if (type == OBJECT && _get_obj().obj == nullptr) { - return RID(); + return ::RID(); } else if (type == OBJECT && _get_obj().obj) { #ifdef DEBUG_ENABLED if (EngineDebugger::is_active()) { - ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, RID(), "Invalid pointer (object was freed)."); + ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, ::RID(), "Invalid pointer (object was freed)."); } #endif Callable::CallError ce; Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); - if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::_RID) { + if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::RID) { return ret; } - return RID(); + return ::RID(); } else { - return RID(); + return ::RID(); } } @@ -2263,9 +2263,9 @@ Variant::operator Vector<Color>() const { /* helpers */ -Variant::operator Vector<RID>() const { +Variant::operator Vector<::RID>() const { Array va = operator Array(); - Vector<RID> rids; + Vector<::RID> rids; rids.resize(va.size()); for (int i = 0; i < rids.size(); i++) { rids.write[i] = va[i]; @@ -2520,9 +2520,9 @@ Variant::Variant(const NodePath &p_node_path) { memnew_placement(_data._mem, NodePath(p_node_path)); } -Variant::Variant(const RID &p_rid) { - type = _RID; - memnew_placement(_data._mem, RID(p_rid)); +Variant::Variant(const ::RID &p_rid) { + type = RID; + memnew_placement(_data._mem, ::RID(p_rid)); } Variant::Variant(const Object *p_object) { @@ -2580,7 +2580,7 @@ Variant::Variant(const Vector<Plane> &p_array) { } } -Variant::Variant(const Vector<RID> &p_array) { +Variant::Variant(const Vector<::RID> &p_array) { type = ARRAY; Array *rid_array = memnew_placement(_data._mem, Array); @@ -2753,8 +2753,8 @@ void Variant::operator=(const Variant &p_variant) { case COLOR: { *reinterpret_cast<Color *>(_data._mem) = *reinterpret_cast<const Color *>(p_variant._data._mem); } break; - case _RID: { - *reinterpret_cast<RID *>(_data._mem) = *reinterpret_cast<const RID *>(p_variant._data._mem); + case RID: { + *reinterpret_cast<::RID *>(_data._mem) = *reinterpret_cast<const ::RID *>(p_variant._data._mem); } break; case OBJECT: { if (_get_obj().id.is_reference()) { @@ -2955,8 +2955,8 @@ uint32_t Variant::hash() const { return hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->a, hash); } break; - case _RID: { - return hash_djb2_one_64(reinterpret_cast<const RID *>(_data._mem)->get_id()); + case RID: { + return hash_djb2_one_64(reinterpret_cast<const ::RID *>(_data._mem)->get_id()); } break; case OBJECT: { return hash_djb2_one_64(make_uint64_t(_get_obj().obj)); @@ -3401,7 +3401,8 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) { Callable::CallError error; - Variant ret = call(p_method, argptr, argc, error); + Variant ret; + call(p_method, argptr, argc, ret, error); switch (error.error) { case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: { @@ -3435,6 +3436,30 @@ String Variant::get_construct_string() const { return vars; } +String Variant::get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { + String err_text; + + if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { + int errorarg = ce.argument; + if (p_argptrs) { + err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; + } else { + err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; + } + } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { + err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; + } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { + err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; + } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { + err_text = "Method not found."; + } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { + err_text = "Instance is null"; + } else if (ce.error == Callable::CallError::CALL_OK) { + return "Call OK"; + } + return "'" + String(p_method) + "': " + err_text; +} + String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { String err_text; @@ -3519,3 +3544,18 @@ String vformat(const String &p_text, const Variant &p1, const Variant &p2, const return fmt; } + +void Variant::register_types() { + _register_variant_operators(); + _register_variant_methods(); + _register_variant_setters_getters(); + _register_variant_constructors(); + _register_variant_utility_functions(); +} +void Variant::unregister_types() { + _unregister_variant_operators(); + _unregister_variant_methods(); + _unregister_variant_setters_getters(); + _unregister_variant_constructors(); + _unregister_variant_utility_functions(); +} diff --git a/core/variant.h b/core/variant/variant.h index 84e5427b21..1a684eeea0 100644 --- a/core/variant.h +++ b/core/variant/variant.h @@ -31,13 +31,10 @@ #ifndef VARIANT_H #define VARIANT_H -#include "core/array.h" -#include "core/callable.h" -#include "core/color.h" -#include "core/dictionary.h" #include "core/io/ip_address.h" #include "core/math/aabb.h" #include "core/math/basis.h" +#include "core/math/color.h" #include "core/math/face3.h" #include "core/math/plane.h" #include "core/math/quat.h" @@ -45,10 +42,13 @@ #include "core/math/transform_2d.h" #include "core/math/vector3.h" #include "core/math/vector3i.h" -#include "core/node_path.h" -#include "core/object_id.h" -#include "core/rid.h" -#include "core/ustring.h" +#include "core/object/object_id.h" +#include "core/string/node_path.h" +#include "core/string/ustring.h" +#include "core/templates/rid.h" +#include "core/variant/array.h" +#include "core/variant/callable.h" +#include "core/variant/dictionary.h" class Object; class Node; // helper @@ -97,7 +97,7 @@ public: COLOR, STRING_NAME, NODE_PATH, - _RID, + RID, OBJECT, CALLABLE, SIGNAL, @@ -207,7 +207,68 @@ private: } _data alignas(8); void reference(const Variant &p_variant); - void clear(); + + void _clear_internal(); + + _FORCE_INLINE_ void clear() { + static const bool needs_deinit[Variant::VARIANT_MAX] = { + false, //NIL, + false, //BOOL, + false, //INT, + false, //FLOAT, + true, //STRING, + false, //VECTOR2, + false, //VECTOR2I, + false, //RECT2, + false, //RECT2I, + false, //VECTOR3, + false, //VECTOR3I, + true, //TRANSFORM2D, + false, //PLANE, + false, //QUAT, + true, //AABB, + true, //BASIS, + true, //TRANSFORM, + + // misc types + false, //COLOR, + true, //STRING_NAME, + true, //NODE_PATH, + false, //RID, + true, //OBJECT, + true, //CALLABLE, + true, //SIGNAL, + true, //DICTIONARY, + true, //ARRAY, + + // typed arrays + true, //PACKED_BYTE_ARRAY, + true, //PACKED_INT32_ARRAY, + true, //PACKED_INT64_ARRAY, + true, //PACKED_FLOAT32_ARRAY, + true, //PACKED_FLOAT64_ARRAY, + true, //PACKED_STRING_ARRAY, + true, //PACKED_VECTOR2_ARRAY, + true, //PACKED_VECTOR3_ARRAY, + true, //PACKED_COLOR_ARRAY, + }; + + if (unlikely(needs_deinit[type])) { //make it fast for types that dont need deinit + _clear_internal(); + } + type = NIL; + } + + static void _register_variant_operators(); + static void _unregister_variant_operators(); + static void _register_variant_methods(); + static void _unregister_variant_methods(); + static void _register_variant_setters_getters(); + static void _unregister_variant_setters_getters(); + static void _register_variant_constructors(); + static void _unregister_variant_constructors(); + static void _register_variant_utility_functions(); + static void _unregister_variant_utility_functions(); public: _FORCE_INLINE_ Type get_type() const { @@ -266,7 +327,7 @@ public: operator Color() const; operator NodePath() const; - operator RID() const; + operator ::RID() const; operator Object *() const; operator Node *() const; @@ -291,7 +352,7 @@ public: operator Vector<Variant>() const; operator Vector<StringName>() const; - operator Vector<RID>() const; + operator Vector<::RID>() const; operator Vector<Vector2>() const; // some core type enums to convert to @@ -338,7 +399,7 @@ public: Variant(const Transform &p_transform); Variant(const Color &p_color); Variant(const NodePath &p_node_path); - Variant(const RID &p_rid); + Variant(const ::RID &p_rid); Variant(const Object *p_object); Variant(const Callable &p_callable); Variant(const Signal &p_signal); @@ -358,7 +419,7 @@ public: Variant(const Vector<Variant> &p_array); Variant(const Vector<StringName> &p_array); - Variant(const Vector<RID> &p_array); // helper + Variant(const Vector<::RID> &p_array); // helper Variant(const Vector<Vector2> &p_array); // helper Variant(const IP_Address &p_address); @@ -381,7 +442,6 @@ public: OP_NEGATE, OP_POSITIVE, OP_MODULE, - OP_STRING_CONCAT, //bitwise OP_SHIFT_LEFT, OP_SHIFT_RIGHT, @@ -409,69 +469,133 @@ public: return res; } + static Variant::Type get_operator_return_type(Operator p_operator, Type p_type_a, Type p_type_b); + typedef void (*ValidatedOperatorEvaluator)(const Variant *left, const Variant *right, Variant *r_ret); + static ValidatedOperatorEvaluator get_validated_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b); +#ifdef PTRCALL_ENABLED + typedef void (*PTROperatorEvaluator)(const void *left, const void *right, void *r_ret); + static PTROperatorEvaluator get_ptr_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b); +#endif + void zero(); Variant duplicate(bool deep = false) const; static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst); static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst); - class InternalMethod { -#ifdef DEBUG_ENABLED - protected: - StringName method_name; - Variant::Type base_type; -#endif - public: - enum Flags { - FLAG_IS_CONST = 1, - FLAG_RETURNS_VARIANT = 2, - FLAG_NO_PTRCALL = 4, - FLAG_VARARGS = 8 - }; + /* Built-In Methods */ - virtual int get_argument_count() const = 0; - virtual Type get_argument_type(int p_arg) const = 0; - virtual Type get_return_type() const = 0; - virtual uint32_t get_flags() const = 0; + typedef void (*ValidatedBuiltInMethod)(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret); + typedef void (*PTRBuiltInMethod)(void *p_base, const void **p_args, void *r_ret, int p_argcount); -#ifdef DEBUG_ENABLED - virtual String get_argument_name(int p_arg) const = 0; - StringName get_name() const { - return method_name; - } - Variant::Type get_base_type() const { - return base_type; - } -#endif - virtual Vector<Variant> get_default_arguments() const = 0; - virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) = 0; - virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) = 0; -#ifdef PTRCALL_ENABLED - virtual void ptrcall(void *p_base, const void **p_args, void *r_ret) = 0; -#endif - virtual ~InternalMethod() {} - }; + static bool has_builtin_method(Variant::Type p_type, const StringName &p_method); + + static ValidatedBuiltInMethod get_validated_builtin_method(Variant::Type p_type, const StringName &p_method); + static PTRBuiltInMethod get_ptr_builtin_method(Variant::Type p_type, const StringName &p_method); - static InternalMethod *get_internal_method(Type p_type, const StringName &p_method_name); + static int get_builtin_method_argument_count(Variant::Type p_type, const StringName &p_method); + static Variant::Type get_builtin_method_argument_type(Variant::Type p_type, const StringName &p_method, int p_argument); + static String get_builtin_method_argument_name(Variant::Type p_type, const StringName &p_method, int p_argument); + static Vector<Variant> get_builtin_method_default_arguments(Variant::Type p_type, const StringName &p_method); + static bool has_builtin_method_return_value(Variant::Type p_type, const StringName &p_method); + static Variant::Type get_builtin_method_return_type(Variant::Type p_type, const StringName &p_method); + static bool is_builtin_method_const(Variant::Type p_type, const StringName &p_method); + static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method); + static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list); - void call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, Callable::CallError &r_error); - Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant()); + static String get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); - static Variant construct(const Variant::Type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict = true); - + //dynamic (includes Object) void get_method_list(List<MethodInfo> *p_list) const; bool has_method(const StringName &p_method) const; - static Vector<Variant::Type> get_method_argument_types(Variant::Type p_type, const StringName &p_method); - static Vector<Variant> get_method_default_arguments(Variant::Type p_type, const StringName &p_method); - static Variant::Type get_method_return_type(Variant::Type p_type, const StringName &p_method, bool *r_has_return = nullptr); - static Vector<StringName> get_method_argument_names(Variant::Type p_type, const StringName &p_method); - static bool is_method_const(Variant::Type p_type, const StringName &p_method); - void set_named(const StringName &p_index, const Variant &p_value, bool *r_valid = nullptr); - Variant get_named(const StringName &p_index, bool *r_valid = nullptr) const; + /* Constructors */ + + typedef void (*ValidatedConstructor)(Variant &r_base, const Variant **p_args); + typedef void (*PTRConstructor)(void *base, const void **p_args); + + static int get_constructor_count(Variant::Type p_type); + static ValidatedConstructor get_validated_constructor(Variant::Type p_type, int p_constructor); + static PTRConstructor get_ptr_constructor(Variant::Type p_type, int p_constructor); + static int get_constructor_argument_count(Variant::Type p_type, int p_constructor); + static Variant::Type get_constructor_argument_type(Variant::Type p_type, int p_constructor, int p_argument); + static String get_constructor_argument_name(Variant::Type p_type, int p_constructor, int p_argument); + static void construct(Variant::Type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + + static void get_constructor_list(Type p_type, List<MethodInfo> *r_list); //convenience + + /* Properties */ + + void set_named(const StringName &p_member, const Variant &p_value, bool &r_valid); + Variant get_named(const StringName &p_member, bool &r_valid) const; + + typedef void (*ValidatedSetter)(Variant *base, const Variant *value); + typedef void (*ValidatedGetter)(const Variant *base, Variant *value); + + static bool has_member(Variant::Type p_type, const StringName &p_member); + static Variant::Type get_member_type(Variant::Type p_type, const StringName &p_member); + static void get_member_list(Type p_type, List<StringName> *r_members); + + static ValidatedSetter get_member_validated_setter(Variant::Type p_type, const StringName &p_member); + static ValidatedGetter get_member_validated_getter(Variant::Type p_type, const StringName &p_member); + + typedef void (*PTRSetter)(void *base, const void *value); + typedef void (*PTRGetter)(const void *base, void *value); + + static PTRSetter get_member_ptr_setter(Variant::Type p_type, const StringName &p_member); + static PTRGetter get_member_ptr_getter(Variant::Type p_type, const StringName &p_member); + + /* Indexing */ + + static bool has_indexing(Variant::Type p_type); + static Variant::Type get_indexed_element_type(Variant::Type p_type); + + typedef void (*ValidatedIndexedSetter)(Variant *base, int64_t index, const Variant *value, bool &oob); + typedef void (*ValidatedIndexedGetter)(const Variant *base, int64_t index, Variant *value, bool &oob); + + static ValidatedIndexedSetter get_member_validated_indexed_setter(Variant::Type p_type); + static ValidatedIndexedGetter get_member_validated_indexed_getter(Variant::Type p_type); + + typedef void (*PTRIndexedSetter)(void *base, int64_t index, const void *value); + typedef void (*PTRIndexedGetter)(const void *base, int64_t index, void *value); + + static PTRIndexedSetter get_member_ptr_indexed_setter(Variant::Type p_type); + static PTRIndexedGetter get_member_ptr_indexed_getter(Variant::Type p_type); + + void set_indexed(int64_t p_index, const Variant &p_value, bool &r_valid, bool &r_oob); + Variant get_indexed(int64_t p_index, bool &r_valid, bool &r_oob) const; + + uint64_t get_indexed_size() const; + + /* Keying */ + + static bool is_keyed(Variant::Type p_type); + + typedef void (*ValidatedKeyedSetter)(Variant *base, const Variant *key, const Variant *value, bool &valid); + typedef void (*ValidatedKeyedGetter)(const Variant *base, const Variant *key, Variant *value, bool &valid); + typedef bool (*ValidatedKeyedChecker)(const Variant *base, const Variant *key, bool &valid); + + static ValidatedKeyedSetter get_member_validated_keyed_setter(Variant::Type p_type); + static ValidatedKeyedGetter get_member_validated_keyed_getter(Variant::Type p_type); + static ValidatedKeyedChecker get_member_validated_keyed_checker(Variant::Type p_type); + + typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value); + typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value); + typedef bool (*PTRKeyedChecker)(const void *base, const void *key); + + static PTRKeyedSetter get_member_ptr_keyed_setter(Variant::Type p_type); + static PTRKeyedGetter get_member_ptr_keyed_getter(Variant::Type p_type); + static PTRKeyedChecker get_member_ptr_keyed_checker(Variant::Type p_type); + + void set_keyed(const Variant &p_key, const Variant &p_value, bool &r_valid); + Variant get_keyed(const Variant &p_key, bool &r_valid) const; + bool has_key(const Variant &p_key, bool &r_valid) const; + + /* Generic */ void set(const Variant &p_index, const Variant &p_value, bool *r_valid = nullptr); Variant get(const Variant &p_index, bool *r_valid = nullptr) const; @@ -483,6 +607,32 @@ public: void get_property_list(List<PropertyInfo> *p_list) const; + static void call_utility_function(const StringName &p_name, Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + static bool has_utility_function(const StringName &p_name); + + typedef void (*ValidatedUtilityFunction)(Variant *r_ret, const Variant **p_args, int p_argcount); + typedef void (*PTRUtilityFunction)(void *r_ret, const void **p_args, int p_argcount); + + static ValidatedUtilityFunction get_validated_utility_function(const StringName &p_name); + static PTRUtilityFunction get_ptr_utility_function(const StringName &p_name); + + enum UtilityFunctionType { + UTILITY_FUNC_TYPE_MATH, + UTILITY_FUNC_TYPE_RANDOM, + UTILITY_FUNC_TYPE_GENERAL, + }; + + static UtilityFunctionType get_utility_function_type(const StringName &p_name); + + static int get_utility_function_argument_count(const StringName &p_name); + static Variant::Type get_utility_function_argument_type(const StringName &p_name, int p_arg); + static String get_utility_function_argument_name(const StringName &p_name, int p_arg); + static bool has_utility_function_return_value(const StringName &p_name); + static Variant::Type get_utility_function_return_type(const StringName &p_name); + static bool is_utility_function_vararg(const StringName &p_name); + + static void get_utility_function_list(List<StringName> *r_functions); + //argsVariant call() bool operator==(const Variant &p_variant) const; @@ -495,7 +645,6 @@ public: String stringify(List<const void *> &stack) const; void static_assign(const Variant &p_variant); - static void get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list); static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants); static bool has_constant(Variant::Type p_type, const StringName &p_value); static Variant get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid = nullptr); @@ -508,12 +657,13 @@ public: void operator=(const Variant &p_variant); // only this is enough for all the other types + static void register_types(); + static void unregister_types(); + Variant(const Variant &p_variant); _FORCE_INLINE_ Variant() {} _FORCE_INLINE_ ~Variant() { - if (type != Variant::NIL) { - clear(); - } + clear(); } }; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp new file mode 100644 index 0000000000..4cb8457ccd --- /dev/null +++ b/core/variant/variant_call.cpp @@ -0,0 +1,1555 @@ +/*************************************************************************/ +/* variant_call.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/crypto/crypto_core.h" +#include "core/debugger/engine_debugger.h" +#include "core/io/compression.h" +#include "core/object/class_db.h" +#include "core/os/os.h" +#include "core/templates/local_vector.h" +#include "core/templates/oa_hash_map.h" + +typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args); +typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args); + +template <class T> +struct TypeAdjust { + _FORCE_INLINE_ static void adjust(Variant *r_ret) { + VariantTypeChanger<typename GetSimpleTypeT<T>::type_t>::change(r_ret); + } +}; + +template <> //do nothing for variant +struct TypeAdjust<Variant> { + _FORCE_INLINE_ static void adjust(Variant *r_ret) { + } +}; + +template <> //do nothing for variant +struct TypeAdjust<Object *> { + _FORCE_INLINE_ static void adjust(Variant *r_ret) { + VariantInternal::clear(r_ret); + *r_ret = (Object *)nullptr; + } +}; + +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, p_defvals); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_retc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, p_defvals); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, p_defvals); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_argsc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, p_defvals); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_validated_call(R (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_ret(base, method, p_args, r_ret); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_validated_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_retc(base, method, p_args, r_ret); +} +template <class T, class... P> +static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args(base, method, p_args); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_argsc(base, method, p_args); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args_ret(reinterpret_cast<T *>(p_base), method, p_args, r_ret); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args_retc(reinterpret_cast<T *>(p_base), method, p_args, r_ret); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args(reinterpret_cast<T *>(p_base), method, p_args); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_argsc(reinterpret_cast<T *>(p_base), method, p_args); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ int vc_get_argument_count(R (T::*method)(P...)) { + return sizeof...(P); +} +template <class R, class T, class... P> +static _FORCE_INLINE_ int vc_get_argument_count(R (T::*method)(P...) const) { + return sizeof...(P); +} + +template <class T, class... P> +static _FORCE_INLINE_ int vc_get_argument_count(void (T::*method)(P...)) { + return sizeof...(P); +} + +template <class T, class... P> +static _FORCE_INLINE_ int vc_get_argument_count(void (T::*method)(P...) const) { + return sizeof...(P); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ int vc_get_argument_count(R (*method)(T *, P...)) { + return sizeof...(P); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (T::*method)(P...), int p_arg) { + return call_get_argument_type<P...>(p_arg); +} +template <class R, class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (T::*method)(P...) const, int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + +template <class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_argument_type(void (T::*method)(P...), int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + +template <class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_argument_type(void (T::*method)(P...) const, int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (*method)(T *, P...), int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (T::*method)(P...)) { + return GetTypeInfo<R>::VARIANT_TYPE; +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (T::*method)(P...) const) { + return GetTypeInfo<R>::VARIANT_TYPE; +} + +template <class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (T::*method)(P...)) { + return Variant::NIL; +} + +template <class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (T::*method)(P...) const) { + return Variant::NIL; +} + +template <class R, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (*method)(P...)) { + return GetTypeInfo<R>::VARIANT_TYPE; +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ bool vc_has_return_type(R (T::*method)(P...)) { + return true; +} +template <class R, class T, class... P> +static _FORCE_INLINE_ bool vc_has_return_type(R (T::*method)(P...) const) { + return true; +} + +template <class T, class... P> +static _FORCE_INLINE_ bool vc_has_return_type(void (T::*method)(P...)) { + return false; +} + +template <class T, class... P> +static _FORCE_INLINE_ bool vc_has_return_type(void (T::*method)(P...) const) { + return false; +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ bool vc_is_const(R (T::*method)(P...)) { + return false; +} +template <class R, class T, class... P> +static _FORCE_INLINE_ bool vc_is_const(R (T::*method)(P...) const) { + return true; +} + +template <class T, class... P> +static _FORCE_INLINE_ bool vc_is_const(void (T::*method)(P...)) { + return false; +} + +template <class T, class... P> +static _FORCE_INLINE_ bool vc_is_const(void (T::*method)(P...) const) { + return true; +} + +template <class R, class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_base_type(R (T::*method)(P...)) { + return GetTypeInfo<T>::VARIANT_TYPE; +} +template <class R, class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_base_type(R (T::*method)(P...) const) { + return GetTypeInfo<T>::VARIANT_TYPE; +} + +template <class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...)) { + return GetTypeInfo<T>::VARIANT_TYPE; +} + +template <class T, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) const) { + return GetTypeInfo<T>::VARIANT_TYPE; +} + +#define METHOD_CLASS(m_class, m_method_name, m_method_ptr) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + vc_method_call(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + TypeAdjust<m_class>::adjust(r_ret); \ + vc_validated_call(m_method_ptr, base, p_args, r_ret); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \ + } \ + static int get_argument_count() { \ + return vc_get_argument_count(m_method_ptr); \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return vc_get_argument_type(m_method_ptr, p_arg); \ + } \ + static Variant::Type get_return_type() { \ + return vc_get_return_type(m_method_ptr); \ + } \ + static bool has_return_type() { \ + return vc_has_return_type(m_method_ptr); \ + } \ + static bool is_const() { \ + return vc_is_const(m_method_ptr); \ + } \ + static bool is_vararg() { \ + return false; \ + } \ + static Variant::Type get_base_type() { \ + return vc_get_base_type(m_method_ptr); \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ + }; + +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args_static_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret); +} + +#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<m_class>::get_ptr(base), m_method_ptr, p_args, p_argcount, r_ret, p_defvals, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + TypeAdjust<m_class>::adjust(r_ret); \ + call_with_validated_variant_args_static_retc(base, m_method_ptr, p_args, r_ret); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \ + } \ + static int get_argument_count() { \ + return vc_get_argument_count(m_method_ptr); \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return vc_get_argument_type(m_method_ptr, p_arg); \ + } \ + static Variant::Type get_return_type() { \ + return vc_get_return_type(m_method_ptr); \ + } \ + static bool has_return_type() { \ + return true; \ + } \ + static bool is_const() { \ + return true; \ + } \ + static bool is_vararg() { \ + return false; \ + } \ + static Variant::Type get_base_type() { \ + return GetTypeInfo<m_class>::VARIANT_TYPE; \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ + }; + +#define VARARG_CLASS(m_class, m_method_name, m_method_ptr, m_has_return, m_return_type) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + m_method_ptr(base, p_args, p_argcount, r_ret, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + Callable::CallError ce; \ + m_method_ptr(base, p_args, p_argcount, *r_ret, ce); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + LocalVector<Variant> vars; \ + vars.resize(p_argcount); \ + LocalVector<const Variant *> vars_ptrs; \ + vars_ptrs.resize(p_argcount); \ + for (int i = 0; i < p_argcount; i++) { \ + vars[i] = PtrToArg<Variant>::convert(p_args[i]); \ + vars_ptrs[i] = &vars[i]; \ + } \ + Variant base = PtrToArg<m_class>::convert(p_base); \ + Variant ret; \ + Callable::CallError ce; \ + m_method_ptr(&base, (const Variant **)&vars_ptrs[0], p_argcount, ret, ce); \ + if (m_has_return) { \ + m_return_type r = ret; \ + PtrToArg<m_return_type>::encode(ret, r_ret); \ + } \ + } \ + static int get_argument_count() { \ + return 0; \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return Variant::NIL; \ + } \ + static Variant::Type get_return_type() { \ + return GetTypeInfo<m_return_type>::VARIANT_TYPE; \ + } \ + static bool has_return_type() { \ + return m_has_return; \ + } \ + static bool is_const() { \ + return true; \ + } \ + static bool is_vararg() { \ + return true; \ + } \ + static Variant::Type get_base_type() { \ + return GetTypeInfo<m_class>::VARIANT_TYPE; \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ + }; + +struct _VariantCall { + static String func_PackedByteArray_get_string_from_ascii(PackedByteArray *p_instance) { + String s; + if (p_instance->size() > 0) { + const uint8_t *r = p_instance->ptr(); + CharString cs; + cs.resize(p_instance->size() + 1); + copymem(cs.ptrw(), r, p_instance->size()); + cs[p_instance->size()] = 0; + + s = cs.get_data(); + } + return s; + } + + static String func_PackedByteArray_get_string_from_utf8(PackedByteArray *p_instance) { + String s; + if (p_instance->size() > 0) { + const uint8_t *r = p_instance->ptr(); + s.parse_utf8((const char *)r, p_instance->size()); + } + return s; + } + + static String func_PackedByteArray_get_string_from_utf16(PackedByteArray *p_instance) { + String s; + if (p_instance->size() > 0) { + const uint8_t *r = p_instance->ptr(); + s.parse_utf16((const char16_t *)r, p_instance->size() / 2); + } + return s; + } + + static String func_PackedByteArray_get_string_from_utf32(PackedByteArray *p_instance) { + String s; + if (p_instance->size() > 0) { + const uint8_t *r = p_instance->ptr(); + s = String((const char32_t *)r, p_instance->size() / 4); + } + return s; + } + + static PackedByteArray func_PackedByteArray_compress(PackedByteArray *p_instance, int p_mode) { + PackedByteArray compressed; + + if (p_instance->size() > 0) { + Compression::Mode mode = (Compression::Mode)(p_mode); + compressed.resize(Compression::get_max_compressed_buffer_size(p_instance->size(), mode)); + int result = Compression::compress(compressed.ptrw(), p_instance->ptr(), p_instance->size(), mode); + + result = result >= 0 ? result : 0; + compressed.resize(result); + } + + return compressed; + } + + static PackedByteArray func_PackedByteArray_decompress(PackedByteArray *p_instance, int64_t p_buffer_size, int p_mode) { + PackedByteArray decompressed; + Compression::Mode mode = (Compression::Mode)(p_mode); + + int64_t buffer_size = p_buffer_size; + + if (buffer_size <= 0) { + ERR_FAIL_V_MSG(decompressed, "Decompression buffer size must be greater than zero."); + } + + decompressed.resize(buffer_size); + int result = Compression::decompress(decompressed.ptrw(), buffer_size, p_instance->ptr(), p_instance->size(), mode); + + result = result >= 0 ? result : 0; + decompressed.resize(result); + + return decompressed; + } + + static PackedByteArray func_PackedByteArray_decompress_dynamic(PackedByteArray *p_instance, int64_t p_buffer_size, int p_mode) { + PackedByteArray decompressed; + int64_t max_output_size = p_buffer_size; + Compression::Mode mode = (Compression::Mode)(p_mode); + + int result = Compression::decompress_dynamic(&decompressed, max_output_size, p_instance->ptr(), p_instance->size(), mode); + + if (result == OK) { + return decompressed; + } else { + decompressed.clear(); + ERR_FAIL_V_MSG(decompressed, "Decompression failed."); + } + } + + static String func_PackedByteArray_hex_encode(PackedByteArray *p_instance) { + if (p_instance->size() == 0) { + return String(); + } + const uint8_t *r = p_instance->ptr(); + String s = String::hex_encode_buffer(&r[0], p_instance->size()); + return s; + } + + static void func_Callable_call(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { + Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); + callable->call(p_args, p_argcount, r_ret, r_error); + } + + static void func_Callable_call_deferred(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { + Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); + callable->call_deferred(p_args, p_argcount); + } + + static void func_Callable_bind(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { + Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); + r_ret = callable->bind(p_args, p_argcount); + } + + static void func_Signal_emit(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { + Signal *signal = VariantGetInternalPtr<Signal>::get_ptr(v); + signal->emit(p_args, p_argcount); + } + + struct ConstantData { + Map<StringName, int> value; +#ifdef DEBUG_ENABLED + List<StringName> value_ordered; +#endif + Map<StringName, Variant> variant_value; +#ifdef DEBUG_ENABLED + List<StringName> variant_value_ordered; +#endif + }; + + static ConstantData *constant_data; + + static void add_constant(int p_type, StringName p_constant_name, int p_constant_value) { + constant_data[p_type].value[p_constant_name] = p_constant_value; +#ifdef DEBUG_ENABLED + constant_data[p_type].value_ordered.push_back(p_constant_name); +#endif + } + + static void add_variant_constant(int p_type, StringName p_constant_name, const Variant &p_constant_value) { + constant_data[p_type].variant_value[p_constant_name] = p_constant_value; +#ifdef DEBUG_ENABLED + constant_data[p_type].variant_value_ordered.push_back(p_constant_name); +#endif + } +}; + +_VariantCall::ConstantData *_VariantCall::constant_data = nullptr; + +struct VariantBuiltInMethodInfo { + void (*call)(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error); + Variant::ValidatedBuiltInMethod validated_call; + Variant::PTRBuiltInMethod ptrcall; + + Vector<Variant> default_arguments; + Vector<String> argument_names; + + bool is_const; + bool has_return_type; + bool is_vararg; + Variant::Type return_type; + int argument_count; + Variant::Type (*get_argument_type)(int p_arg); +}; + +typedef OAHashMap<StringName, VariantBuiltInMethodInfo> BuiltinMethodMap; +static BuiltinMethodMap *builtin_method_info; +static List<StringName> *builtin_method_names; + +template <class T> +static void register_builtin_method(const Vector<String> &p_argnames, const Vector<Variant> &p_def_args) { + StringName name = T::get_name(); + + ERR_FAIL_COND(builtin_method_info[T::get_base_type()].has(name)); + + VariantBuiltInMethodInfo imi; + + imi.call = T::call; + imi.validated_call = T::validated_call; + if (T::is_vararg()) { + imi.ptrcall = nullptr; + } else { + imi.ptrcall = T::ptrcall; + } + + imi.default_arguments = p_def_args; + imi.argument_names = p_argnames; + + imi.is_const = T::is_const(); + imi.is_vararg = T::is_vararg(); + imi.has_return_type = T::has_return_type(); + imi.return_type = T::get_return_type(); + imi.argument_count = T::get_argument_count(); + imi.get_argument_type = T::get_argument_type; +#ifdef DEBUG_METHODS_ENABLED + ERR_FAIL_COND(!imi.is_vararg && imi.argument_count != imi.argument_names.size()); +#endif + + builtin_method_info[T::get_base_type()].insert(name, imi); + builtin_method_names[T::get_base_type()].push_back(name); +} + +void Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { + if (type == Variant::OBJECT) { + //call object + Object *obj = _get_obj().obj; + if (!obj) { + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return; + } +#ifdef DEBUG_ENABLED + if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return; + } + +#endif + r_ret = _get_obj().obj->call(p_method, p_args, p_argcount, r_error); + + //else if (type==Variant::METHOD) { + + } else { + r_error.error = Callable::CallError::CALL_OK; + + const VariantBuiltInMethodInfo *imf = builtin_method_info[type].lookup_ptr(p_method); + + if (!imf) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return; + } + + imf->call(this, p_args, p_argcount, r_ret, imf->default_arguments, r_error); + } +} + +bool Variant::has_method(const StringName &p_method) const { + if (type == OBJECT) { + Object *obj = get_validated_object(); + if (!obj) { + return false; + } + + return obj->has_method(p_method); + } + + return builtin_method_info[type].has(p_method); +} + +bool Variant::has_builtin_method(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + return builtin_method_info[p_type].has(p_method); +} + +Variant::ValidatedBuiltInMethod Variant::get_validated_builtin_method(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, nullptr); + return method->validated_call; +} + +Variant::PTRBuiltInMethod Variant::get_ptr_builtin_method(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, nullptr); + return method->ptrcall; +} + +int Variant::get_builtin_method_argument_count(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, 0); + return method->argument_count; +} + +Variant::Type Variant::get_builtin_method_argument_type(Variant::Type p_type, const StringName &p_method, int p_argument) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::NIL); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, Variant::NIL); + ERR_FAIL_INDEX_V(p_argument, method->argument_count, Variant::NIL); + return method->get_argument_type(p_argument); +} + +String Variant::get_builtin_method_argument_name(Variant::Type p_type, const StringName &p_method, int p_argument) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, String()); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, String()); +#ifdef DEBUG_METHODS_ENABLED + ERR_FAIL_INDEX_V(p_argument, method->argument_count, String()); + return method->argument_names[p_argument]; +#else + return "arg" + itos(p_argument + 1); +#endif +} + +Vector<Variant> Variant::get_builtin_method_default_arguments(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Vector<Variant>()); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, Vector<Variant>()); + return method->default_arguments; +} + +bool Variant::has_builtin_method_return_value(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, false); + return method->has_return_type; +} + +void Variant::get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list) { + ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); + for (List<StringName>::Element *E = builtin_method_names[p_type].front(); E; E = E->next()) { + p_list->push_back(E->get()); + } +} + +Variant::Type Variant::get_builtin_method_return_type(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::NIL); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, Variant::NIL); + return method->return_type; +} + +bool Variant::is_builtin_method_const(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, false); + return method->is_const; +} + +bool Variant::is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, false); + return method->is_vararg; +} + +void Variant::get_method_list(List<MethodInfo> *p_list) const { + if (type == OBJECT) { + Object *obj = get_validated_object(); + if (obj) { + obj->get_method_list(p_list); + } + } else { + for (List<StringName>::Element *E = builtin_method_names[type].front(); E; E = E->next()) { + const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E->get()); + ERR_CONTINUE(!method); + + MethodInfo mi; + mi.name = E->get(); + + //return type + if (method->has_return_type) { + mi.return_val.type = method->return_type; + if (mi.return_val.type == Variant::NIL) { + mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } + } + + if (method->is_const) { + mi.flags |= METHOD_FLAG_CONST; + } + if (method->is_vararg) { + mi.flags |= METHOD_FLAG_VARARG; + } + + for (int i = 0; i < method->argument_count; i++) { + PropertyInfo pi; +#ifdef DEBUG_METHODS_ENABLED + pi.name = method->argument_names[i]; +#else + pi.name = "arg" + itos(i + 1); +#endif + pi.type = method->get_argument_type(i); + if (pi.type == Variant::NIL) { + pi.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } + mi.arguments.push_back(pi); + } + + mi.default_arguments = method->default_arguments; + p_list->push_back(mi); + } + } +} + +void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants) { + ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); + + _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; + +#ifdef DEBUG_ENABLED + for (List<StringName>::Element *E = cd.value_ordered.front(); E; E = E->next()) { + p_constants->push_back(E->get()); +#else + for (Map<StringName, int>::Element *E = cd.value.front(); E; E = E->next()) { + p_constants->push_back(E->key()); +#endif + } + +#ifdef DEBUG_ENABLED + for (List<StringName>::Element *E = cd.variant_value_ordered.front(); E; E = E->next()) { + p_constants->push_back(E->get()); +#else + for (Map<StringName, Variant>::Element *E = cd.variant_value.front(); E; E = E->next()) { + p_constants->push_back(E->key()); +#endif + } +} + +bool Variant::has_constant(Variant::Type p_type, const StringName &p_value) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; + return cd.value.has(p_value) || cd.variant_value.has(p_value); +} + +Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid) { + if (r_valid) { + *r_valid = false; + } + + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0); + _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; + + Map<StringName, int>::Element *E = cd.value.find(p_value); + if (!E) { + Map<StringName, Variant>::Element *F = cd.variant_value.find(p_value); + if (F) { + if (r_valid) { + *r_valid = true; + } + return F->get(); + } else { + return -1; + } + } + if (r_valid) { + *r_valid = true; + } + + return E->get(); +} + +#ifdef DEBUG_METHODS_ENABLED +#define bind_method(m_type, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_method, &m_type::m_method); \ + register_builtin_method<Method_##m_type##_##m_method>(m_arg_names, m_default_args); +#else +#define bind_method(m_type, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_method, &m_type ::m_method); \ + register_builtin_method<Method_##m_type##_##m_method>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED +#define bind_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_name, m_method); \ + register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); +#else +#define bind_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_name, m_method); \ + register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED +#define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_name, m_method); \ + register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); +#else +#define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_name, m_method); \ + register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args); +#endif + +#define bind_custom(m_type, m_name, m_method, m_has_return, m_ret_type) \ + VARARG_CLASS(m_type, m_name, m_method, m_has_return, m_ret_type) \ + register_builtin_method<Method_##m_type##_##m_name>(sarray(), Vector<Variant>()); + +static void _register_variant_builtin_methods() { + _VariantCall::constant_data = memnew_arr(_VariantCall::ConstantData, Variant::VARIANT_MAX); + builtin_method_info = memnew_arr(BuiltinMethodMap, Variant::VARIANT_MAX); + builtin_method_names = memnew_arr(List<StringName>, Variant::VARIANT_MAX); + + /* String */ + + bind_method(String, casecmp_to, sarray("to"), varray()); + bind_method(String, nocasecmp_to, sarray("to"), varray()); + bind_method(String, naturalnocasecmp_to, sarray("to"), varray()); + bind_method(String, length, sarray(), varray()); + bind_method(String, substr, sarray("from", "len"), varray(-1)); + bind_methodv(String, find, static_cast<int (String::*)(const String &, int) const>(&String::find), sarray("what", "from"), varray(0)); + bind_method(String, count, sarray("what", "from", "to"), varray(0, 0)); + bind_method(String, countn, sarray("what", "from", "to"), varray(0, 0)); + bind_method(String, findn, sarray("what", "from"), varray(0)); + bind_method(String, rfind, sarray("what", "from"), varray(-1)); + bind_method(String, rfindn, sarray("what", "from"), varray(-1)); + bind_method(String, match, sarray("expr"), varray()); + bind_method(String, matchn, sarray("expr"), varray()); + bind_methodv(String, begins_with, static_cast<bool (String::*)(const String &) const>(&String::begins_with), sarray("text"), varray()); + bind_method(String, ends_with, sarray("text"), varray()); + bind_method(String, is_subsequence_of, sarray("text"), varray()); + bind_method(String, is_subsequence_ofi, sarray("text"), varray()); + bind_method(String, bigrams, sarray(), varray()); + bind_method(String, similarity, sarray("text"), varray()); + + bind_method(String, format, sarray("values", "placeholder"), varray("{_}")); + bind_methodv(String, replace, static_cast<String (String::*)(const String &, const String &) const>(&String::replace), sarray("what", "forwhat"), varray()); + bind_method(String, replacen, sarray("what", "forwhat"), varray()); + bind_method(String, repeat, sarray("count"), varray()); + bind_method(String, insert, sarray("position", "what"), varray()); + bind_method(String, capitalize, sarray(), varray()); + bind_method(String, split, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0)); + bind_method(String, rsplit, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0)); + bind_method(String, split_floats, sarray("delimiter", "allow_empty"), varray(true)); + bind_method(String, join, sarray("parts"), varray()); + + bind_method(String, to_upper, sarray(), varray()); + bind_method(String, to_lower, sarray(), varray()); + + bind_method(String, left, sarray("position"), varray()); + bind_method(String, right, sarray("position"), varray()); + + bind_method(String, strip_edges, sarray("left", "right"), varray(true, true)); + bind_method(String, strip_escapes, sarray(), varray()); + bind_method(String, lstrip, sarray("chars"), varray()); + bind_method(String, rstrip, sarray("chars"), varray()); + bind_method(String, get_extension, sarray(), varray()); + bind_method(String, get_basename, sarray(), varray()); + bind_method(String, plus_file, sarray("file"), varray()); + bind_method(String, ord_at, sarray("at"), varray()); + bind_method(String, dedent, sarray(), varray()); + // FIXME: String needs to be immutable when binding + //bind_method(String, erase, sarray("position", "chars"), varray()); + bind_method(String, hash, sarray(), varray()); + bind_method(String, md5_text, sarray(), varray()); + bind_method(String, sha1_text, sarray(), varray()); + bind_method(String, sha256_text, sarray(), varray()); + bind_method(String, md5_buffer, sarray(), varray()); + bind_method(String, sha1_buffer, sarray(), varray()); + bind_method(String, sha256_buffer, sarray(), varray()); + bind_method(String, empty, sarray(), varray()); + // FIXME: Static function, not sure how to bind + //bind_method(String, humanize_size, sarray("size"), varray()); + + bind_method(String, is_abs_path, sarray(), varray()); + bind_method(String, is_rel_path, sarray(), varray()); + bind_method(String, get_base_dir, sarray(), varray()); + bind_method(String, get_file, sarray(), varray()); + bind_method(String, xml_escape, sarray("escape_quotes"), varray(false)); + bind_method(String, xml_unescape, sarray(), varray()); + bind_method(String, http_escape, sarray(), varray()); + bind_method(String, http_unescape, sarray(), varray()); + bind_method(String, c_escape, sarray(), varray()); + bind_method(String, c_unescape, sarray(), varray()); + bind_method(String, json_escape, sarray(), varray()); + bind_method(String, percent_encode, sarray(), varray()); + bind_method(String, percent_decode, sarray(), varray()); + + bind_method(String, is_valid_identifier, sarray(), varray()); + bind_method(String, is_valid_integer, sarray(), varray()); + bind_method(String, is_valid_float, sarray(), varray()); + bind_method(String, is_valid_hex_number, sarray("with_prefix"), varray(false)); + bind_method(String, is_valid_html_color, sarray(), varray()); + bind_method(String, is_valid_ip_address, sarray(), varray()); + bind_method(String, is_valid_filename, sarray(), varray()); + + bind_method(String, to_int, sarray(), varray()); + bind_method(String, to_float, sarray(), varray()); + bind_method(String, hex_to_int, sarray("with_prefix"), varray(true)); + bind_method(String, bin_to_int, sarray("with_prefix"), varray(true)); + + bind_method(String, lpad, sarray("min_length", "character"), varray(" ")); + bind_method(String, rpad, sarray("min_length", "character"), varray(" ")); + bind_method(String, pad_decimals, sarray("digits"), varray()); + bind_method(String, pad_zeros, sarray("digits"), varray()); + bind_method(String, trim_prefix, sarray("prefix"), varray()); + bind_method(String, trim_suffix, sarray("suffix"), varray()); + + bind_method(String, to_ascii_buffer, sarray(), varray()); + bind_method(String, to_utf8_buffer, sarray(), varray()); + bind_method(String, to_utf16_buffer, sarray(), varray()); + bind_method(String, to_utf32_buffer, sarray(), varray()); + + /* Vector2 */ + + bind_method(Vector2, angle, sarray(), varray()); + bind_method(Vector2, angle_to, sarray("to"), varray()); + bind_method(Vector2, angle_to_point, sarray("to"), varray()); + bind_method(Vector2, direction_to, sarray("b"), varray()); + bind_method(Vector2, distance_to, sarray("to"), varray()); + bind_method(Vector2, distance_squared_to, sarray("to"), varray()); + bind_method(Vector2, length, sarray(), varray()); + bind_method(Vector2, length_squared, sarray(), varray()); + bind_method(Vector2, normalized, sarray(), varray()); + bind_method(Vector2, is_normalized, sarray(), varray()); + bind_method(Vector2, is_equal_approx, sarray("to"), varray()); + bind_method(Vector2, posmod, sarray("mod"), varray()); + bind_method(Vector2, posmodv, sarray("modv"), varray()); + bind_method(Vector2, project, sarray("b"), varray()); + bind_method(Vector2, lerp, sarray("with", "t"), varray()); + bind_method(Vector2, slerp, sarray("with", "t"), varray()); + bind_method(Vector2, cubic_interpolate, sarray("b", "pre_a", "post_b", "t"), varray()); + bind_method(Vector2, move_toward, sarray("to", "delta"), varray()); + bind_method(Vector2, rotated, sarray("phi"), varray()); + bind_method(Vector2, tangent, sarray(), varray()); + bind_method(Vector2, floor, sarray(), varray()); + bind_method(Vector2, ceil, sarray(), varray()); + bind_method(Vector2, round, sarray(), varray()); + bind_method(Vector2, aspect, sarray(), varray()); + bind_method(Vector2, dot, sarray("with"), varray()); + bind_method(Vector2, slide, sarray("n"), varray()); + bind_method(Vector2, bounce, sarray("n"), varray()); + bind_method(Vector2, reflect, sarray("n"), varray()); + bind_method(Vector2, cross, sarray("with"), varray()); + bind_method(Vector2, abs, sarray(), varray()); + bind_method(Vector2, sign, sarray(), varray()); + bind_method(Vector2, snapped, sarray("by"), varray()); + bind_method(Vector2, clamped, sarray("length"), varray()); + + /* Vector2i */ + + bind_method(Vector2i, aspect, sarray(), varray()); + bind_method(Vector2i, sign, sarray(), varray()); + bind_method(Vector2i, abs, sarray(), varray()); + + /* Rect2 */ + + bind_method(Rect2, get_area, sarray(), varray()); + bind_method(Rect2, has_no_area, sarray(), varray()); + bind_method(Rect2, has_point, sarray("point"), varray()); + bind_method(Rect2, is_equal_approx, sarray("rect"), varray()); + bind_method(Rect2, intersects, sarray("b", "include_borders"), varray(false)); + bind_method(Rect2, encloses, sarray("b"), varray()); + bind_method(Rect2, clip, sarray("b"), varray()); + bind_method(Rect2, merge, sarray("b"), varray()); + bind_method(Rect2, expand, sarray("to"), varray()); + bind_method(Rect2, grow, sarray("by"), varray()); + bind_methodv(Rect2, grow_margin, &Rect2::grow_margin_bind, sarray("margin", "by"), varray()); + bind_method(Rect2, grow_individual, sarray("left", "top", "right", "bottom"), varray()); + bind_method(Rect2, abs, sarray(), varray()); + + /* Rect2i */ + + bind_method(Rect2i, get_area, sarray(), varray()); + bind_method(Rect2i, has_no_area, sarray(), varray()); + bind_method(Rect2i, has_point, sarray("point"), varray()); + bind_method(Rect2i, intersects, sarray("b"), varray()); + bind_method(Rect2i, encloses, sarray("b"), varray()); + bind_method(Rect2i, clip, sarray("b"), varray()); + bind_method(Rect2i, merge, sarray("b"), varray()); + bind_method(Rect2i, expand, sarray("to"), varray()); + bind_method(Rect2i, grow, sarray("by"), varray()); + bind_methodv(Rect2i, grow_margin, &Rect2i::grow_margin_bind, sarray("margin", "by"), varray()); + bind_method(Rect2i, grow_individual, sarray("left", "top", "right", "bottom"), varray()); + bind_method(Rect2i, abs, sarray(), varray()); + + /* Vector3 */ + + bind_method(Vector3, min_axis, sarray(), varray()); + bind_method(Vector3, max_axis, sarray(), varray()); + bind_method(Vector3, angle_to, sarray("to"), varray()); + bind_method(Vector3, direction_to, sarray("b"), varray()); + bind_method(Vector3, distance_to, sarray("b"), varray()); + bind_method(Vector3, distance_squared_to, sarray("b"), varray()); + bind_method(Vector3, length, sarray(), varray()); + bind_method(Vector3, length_squared, sarray(), varray()); + bind_method(Vector3, normalized, sarray(), varray()); + bind_method(Vector3, is_normalized, sarray(), varray()); + bind_method(Vector3, is_equal_approx, sarray("to"), varray()); + bind_method(Vector3, inverse, sarray(), varray()); + bind_method(Vector3, snapped, sarray("by"), varray()); + bind_method(Vector3, rotated, sarray("by_axis", "phi"), varray()); + bind_method(Vector3, lerp, sarray("b", "t"), varray()); + bind_method(Vector3, slerp, sarray("b", "t"), varray()); + bind_method(Vector3, cubic_interpolate, sarray("b", "pre_a", "post_b", "t"), varray()); + bind_method(Vector3, move_toward, sarray("to", "delta"), varray()); + bind_method(Vector3, dot, sarray("with"), varray()); + bind_method(Vector3, cross, sarray("with"), varray()); + bind_method(Vector3, outer, sarray("with"), varray()); + bind_method(Vector3, to_diagonal_matrix, sarray(), varray()); + bind_method(Vector3, abs, sarray(), varray()); + bind_method(Vector3, floor, sarray(), varray()); + bind_method(Vector3, ceil, sarray(), varray()); + bind_method(Vector3, round, sarray(), varray()); + bind_method(Vector3, posmod, sarray("mod"), varray()); + bind_method(Vector3, posmodv, sarray("modv"), varray()); + bind_method(Vector3, project, sarray("b"), varray()); + bind_method(Vector3, slide, sarray("n"), varray()); + bind_method(Vector3, bounce, sarray("n"), varray()); + bind_method(Vector3, reflect, sarray("n"), varray()); + bind_method(Vector3, sign, sarray(), varray()); + + /* Vector3i */ + + bind_method(Vector3i, min_axis, sarray(), varray()); + bind_method(Vector3i, max_axis, sarray(), varray()); + bind_method(Vector3i, sign, sarray(), varray()); + bind_method(Vector3i, abs, sarray(), varray()); + + /* Plane */ + + bind_method(Plane, normalized, sarray(), varray()); + bind_method(Plane, center, sarray(), varray()); + bind_method(Plane, is_equal_approx, sarray("to_plane"), varray()); + bind_method(Plane, is_point_over, sarray("plane"), varray()); + bind_method(Plane, distance_to, sarray("point"), varray()); + bind_method(Plane, has_point, sarray("point", "epsilon"), varray(CMP_EPSILON)); + bind_method(Plane, project, sarray("point"), varray()); + bind_methodv(Plane, intersect_3, &Plane::intersect_3_bind, sarray("b", "c"), varray()); + bind_methodv(Plane, intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray()); + bind_methodv(Plane, intersects_segment, &Plane::intersects_segment_bind, sarray("from", "to"), varray()); + + /* Quat */ + + bind_method(Quat, length, sarray(), varray()); + bind_method(Quat, length_squared, sarray(), varray()); + bind_method(Quat, normalized, sarray(), varray()); + bind_method(Quat, is_normalized, sarray(), varray()); + bind_method(Quat, is_equal_approx, sarray("to"), varray()); + bind_method(Quat, inverse, sarray(), varray()); + bind_method(Quat, dot, sarray("with"), varray()); + bind_method(Quat, slerp, sarray("b", "t"), varray()); + bind_method(Quat, slerpni, sarray("b", "t"), varray()); + bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "t"), varray()); + bind_method(Quat, get_euler, sarray(), varray()); + + // FIXME: Quat is atomic, this should be done via construcror + //ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray()); + //ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", FLOAT, "angle", varray()); + + /* Color */ + + bind_method(Color, to_argb32, sarray(), varray()); + bind_method(Color, to_abgr32, sarray(), varray()); + bind_method(Color, to_rgba32, sarray(), varray()); + bind_method(Color, to_argb64, sarray(), varray()); + bind_method(Color, to_abgr64, sarray(), varray()); + bind_method(Color, to_rgba64, sarray(), varray()); + + bind_method(Color, inverted, sarray(), varray()); + bind_method(Color, lerp, sarray("b", "t"), varray()); + bind_method(Color, lightened, sarray("amount"), varray()); + bind_method(Color, darkened, sarray("amount"), varray()); + bind_method(Color, to_html, sarray("with_alpha"), varray(true)); + bind_method(Color, blend, sarray("over"), varray()); + + // FIXME: Color is immutable, need to probably find a way to do this via constructor + //ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0)); + bind_method(Color, is_equal_approx, sarray("to"), varray()); + + /* RID */ + + bind_method(RID, get_id, sarray(), varray()); + + /* NodePath */ + + bind_method(NodePath, is_absolute, sarray(), varray()); + bind_method(NodePath, get_name_count, sarray(), varray()); + bind_method(NodePath, get_name, sarray("idx"), varray()); + bind_method(NodePath, get_subname_count, sarray(), varray()); + bind_method(NodePath, get_subname, sarray("idx"), varray()); + bind_method(NodePath, get_concatenated_subnames, sarray(), varray()); + bind_method(NodePath, get_as_property_path, sarray(), varray()); + bind_method(NodePath, is_empty, sarray(), varray()); + + /* Callable */ + + bind_method(Callable, is_null, sarray(), varray()); + bind_method(Callable, is_custom, sarray(), varray()); + bind_method(Callable, is_standard, sarray(), varray()); + bind_method(Callable, get_object, sarray(), varray()); + bind_method(Callable, get_object_id, sarray(), varray()); + bind_method(Callable, get_method, sarray(), varray()); + bind_method(Callable, hash, sarray(), varray()); + bind_method(Callable, unbind, sarray("argcount"), varray()); + + bind_custom(Callable, call, _VariantCall::func_Callable_call, true, Variant); + bind_custom(Callable, call_deferred, _VariantCall::func_Callable_call_deferred, false, Variant); + bind_custom(Callable, bind, _VariantCall::func_Callable_bind, true, Callable); + + /* Signal */ + + bind_method(Signal, is_null, sarray(), varray()); + bind_method(Signal, get_object, sarray(), varray()); + bind_method(Signal, get_object_id, sarray(), varray()); + bind_method(Signal, get_name, sarray(), varray()); + + bind_method(Signal, connect, sarray("callable", "binds", "flags"), varray(Array(), 0)); + bind_method(Signal, disconnect, sarray("callable"), varray()); + bind_method(Signal, is_connected, sarray("callable"), varray()); + bind_method(Signal, get_connections, sarray(), varray()); + + bind_custom(Signal, emit, _VariantCall::func_Signal_emit, false, Variant); + + /* Transform2D */ + + bind_method(Transform2D, inverse, sarray(), varray()); + bind_method(Transform2D, affine_inverse, sarray(), varray()); + bind_method(Transform2D, get_rotation, sarray(), varray()); + bind_method(Transform2D, get_origin, sarray(), varray()); + bind_method(Transform2D, get_scale, sarray(), varray()); + bind_method(Transform2D, orthonormalized, sarray(), varray()); + bind_method(Transform2D, rotated, sarray("phi"), varray()); + bind_method(Transform2D, scaled, sarray("scale"), varray()); + bind_method(Transform2D, translated, sarray("offset"), varray()); + bind_method(Transform2D, basis_xform, sarray("v"), varray()); + bind_method(Transform2D, basis_xform_inv, sarray("v"), varray()); + bind_method(Transform2D, interpolate_with, sarray("xform", "t"), varray()); + bind_method(Transform2D, is_equal_approx, sarray("xform"), varray()); + + /* Basis */ + + bind_method(Basis, inverse, sarray(), varray()); + bind_method(Basis, transposed, sarray(), varray()); + bind_method(Basis, orthonormalized, sarray(), varray()); + bind_method(Basis, determinant, sarray(), varray()); + bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, float) const>(&Basis::rotated), sarray("axis", "phi"), varray()); + bind_method(Basis, scaled, sarray("scale"), varray()); + bind_method(Basis, get_scale, sarray(), varray()); + bind_method(Basis, get_euler, sarray(), varray()); + bind_method(Basis, tdotx, sarray("with"), varray()); + bind_method(Basis, tdoty, sarray("with"), varray()); + bind_method(Basis, tdotz, sarray("with"), varray()); + bind_method(Basis, get_orthogonal_index, sarray(), varray()); + bind_method(Basis, slerp, sarray("b", "t"), varray()); + bind_method(Basis, is_equal_approx, sarray("b"), varray()); + bind_method(Basis, get_rotation_quat, sarray(), varray()); + + /* AABB */ + + bind_method(AABB, abs, sarray(), varray()); + bind_method(AABB, get_area, sarray(), varray()); + bind_method(AABB, has_no_area, sarray(), varray()); + bind_method(AABB, has_no_surface, sarray(), varray()); + bind_method(AABB, has_point, sarray("point"), varray()); + bind_method(AABB, is_equal_approx, sarray("aabb"), varray()); + bind_method(AABB, intersects, sarray("with"), varray()); + bind_method(AABB, encloses, sarray("with"), varray()); + bind_method(AABB, intersects_plane, sarray("plane"), varray()); + bind_method(AABB, intersection, sarray("with"), varray()); + bind_method(AABB, merge, sarray("with"), varray()); + bind_method(AABB, expand, sarray("to_point"), varray()); + bind_method(AABB, grow, sarray("by"), varray()); + bind_method(AABB, get_support, sarray("dir"), varray()); + bind_method(AABB, get_longest_axis, sarray(), varray()); + bind_method(AABB, get_longest_axis_index, sarray(), varray()); + bind_method(AABB, get_longest_axis_size, sarray(), varray()); + bind_method(AABB, get_shortest_axis, sarray(), varray()); + bind_method(AABB, get_shortest_axis_index, sarray(), varray()); + bind_method(AABB, get_shortest_axis_size, sarray(), varray()); + bind_method(AABB, get_endpoint, sarray("idx"), varray()); + bind_methodv(AABB, intersects_segment, &AABB::intersects_segment_bind, sarray("from", "to"), varray()); + bind_methodv(AABB, intersects_ray, &AABB::intersects_ray_bind, sarray("from", "dir"), varray()); + + /* Transform */ + + bind_method(Transform, inverse, sarray(), varray()); + bind_method(Transform, affine_inverse, sarray(), varray()); + bind_method(Transform, orthonormalized, sarray(), varray()); + bind_method(Transform, rotated, sarray("axis", "phi"), varray()); + bind_method(Transform, scaled, sarray("scale"), varray()); + bind_method(Transform, translated, sarray("offset"), varray()); + bind_method(Transform, looking_at, sarray("target", "up"), varray()); + bind_method(Transform, interpolate_with, sarray("xform", "weight"), varray()); + bind_method(Transform, is_equal_approx, sarray("xform"), varray()); + + /* Dictionary */ + + bind_method(Dictionary, size, sarray(), varray()); + bind_method(Dictionary, empty, sarray(), varray()); + bind_method(Dictionary, clear, sarray(), varray()); + bind_method(Dictionary, has, sarray("key"), varray()); + bind_method(Dictionary, has_all, sarray("keys"), varray()); + bind_method(Dictionary, erase, sarray("key"), varray()); + bind_method(Dictionary, hash, sarray(), varray()); + bind_method(Dictionary, keys, sarray(), varray()); + bind_method(Dictionary, values, sarray(), varray()); + bind_method(Dictionary, duplicate, sarray("deep"), varray(false)); + bind_method(Dictionary, get, sarray("key", "default"), varray(Variant())); + + /* Array */ + + bind_method(Array, size, sarray(), varray()); + bind_method(Array, empty, sarray(), varray()); + bind_method(Array, clear, sarray(), varray()); + bind_method(Array, hash, sarray(), varray()); + bind_method(Array, push_back, sarray("value"), varray()); + bind_method(Array, push_front, sarray("value"), varray()); + bind_method(Array, append, sarray("value"), varray()); + bind_method(Array, append_array, sarray("array"), varray()); + bind_method(Array, resize, sarray("size"), varray()); + bind_method(Array, insert, sarray("position", "value"), varray()); + bind_method(Array, remove, sarray("position"), varray()); + bind_method(Array, erase, sarray("value"), varray()); + bind_method(Array, front, sarray(), varray()); + bind_method(Array, back, sarray(), varray()); + bind_method(Array, find, sarray("what", "from"), varray(0)); + bind_method(Array, rfind, sarray("what", "from"), varray(-1)); + bind_method(Array, find_last, sarray("value"), varray()); + bind_method(Array, count, sarray("value"), varray()); + bind_method(Array, has, sarray("value"), varray()); + bind_method(Array, pop_back, sarray(), varray()); + bind_method(Array, pop_front, sarray(), varray()); + bind_method(Array, sort, sarray(), varray()); + bind_method(Array, sort_custom, sarray("obj", "func"), varray()); + bind_method(Array, shuffle, sarray(), varray()); + bind_method(Array, bsearch, sarray("value", "before"), varray(true)); + bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true)); + bind_method(Array, invert, sarray(), varray()); + bind_method(Array, duplicate, sarray("deep"), varray(false)); + bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); + bind_method(Array, max, sarray(), varray()); + bind_method(Array, min, sarray(), varray()); + + /* Byte Array */ + bind_method(PackedByteArray, size, sarray(), varray()); + bind_method(PackedByteArray, empty, sarray(), varray()); + bind_method(PackedByteArray, set, sarray("index", "value"), varray()); + bind_method(PackedByteArray, push_back, sarray("value"), varray()); + bind_method(PackedByteArray, append, sarray("value"), varray()); + bind_method(PackedByteArray, append_array, sarray("array"), varray()); + bind_method(PackedByteArray, remove, sarray("index"), varray()); + bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray()); + bind_method(PackedByteArray, resize, sarray("new_size"), varray()); + bind_method(PackedByteArray, has, sarray("value"), varray()); + bind_method(PackedByteArray, invert, sarray(), varray()); + bind_method(PackedByteArray, subarray, sarray("from", "to"), varray()); + bind_method(PackedByteArray, sort, sarray(), varray()); + + bind_function(PackedByteArray, get_string_from_ascii, _VariantCall::func_PackedByteArray_get_string_from_ascii, sarray(), varray()); + bind_function(PackedByteArray, get_string_from_utf8, _VariantCall::func_PackedByteArray_get_string_from_utf8, sarray(), varray()); + bind_function(PackedByteArray, get_string_from_utf16, _VariantCall::func_PackedByteArray_get_string_from_utf16, sarray(), varray()); + bind_function(PackedByteArray, get_string_from_utf32, _VariantCall::func_PackedByteArray_get_string_from_utf32, sarray(), varray()); + bind_function(PackedByteArray, hex_encode, _VariantCall::func_PackedByteArray_hex_encode, sarray(), varray()); + bind_function(PackedByteArray, compress, _VariantCall::func_PackedByteArray_compress, sarray("compression_mode"), varray(0)); + bind_function(PackedByteArray, decompress, _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray(0)); + bind_function(PackedByteArray, decompress_dynamic, _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray(0)); + + /* Int32 Array */ + + bind_method(PackedInt32Array, size, sarray(), varray()); + bind_method(PackedInt32Array, empty, sarray(), varray()); + bind_method(PackedInt32Array, set, sarray("index", "value"), varray()); + bind_method(PackedInt32Array, push_back, sarray("value"), varray()); + bind_method(PackedInt32Array, append, sarray("value"), varray()); + bind_method(PackedInt32Array, append_array, sarray("array"), varray()); + bind_method(PackedInt32Array, remove, sarray("index"), varray()); + bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedInt32Array, resize, sarray("new_size"), varray()); + bind_method(PackedInt32Array, has, sarray("value"), varray()); + bind_method(PackedInt32Array, invert, sarray(), varray()); + bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray()); + bind_method(PackedInt32Array, to_byte_array, sarray(), varray()); + bind_method(PackedInt32Array, sort, sarray(), varray()); + + /* Int64 Array */ + + bind_method(PackedInt64Array, size, sarray(), varray()); + bind_method(PackedInt64Array, empty, sarray(), varray()); + bind_method(PackedInt64Array, set, sarray("index", "value"), varray()); + bind_method(PackedInt64Array, push_back, sarray("value"), varray()); + bind_method(PackedInt64Array, append, sarray("value"), varray()); + bind_method(PackedInt64Array, append_array, sarray("array"), varray()); + bind_method(PackedInt64Array, remove, sarray("index"), varray()); + bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedInt64Array, resize, sarray("new_size"), varray()); + bind_method(PackedInt64Array, has, sarray("value"), varray()); + bind_method(PackedInt64Array, invert, sarray(), varray()); + bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray()); + bind_method(PackedInt64Array, to_byte_array, sarray(), varray()); + bind_method(PackedInt64Array, sort, sarray(), varray()); + + /* Float32 Array */ + + bind_method(PackedFloat32Array, size, sarray(), varray()); + bind_method(PackedFloat32Array, empty, sarray(), varray()); + bind_method(PackedFloat32Array, set, sarray("index", "value"), varray()); + bind_method(PackedFloat32Array, push_back, sarray("value"), varray()); + bind_method(PackedFloat32Array, append, sarray("value"), varray()); + bind_method(PackedFloat32Array, append_array, sarray("array"), varray()); + bind_method(PackedFloat32Array, remove, sarray("index"), varray()); + bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedFloat32Array, resize, sarray("new_size"), varray()); + bind_method(PackedFloat32Array, has, sarray("value"), varray()); + bind_method(PackedFloat32Array, invert, sarray(), varray()); + bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray()); + bind_method(PackedFloat32Array, to_byte_array, sarray(), varray()); + bind_method(PackedFloat32Array, sort, sarray(), varray()); + + /* Float64 Array */ + + bind_method(PackedFloat64Array, size, sarray(), varray()); + bind_method(PackedFloat64Array, empty, sarray(), varray()); + bind_method(PackedFloat64Array, set, sarray("index", "value"), varray()); + bind_method(PackedFloat64Array, push_back, sarray("value"), varray()); + bind_method(PackedFloat64Array, append, sarray("value"), varray()); + bind_method(PackedFloat64Array, append_array, sarray("array"), varray()); + bind_method(PackedFloat64Array, remove, sarray("index"), varray()); + bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedFloat64Array, resize, sarray("new_size"), varray()); + bind_method(PackedFloat64Array, has, sarray("value"), varray()); + bind_method(PackedFloat64Array, invert, sarray(), varray()); + bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray()); + bind_method(PackedFloat64Array, to_byte_array, sarray(), varray()); + bind_method(PackedFloat64Array, sort, sarray(), varray()); + + /* String Array */ + + bind_method(PackedStringArray, size, sarray(), varray()); + bind_method(PackedStringArray, empty, sarray(), varray()); + bind_method(PackedStringArray, set, sarray("index", "value"), varray()); + bind_method(PackedStringArray, push_back, sarray("value"), varray()); + bind_method(PackedStringArray, append, sarray("value"), varray()); + bind_method(PackedStringArray, append_array, sarray("array"), varray()); + bind_method(PackedStringArray, remove, sarray("index"), varray()); + bind_method(PackedStringArray, insert, sarray("at_index", "value"), varray()); + bind_method(PackedStringArray, resize, sarray("new_size"), varray()); + bind_method(PackedStringArray, has, sarray("value"), varray()); + bind_method(PackedStringArray, invert, sarray(), varray()); + bind_method(PackedStringArray, subarray, sarray("from", "to"), varray()); + bind_method(PackedStringArray, to_byte_array, sarray(), varray()); + bind_method(PackedStringArray, sort, sarray(), varray()); + + /* Vector2 Array */ + + bind_method(PackedVector2Array, size, sarray(), varray()); + bind_method(PackedVector2Array, empty, sarray(), varray()); + bind_method(PackedVector2Array, set, sarray("index", "value"), varray()); + bind_method(PackedVector2Array, push_back, sarray("value"), varray()); + bind_method(PackedVector2Array, append, sarray("value"), varray()); + bind_method(PackedVector2Array, append_array, sarray("array"), varray()); + bind_method(PackedVector2Array, remove, sarray("index"), varray()); + bind_method(PackedVector2Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedVector2Array, resize, sarray("new_size"), varray()); + bind_method(PackedVector2Array, has, sarray("value"), varray()); + bind_method(PackedVector2Array, invert, sarray(), varray()); + bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray()); + bind_method(PackedVector2Array, to_byte_array, sarray(), varray()); + bind_method(PackedVector2Array, sort, sarray(), varray()); + + /* Vector3 Array */ + + bind_method(PackedVector3Array, size, sarray(), varray()); + bind_method(PackedVector3Array, empty, sarray(), varray()); + bind_method(PackedVector3Array, set, sarray("index", "value"), varray()); + bind_method(PackedVector3Array, push_back, sarray("value"), varray()); + bind_method(PackedVector3Array, append, sarray("value"), varray()); + bind_method(PackedVector3Array, append_array, sarray("array"), varray()); + bind_method(PackedVector3Array, remove, sarray("index"), varray()); + bind_method(PackedVector3Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedVector3Array, resize, sarray("new_size"), varray()); + bind_method(PackedVector3Array, has, sarray("value"), varray()); + bind_method(PackedVector3Array, invert, sarray(), varray()); + bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray()); + bind_method(PackedVector3Array, to_byte_array, sarray(), varray()); + bind_method(PackedVector3Array, sort, sarray(), varray()); + + /* Color Array */ + + bind_method(PackedColorArray, size, sarray(), varray()); + bind_method(PackedColorArray, empty, sarray(), varray()); + bind_method(PackedColorArray, set, sarray("index", "value"), varray()); + bind_method(PackedColorArray, push_back, sarray("value"), varray()); + bind_method(PackedColorArray, append, sarray("value"), varray()); + bind_method(PackedColorArray, append_array, sarray("array"), varray()); + bind_method(PackedColorArray, remove, sarray("index"), varray()); + bind_method(PackedColorArray, insert, sarray("at_index", "value"), varray()); + bind_method(PackedColorArray, resize, sarray("new_size"), varray()); + bind_method(PackedColorArray, has, sarray("value"), varray()); + bind_method(PackedColorArray, invert, sarray(), varray()); + bind_method(PackedColorArray, subarray, sarray("from", "to"), varray()); + bind_method(PackedColorArray, to_byte_array, sarray(), varray()); + bind_method(PackedColorArray, sort, sarray(), varray()); + + /* Register constants */ + + int ncc = Color::get_named_color_count(); + for (int i = 0; i < ncc; i++) { + _VariantCall::add_variant_constant(Variant::COLOR, Color::get_named_color_name(i), Color::get_named_color(i)); + } + + _VariantCall::add_constant(Variant::VECTOR3, "AXIS_X", Vector3::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR3, "AXIS_Y", Vector3::AXIS_Y); + _VariantCall::add_constant(Variant::VECTOR3, "AXIS_Z", Vector3::AXIS_Z); + + _VariantCall::add_variant_constant(Variant::VECTOR3, "ZERO", Vector3(0, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "ONE", Vector3(1, 1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(Math_INF, Math_INF, Math_INF)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "LEFT", Vector3(-1, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "RIGHT", Vector3(1, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "UP", Vector3(0, 1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "DOWN", Vector3(0, -1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1)); + + _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3i::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3i::AXIS_Y); + _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3i::AXIS_Z); + + _VariantCall::add_variant_constant(Variant::VECTOR3I, "ZERO", Vector3i(0, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "ONE", Vector3i(1, 1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "LEFT", Vector3i(-1, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "RIGHT", Vector3i(1, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "UP", Vector3i(0, 1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "DOWN", Vector3i(0, -1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "FORWARD", Vector3i(0, 0, -1)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "BACK", Vector3i(0, 0, 1)); + + _VariantCall::add_constant(Variant::VECTOR2, "AXIS_X", Vector2::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR2, "AXIS_Y", Vector2::AXIS_Y); + + _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_X", Vector2i::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_Y", Vector2i::AXIS_Y); + + _VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "LEFT", Vector2(-1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "RIGHT", Vector2(1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "DOWN", Vector2(0, 1)); + + _VariantCall::add_variant_constant(Variant::VECTOR2I, "ZERO", Vector2i(0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR2I, "ONE", Vector2i(1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR2I, "LEFT", Vector2i(-1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR2I, "RIGHT", Vector2i(1, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR2I, "UP", Vector2i(0, -1)); + _VariantCall::add_variant_constant(Variant::VECTOR2I, "DOWN", Vector2i(0, 1)); + + _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D()); + _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0)); + _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0)); + + Transform identity_transform = Transform(); + Transform flip_x_transform = Transform(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); + Transform flip_y_transform = Transform(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0); + Transform flip_z_transform = Transform(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0); + _VariantCall::add_variant_constant(Variant::TRANSFORM, "IDENTITY", identity_transform); + _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", flip_x_transform); + _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", flip_y_transform); + _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", flip_z_transform); + + Basis identity_basis = Basis(); + Basis flip_x_basis = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1); + Basis flip_y_basis = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1); + Basis flip_z_basis = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1); + _VariantCall::add_variant_constant(Variant::BASIS, "IDENTITY", identity_basis); + _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_X", flip_x_basis); + _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Y", flip_y_basis); + _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Z", flip_z_basis); + + _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_YZ", Plane(Vector3(1, 0, 0), 0)); + _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XZ", Plane(Vector3(0, 1, 0), 0)); + _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0)); + + _VariantCall::add_variant_constant(Variant::QUAT, "IDENTITY", Quat(0, 0, 0, 1)); +} + +void Variant::_register_variant_methods() { + _register_variant_builtin_methods(); //needs to be out due to namespace +} + +void Variant::_unregister_variant_methods() { + //clear methods + memdelete_arr(builtin_method_names); + memdelete_arr(builtin_method_info); + memdelete_arr(_VariantCall::constant_data); +} diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp new file mode 100644 index 0000000000..01f5b7df59 --- /dev/null +++ b/core/variant/variant_construct.cpp @@ -0,0 +1,812 @@ +/*************************************************************************/ +/* variant_construct.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/crypto/crypto_core.h" +#include "core/debugger/engine_debugger.h" +#include "core/io/compression.h" +#include "core/object/class_db.h" +#include "core/os/os.h" +#include "core/templates/local_vector.h" +#include "core/templates/oa_hash_map.h" + +template <class T, class... P> +class VariantConstructor { + template <size_t... Is> + static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + base = T(VariantCaster<P>::cast(*p_args[Is])...); +#endif + } + + template <size_t... Is> + static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) { + base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...); + } + + template <size_t... Is> + static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) { + PtrToArg<T>::encode(T(PtrToArg<P>::convert(p_args[Is])...), base); + } + +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + VariantTypeChanger<T>::change(&r_ret); + construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(&r_ret); + validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, BuildIndexSequence<sizeof...(P)>{}); + } + static void ptr_construct(void *base, const void **p_args) { + ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{}); + } + + static int get_argument_count() { + return sizeof...(P); + } + + static Variant::Type get_argument_type(int p_arg) { + return call_get_argument_type<P...>(p_arg); + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + if (p_args[0]->get_type() == Variant::NIL) { + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } else if (p_args[0]->get_type() == Variant::OBJECT) { + VariantInternal::object_assign(&r_ret, p_args[0]); + r_error.error = Callable::CallError::CALL_OK; + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + } + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign(&r_ret, p_args[0]); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Object *>::encode(PtrToArg<Object *>::convert(p_args[0]), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::OBJECT; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorNilObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + } + + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Object *>::encode(nullptr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorCallableArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Callable>::change(&r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<Callable>::change(&r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Callable>::encode(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::CALLABLE; + } +}; + +class VariantConstructorSignalArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Signal>::change(&r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<Signal>::change(&r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Signal>::encode(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::SIGNAL; + } +}; + +template <class T> +class VariantConstructorToArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = GetTypeInfo<T>::VARIANT_TYPE; + return; + } + + VariantTypeChanger<Array>::change(&r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<Array>::change(&r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array dst_arr; + T src_arr = PtrToArg<T>::convert(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + + PtrToArg<Array>::encode(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return GetTypeInfo<T>::VARIANT_TYPE; + } + + static Variant::Type get_base_type() { + return Variant::ARRAY; + } +}; + +template <class T> +class VariantConstructorFromArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::ARRAY) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::ARRAY; + return; + } + + VariantTypeChanger<T>::change(&r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(&r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array src_arr = PtrToArg<Array>::convert(p_args[0]); + T dst_arr; + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + + PtrToArg<T>::encode(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::ARRAY; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + return; + } + + r_error.error = Callable::CallError::CALL_OK; + VariantInternal::clear(&r_ret); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Variant>::encode(Variant(), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +template <class T> +class VariantConstructNoArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantTypeChanger<T>::change_and_reset(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change_and_reset(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<T>::encode(T(), base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructNoArgsNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + ERR_FAIL_MSG("can't ptrcall nil constructor"); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +class VariantConstructNoArgsObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Object *>::encode(nullptr, base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +struct VariantConstructData { + void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error); + Variant::ValidatedConstructor validated_construct; + Variant::PTRConstructor ptr_construct; + Variant::Type (*get_argument_type)(int); + int argument_count; + Vector<String> arg_names; +}; + +static LocalVector<VariantConstructData> construct_data[Variant::VARIANT_MAX]; + +template <class T> +static void add_constructor(const Vector<String> &arg_names) { + ERR_FAIL_COND_MSG(arg_names.size() != T::get_argument_count(), "Argument names size mismatch for " + Variant::get_type_name(T::get_base_type()) + "."); + + VariantConstructData cd; + cd.construct = T::construct; + cd.validated_construct = T::validated_construct; + cd.ptr_construct = T::ptr_construct; + cd.get_argument_type = T::get_argument_type; + cd.argument_count = T::get_argument_count(); + cd.arg_names = arg_names; + construct_data[T::get_base_type()].push_back(cd); +} + +void Variant::_register_variant_constructors() { + add_constructor<VariantConstructNoArgsNil>(sarray()); + add_constructor<VariantConstructorNil>(sarray("from")); + + add_constructor<VariantConstructNoArgs<bool>>(sarray()); + add_constructor<VariantConstructor<bool, bool>>(sarray("from")); + add_constructor<VariantConstructor<bool, int64_t>>(sarray("from")); + add_constructor<VariantConstructor<bool, double>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<int64_t>>(sarray()); + add_constructor<VariantConstructor<int64_t, int64_t>>(sarray("from")); + add_constructor<VariantConstructor<int64_t, double>>(sarray("from")); + add_constructor<VariantConstructor<int64_t, bool>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<double>>(sarray()); + add_constructor<VariantConstructor<double, double>>(sarray("from")); + add_constructor<VariantConstructor<double, int64_t>>(sarray("from")); + add_constructor<VariantConstructor<double, bool>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<String>>(sarray()); + add_constructor<VariantConstructor<String, String>>(sarray("from")); + add_constructor<VariantConstructor<String, StringName>>(sarray("from")); + add_constructor<VariantConstructor<String, NodePath>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<Vector2>>(sarray()); + add_constructor<VariantConstructor<Vector2, Vector2>>(sarray("from")); + add_constructor<VariantConstructor<Vector2, Vector2i>>(sarray("from")); + add_constructor<VariantConstructor<Vector2, double, double>>(sarray("x", "y")); + + add_constructor<VariantConstructNoArgs<Vector2i>>(sarray()); + add_constructor<VariantConstructor<Vector2i, Vector2i>>(sarray("from")); + add_constructor<VariantConstructor<Vector2i, Vector2>>(sarray("from")); + add_constructor<VariantConstructor<Vector2i, int64_t, int64_t>>(sarray("x", "y")); + + add_constructor<VariantConstructNoArgs<Rect2>>(sarray()); + add_constructor<VariantConstructor<Rect2, Rect2>>(sarray("from")); + add_constructor<VariantConstructor<Rect2, Rect2i>>(sarray("from")); + add_constructor<VariantConstructor<Rect2, Vector2, Vector2>>(sarray("position", "size")); + add_constructor<VariantConstructor<Rect2, double, double, double, double>>(sarray("x", "y", "width", "height")); + + add_constructor<VariantConstructNoArgs<Rect2i>>(sarray()); + add_constructor<VariantConstructor<Rect2i, Rect2i>>(sarray("from")); + add_constructor<VariantConstructor<Rect2i, Rect2>>(sarray("from")); + add_constructor<VariantConstructor<Rect2i, Vector2i, Vector2i>>(sarray("position", "size")); + add_constructor<VariantConstructor<Rect2i, int64_t, int64_t, int64_t, int64_t>>(sarray("x", "y", "width", "height")); + + add_constructor<VariantConstructNoArgs<Vector3>>(sarray()); + add_constructor<VariantConstructor<Vector3, Vector3>>(sarray("from")); + add_constructor<VariantConstructor<Vector3, Vector3i>>(sarray("from")); + add_constructor<VariantConstructor<Vector3, double, double, double>>(sarray("x", "y", "z")); + + add_constructor<VariantConstructNoArgs<Vector3i>>(sarray()); + add_constructor<VariantConstructor<Vector3i, Vector3i>>(sarray("from")); + add_constructor<VariantConstructor<Vector3i, Vector3>>(sarray("from")); + add_constructor<VariantConstructor<Vector3i, int64_t, int64_t, int64_t>>(sarray("x", "y", "z")); + + add_constructor<VariantConstructNoArgs<Transform2D>>(sarray()); + add_constructor<VariantConstructor<Transform2D, Transform2D>>(sarray("from")); + add_constructor<VariantConstructor<Transform2D, float, Vector2>>(sarray("rotation", "position")); + add_constructor<VariantConstructor<Transform2D, Vector2, Vector2, Vector2>>(sarray("x_axis", "y_axis", "origin")); + + add_constructor<VariantConstructNoArgs<Plane>>(sarray()); + add_constructor<VariantConstructor<Plane, Plane>>(sarray("from")); + add_constructor<VariantConstructor<Plane, Vector3, double>>(sarray("normal", "d")); + add_constructor<VariantConstructor<Plane, Vector3, Vector3>>(sarray("point", "normal")); + add_constructor<VariantConstructor<Plane, Vector3, Vector3, Vector3>>(sarray("point1", "point2", "point3")); + add_constructor<VariantConstructor<Plane, double, double, double, double>>(sarray("a", "b", "c", "d")); + + add_constructor<VariantConstructNoArgs<Quat>>(sarray()); + add_constructor<VariantConstructor<Quat, Quat>>(sarray("from")); + add_constructor<VariantConstructor<Quat, Basis>>(sarray("from")); + add_constructor<VariantConstructor<Quat, Vector3>>(sarray("euler")); + add_constructor<VariantConstructor<Quat, Vector3, double>>(sarray("axis", "angle")); + add_constructor<VariantConstructor<Quat, Vector3, Vector3>>(sarray("arc_from", "arc_to")); + add_constructor<VariantConstructor<Quat, double, double, double, double>>(sarray("x", "y", "z", "w")); + + add_constructor<VariantConstructNoArgs<::AABB>>(sarray()); + add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from")); + add_constructor<VariantConstructor<::AABB, Vector3, Vector3>>(sarray("position", "size")); + + add_constructor<VariantConstructNoArgs<Basis>>(sarray()); + add_constructor<VariantConstructor<Basis, Basis>>(sarray("from")); + add_constructor<VariantConstructor<Basis, Quat>>(sarray("from")); + add_constructor<VariantConstructor<Basis, Vector3>>(sarray("euler")); + add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "phi")); + add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis")); + + add_constructor<VariantConstructNoArgs<Transform>>(sarray()); + add_constructor<VariantConstructor<Transform, Transform>>(sarray("from")); + add_constructor<VariantConstructor<Transform, Basis, Vector3>>(sarray("basis", "origin")); + add_constructor<VariantConstructor<Transform, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin")); + + add_constructor<VariantConstructNoArgs<Color>>(sarray()); + add_constructor<VariantConstructor<Color, Color>>(sarray("from")); + add_constructor<VariantConstructor<Color, Color, double>>(sarray("from", "alpha")); + add_constructor<VariantConstructor<Color, double, double, double>>(sarray("r", "g", "b")); + add_constructor<VariantConstructor<Color, double, double, double, double>>(sarray("r", "g", "b", "a")); + + add_constructor<VariantConstructNoArgs<StringName>>(sarray()); + add_constructor<VariantConstructor<StringName, StringName>>(sarray("from")); + add_constructor<VariantConstructor<StringName, String>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<NodePath>>(sarray()); + add_constructor<VariantConstructor<NodePath, NodePath>>(sarray("from")); + add_constructor<VariantConstructor<NodePath, String>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<::RID>>(sarray()); + add_constructor<VariantConstructor<::RID, ::RID>>(sarray("from")); + + add_constructor<VariantConstructNoArgsObject>(sarray()); + add_constructor<VariantConstructorObject>(sarray("from")); + add_constructor<VariantConstructorNilObject>(sarray("from")); + + add_constructor<VariantConstructNoArgs<Callable>>(sarray()); + add_constructor<VariantConstructor<Callable, Callable>>(sarray("from")); + add_constructor<VariantConstructorCallableArgs>(sarray("object", "method")); + + add_constructor<VariantConstructNoArgs<Signal>>(sarray()); + add_constructor<VariantConstructor<Signal, Signal>>(sarray("from")); + add_constructor<VariantConstructorSignalArgs>(sarray("object", "signal")); + + add_constructor<VariantConstructNoArgs<Dictionary>>(sarray()); + add_constructor<VariantConstructor<Dictionary, Dictionary>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<Array>>(sarray()); + add_constructor<VariantConstructor<Array, Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedByteArray>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedInt32Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedInt64Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedFloat32Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedFloat64Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedStringArray>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedVector2Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedVector3Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedColorArray>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedByteArray>>(sarray()); + add_constructor<VariantConstructor<PackedByteArray, PackedByteArray>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedByteArray>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedInt32Array>>(sarray()); + add_constructor<VariantConstructor<PackedInt32Array, PackedInt32Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedInt32Array>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedInt64Array>>(sarray()); + add_constructor<VariantConstructor<PackedInt64Array, PackedInt64Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedInt64Array>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedFloat32Array>>(sarray()); + add_constructor<VariantConstructor<PackedFloat32Array, PackedFloat32Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedFloat32Array>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedFloat64Array>>(sarray()); + add_constructor<VariantConstructor<PackedFloat64Array, PackedFloat64Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedFloat64Array>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedStringArray>>(sarray()); + add_constructor<VariantConstructor<PackedStringArray, PackedStringArray>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedStringArray>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedVector2Array>>(sarray()); + add_constructor<VariantConstructor<PackedVector2Array, PackedVector2Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedVector2Array>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedVector3Array>>(sarray()); + add_constructor<VariantConstructor<PackedVector3Array, PackedVector3Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedVector3Array>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<PackedColorArray>>(sarray()); + add_constructor<VariantConstructor<PackedColorArray, PackedColorArray>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedColorArray>>(sarray("from")); +} + +void Variant::_unregister_variant_constructors() { + for (int i = 0; i < Variant::VARIANT_MAX; i++) { + construct_data[i].clear(); + } +} + +void Variant::construct(Variant::Type p_type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + uint32_t s = construct_data[p_type].size(); + for (uint32_t i = 0; i < s; i++) { + int argc = construct_data[p_type][i].argument_count; + if (argc != p_argcount) { + continue; + } + bool args_match = true; + for (int j = 0; j < argc; j++) { + if (!Variant::can_convert_strict(p_args[j]->get_type(), construct_data[p_type][i].get_argument_type(j))) { + args_match = false; + break; + } + } + + if (!args_match) { + continue; + } + + construct_data[p_type][i].construct(base, p_args, r_error); + return; + } + + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; +} + +int Variant::get_constructor_count(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1); + return construct_data[p_type].size(); +} + +Variant::ValidatedConstructor Variant::get_validated_constructor(Variant::Type p_type, int p_constructor) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), nullptr); + return construct_data[p_type][p_constructor].validated_construct; +} + +Variant::PTRConstructor Variant::get_ptr_constructor(Variant::Type p_type, int p_constructor) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), nullptr); + return construct_data[p_type][p_constructor].ptr_construct; +} + +int Variant::get_constructor_argument_count(Variant::Type p_type, int p_constructor) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), -1); + return construct_data[p_type][p_constructor].argument_count; +} + +Variant::Type Variant::get_constructor_argument_type(Variant::Type p_type, int p_constructor, int p_argument) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::VARIANT_MAX); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), Variant::VARIANT_MAX); + return construct_data[p_type][p_constructor].get_argument_type(p_argument); +} + +String Variant::get_constructor_argument_name(Variant::Type p_type, int p_constructor, int p_argument) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, String()); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), String()); + return construct_data[p_type][p_constructor].arg_names[p_argument]; +} + +void VariantInternal::object_assign(Variant *v, const Variant *o) { + if (o->_get_obj().obj && o->_get_obj().id.is_reference()) { + Reference *reference = static_cast<Reference *>(o->_get_obj().obj); + if (!reference->reference()) { + v->_get_obj().obj = nullptr; + v->_get_obj().id = ObjectID(); + return; + } + } + + v->_get_obj().obj = const_cast<Object *>(o->_get_obj().obj); + v->_get_obj().id = o->_get_obj().id; +} + +void Variant::get_constructor_list(Type p_type, List<MethodInfo> *r_list) { + ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); + + MethodInfo mi; + mi.return_val.type = p_type; + mi.name = get_type_name(p_type); + + for (int i = 0; i < get_constructor_count(p_type); i++) { + int ac = get_constructor_argument_count(p_type, i); + mi.arguments.clear(); + for (int j = 0; j < ac; j++) { + PropertyInfo arg; + arg.name = get_constructor_argument_name(p_type, i, j); + arg.type = get_constructor_argument_type(p_type, i, j); + mi.arguments.push_back(arg); + } + r_list->push_back(mi); + } +} diff --git a/core/variant_internal.h b/core/variant/variant_internal.h index 7893c6d382..3ac7f32dec 100644 --- a/core/variant_internal.h +++ b/core/variant/variant_internal.h @@ -83,8 +83,8 @@ public: _FORCE_INLINE_ static const StringName *get_string_name(const Variant *v) { return reinterpret_cast<const StringName *>(v->_data._mem); } _FORCE_INLINE_ static NodePath *get_node_path(Variant *v) { return reinterpret_cast<NodePath *>(v->_data._mem); } _FORCE_INLINE_ static const NodePath *get_node_path(const Variant *v) { return reinterpret_cast<const NodePath *>(v->_data._mem); } - _FORCE_INLINE_ static RID *get_rid(Variant *v) { return reinterpret_cast<RID *>(v->_data._mem); } - _FORCE_INLINE_ static const RID *get_rid(const Variant *v) { return reinterpret_cast<const RID *>(v->_data._mem); } + _FORCE_INLINE_ static ::RID *get_rid(Variant *v) { return reinterpret_cast<::RID *>(v->_data._mem); } + _FORCE_INLINE_ static const ::RID *get_rid(const Variant *v) { return reinterpret_cast<const ::RID *>(v->_data._mem); } _FORCE_INLINE_ static Callable *get_callable(Variant *v) { return reinterpret_cast<Callable *>(v->_data._mem); } _FORCE_INLINE_ static const Callable *get_callable(const Variant *v) { return reinterpret_cast<const Callable *>(v->_data._mem); } _FORCE_INLINE_ static Signal *get_signal(Variant *v) { return reinterpret_cast<Signal *>(v->_data._mem); } @@ -116,6 +116,106 @@ public: _FORCE_INLINE_ static Object **get_object(Variant *v) { return (Object **)&v->_get_obj().obj; } _FORCE_INLINE_ static const Object **get_object(const Variant *v) { return (const Object **)&v->_get_obj().obj; } + + _FORCE_INLINE_ static const ObjectID get_object_id(const Variant *v) { return v->_get_obj().id; } + + template <class T> + _FORCE_INLINE_ static void init_generic(Variant *v) { + v->type = GetTypeInfo<T>::VARIANT_TYPE; + } + + _FORCE_INLINE_ static void init_string(Variant *v) { + memnew_placement(v->_data._mem, String); + v->type = Variant::STRING; + } + + _FORCE_INLINE_ static void init_transform2d(Variant *v) { + v->_data._transform2d = memnew(Transform2D); + v->type = Variant::TRANSFORM2D; + } + _FORCE_INLINE_ static void init_aabb(Variant *v) { + v->_data._aabb = memnew(AABB); + v->type = Variant::AABB; + } + _FORCE_INLINE_ static void init_basis(Variant *v) { + v->_data._basis = memnew(Basis); + v->type = Variant::BASIS; + } + _FORCE_INLINE_ static void init_transform(Variant *v) { + v->_data._transform = memnew(Transform); + v->type = Variant::TRANSFORM; + } + _FORCE_INLINE_ static void init_string_name(Variant *v) { + memnew_placement(v->_data._mem, StringName); + v->type = Variant::STRING_NAME; + } + _FORCE_INLINE_ static void init_node_path(Variant *v) { + memnew_placement(v->_data._mem, NodePath); + v->type = Variant::NODE_PATH; + } + _FORCE_INLINE_ static void init_callable(Variant *v) { + memnew_placement(v->_data._mem, Callable); + v->type = Variant::CALLABLE; + } + _FORCE_INLINE_ static void init_signal(Variant *v) { + memnew_placement(v->_data._mem, Signal); + v->type = Variant::SIGNAL; + } + _FORCE_INLINE_ static void init_dictionary(Variant *v) { + memnew_placement(v->_data._mem, Dictionary); + v->type = Variant::DICTIONARY; + } + _FORCE_INLINE_ static void init_array(Variant *v) { + memnew_placement(v->_data._mem, Array); + v->type = Variant::ARRAY; + } + _FORCE_INLINE_ static void init_byte_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<uint8_t>::create(Vector<uint8_t>()); + v->type = Variant::PACKED_BYTE_ARRAY; + } + _FORCE_INLINE_ static void init_int32_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<int32_t>::create(Vector<int32_t>()); + v->type = Variant::PACKED_INT32_ARRAY; + } + _FORCE_INLINE_ static void init_int64_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<int64_t>::create(Vector<int64_t>()); + v->type = Variant::PACKED_INT64_ARRAY; + } + _FORCE_INLINE_ static void init_float32_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<float>::create(Vector<float>()); + v->type = Variant::PACKED_FLOAT32_ARRAY; + } + _FORCE_INLINE_ static void init_float64_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<double>::create(Vector<double>()); + v->type = Variant::PACKED_FLOAT64_ARRAY; + } + _FORCE_INLINE_ static void init_string_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<String>::create(Vector<String>()); + v->type = Variant::PACKED_STRING_ARRAY; + } + _FORCE_INLINE_ static void init_vector2_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<Vector2>::create(Vector<Vector2>()); + v->type = Variant::PACKED_VECTOR2_ARRAY; + } + _FORCE_INLINE_ static void init_vector3_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<Vector3>::create(Vector<Vector3>()); + v->type = Variant::PACKED_VECTOR3_ARRAY; + } + _FORCE_INLINE_ static void init_color_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<Color>::create(Vector<Color>()); + v->type = Variant::PACKED_COLOR_ARRAY; + } + + _FORCE_INLINE_ static void clear(Variant *v) { + v->clear(); + } + + static void object_assign(Variant *v, const Variant *o); //needs to use reference, do away + + _FORCE_INLINE_ static void object_assign_null(Variant *v) { + v->_get_obj().obj = nullptr; + v->_get_obj().id = ObjectID(); + } }; template <class T> @@ -305,9 +405,9 @@ struct VariantGetInternalPtr<NodePath> { }; template <> -struct VariantGetInternalPtr<RID> { - static RID *get_ptr(Variant *v) { return VariantInternal::get_rid(v); } - static const RID *get_ptr(const Variant *v) { return VariantInternal::get_rid(v); } +struct VariantGetInternalPtr<::RID> { + static ::RID *get_ptr(Variant *v) { return VariantInternal::get_rid(v); } + static const ::RID *get_ptr(const Variant *v) { return VariantInternal::get_rid(v); } }; template <> @@ -532,9 +632,9 @@ struct VariantInternalAccessor<NodePath> { }; template <> -struct VariantInternalAccessor<RID> { - static _FORCE_INLINE_ const RID &get(const Variant *v) { return *VariantInternal::get_rid(v); } - static _FORCE_INLINE_ void set(Variant *v, const RID &p_value) { *VariantInternal::get_rid(v) = p_value; } +struct VariantInternalAccessor<::RID> { + static _FORCE_INLINE_ const ::RID &get(const Variant *v) { return *VariantInternal::get_rid(v); } + static _FORCE_INLINE_ void set(Variant *v, const ::RID &p_value) { *VariantInternal::get_rid(v) = p_value; } }; template <> @@ -649,4 +749,383 @@ struct VariantInternalAccessor<Vector<Variant>> { } }; +template <class T> +struct VariantInitializer { +}; + +template <> +struct VariantInitializer<bool> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<bool>(v); } +}; + +#define INITIALIZER_INT(m_type) \ + template <> \ + struct VariantInitializer<m_type> { \ + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<int64_t>(v); } \ + }; + +INITIALIZER_INT(uint8_t) +INITIALIZER_INT(int8_t) +INITIALIZER_INT(uint16_t) +INITIALIZER_INT(int16_t) +INITIALIZER_INT(uint32_t) +INITIALIZER_INT(int32_t) +INITIALIZER_INT(uint64_t) +INITIALIZER_INT(int64_t) +INITIALIZER_INT(char32_t) +INITIALIZER_INT(Error) +INITIALIZER_INT(ObjectID) + +template <> +struct VariantInitializer<double> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<double>(v); } +}; + +template <> +struct VariantInitializer<float> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<double>(v); } +}; + +template <> +struct VariantInitializer<String> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string(v); } +}; + +template <> +struct VariantInitializer<Vector2> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector2>(v); } +}; + +template <> +struct VariantInitializer<Vector2i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector2i>(v); } +}; + +template <> +struct VariantInitializer<Rect2> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Rect2>(v); } +}; + +template <> +struct VariantInitializer<Rect2i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Rect2i>(v); } +}; + +template <> +struct VariantInitializer<Vector3> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3>(v); } +}; + +template <> +struct VariantInitializer<Vector3i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3i>(v); } +}; + +template <> +struct VariantInitializer<Transform2D> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform2d(v); } +}; + +template <> +struct VariantInitializer<Plane> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Plane>(v); } +}; + +template <> +struct VariantInitializer<Quat> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Quat>(v); } +}; + +template <> +struct VariantInitializer<AABB> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_aabb(v); } +}; + +template <> +struct VariantInitializer<Basis> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_basis(v); } +}; + +template <> +struct VariantInitializer<Transform> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); } +}; + +template <> +struct VariantInitializer<Color> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Color>(v); } +}; + +template <> +struct VariantInitializer<StringName> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string_name(v); } +}; + +template <> +struct VariantInitializer<NodePath> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_node_path(v); } +}; + +template <> +struct VariantInitializer<::RID> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<::RID>(v); } +}; + +template <> +struct VariantInitializer<Callable> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_callable(v); } +}; + +template <> +struct VariantInitializer<Signal> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_signal(v); } +}; + +template <> +struct VariantInitializer<Dictionary> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_dictionary(v); } +}; + +template <> +struct VariantInitializer<Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_array(v); } +}; + +template <> +struct VariantInitializer<PackedByteArray> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_byte_array(v); } +}; + +template <> +struct VariantInitializer<PackedInt32Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_int32_array(v); } +}; + +template <> +struct VariantInitializer<PackedInt64Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_int64_array(v); } +}; + +template <> +struct VariantInitializer<PackedFloat32Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_float32_array(v); } +}; + +template <> +struct VariantInitializer<PackedFloat64Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_float64_array(v); } +}; + +template <> +struct VariantInitializer<PackedStringArray> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string_array(v); } +}; + +template <> +struct VariantInitializer<PackedVector2Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_vector2_array(v); } +}; + +template <> +struct VariantInitializer<PackedVector3Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_vector3_array(v); } +}; + +template <> +struct VariantInitializer<PackedColorArray> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_color_array(v); } +}; + +template <class T> +struct VariantZeroAssigner { +}; + +template <> +struct VariantZeroAssigner<bool> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_bool(v) = false; } +}; + +template <> +struct VariantZeroAssigner<int64_t> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_int(v) = 0; } +}; + +template <> +struct VariantZeroAssigner<double> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float(v) = 0.0; } +}; + +template <> +struct VariantZeroAssigner<float> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float(v) = 0.0; } +}; + +template <> +struct VariantZeroAssigner<String> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<Vector2> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2(v) = Vector2(); } +}; + +template <> +struct VariantZeroAssigner<Vector2i> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2i(v) = Vector2i(); } +}; + +template <> +struct VariantZeroAssigner<Rect2> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rect2(v) = Rect2(); } +}; + +template <> +struct VariantZeroAssigner<Rect2i> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rect2i(v) = Rect2i(); } +}; + +template <> +struct VariantZeroAssigner<Vector3> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3(v) = Vector3(); } +}; + +template <> +struct VariantZeroAssigner<Vector3i> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3i(v) = Vector3i(); } +}; + +template <> +struct VariantZeroAssigner<Transform2D> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform2d(v) = Transform2D(); } +}; + +template <> +struct VariantZeroAssigner<Plane> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_plane(v) = Plane(); } +}; + +template <> +struct VariantZeroAssigner<Quat> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_quat(v) = Quat(); } +}; + +template <> +struct VariantZeroAssigner<AABB> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_aabb(v) = AABB(); } +}; + +template <> +struct VariantZeroAssigner<Basis> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_basis(v) = Basis(); } +}; + +template <> +struct VariantZeroAssigner<Transform> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform(v) = Transform(); } +}; + +template <> +struct VariantZeroAssigner<Color> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color(v) = Color(); } +}; + +template <> +struct VariantZeroAssigner<StringName> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<NodePath> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<::RID> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rid(v) = RID(); } +}; + +template <> +struct VariantZeroAssigner<Callable> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<Signal> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<Dictionary> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<Array> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedByteArray> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedInt32Array> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedInt64Array> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedFloat32Array> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedFloat64Array> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedStringArray> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedVector2Array> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedVector3Array> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<PackedColorArray> { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <class T> +struct VariantTypeChanger { + static _FORCE_INLINE_ void change(Variant *v) { + if (v->get_type() != GetTypeInfo<T>::VARIANT_TYPE || GetTypeInfo<T>::VARIANT_TYPE >= Variant::PACKED_BYTE_ARRAY) { //second condition removed by optimizer + VariantInternal::clear(v); + VariantInitializer<T>::init(v); + } + } + static _FORCE_INLINE_ void change_and_reset(Variant *v) { + if (v->get_type() != GetTypeInfo<T>::VARIANT_TYPE || GetTypeInfo<T>::VARIANT_TYPE >= Variant::PACKED_BYTE_ARRAY) { //second condition removed by optimizer + VariantInternal::clear(v); + VariantInitializer<T>::init(v); + } + + VariantZeroAssigner<T>::zero(v); + } +}; + #endif // VARIANT_INTERNAL_H diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp new file mode 100644 index 0000000000..8e55c1d6cd --- /dev/null +++ b/core/variant/variant_op.cpp @@ -0,0 +1,2190 @@ +/*************************************************************************/ +/* variant_op.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/debugger/engine_debugger.h" +#include "core/object/class_db.h" + +template <class R, class A, class B> +class OperatorEvaluatorAdd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a + b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) + *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) + PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorSub { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a - b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) - *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) - PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorMul { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a * b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) * *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) * PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorXForm { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a.xform(b); + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<A>::get_ptr(left)->xform(*VariantGetInternalPtr<B>::get_ptr(right)); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left).xform(PtrToArg<B>::convert(right)), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorXFormInv { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = b.xform_inv(a); + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<B>::get_ptr(right)->xform_inv(*VariantGetInternalPtr<A>::get_ptr(left)); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<B>::convert(right).xform_inv(PtrToArg<A>::convert(left)), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorDiv { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a / b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorDivNZ { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + if (b == 0) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = a / b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorMod { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a % b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorModNZ { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + if (b == 0) { + r_valid = false; + *r_ret = "Module by zero error"; + return; + } + *r_ret = a % b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorNeg { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = -a; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = -*VariantGetInternalPtr<A>::get_ptr(left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(-PtrToArg<A>::convert(left), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorPos { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = a; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorShiftLeft { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a << b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) << *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) << PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorShiftRight { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a >> b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >> *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) >> PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitOr { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a | b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) | *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) | PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitAnd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a & b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) & *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) & PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitXor { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a ^ b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) ^ *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) ^ PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorBitNeg { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = ~a; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); + *VariantGetInternalPtr<R>::get_ptr(r_ret) = ~*VariantGetInternalPtr<A>::get_ptr(left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(~PtrToArg<A>::convert(left), r_ret); + } +#endif + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class A, class B> +class OperatorEvaluatorEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a == b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) == *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) == PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; +//equalobject +class OperatorEvaluatorEqualObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *a = p_left.get_validated_object(); + const Object *b = p_right.get_validated_object(); + *r_ret = a == b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *a = left->get_validated_object(); + const Object *b = right->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == b; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == PtrToArg<Object *>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualObjectNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *a = p_left.get_validated_object(); + *r_ret = a == nullptr; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *a = left->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == nullptr; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualNilObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *b = p_right.get_validated_object(); + *r_ret = nullptr == b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *b = right->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr == b; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(nullptr == PtrToArg<Object *>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorNotEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a != b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) != *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) != PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *a = p_left.get_validated_object(); + Object *b = p_right.get_validated_object(); + *r_ret = a != b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *a = left->get_validated_object(); + Object *b = right->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != b; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != PtrToArg<Object *>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualObjectNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *a = p_left.get_validated_object(); + *r_ret = a != nullptr; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *a = left->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != nullptr; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != nullptr, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualNilObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + *r_ret = nullptr != b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *b = right->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr != b; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(nullptr != PtrToArg<Object *>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorLess { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a < b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) < *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) < PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorLessEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a <= b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) <= *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) <= PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorGreater { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a > b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) > *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) > PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorGreaterEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a >= b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >= *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) >= PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorAnd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a && b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) && *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) && PtrToArg<B>::convert(right), r_ret); + } +#endif + + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorOr { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a || b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) || *VariantGetInternalPtr<B>::get_ptr(right); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) || PtrToArg<B>::convert(right), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +#define XOR_OP(m_a, m_b) (((m_a) || (m_b)) && !((m_a) && (m_b))) +template <class A, class B> +class OperatorEvaluatorXor { +public: + _FORCE_INLINE_ static bool xor_op(const A &a, const B &b) { + return ((a) || (b)) && !((a) && (b)); + } + + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = xor_op(a, b); + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = xor_op(*VariantGetInternalPtr<A>::get_ptr(left), *VariantGetInternalPtr<B>::get_ptr(right)); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(xor_op(PtrToArg<A>::convert(left), PtrToArg<B>::convert(right)), r_ret); + } +#endif + + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A> +class OperatorEvaluatorNot { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = !a; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<A>::get_ptr(left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<A>::convert(left)); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +//// CUSTOM //// + +class OperatorEvaluatorAddArray { +public: + _FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) { + int asize = array_a.size(); + int bsize = array_b.size(); + sum.resize(asize + bsize); + for (int i = 0; i < asize; i++) { + sum[i] = array_a[i]; + } + for (int i = 0; i < bsize; i++) { + sum[i + asize] = array_b[i]; + } + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &array_a = *VariantGetInternalPtr<Array>::get_ptr(&p_left); + const Array &array_b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + Array sum; + _add_arrays(sum, array_a, array_b); + *r_ret = sum; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Array>::change(r_ret); + _add_arrays(*VariantGetInternalPtr<Array>::get_ptr(r_ret), *VariantGetInternalPtr<Array>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right)); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + Array ret; + _add_arrays(ret, PtrToArg<Array>::convert(left), PtrToArg<Array>::convert(right)); + PtrToArg<Array>::encode(ret, r_ret); + } +#endif + + static Variant::Type get_return_type() { return Variant::ARRAY; } +}; + +template <class T> +class OperatorEvaluatorAppendArray { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector<T> &array_a = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_left); + const Vector<T> &array_b = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_right); + Vector<T> sum = array_a; + sum.append_array(array_b); + *r_ret = sum; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector<T>>::change(r_ret); + *VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector<T>>::get_ptr(left); + VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret)->append_array(*VariantGetInternalPtr<Vector<T>>::get_ptr(right)); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + Vector<T> sum = PtrToArg<Vector<T>>::convert(left); + sum.append_array(PtrToArg<Vector<T>>::convert(right)); + PtrToArg<Vector<T>>::encode(sum, r_ret); + } +#endif + + static Variant::Type get_return_type() { return GetTypeInfo<Vector<T>>::VARIANT_TYPE; } +}; + +class OperatorEvaluatorStringModNil { +public: + _FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) { + Array values; + values.push_back(Variant()); + + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, &r_valid); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), nullptr), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +class OperatorEvaluatorStringModArray { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const Array &p_values, bool *r_valid) { + String a = s.sprintf(p_values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +class OperatorEvaluatorStringModObject { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) { + Array values; + values.push_back(p_object); + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, p_right.get_validated_object(), &r_valid); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +template <class T> +class OperatorEvaluatorStringModT { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) { + Array values; + values.push_back(p_value); + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> +class OperatorEvaluatorAlwaysTrue { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = true; + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = true; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(true, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> +class OperatorEvaluatorAlwaysFalse { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = false; + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(false, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +///// OR /////// + +_FORCE_INLINE_ static bool _operate_or(bool p_left, bool p_right) { + return p_left || p_right; +} +_FORCE_INLINE_ static bool _operate_and(bool p_left, bool p_right) { + return p_left && p_right; +} +_FORCE_INLINE_ static bool _operate_xor(bool p_left, bool p_right) { + return (p_left || p_right) && !(p_left && p_right); +} + +_FORCE_INLINE_ static bool _operate_get_nil(const Variant *p_ptr) { + return p_ptr->get_validated_object() != nullptr; +} + +_FORCE_INLINE_ static bool _operate_get_bool(const Variant *p_ptr) { + return *VariantGetInternalPtr<bool>::get_ptr(p_ptr); +} + +_FORCE_INLINE_ static bool _operate_get_int(const Variant *p_ptr) { + return *VariantGetInternalPtr<int64_t>::get_ptr(p_ptr) != 0; +} + +_FORCE_INLINE_ static bool _operate_get_float(const Variant *p_ptr) { + return *VariantGetInternalPtr<double>::get_ptr(p_ptr) != 0.0; +} + +_FORCE_INLINE_ static bool _operate_get_object(const Variant *p_ptr) { + return p_ptr->get_validated_object() != nullptr; +} + +#ifndef PTRCALL_ENABLED + +#define OP_EVALUATOR(m_class_name, m_left, m_right, m_op) \ + class m_class_name { \ + public: \ + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { \ + *r_ret = m_op(_operate_get_##m_left(&p_left), _operate_get_##m_right(&p_right)); \ + r_valid = true; \ + } \ + \ + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ + VariantTypeChanger<bool>::change(r_ret); \ + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ + } \ + \ + static Variant::Type \ + get_return_type() { \ + return Variant::BOOL; \ + } \ + }; + +#else + +_FORCE_INLINE_ static bool _operate_get_ptr_nil(const void *p_ptr) { + return false; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_bool(const void *p_ptr) { + return PtrToArg<bool>::convert(p_ptr); +} + +_FORCE_INLINE_ static bool _operate_get_ptr_int(const void *p_ptr) { + return PtrToArg<int64_t>::convert(p_ptr) != 0; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_float(const void *p_ptr) { + return PtrToArg<double>::convert(p_ptr) != 0.0; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_object(const void *p_ptr) { + return PtrToArg<Object *>::convert(p_ptr) != nullptr; +} + +#define OP_EVALUATOR(m_class_name, m_left, m_right, m_op) \ + class m_class_name { \ + public: \ + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { \ + *r_ret = m_op(_operate_get_##m_left(&p_left), _operate_get_##m_right(&p_right)); \ + r_valid = true; \ + } \ + \ + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ + VariantTypeChanger<bool>::change(r_ret); \ + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ + } \ + \ + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { \ + PtrToArg<bool>::encode(m_op(_operate_get_ptr_##m_left(left), _operate_get_ptr_##m_right(right)), r_ret); \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::BOOL; \ + } \ + }; + +#endif + +// OR + +//nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolOr, nil, bool, _operate_or) +OP_EVALUATOR(OperatorEvaluatorBoolXNilOr, bool, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorNilXIntOr, nil, int, _operate_or) +OP_EVALUATOR(OperatorEvaluatorIntXNilOr, int, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatOr, nil, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXNilOr, float, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilOr, object, nil, _operate_or) +OP_EVALUATOR(OperatorEvaluatorNilXObjectOr, nil, object, _operate_or) + +//bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolOr, bool, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntOr, bool, int, _operate_or) +OP_EVALUATOR(OperatorEvaluatorIntXBoolOr, int, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatOr, bool, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolOr, float, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectOr, bool, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolOr, object, bool, _operate_or) + +//int + +OP_EVALUATOR(OperatorEvaluatorIntXIntOr, int, int, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatOr, int, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXIntOr, float, int, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectOr, int, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXIntOr, object, int, _operate_or) + +//float + +OP_EVALUATOR(OperatorEvaluatorFloatXFloatOr, float, float, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectOr, float, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatOr, object, float, _operate_or) + +//object + +OP_EVALUATOR(OperatorEvaluatorObjectXObjectOr, object, object, _operate_or) + +// AND + +//nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolAnd, nil, bool, _operate_and) +OP_EVALUATOR(OperatorEvaluatorBoolXNilAnd, bool, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorNilXIntAnd, nil, int, _operate_and) +OP_EVALUATOR(OperatorEvaluatorIntXNilAnd, int, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatAnd, nil, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXNilAnd, float, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilAnd, object, nil, _operate_and) +OP_EVALUATOR(OperatorEvaluatorNilXObjectAnd, nil, object, _operate_and) + +//bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolAnd, bool, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntAnd, bool, int, _operate_and) +OP_EVALUATOR(OperatorEvaluatorIntXBoolAnd, int, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatAnd, bool, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolAnd, float, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectAnd, bool, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolAnd, object, bool, _operate_and) + +//int + +OP_EVALUATOR(OperatorEvaluatorIntXIntAnd, int, int, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatAnd, int, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXIntAnd, float, int, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectAnd, int, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXIntAnd, object, int, _operate_and) + +//float + +OP_EVALUATOR(OperatorEvaluatorFloatXFloatAnd, float, float, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectAnd, float, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatAnd, object, float, _operate_and) + +//object + +OP_EVALUATOR(OperatorEvaluatorObjectXObjectAnd, object, object, _operate_and) + +// XOR + +//nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolXor, nil, bool, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorBoolXNilXor, bool, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorNilXIntXor, nil, int, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorIntXNilXor, int, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatXor, nil, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXNilXor, float, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilXor, object, nil, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorNilXObjectXor, nil, object, _operate_xor) + +//bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolXor, bool, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntXor, bool, int, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorIntXBoolXor, int, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatXor, bool, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolXor, float, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectXor, bool, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolXor, object, bool, _operate_xor) + +//int + +OP_EVALUATOR(OperatorEvaluatorIntXIntXor, int, int, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatXor, int, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXIntXor, float, int, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectXor, int, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXIntXor, object, int, _operate_xor) + +//float + +OP_EVALUATOR(OperatorEvaluatorFloatXFloatXor, float, float, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectXor, float, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatXor, object, float, _operate_xor) + +//object + +OP_EVALUATOR(OperatorEvaluatorObjectXObjectXor, object, object, _operate_xor) + +class OperatorEvaluatorNotBool { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<bool>::get_ptr(&p_left); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<bool>::get_ptr(left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<bool>::convert(left), r_ret); + } +#endif + + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotInt { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<int64_t>::get_ptr(&p_left); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<int64_t>::get_ptr(left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<int64_t>::convert(left), r_ret); + } +#endif + + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotFloat { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<double>::get_ptr(&p_left); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<double>::get_ptr(left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<double>::convert(left), r_ret); + } +#endif + + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = p_left.get_validated_object() == nullptr; + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = left->get_validated_object() == nullptr; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); + } +#endif + + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +//// + +class OperatorEvaluatorInStringFind { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &str_a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + const String &str_b = *VariantGetInternalPtr<String>::get_ptr(&p_right); + + *r_ret = str_b.find(str_a) != -1; + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const String &str_a = *VariantGetInternalPtr<String>::get_ptr(left); + const String &str_b = *VariantGetInternalPtr<String>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<String>::convert(left)) != -1, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorInArrayFind { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + + *r_ret = b.find(a) != -1; + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(a) != -1; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<B>::convert(right).find(PtrToArg<A>::convert(left)) != -1, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInArrayFindNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + *r_ret = b.find(Variant()) != -1; + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(Variant()) != -1; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(Variant()) != -1, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInArrayFindObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + *r_ret = b.find(p_left) != -1; + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(*left) != -1; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(PtrToArg<Object *>::convert(left)) != -1, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A> +class OperatorEvaluatorInDictionaryHas { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + + *r_ret = b.has(a); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + const A &a = *VariantGetInternalPtr<A>::get_ptr(left); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(a); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<A>::convert(left)), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInDictionaryHasNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + + *r_ret = b.has(Variant()); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(Variant()); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(Variant()), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInDictionaryHasObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + + *r_ret = b.has(p_left); + r_valid = true; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(*left); + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<Object *>::convert(left)), r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorObjectHasPropertyString { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + if (!b) { + *r_ret = "Invalid base object for 'in'"; + r_valid = false; + return; + } + + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + + b->get(a, &r_valid); + *r_ret = r_valid; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *l = right->get_validated_object(); + ERR_FAIL_COND(l == nullptr); + const String &a = *VariantGetInternalPtr<String>::get_ptr(left); + + bool valid; + l->get(a, &valid); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + bool valid; + PtrToArg<Object *>::convert(right)->get(PtrToArg<String>::convert(left), &valid); + PtrToArg<bool>::encode(valid, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorObjectHasPropertyStringName { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + if (!b) { + *r_ret = "Invalid base object for 'in'"; + r_valid = false; + return; + } + + const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(&p_left); + + b->get(a, &r_valid); + *r_ret = r_valid; + } + + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *l = right->get_validated_object(); + ERR_FAIL_COND(l == nullptr); + const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left); + + bool valid; + l->get(a, &valid); + VariantTypeChanger<bool>::change(r_ret); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; + } +#ifdef PTRCALL_ENABLED + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + bool valid; + PtrToArg<Object *>::convert(right)->get(PtrToArg<StringName>::convert(left), &valid); + PtrToArg<bool>::encode(valid, r_ret); + } +#endif + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +typedef void (*VariantEvaluatorFunction)(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid); + +static Variant::Type operator_return_type_table[Variant::OP_MAX][Variant::VARIANT_MAX][Variant::VARIANT_MAX]; +static VariantEvaluatorFunction operator_evaluator_table[Variant::OP_MAX][Variant::VARIANT_MAX][Variant::VARIANT_MAX]; +static Variant::ValidatedOperatorEvaluator validated_operator_evaluator_table[Variant::OP_MAX][Variant::VARIANT_MAX][Variant::VARIANT_MAX]; +#ifdef PTRCALL_ENABLED +static Variant::PTROperatorEvaluator ptr_operator_evaluator_table[Variant::OP_MAX][Variant::VARIANT_MAX][Variant::VARIANT_MAX]; +#endif + +template <class T> +void register_op(Variant::Operator p_op, Variant::Type p_type_a, Variant::Type p_type_b) { + operator_return_type_table[p_op][p_type_a][p_type_b] = T::get_return_type(); + operator_evaluator_table[p_op][p_type_a][p_type_b] = T::evaluate; + validated_operator_evaluator_table[p_op][p_type_a][p_type_b] = T::validated_evaluate; +#ifdef PTRCALL_ENABLED + ptr_operator_evaluator_table[p_op][p_type_a][p_type_b] = T::ptr_evaluate; +#endif +} + +void Variant::_register_variant_operators() { + zeromem(operator_return_type_table, sizeof(operator_return_type_table)); + zeromem(operator_evaluator_table, sizeof(operator_evaluator_table)); + zeromem(validated_operator_evaluator_table, sizeof(validated_operator_evaluator_table)); +#ifdef PTRCALL_ENABLED + zeromem(ptr_operator_evaluator_table, sizeof(ptr_operator_evaluator_table)); +#endif + + register_op<OperatorEvaluatorAdd<int64_t, int64_t, int64_t>>(Variant::OP_ADD, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorAdd<double, int64_t, double>>(Variant::OP_ADD, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorAdd<double, double, int64_t>>(Variant::OP_ADD, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorAdd<double, double, double>>(Variant::OP_ADD, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorAdd<String, String, String>>(Variant::OP_ADD, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorAdd<Vector2, Vector2, Vector2>>(Variant::OP_ADD, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorAdd<Vector3i, Vector3i, Vector3i>>(Variant::OP_ADD, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorAdd<Quat, Quat, Quat>>(Variant::OP_ADD, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorAdd<Color, Color, Color>>(Variant::OP_ADD, Variant::COLOR, Variant::COLOR); + register_op<OperatorEvaluatorAddArray>(Variant::OP_ADD, Variant::ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorAppendArray<uint8_t>>(Variant::OP_ADD, Variant::PACKED_BYTE_ARRAY, Variant::PACKED_BYTE_ARRAY); + register_op<OperatorEvaluatorAppendArray<int32_t>>(Variant::OP_ADD, Variant::PACKED_INT32_ARRAY, Variant::PACKED_INT32_ARRAY); + register_op<OperatorEvaluatorAppendArray<int64_t>>(Variant::OP_ADD, Variant::PACKED_INT64_ARRAY, Variant::PACKED_INT64_ARRAY); + register_op<OperatorEvaluatorAppendArray<float>>(Variant::OP_ADD, Variant::PACKED_FLOAT32_ARRAY, Variant::PACKED_FLOAT32_ARRAY); + register_op<OperatorEvaluatorAppendArray<double>>(Variant::OP_ADD, Variant::PACKED_FLOAT64_ARRAY, Variant::PACKED_FLOAT64_ARRAY); + register_op<OperatorEvaluatorAppendArray<String>>(Variant::OP_ADD, Variant::PACKED_STRING_ARRAY, Variant::PACKED_STRING_ARRAY); + register_op<OperatorEvaluatorAppendArray<Vector2>>(Variant::OP_ADD, Variant::PACKED_VECTOR2_ARRAY, Variant::PACKED_VECTOR2_ARRAY); + register_op<OperatorEvaluatorAppendArray<Vector3>>(Variant::OP_ADD, Variant::PACKED_VECTOR3_ARRAY, Variant::PACKED_VECTOR3_ARRAY); + register_op<OperatorEvaluatorAppendArray<Color>>(Variant::OP_ADD, Variant::PACKED_COLOR_ARRAY, Variant::PACKED_COLOR_ARRAY); + + register_op<OperatorEvaluatorSub<int64_t, int64_t, int64_t>>(Variant::OP_SUBTRACT, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorSub<double, int64_t, double>>(Variant::OP_SUBTRACT, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorSub<double, double, int64_t>>(Variant::OP_SUBTRACT, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorSub<double, double, double>>(Variant::OP_SUBTRACT, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorSub<Vector2, Vector2, Vector2>>(Variant::OP_SUBTRACT, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I); + + register_op<OperatorEvaluatorMul<int64_t, int64_t, int64_t>>(Variant::OP_MULTIPLY, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorMul<double, int64_t, double>>(Variant::OP_MULTIPLY, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Vector2, int64_t, Vector2>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR2); + register_op<OperatorEvaluatorMul<Vector2i, int64_t, Vector2i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR2I); + register_op<OperatorEvaluatorMul<Vector3, int64_t, Vector3>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3); + register_op<OperatorEvaluatorMul<Vector3i, int64_t, Vector3i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3I); + + register_op<OperatorEvaluatorMul<double, double, double>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorMul<double, double, int64_t>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorMul<Vector2, double, Vector2>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR2); + register_op<OperatorEvaluatorMul<Vector2i, double, Vector2i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR2I); + register_op<OperatorEvaluatorMul<Vector3, double, Vector3>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3); + register_op<OperatorEvaluatorMul<Vector3i, double, Vector3i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3I); + + register_op<OperatorEvaluatorMul<Vector2, Vector2, Vector2>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorMul<Vector2, Vector2, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::INT); + register_op<OperatorEvaluatorMul<Vector2, Vector2, double>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Vector2i, Vector2i, Vector2i>>(Variant::OP_MULTIPLY, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorMul<Vector2i, Vector2i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR2I, Variant::INT); + register_op<OperatorEvaluatorMul<Vector2i, Vector2i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR2I, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Vector3, Vector3, Vector3>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorMul<Vector3, Vector3, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::INT); + register_op<OperatorEvaluatorMul<Vector3, Vector3, double>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Vector3i, Vector3i, Vector3i>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorMul<Vector3i, Vector3i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::INT); + register_op<OperatorEvaluatorMul<Vector3i, Vector3i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Quat, Quat, Quat>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorMul<Quat, Quat, int64_t>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::INT); + register_op<OperatorEvaluatorMul<Quat, Quat, double>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Color, Color, Color>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::COLOR); + register_op<OperatorEvaluatorMul<Color, Color, int64_t>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::INT); + register_op<OperatorEvaluatorMul<Color, Color, double>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Transform2D, Transform2D, Transform2D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorXForm<Vector2, Transform2D, Vector2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::VECTOR2); + register_op<OperatorEvaluatorXFormInv<Vector2, Vector2, Transform2D>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorXForm<Rect2, Transform2D, Rect2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::RECT2); + register_op<OperatorEvaluatorXFormInv<Rect2, Rect2, Transform2D>>(Variant::OP_MULTIPLY, Variant::RECT2, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorXForm<Vector<Vector2>, Transform2D, Vector<Vector2>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::PACKED_VECTOR2_ARRAY); + register_op<OperatorEvaluatorXFormInv<Vector<Vector2>, Vector<Vector2>, Transform2D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR2_ARRAY, Variant::TRANSFORM2D); + + register_op<OperatorEvaluatorMul<Transform, Transform, Transform>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::TRANSFORM); + register_op<OperatorEvaluatorXForm<Vector3, Transform, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::VECTOR3); + register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM); + register_op<OperatorEvaluatorXForm<::AABB, Transform, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::AABB); + register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM); + register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::PACKED_VECTOR3_ARRAY); + register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM); + + register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS); + register_op<OperatorEvaluatorXForm<Vector3, Basis, Vector3>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::VECTOR3); + register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Basis>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::BASIS); + + register_op<OperatorEvaluatorMul<Quat, Quat, Quat>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorMul<Quat, Quat, int64_t>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::INT); + register_op<OperatorEvaluatorMul<Quat, int64_t, Quat>>(Variant::OP_MULTIPLY, Variant::INT, Variant::QUAT); + register_op<OperatorEvaluatorMul<Quat, Quat, double>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Quat, double, Quat>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::QUAT); + register_op<OperatorEvaluatorXForm<Vector3, Quat, Vector3>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::VECTOR3); + register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Quat>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::QUAT); + + register_op<OperatorEvaluatorMul<Color, Color, Color>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::COLOR); + register_op<OperatorEvaluatorMul<Color, Color, int64_t>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::INT); + register_op<OperatorEvaluatorMul<Color, int64_t, Color>>(Variant::OP_MULTIPLY, Variant::INT, Variant::COLOR); + register_op<OperatorEvaluatorMul<Color, Color, double>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Color, double, Color>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::COLOR); + + register_op<OperatorEvaluatorDivNZ<int64_t, int64_t, int64_t>>(Variant::OP_DIVIDE, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorDiv<double, double, int64_t>>(Variant::OP_DIVIDE, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorDiv<double, int64_t, double>>(Variant::OP_DIVIDE, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<double, double, double>>(Variant::OP_DIVIDE, Variant::FLOAT, Variant::FLOAT); + + register_op<OperatorEvaluatorDiv<Vector2, Vector2, Vector2>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorDiv<Vector2, Vector2, double>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Vector2, Vector2, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::INT); + + register_op<OperatorEvaluatorDiv<Vector2i, Vector2i, Vector2i>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, double>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::FLOAT); + register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::INT); + + register_op<OperatorEvaluatorDiv<Vector2, Vector2, Vector2>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorDiv<Vector2, Vector2, double>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Vector2, Vector2, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::INT); + + register_op<OperatorEvaluatorDiv<Vector3, Vector3, Vector3>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorDiv<Vector3, Vector3, double>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Vector3, Vector3, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::INT); + + register_op<OperatorEvaluatorDiv<Vector3i, Vector3i, Vector3i>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT); + register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT); + + register_op<OperatorEvaluatorDiv<Quat, Quat, double>>(Variant::OP_DIVIDE, Variant::QUAT, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Quat, Quat, int64_t>>(Variant::OP_DIVIDE, Variant::QUAT, Variant::INT); + + register_op<OperatorEvaluatorDiv<Color, Color, Color>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::COLOR); + register_op<OperatorEvaluatorDiv<Color, Color, double>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Color, Color, int64_t>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::INT); + + register_op<OperatorEvaluatorModNZ<int64_t, int64_t, int64_t>>(Variant::OP_MODULE, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorMod<Vector2i, Vector2i, Vector2i>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorModNZ<Vector2i, Vector2i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::INT); + + register_op<OperatorEvaluatorMod<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::INT); + + register_op<OperatorEvaluatorStringModNil>(Variant::OP_MODULE, Variant::STRING, Variant::NIL); + + register_op<OperatorEvaluatorStringModT<bool>>(Variant::OP_MODULE, Variant::STRING, Variant::BOOL); + register_op<OperatorEvaluatorStringModT<int64_t>>(Variant::OP_MODULE, Variant::STRING, Variant::INT); + register_op<OperatorEvaluatorStringModT<double>>(Variant::OP_MODULE, Variant::STRING, Variant::FLOAT); + register_op<OperatorEvaluatorStringModT<String>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorStringModT<Vector2>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR2); + register_op<OperatorEvaluatorStringModT<Vector2i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR2I); + register_op<OperatorEvaluatorStringModT<Rect2>>(Variant::OP_MODULE, Variant::STRING, Variant::RECT2); + register_op<OperatorEvaluatorStringModT<Rect2i>>(Variant::OP_MODULE, Variant::STRING, Variant::RECT2I); + register_op<OperatorEvaluatorStringModT<Vector3>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3); + register_op<OperatorEvaluatorStringModT<Vector3i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3I); + register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE); + register_op<OperatorEvaluatorStringModT<Quat>>(Variant::OP_MODULE, Variant::STRING, Variant::QUAT); + register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB); + register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS); + register_op<OperatorEvaluatorStringModT<Transform>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM); + + register_op<OperatorEvaluatorStringModT<Color>>(Variant::OP_MODULE, Variant::STRING, Variant::COLOR); + register_op<OperatorEvaluatorStringModT<StringName>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING_NAME); + register_op<OperatorEvaluatorStringModT<NodePath>>(Variant::OP_MODULE, Variant::STRING, Variant::NODE_PATH); + register_op<OperatorEvaluatorStringModObject>(Variant::OP_MODULE, Variant::STRING, Variant::OBJECT); + register_op<OperatorEvaluatorStringModT<Callable>>(Variant::OP_MODULE, Variant::STRING, Variant::CALLABLE); + register_op<OperatorEvaluatorStringModT<Signal>>(Variant::OP_MODULE, Variant::STRING, Variant::SIGNAL); + register_op<OperatorEvaluatorStringModT<Dictionary>>(Variant::OP_MODULE, Variant::STRING, Variant::DICTIONARY); + register_op<OperatorEvaluatorStringModArray>(Variant::OP_MODULE, Variant::STRING, Variant::ARRAY); + + register_op<OperatorEvaluatorStringModT<PackedByteArray>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_BYTE_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedInt32Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_INT32_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedInt64Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_INT64_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedFloat32Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_FLOAT32_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedFloat64Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_FLOAT64_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedStringArray>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_STRING_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedVector2Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_VECTOR2_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedVector3Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_VECTOR3_ARRAY); + register_op<OperatorEvaluatorStringModT<PackedColorArray>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_COLOR_ARRAY); + + register_op<OperatorEvaluatorNeg<int64_t, int64_t>>(Variant::OP_NEGATE, Variant::INT, Variant::NIL); + register_op<OperatorEvaluatorNeg<double, double>>(Variant::OP_NEGATE, Variant::FLOAT, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector2, Vector2>>(Variant::OP_NEGATE, Variant::VECTOR2, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector2i, Vector2i>>(Variant::OP_NEGATE, Variant::VECTOR2I, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector3, Vector3>>(Variant::OP_NEGATE, Variant::VECTOR3, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector3i, Vector3i>>(Variant::OP_NEGATE, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorNeg<Quat, Quat>>(Variant::OP_NEGATE, Variant::QUAT, Variant::NIL); + register_op<OperatorEvaluatorNeg<Plane, Plane>>(Variant::OP_NEGATE, Variant::PLANE, Variant::NIL); + register_op<OperatorEvaluatorNeg<Color, Color>>(Variant::OP_NEGATE, Variant::COLOR, Variant::NIL); + + register_op<OperatorEvaluatorPos<int64_t, int64_t>>(Variant::OP_POSITIVE, Variant::INT, Variant::NIL); + register_op<OperatorEvaluatorPos<double, double>>(Variant::OP_POSITIVE, Variant::FLOAT, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector2, Vector2>>(Variant::OP_POSITIVE, Variant::VECTOR2, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector2i, Vector2i>>(Variant::OP_POSITIVE, Variant::VECTOR2I, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector3, Vector3>>(Variant::OP_POSITIVE, Variant::VECTOR3, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector3i, Vector3i>>(Variant::OP_POSITIVE, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorPos<Quat, Quat>>(Variant::OP_POSITIVE, Variant::QUAT, Variant::NIL); + register_op<OperatorEvaluatorPos<Plane, Plane>>(Variant::OP_POSITIVE, Variant::PLANE, Variant::NIL); + register_op<OperatorEvaluatorPos<Color, Color>>(Variant::OP_POSITIVE, Variant::COLOR, Variant::NIL); + + register_op<OperatorEvaluatorShiftLeft<int64_t, int64_t, int64_t>>(Variant::OP_SHIFT_LEFT, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorShiftRight<int64_t, int64_t, int64_t>>(Variant::OP_SHIFT_RIGHT, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorBitOr<int64_t, int64_t, int64_t>>(Variant::OP_BIT_OR, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorBitAnd<int64_t, int64_t, int64_t>>(Variant::OP_BIT_AND, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorBitXor<int64_t, int64_t, int64_t>>(Variant::OP_BIT_XOR, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorBitNeg<int64_t, int64_t>>(Variant::OP_BIT_NEGATE, Variant::INT, Variant::NIL); + + register_op<OperatorEvaluatorBitNeg<int64_t, int64_t>>(Variant::OP_BIT_NEGATE, Variant::INT, Variant::NIL); + + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_EQUAL, Variant::NIL, Variant::NIL>>(Variant::OP_EQUAL, Variant::NIL, Variant::NIL); + register_op<OperatorEvaluatorEqual<bool, bool>>(Variant::OP_EQUAL, Variant::BOOL, Variant::BOOL); + register_op<OperatorEvaluatorEqual<int64_t, int64_t>>(Variant::OP_EQUAL, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorEqual<int64_t, double>>(Variant::OP_EQUAL, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorEqual<double, int64_t>>(Variant::OP_EQUAL, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorEqual<double, double>>(Variant::OP_EQUAL, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorEqual<String, String>>(Variant::OP_EQUAL, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorEqual<Vector2, Vector2>>(Variant::OP_EQUAL, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorEqual<Vector2i, Vector2i>>(Variant::OP_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorEqual<Rect2, Rect2>>(Variant::OP_EQUAL, Variant::RECT2, Variant::RECT2); + register_op<OperatorEvaluatorEqual<Rect2i, Rect2i>>(Variant::OP_EQUAL, Variant::RECT2I, Variant::RECT2I); + register_op<OperatorEvaluatorEqual<Vector3, Vector3>>(Variant::OP_EQUAL, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorEqual<Vector3i, Vector3i>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorEqual<Transform2D, Transform2D>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorEqual<Plane, Plane>>(Variant::OP_EQUAL, Variant::PLANE, Variant::PLANE); + register_op<OperatorEvaluatorEqual<Quat, Quat>>(Variant::OP_EQUAL, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorEqual<::AABB, ::AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB); + register_op<OperatorEvaluatorEqual<Basis, Basis>>(Variant::OP_EQUAL, Variant::BASIS, Variant::BASIS); + register_op<OperatorEvaluatorEqual<Transform, Transform>>(Variant::OP_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM); + register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR); + + register_op<OperatorEvaluatorEqual<StringName, String>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING); + register_op<OperatorEvaluatorEqual<String, StringName>>(Variant::OP_EQUAL, Variant::STRING, Variant::STRING_NAME); + register_op<OperatorEvaluatorEqual<StringName, StringName>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING_NAME); + + register_op<OperatorEvaluatorEqual<NodePath, NodePath>>(Variant::OP_EQUAL, Variant::NODE_PATH, Variant::NODE_PATH); + register_op<OperatorEvaluatorEqual<::RID, ::RID>>(Variant::OP_EQUAL, Variant::RID, Variant::RID); + + register_op<OperatorEvaluatorEqualObject>(Variant::OP_EQUAL, Variant::OBJECT, Variant::OBJECT); + register_op<OperatorEvaluatorEqualObjectNil>(Variant::OP_EQUAL, Variant::OBJECT, Variant::NIL); + register_op<OperatorEvaluatorEqualNilObject>(Variant::OP_EQUAL, Variant::NIL, Variant::OBJECT); + + register_op<OperatorEvaluatorEqual<Callable, Callable>>(Variant::OP_EQUAL, Variant::CALLABLE, Variant::CALLABLE); + register_op<OperatorEvaluatorEqual<Signal, Signal>>(Variant::OP_EQUAL, Variant::SIGNAL, Variant::SIGNAL); + register_op<OperatorEvaluatorEqual<Dictionary, Dictionary>>(Variant::OP_EQUAL, Variant::DICTIONARY, Variant::DICTIONARY); + register_op<OperatorEvaluatorEqual<Array, Array>>(Variant::OP_EQUAL, Variant::ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorEqual<PackedByteArray, PackedByteArray>>(Variant::OP_EQUAL, Variant::PACKED_BYTE_ARRAY, Variant::PACKED_BYTE_ARRAY); + register_op<OperatorEvaluatorEqual<PackedInt32Array, PackedInt32Array>>(Variant::OP_EQUAL, Variant::PACKED_INT32_ARRAY, Variant::PACKED_INT32_ARRAY); + register_op<OperatorEvaluatorEqual<PackedInt64Array, PackedInt64Array>>(Variant::OP_EQUAL, Variant::PACKED_INT64_ARRAY, Variant::PACKED_INT64_ARRAY); + register_op<OperatorEvaluatorEqual<PackedFloat32Array, PackedFloat32Array>>(Variant::OP_EQUAL, Variant::PACKED_FLOAT32_ARRAY, Variant::PACKED_FLOAT32_ARRAY); + register_op<OperatorEvaluatorEqual<PackedFloat64Array, PackedFloat64Array>>(Variant::OP_EQUAL, Variant::PACKED_FLOAT64_ARRAY, Variant::PACKED_FLOAT64_ARRAY); + register_op<OperatorEvaluatorEqual<PackedStringArray, PackedStringArray>>(Variant::OP_EQUAL, Variant::PACKED_STRING_ARRAY, Variant::PACKED_STRING_ARRAY); + register_op<OperatorEvaluatorEqual<PackedVector2Array, PackedVector2Array>>(Variant::OP_EQUAL, Variant::PACKED_VECTOR2_ARRAY, Variant::PACKED_VECTOR2_ARRAY); + register_op<OperatorEvaluatorEqual<PackedVector3Array, PackedVector3Array>>(Variant::OP_EQUAL, Variant::PACKED_VECTOR3_ARRAY, Variant::PACKED_VECTOR3_ARRAY); + register_op<OperatorEvaluatorEqual<PackedColorArray, PackedColorArray>>(Variant::OP_EQUAL, Variant::PACKED_COLOR_ARRAY, Variant::PACKED_COLOR_ARRAY); + + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::NIL); + register_op<OperatorEvaluatorNotEqual<bool, bool>>(Variant::OP_NOT_EQUAL, Variant::BOOL, Variant::BOOL); + register_op<OperatorEvaluatorNotEqual<int64_t, int64_t>>(Variant::OP_NOT_EQUAL, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorNotEqual<int64_t, double>>(Variant::OP_NOT_EQUAL, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorNotEqual<double, int64_t>>(Variant::OP_NOT_EQUAL, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorNotEqual<double, double>>(Variant::OP_NOT_EQUAL, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorNotEqual<String, String>>(Variant::OP_NOT_EQUAL, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorNotEqual<Vector2, Vector2>>(Variant::OP_NOT_EQUAL, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorNotEqual<Vector2i, Vector2i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorNotEqual<Rect2, Rect2>>(Variant::OP_NOT_EQUAL, Variant::RECT2, Variant::RECT2); + register_op<OperatorEvaluatorNotEqual<Rect2i, Rect2i>>(Variant::OP_NOT_EQUAL, Variant::RECT2I, Variant::RECT2I); + register_op<OperatorEvaluatorNotEqual<Vector3, Vector3>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorNotEqual<Vector3i, Vector3i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorNotEqual<Transform2D, Transform2D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorNotEqual<Plane, Plane>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::PLANE); + register_op<OperatorEvaluatorNotEqual<Quat, Quat>>(Variant::OP_NOT_EQUAL, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorNotEqual<::AABB, ::AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB); + register_op<OperatorEvaluatorNotEqual<Basis, Basis>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::BASIS); + register_op<OperatorEvaluatorNotEqual<Transform, Transform>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM); + register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR); + + register_op<OperatorEvaluatorNotEqual<StringName, String>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING); + register_op<OperatorEvaluatorNotEqual<String, StringName>>(Variant::OP_NOT_EQUAL, Variant::STRING, Variant::STRING_NAME); + register_op<OperatorEvaluatorNotEqual<StringName, StringName>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING_NAME); + + register_op<OperatorEvaluatorNotEqual<NodePath, NodePath>>(Variant::OP_NOT_EQUAL, Variant::NODE_PATH, Variant::NODE_PATH); + register_op<OperatorEvaluatorNotEqual<::RID, ::RID>>(Variant::OP_NOT_EQUAL, Variant::RID, Variant::RID); + + register_op<OperatorEvaluatorNotEqualObject>(Variant::OP_NOT_EQUAL, Variant::OBJECT, Variant::OBJECT); + register_op<OperatorEvaluatorNotEqualObjectNil>(Variant::OP_NOT_EQUAL, Variant::OBJECT, Variant::NIL); + register_op<OperatorEvaluatorNotEqualNilObject>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::OBJECT); + + register_op<OperatorEvaluatorNotEqual<Callable, Callable>>(Variant::OP_NOT_EQUAL, Variant::CALLABLE, Variant::CALLABLE); + register_op<OperatorEvaluatorNotEqual<Signal, Signal>>(Variant::OP_NOT_EQUAL, Variant::SIGNAL, Variant::SIGNAL); + register_op<OperatorEvaluatorNotEqual<Dictionary, Dictionary>>(Variant::OP_NOT_EQUAL, Variant::DICTIONARY, Variant::DICTIONARY); + register_op<OperatorEvaluatorNotEqual<Array, Array>>(Variant::OP_NOT_EQUAL, Variant::ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedByteArray, PackedByteArray>>(Variant::OP_NOT_EQUAL, Variant::PACKED_BYTE_ARRAY, Variant::PACKED_BYTE_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedInt32Array, PackedInt32Array>>(Variant::OP_NOT_EQUAL, Variant::PACKED_INT32_ARRAY, Variant::PACKED_INT32_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedInt64Array, PackedInt64Array>>(Variant::OP_NOT_EQUAL, Variant::PACKED_INT64_ARRAY, Variant::PACKED_INT64_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedFloat32Array, PackedFloat32Array>>(Variant::OP_NOT_EQUAL, Variant::PACKED_FLOAT32_ARRAY, Variant::PACKED_FLOAT32_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedFloat64Array, PackedFloat64Array>>(Variant::OP_NOT_EQUAL, Variant::PACKED_FLOAT64_ARRAY, Variant::PACKED_FLOAT64_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedStringArray, PackedStringArray>>(Variant::OP_NOT_EQUAL, Variant::PACKED_STRING_ARRAY, Variant::PACKED_STRING_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedVector2Array, PackedVector2Array>>(Variant::OP_NOT_EQUAL, Variant::PACKED_VECTOR2_ARRAY, Variant::PACKED_VECTOR2_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedVector3Array, PackedVector3Array>>(Variant::OP_NOT_EQUAL, Variant::PACKED_VECTOR3_ARRAY, Variant::PACKED_VECTOR3_ARRAY); + register_op<OperatorEvaluatorNotEqual<PackedColorArray, PackedColorArray>>(Variant::OP_NOT_EQUAL, Variant::PACKED_COLOR_ARRAY, Variant::PACKED_COLOR_ARRAY); + + register_op<OperatorEvaluatorLess<bool, bool>>(Variant::OP_LESS, Variant::BOOL, Variant::BOOL); + register_op<OperatorEvaluatorLess<int64_t, int64_t>>(Variant::OP_LESS, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorLess<int64_t, double>>(Variant::OP_LESS, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorLess<double, int64_t>>(Variant::OP_LESS, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorLess<double, double>>(Variant::OP_LESS, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorLess<String, String>>(Variant::OP_LESS, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorLess<Vector2, Vector2>>(Variant::OP_LESS, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorLess<Vector2i, Vector2i>>(Variant::OP_LESS, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorLess<Vector3, Vector3>>(Variant::OP_LESS, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorLess<Vector3i, Vector3i>>(Variant::OP_LESS, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorLess<::RID, ::RID>>(Variant::OP_LESS, Variant::RID, Variant::RID); + register_op<OperatorEvaluatorLess<Array, Array>>(Variant::OP_LESS, Variant::ARRAY, Variant::ARRAY); + + register_op<OperatorEvaluatorLessEqual<int64_t, int64_t>>(Variant::OP_LESS_EQUAL, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorLessEqual<int64_t, double>>(Variant::OP_LESS_EQUAL, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorLessEqual<double, int64_t>>(Variant::OP_LESS_EQUAL, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorLessEqual<double, double>>(Variant::OP_LESS_EQUAL, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorLessEqual<String, String>>(Variant::OP_LESS_EQUAL, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorLessEqual<Vector2, Vector2>>(Variant::OP_LESS_EQUAL, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorLessEqual<Vector2i, Vector2i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorLessEqual<Vector3, Vector3>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorLessEqual<Vector3i, Vector3i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorLessEqual<::RID, ::RID>>(Variant::OP_LESS_EQUAL, Variant::RID, Variant::RID); + register_op<OperatorEvaluatorLessEqual<Array, Array>>(Variant::OP_LESS_EQUAL, Variant::ARRAY, Variant::ARRAY); + + register_op<OperatorEvaluatorGreater<bool, bool>>(Variant::OP_GREATER, Variant::BOOL, Variant::BOOL); + register_op<OperatorEvaluatorGreater<int64_t, int64_t>>(Variant::OP_GREATER, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorGreater<int64_t, double>>(Variant::OP_GREATER, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorGreater<double, int64_t>>(Variant::OP_GREATER, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorGreater<double, double>>(Variant::OP_GREATER, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorGreater<String, String>>(Variant::OP_GREATER, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorGreater<Vector2, Vector2>>(Variant::OP_GREATER, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorGreater<Vector2i, Vector2i>>(Variant::OP_GREATER, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorGreater<Vector3, Vector3>>(Variant::OP_GREATER, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorGreater<Vector3i, Vector3i>>(Variant::OP_GREATER, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorGreater<::RID, ::RID>>(Variant::OP_GREATER, Variant::RID, Variant::RID); + register_op<OperatorEvaluatorGreater<Array, Array>>(Variant::OP_GREATER, Variant::ARRAY, Variant::ARRAY); + + register_op<OperatorEvaluatorGreaterEqual<int64_t, int64_t>>(Variant::OP_GREATER_EQUAL, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorGreaterEqual<int64_t, double>>(Variant::OP_GREATER_EQUAL, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorGreaterEqual<double, int64_t>>(Variant::OP_GREATER_EQUAL, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorGreaterEqual<double, double>>(Variant::OP_GREATER_EQUAL, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorGreaterEqual<String, String>>(Variant::OP_GREATER_EQUAL, Variant::STRING, Variant::STRING); + register_op<OperatorEvaluatorGreaterEqual<Vector2, Vector2>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR2, Variant::VECTOR2); + register_op<OperatorEvaluatorGreaterEqual<Vector2i, Vector2i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorGreaterEqual<Vector3, Vector3>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3, Variant::VECTOR3); + register_op<OperatorEvaluatorGreaterEqual<Vector3i, Vector3i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorGreaterEqual<::RID, ::RID>>(Variant::OP_GREATER_EQUAL, Variant::RID, Variant::RID); + register_op<OperatorEvaluatorGreaterEqual<Array, Array>>(Variant::OP_GREATER_EQUAL, Variant::ARRAY, Variant::ARRAY); + + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_OR, Variant::NIL, Variant::NIL>>(Variant::OP_OR, Variant::NIL, Variant::NIL); + + //OR + register_op<OperatorEvaluatorNilXBoolOr>(Variant::OP_OR, Variant::NIL, Variant::BOOL); + register_op<OperatorEvaluatorBoolXNilOr>(Variant::OP_OR, Variant::BOOL, Variant::NIL); + register_op<OperatorEvaluatorNilXIntOr>(Variant::OP_OR, Variant::NIL, Variant::INT); + register_op<OperatorEvaluatorIntXNilOr>(Variant::OP_OR, Variant::INT, Variant::NIL); + register_op<OperatorEvaluatorNilXFloatOr>(Variant::OP_OR, Variant::NIL, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXNilOr>(Variant::OP_OR, Variant::FLOAT, Variant::NIL); + register_op<OperatorEvaluatorNilXObjectOr>(Variant::OP_OR, Variant::NIL, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXNilOr>(Variant::OP_OR, Variant::OBJECT, Variant::NIL); + + register_op<OperatorEvaluatorBoolXBoolOr>(Variant::OP_OR, Variant::BOOL, Variant::BOOL); + register_op<OperatorEvaluatorBoolXIntOr>(Variant::OP_OR, Variant::BOOL, Variant::INT); + register_op<OperatorEvaluatorIntXBoolOr>(Variant::OP_OR, Variant::INT, Variant::BOOL); + register_op<OperatorEvaluatorBoolXFloatOr>(Variant::OP_OR, Variant::BOOL, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXBoolOr>(Variant::OP_OR, Variant::FLOAT, Variant::BOOL); + register_op<OperatorEvaluatorBoolXObjectOr>(Variant::OP_OR, Variant::BOOL, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXBoolOr>(Variant::OP_OR, Variant::OBJECT, Variant::BOOL); + + register_op<OperatorEvaluatorIntXIntOr>(Variant::OP_OR, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorIntXFloatOr>(Variant::OP_OR, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXIntOr>(Variant::OP_OR, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorIntXObjectOr>(Variant::OP_OR, Variant::INT, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXIntOr>(Variant::OP_OR, Variant::OBJECT, Variant::INT); + + register_op<OperatorEvaluatorFloatXFloatOr>(Variant::OP_OR, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXObjectOr>(Variant::OP_OR, Variant::FLOAT, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXFloatOr>(Variant::OP_OR, Variant::OBJECT, Variant::FLOAT); + register_op<OperatorEvaluatorObjectXObjectOr>(Variant::OP_OR, Variant::OBJECT, Variant::OBJECT); + //AND + register_op<OperatorEvaluatorNilXBoolAnd>(Variant::OP_AND, Variant::NIL, Variant::BOOL); + register_op<OperatorEvaluatorBoolXNilAnd>(Variant::OP_AND, Variant::BOOL, Variant::NIL); + register_op<OperatorEvaluatorNilXIntAnd>(Variant::OP_AND, Variant::NIL, Variant::INT); + register_op<OperatorEvaluatorIntXNilAnd>(Variant::OP_AND, Variant::INT, Variant::NIL); + register_op<OperatorEvaluatorNilXFloatAnd>(Variant::OP_AND, Variant::NIL, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXNilAnd>(Variant::OP_AND, Variant::FLOAT, Variant::NIL); + register_op<OperatorEvaluatorNilXObjectAnd>(Variant::OP_AND, Variant::NIL, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXNilAnd>(Variant::OP_AND, Variant::OBJECT, Variant::NIL); + + register_op<OperatorEvaluatorBoolXBoolAnd>(Variant::OP_AND, Variant::BOOL, Variant::BOOL); + register_op<OperatorEvaluatorBoolXIntAnd>(Variant::OP_AND, Variant::BOOL, Variant::INT); + register_op<OperatorEvaluatorIntXBoolAnd>(Variant::OP_AND, Variant::INT, Variant::BOOL); + register_op<OperatorEvaluatorBoolXFloatAnd>(Variant::OP_AND, Variant::BOOL, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXBoolAnd>(Variant::OP_AND, Variant::FLOAT, Variant::BOOL); + register_op<OperatorEvaluatorBoolXObjectAnd>(Variant::OP_AND, Variant::BOOL, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXBoolAnd>(Variant::OP_AND, Variant::OBJECT, Variant::BOOL); + + register_op<OperatorEvaluatorIntXIntAnd>(Variant::OP_AND, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorIntXFloatAnd>(Variant::OP_AND, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXIntAnd>(Variant::OP_AND, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorIntXObjectAnd>(Variant::OP_AND, Variant::INT, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXIntAnd>(Variant::OP_AND, Variant::OBJECT, Variant::INT); + + register_op<OperatorEvaluatorFloatXFloatAnd>(Variant::OP_AND, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXObjectAnd>(Variant::OP_AND, Variant::FLOAT, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXFloatAnd>(Variant::OP_AND, Variant::OBJECT, Variant::FLOAT); + register_op<OperatorEvaluatorObjectXObjectAnd>(Variant::OP_AND, Variant::OBJECT, Variant::OBJECT); + //XOR + register_op<OperatorEvaluatorNilXBoolXor>(Variant::OP_XOR, Variant::NIL, Variant::BOOL); + register_op<OperatorEvaluatorBoolXNilXor>(Variant::OP_XOR, Variant::BOOL, Variant::NIL); + register_op<OperatorEvaluatorNilXIntXor>(Variant::OP_XOR, Variant::NIL, Variant::INT); + register_op<OperatorEvaluatorIntXNilXor>(Variant::OP_XOR, Variant::INT, Variant::NIL); + register_op<OperatorEvaluatorNilXFloatXor>(Variant::OP_XOR, Variant::NIL, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXNilXor>(Variant::OP_XOR, Variant::FLOAT, Variant::NIL); + register_op<OperatorEvaluatorNilXObjectXor>(Variant::OP_XOR, Variant::NIL, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXNilXor>(Variant::OP_XOR, Variant::OBJECT, Variant::NIL); + + register_op<OperatorEvaluatorBoolXBoolXor>(Variant::OP_XOR, Variant::BOOL, Variant::BOOL); + register_op<OperatorEvaluatorBoolXIntXor>(Variant::OP_XOR, Variant::BOOL, Variant::INT); + register_op<OperatorEvaluatorIntXBoolXor>(Variant::OP_XOR, Variant::INT, Variant::BOOL); + register_op<OperatorEvaluatorBoolXFloatXor>(Variant::OP_XOR, Variant::BOOL, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXBoolXor>(Variant::OP_XOR, Variant::FLOAT, Variant::BOOL); + register_op<OperatorEvaluatorBoolXObjectXor>(Variant::OP_XOR, Variant::BOOL, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXBoolXor>(Variant::OP_XOR, Variant::OBJECT, Variant::BOOL); + + register_op<OperatorEvaluatorIntXIntXor>(Variant::OP_XOR, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorIntXFloatXor>(Variant::OP_XOR, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXIntXor>(Variant::OP_XOR, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorIntXObjectXor>(Variant::OP_XOR, Variant::INT, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXIntXor>(Variant::OP_XOR, Variant::OBJECT, Variant::INT); + + register_op<OperatorEvaluatorFloatXFloatXor>(Variant::OP_XOR, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorFloatXObjectXor>(Variant::OP_XOR, Variant::FLOAT, Variant::OBJECT); + register_op<OperatorEvaluatorObjectXFloatXor>(Variant::OP_XOR, Variant::OBJECT, Variant::FLOAT); + register_op<OperatorEvaluatorObjectXObjectXor>(Variant::OP_XOR, Variant::OBJECT, Variant::OBJECT); + + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT, Variant::NIL, Variant::NIL>>(Variant::OP_NOT, Variant::NIL, Variant::NIL); + register_op<OperatorEvaluatorNotBool>(Variant::OP_NOT, Variant::BOOL, Variant::NIL); + register_op<OperatorEvaluatorNotInt>(Variant::OP_NOT, Variant::INT, Variant::NIL); + register_op<OperatorEvaluatorNotFloat>(Variant::OP_NOT, Variant::FLOAT, Variant::NIL); + register_op<OperatorEvaluatorNotObject>(Variant::OP_NOT, Variant::OBJECT, Variant::NIL); + + register_op<OperatorEvaluatorInStringFind>(Variant::OP_IN, Variant::STRING, Variant::STRING); + + register_op<OperatorEvaluatorInDictionaryHasNil>(Variant::OP_IN, Variant::NIL, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<bool>>(Variant::OP_IN, Variant::BOOL, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<int64_t>>(Variant::OP_IN, Variant::INT, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<double>>(Variant::OP_IN, Variant::FLOAT, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<String>>(Variant::OP_IN, Variant::STRING, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector2>>(Variant::OP_IN, Variant::VECTOR2, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector2i>>(Variant::OP_IN, Variant::VECTOR2I, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Rect2>>(Variant::OP_IN, Variant::RECT2, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Rect2i>>(Variant::OP_IN, Variant::RECT2I, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector3>>(Variant::OP_IN, Variant::VECTOR3, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector3i>>(Variant::OP_IN, Variant::VECTOR3I, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Transform2D>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Plane>>(Variant::OP_IN, Variant::PLANE, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Quat>>(Variant::OP_IN, Variant::QUAT, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<::AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Basis>>(Variant::OP_IN, Variant::BASIS, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Transform>>(Variant::OP_IN, Variant::TRANSFORM, Variant::DICTIONARY); + + register_op<OperatorEvaluatorInDictionaryHas<Color>>(Variant::OP_IN, Variant::COLOR, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<NodePath>>(Variant::OP_IN, Variant::NODE_PATH, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHasObject>(Variant::OP_IN, Variant::OBJECT, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Callable>>(Variant::OP_IN, Variant::CALLABLE, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Signal>>(Variant::OP_IN, Variant::SIGNAL, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Dictionary>>(Variant::OP_IN, Variant::DICTIONARY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Array>>(Variant::OP_IN, Variant::ARRAY, Variant::DICTIONARY); + + register_op<OperatorEvaluatorInDictionaryHas<PackedByteArray>>(Variant::OP_IN, Variant::PACKED_BYTE_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedInt32Array>>(Variant::OP_IN, Variant::PACKED_INT32_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedInt64Array>>(Variant::OP_IN, Variant::PACKED_INT64_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedFloat32Array>>(Variant::OP_IN, Variant::PACKED_FLOAT32_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedFloat64Array>>(Variant::OP_IN, Variant::PACKED_FLOAT64_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedStringArray>>(Variant::OP_IN, Variant::PACKED_STRING_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedVector2Array>>(Variant::OP_IN, Variant::PACKED_VECTOR2_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedVector3Array>>(Variant::OP_IN, Variant::PACKED_VECTOR3_ARRAY, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<PackedColorArray>>(Variant::OP_IN, Variant::PACKED_COLOR_ARRAY, Variant::DICTIONARY); + + register_op<OperatorEvaluatorInArrayFindNil>(Variant::OP_IN, Variant::NIL, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<bool, Array>>(Variant::OP_IN, Variant::BOOL, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<int64_t, Array>>(Variant::OP_IN, Variant::INT, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<double, Array>>(Variant::OP_IN, Variant::FLOAT, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<String, Array>>(Variant::OP_IN, Variant::STRING, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector2, Array>>(Variant::OP_IN, Variant::VECTOR2, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector2i, Array>>(Variant::OP_IN, Variant::VECTOR2I, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Rect2, Array>>(Variant::OP_IN, Variant::RECT2, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Rect2i, Array>>(Variant::OP_IN, Variant::RECT2I, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector3, Array>>(Variant::OP_IN, Variant::VECTOR3, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector3i, Array>>(Variant::OP_IN, Variant::VECTOR3I, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Transform2D, Array>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Plane, Array>>(Variant::OP_IN, Variant::PLANE, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Quat, Array>>(Variant::OP_IN, Variant::QUAT, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<::AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Basis, Array>>(Variant::OP_IN, Variant::BASIS, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Transform, Array>>(Variant::OP_IN, Variant::TRANSFORM, Variant::ARRAY); + + register_op<OperatorEvaluatorInArrayFind<Color, Array>>(Variant::OP_IN, Variant::COLOR, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<StringName, Array>>(Variant::OP_IN, Variant::STRING_NAME, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<NodePath, Array>>(Variant::OP_IN, Variant::NODE_PATH, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFindObject>(Variant::OP_IN, Variant::OBJECT, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Callable, Array>>(Variant::OP_IN, Variant::CALLABLE, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Signal, Array>>(Variant::OP_IN, Variant::SIGNAL, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Dictionary, Array>>(Variant::OP_IN, Variant::DICTIONARY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Array, Array>>(Variant::OP_IN, Variant::ARRAY, Variant::ARRAY); + + register_op<OperatorEvaluatorInArrayFind<PackedByteArray, Array>>(Variant::OP_IN, Variant::PACKED_BYTE_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedInt32Array, Array>>(Variant::OP_IN, Variant::PACKED_INT32_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedInt64Array, Array>>(Variant::OP_IN, Variant::PACKED_INT64_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedFloat32Array, Array>>(Variant::OP_IN, Variant::PACKED_FLOAT32_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedFloat64Array, Array>>(Variant::OP_IN, Variant::PACKED_FLOAT64_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedStringArray, Array>>(Variant::OP_IN, Variant::PACKED_STRING_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedVector2Array, Array>>(Variant::OP_IN, Variant::PACKED_VECTOR2_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedVector3Array, Array>>(Variant::OP_IN, Variant::PACKED_VECTOR3_ARRAY, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<PackedColorArray, Array>>(Variant::OP_IN, Variant::PACKED_COLOR_ARRAY, Variant::ARRAY); + + register_op<OperatorEvaluatorInArrayFind<int, PackedByteArray>>(Variant::OP_IN, Variant::INT, Variant::PACKED_BYTE_ARRAY); + register_op<OperatorEvaluatorInArrayFind<float, PackedByteArray>>(Variant::OP_IN, Variant::FLOAT, Variant::PACKED_BYTE_ARRAY); + + register_op<OperatorEvaluatorInArrayFind<int, PackedInt32Array>>(Variant::OP_IN, Variant::INT, Variant::PACKED_INT32_ARRAY); + register_op<OperatorEvaluatorInArrayFind<float, PackedInt32Array>>(Variant::OP_IN, Variant::FLOAT, Variant::PACKED_INT32_ARRAY); + + register_op<OperatorEvaluatorInArrayFind<int, PackedInt64Array>>(Variant::OP_IN, Variant::INT, Variant::PACKED_INT64_ARRAY); + register_op<OperatorEvaluatorInArrayFind<float, PackedInt64Array>>(Variant::OP_IN, Variant::FLOAT, Variant::PACKED_INT64_ARRAY); + + register_op<OperatorEvaluatorInArrayFind<int, PackedFloat32Array>>(Variant::OP_IN, Variant::INT, Variant::PACKED_FLOAT32_ARRAY); + register_op<OperatorEvaluatorInArrayFind<float, PackedFloat32Array>>(Variant::OP_IN, Variant::FLOAT, Variant::PACKED_FLOAT32_ARRAY); + + register_op<OperatorEvaluatorInArrayFind<int, PackedFloat64Array>>(Variant::OP_IN, Variant::INT, Variant::PACKED_FLOAT64_ARRAY); + register_op<OperatorEvaluatorInArrayFind<float, PackedFloat64Array>>(Variant::OP_IN, Variant::FLOAT, Variant::PACKED_FLOAT64_ARRAY); + + register_op<OperatorEvaluatorInArrayFind<String, PackedStringArray>>(Variant::OP_IN, Variant::STRING, Variant::PACKED_STRING_ARRAY); + + register_op<OperatorEvaluatorInArrayFind<Vector2, PackedVector2Array>>(Variant::OP_IN, Variant::VECTOR2, Variant::PACKED_VECTOR2_ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector3, PackedVector3Array>>(Variant::OP_IN, Variant::VECTOR3, Variant::PACKED_VECTOR3_ARRAY); + + register_op<OperatorEvaluatorInArrayFind<Color, PackedColorArray>>(Variant::OP_IN, Variant::COLOR, Variant::PACKED_COLOR_ARRAY); + + register_op<OperatorEvaluatorObjectHasPropertyString>(Variant::OP_IN, Variant::STRING, Variant::OBJECT); + register_op<OperatorEvaluatorObjectHasPropertyStringName>(Variant::OP_IN, Variant::STRING_NAME, Variant::OBJECT); +} + +void Variant::_unregister_variant_operators() { +} + +void Variant::evaluate(const Operator &p_op, const Variant &p_a, + const Variant &p_b, Variant &r_ret, bool &r_valid) { + ERR_FAIL_INDEX(p_op, Variant::OP_MAX); + Variant::Type type_a = p_a.get_type(); + Variant::Type type_b = p_b.get_type(); + ERR_FAIL_INDEX(type_a, Variant::VARIANT_MAX); + ERR_FAIL_INDEX(type_b, Variant::VARIANT_MAX); + + VariantEvaluatorFunction ev = operator_evaluator_table[p_op][type_a][type_b]; + if (unlikely(!ev)) { + r_valid = false; + r_ret = Variant(); + return; + } + + ev(p_a, p_b, &r_ret, r_valid); +} + +Variant::Type Variant::get_operator_return_type(Operator p_operator, Type p_type_a, Type p_type_b) { + ERR_FAIL_INDEX_V(p_operator, Variant::OP_MAX, Variant::NIL); + ERR_FAIL_INDEX_V(p_type_a, Variant::VARIANT_MAX, Variant::NIL); + ERR_FAIL_INDEX_V(p_type_b, Variant::VARIANT_MAX, Variant::NIL); + + return operator_return_type_table[p_operator][p_type_a][p_type_b]; +} + +Variant::ValidatedOperatorEvaluator Variant::get_validated_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b) { + ERR_FAIL_INDEX_V(p_operator, Variant::OP_MAX, nullptr); + ERR_FAIL_INDEX_V(p_type_a, Variant::VARIANT_MAX, nullptr); + ERR_FAIL_INDEX_V(p_type_b, Variant::VARIANT_MAX, nullptr); + return validated_operator_evaluator_table[p_operator][p_type_a][p_type_b]; +} +#ifdef PTRCALL_ENABLED +Variant::PTROperatorEvaluator Variant::get_ptr_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b) { + ERR_FAIL_INDEX_V(p_operator, Variant::OP_MAX, nullptr); + ERR_FAIL_INDEX_V(p_type_a, Variant::VARIANT_MAX, nullptr); + ERR_FAIL_INDEX_V(p_type_b, Variant::VARIANT_MAX, nullptr); + return ptr_operator_evaluator_table[p_operator][p_type_a][p_type_b]; +} + +#endif + +static const char *_op_names[Variant::OP_MAX] = { + "==", + "!=", + "<", + "<=", + ">", + ">=", + "+", + "-", + "*", + "/", + "-", + "+", + "%", + "<<", + ">>", + "&", + "|", + "^", + "~", + "and", + "or", + "xor", + "not", + "in" + +}; + +String Variant::get_operator_name(Operator p_op) { + ERR_FAIL_INDEX_V(p_op, OP_MAX, ""); + return _op_names[p_op]; +} + +Variant::operator bool() const { + return booleanize(); +} + +// We consider all uninitialized or empty types to be false based on the type's +// zeroiness. +bool Variant::booleanize() const { + return !is_zero(); +} + +bool Variant::in(const Variant &p_index, bool *r_valid) const { + bool valid; + Variant ret; + evaluate(OP_IN, p_index, *this, ret, valid); + if (r_valid) { + *r_valid = valid; + return false; + } + ERR_FAIL_COND_V(ret.type != BOOL, false); + return *VariantGetInternalPtr<bool>::get_ptr(&ret); +} diff --git a/core/variant_parser.cpp b/core/variant/variant_parser.cpp index 04cd4c1b9b..5a0bbf041b 100644 --- a/core/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -33,7 +33,7 @@ #include "core/input/input_event.h" #include "core/io/resource_loader.h" #include "core/os/keyboard.h" -#include "core/string_buffer.h" +#include "core/string/string_buffer.h" char32_t VariantParser::StreamFile::get_char() { return f->get_8(); diff --git a/core/variant_parser.h b/core/variant/variant_parser.h index 12329e2db6..59d18a8b9f 100644 --- a/core/variant_parser.h +++ b/core/variant/variant_parser.h @@ -31,9 +31,9 @@ #ifndef VARIANT_PARSER_H #define VARIANT_PARSER_H +#include "core/io/resource.h" #include "core/os/file_access.h" -#include "core/resource.h" -#include "core/variant.h" +#include "core/variant/variant.h" class VariantParser { public: diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp new file mode 100644 index 0000000000..05fe2b80d9 --- /dev/null +++ b/core/variant/variant_setget.cpp @@ -0,0 +1,2587 @@ +/*************************************************************************/ +/* variant_setget.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/debugger/engine_debugger.h" +#include "core/object/class_db.h" +#include "core/templates/local_vector.h" +#include "core/variant/variant_internal.h" + +/**** NAMED SETTERS AND GETTERS ****/ + +#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_member = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_member = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_custom = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_custom = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ + } \ + static void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +SETGET_NUMBER_STRUCT(Vector2, double, x) +SETGET_NUMBER_STRUCT(Vector2, double, y) + +SETGET_NUMBER_STRUCT(Vector2i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector2i, int64_t, y) + +SETGET_NUMBER_STRUCT(Vector3, double, x) +SETGET_NUMBER_STRUCT(Vector3, double, y) +SETGET_NUMBER_STRUCT(Vector3, double, z) + +SETGET_NUMBER_STRUCT(Vector3i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector3i, int64_t, y) +SETGET_NUMBER_STRUCT(Vector3i, int64_t, z) + +SETGET_STRUCT(Rect2, Vector2, position) +SETGET_STRUCT(Rect2, Vector2, size) +SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end) + +SETGET_STRUCT(Rect2i, Vector2i, position) +SETGET_STRUCT(Rect2i, Vector2i, size) +SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end) + +SETGET_STRUCT(AABB, Vector3, position) +SETGET_STRUCT(AABB, Vector3, size) +SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end) + +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2]) + +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x) +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y) +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z) +SETGET_STRUCT(Plane, Vector3, normal) +SETGET_NUMBER_STRUCT(Plane, double, d) + +SETGET_NUMBER_STRUCT(Quat, double, x) +SETGET_NUMBER_STRUCT(Quat, double, y) +SETGET_NUMBER_STRUCT(Quat, double, z) +SETGET_NUMBER_STRUCT(Quat, double, w) + +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2) + +SETGET_STRUCT(Transform, Basis, basis) +SETGET_STRUCT(Transform, Vector3, origin) + +SETGET_NUMBER_STRUCT(Color, double, r) +SETGET_NUMBER_STRUCT(Color, double, g) +SETGET_NUMBER_STRUCT(Color, double, b) +SETGET_NUMBER_STRUCT(Color, double, a) + +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, r8, set_r8, get_r8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, g8, set_g8, get_g8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, b8, set_b8, get_b8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, a8, set_a8, get_a8) + +SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h) +SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s) +SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v) + +struct VariantSetterGetterInfo { + void (*setter)(Variant *base, const Variant *value, bool &valid); + void (*getter)(const Variant *base, Variant *value); + Variant::ValidatedSetter validated_setter; + Variant::ValidatedGetter validated_getter; + Variant::PTRSetter ptr_setter; + Variant::PTRGetter ptr_getter; + Variant::Type member_type; +}; + +static LocalVector<VariantSetterGetterInfo> variant_setters_getters[Variant::VARIANT_MAX]; +static LocalVector<StringName> variant_setters_getters_names[Variant::VARIANT_MAX]; //one next to another to make it cache friendly + +template <class T> +static void register_member(Variant::Type p_type, const StringName &p_member) { + VariantSetterGetterInfo sgi; + sgi.setter = T::set; + sgi.validated_setter = T::validated_set; + sgi.ptr_setter = T::ptr_set; + + sgi.getter = T::get; + sgi.validated_getter = T::validated_get; + sgi.ptr_getter = T::ptr_get; + + sgi.member_type = T::get_type(); + + variant_setters_getters[p_type].push_back(sgi); + variant_setters_getters_names[p_type].push_back(p_member); +} + +void register_named_setters_getters() { +#define REGISTER_MEMBER(m_base_type, m_member) register_member<VariantSetGet_##m_base_type##_##m_member>(GetTypeInfo<m_base_type>::VARIANT_TYPE, #m_member) + + REGISTER_MEMBER(Vector2, x); + REGISTER_MEMBER(Vector2, y); + + REGISTER_MEMBER(Vector2i, x); + REGISTER_MEMBER(Vector2i, y); + + REGISTER_MEMBER(Vector3, x); + REGISTER_MEMBER(Vector3, y); + REGISTER_MEMBER(Vector3, z); + + REGISTER_MEMBER(Vector3i, x); + REGISTER_MEMBER(Vector3i, y); + REGISTER_MEMBER(Vector3i, z); + + REGISTER_MEMBER(Rect2, position); + REGISTER_MEMBER(Rect2, size); + REGISTER_MEMBER(Rect2, end); + + REGISTER_MEMBER(Rect2i, position); + REGISTER_MEMBER(Rect2i, size); + REGISTER_MEMBER(Rect2i, end); + + REGISTER_MEMBER(AABB, position); + REGISTER_MEMBER(AABB, size); + REGISTER_MEMBER(AABB, end); + + REGISTER_MEMBER(Transform2D, x); + REGISTER_MEMBER(Transform2D, y); + REGISTER_MEMBER(Transform2D, origin); + + REGISTER_MEMBER(Plane, x); + REGISTER_MEMBER(Plane, y); + REGISTER_MEMBER(Plane, z); + REGISTER_MEMBER(Plane, d); + REGISTER_MEMBER(Plane, normal); + + REGISTER_MEMBER(Quat, x); + REGISTER_MEMBER(Quat, y); + REGISTER_MEMBER(Quat, z); + REGISTER_MEMBER(Quat, w); + + REGISTER_MEMBER(Basis, x); + REGISTER_MEMBER(Basis, y); + REGISTER_MEMBER(Basis, z); + + REGISTER_MEMBER(Transform, basis); + REGISTER_MEMBER(Transform, origin); + + REGISTER_MEMBER(Color, r); + REGISTER_MEMBER(Color, g); + REGISTER_MEMBER(Color, b); + REGISTER_MEMBER(Color, a); + + REGISTER_MEMBER(Color, r8); + REGISTER_MEMBER(Color, g8); + REGISTER_MEMBER(Color, b8); + REGISTER_MEMBER(Color, a8); + + REGISTER_MEMBER(Color, h); + REGISTER_MEMBER(Color, s); + REGISTER_MEMBER(Color, v); +} + +void unregister_named_setters_getters() { + for (int i = 0; i < Variant::VARIANT_MAX; i++) { + variant_setters_getters[i].clear(); + variant_setters_getters_names[i].clear(); + } +} + +bool Variant::has_member(Variant::Type p_type, const StringName &p_member) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + + for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { + if (variant_setters_getters_names[p_type][i] == p_member) { + return true; + } + } + return false; +} + +Variant::Type Variant::get_member_type(Variant::Type p_type, const StringName &p_member) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::VARIANT_MAX); + + for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { + if (variant_setters_getters_names[p_type][i] == p_member) { + return variant_setters_getters[p_type][i].member_type; + } + } + + return Variant::NIL; +} + +void Variant::get_member_list(Variant::Type p_type, List<StringName> *r_members) { + for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { + r_members->push_back(variant_setters_getters_names[p_type][i]); + } +} + +Variant::ValidatedSetter Variant::get_member_validated_setter(Variant::Type p_type, const StringName &p_member) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + + for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { + if (variant_setters_getters_names[p_type][i] == p_member) { + return variant_setters_getters[p_type][i].validated_setter; + } + } + + return nullptr; +} +Variant::ValidatedGetter Variant::get_member_validated_getter(Variant::Type p_type, const StringName &p_member) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + + for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { + if (variant_setters_getters_names[p_type][i] == p_member) { + return variant_setters_getters[p_type][i].validated_getter; + } + } + + return nullptr; +} + +Variant::PTRSetter Variant::get_member_ptr_setter(Variant::Type p_type, const StringName &p_member) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + + for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { + if (variant_setters_getters_names[p_type][i] == p_member) { + return variant_setters_getters[p_type][i].ptr_setter; + } + } + + return nullptr; +} + +Variant::PTRGetter Variant::get_member_ptr_getter(Variant::Type p_type, const StringName &p_member) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + + for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { + if (variant_setters_getters_names[p_type][i] == p_member) { + return variant_setters_getters[p_type][i].ptr_getter; + } + } + + return nullptr; +} + +void Variant::set_named(const StringName &p_member, const Variant &p_value, bool &r_valid) { + uint32_t s = variant_setters_getters[type].size(); + if (s) { + for (uint32_t i = 0; i < s; i++) { + if (variant_setters_getters_names[type][i] == p_member) { + variant_setters_getters[type][i].setter(this, &p_value, r_valid); + return; + } + } + r_valid = false; + + } else if (type == Variant::OBJECT) { + Object *obj = get_validated_object(); + if (!obj) { + r_valid = false; + } else { + obj->set(p_member, p_value, &r_valid); + return; + } + } else if (type == Variant::DICTIONARY) { + Variant *v = VariantGetInternalPtr<Dictionary>::get_ptr(this)->getptr(p_member); + if (v) { + *v = p_value; + r_valid = true; + } else { + r_valid = false; + } + + } else { + r_valid = false; + } +} + +Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { + Variant ret; + uint32_t s = variant_setters_getters[type].size(); + if (s) { + for (uint32_t i = 0; i < s; i++) { + if (variant_setters_getters_names[type][i] == p_member) { + variant_setters_getters[type][i].getter(this, &ret); + r_valid = true; + return ret; + } + } + + r_valid = false; + + } else if (type == Variant::OBJECT) { + Object *obj = get_validated_object(); + if (!obj) { + r_valid = false; + return "Instance base is null."; + } else { + return obj->get(p_member, &r_valid); + } + } else if (type == Variant::DICTIONARY) { + const Variant *v = VariantGetInternalPtr<Dictionary>::get_ptr(this)->getptr(p_member); + if (v) { + r_valid = true; + + return *v; + } else { + r_valid = false; + } + + } else { + r_valid = false; + } + + return ret; +} + +/**** INDEXED SETTERS AND GETTERS ****/ + +#ifdef DEBUG_ENABLED + +#define OOB_TEST(m_idx, m_v) \ + ERR_FAIL_INDEX(m_idx, m_v) + +#else + +#define OOB_TEST(m_idx, m_v) + +#endif + +#ifdef DEBUG_ENABLED + +#define NULL_TEST(m_key) \ + ERR_FAIL_COND(!m_key) + +#else + +#define NULL_TEST(m_key) + +#endif + +#define INDEXED_SETGET_STRUCT_TYPED(m_base_type, m_elem_type) \ + struct VariantIndexedSetGet_##m_base_type { \ + static void get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + *VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void ptr_get(const void *base, int64_t index, void *member) { \ + /* avoid ptrconvert for performance*/ \ + const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ + if (index < 0) \ + index += v.size(); \ + OOB_TEST(index, v.size()); \ + PtrToArg<m_elem_type>::encode(v[index], member); \ + } \ + static void set(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob) { \ + if (value->get_type() != GetTypeInfo<m_elem_type>::VARIANT_TYPE) { \ + oob = false; \ + valid = false; \ + return; \ + } \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + valid = false; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \ + oob = false; \ + valid = true; \ + } \ + static void validated_set(Variant *base, int64_t index, const Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \ + oob = false; \ + } \ + static void ptr_set(void *base, int64_t index, const void *member) { \ + /* avoid ptrconvert for performance*/ \ + m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ + if (index < 0) \ + index += v.size(); \ + OOB_TEST(index, v.size()); \ + v.write[index] = PtrToArg<m_elem_type>::convert(member); \ + } \ + static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ + }; + +#define INDEXED_SETGET_STRUCT_TYPED_NUMERIC(m_base_type, m_elem_type, m_assign_type) \ + struct VariantIndexedSetGet_##m_base_type { \ + static void get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + *VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void ptr_get(const void *base, int64_t index, void *member) { \ + /* avoid ptrconvert for performance*/ \ + const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ + if (index < 0) \ + index += v.size(); \ + OOB_TEST(index, v.size()); \ + PtrToArg<m_elem_type>::encode(v[index], member); \ + } \ + static void set(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + valid = false; \ + return; \ + } \ + m_assign_type num; \ + if (value->get_type() == Variant::INT) { \ + num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \ + } else if (value->get_type() == Variant::FLOAT) { \ + num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \ + } else { \ + oob = false; \ + valid = false; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = num; \ + oob = false; \ + valid = true; \ + } \ + static void validated_set(Variant *base, int64_t index, const Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \ + oob = false; \ + } \ + static void ptr_set(void *base, int64_t index, const void *member) { \ + /* avoid ptrconvert for performance*/ \ + m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ + if (index < 0) \ + index += v.size(); \ + OOB_TEST(index, v.size()); \ + v.write[index] = PtrToArg<m_elem_type>::convert(member); \ + } \ + static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ + }; + +#define INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(m_base_type, m_elem_type, m_assign_type, m_max) \ + struct VariantIndexedSetGet_##m_base_type { \ + static void get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + *VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void ptr_get(const void *base, int64_t index, void *member) { \ + /* avoid ptrconvert for performance*/ \ + const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ + OOB_TEST(index, m_max); \ + PtrToArg<m_elem_type>::encode(v[index], member); \ + } \ + static void set(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + valid = false; \ + return; \ + } \ + m_assign_type num; \ + if (value->get_type() == Variant::INT) { \ + num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \ + } else if (value->get_type() == Variant::FLOAT) { \ + num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \ + } else { \ + oob = false; \ + valid = false; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = num; \ + oob = false; \ + valid = true; \ + } \ + static void validated_set(Variant *base, int64_t index, const Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \ + oob = false; \ + } \ + static void ptr_set(void *base, int64_t index, const void *member) { \ + /* avoid ptrconvert for performance*/ \ + m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ + OOB_TEST(index, m_max); \ + v[index] = PtrToArg<m_elem_type>::convert(member); \ + } \ + static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ + }; + +#define INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(m_base_type, m_elem_type, m_accessor, m_max) \ + struct VariantIndexedSetGet_##m_base_type { \ + static void get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))m_accessor[index]; \ + oob = false; \ + } \ + static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + *VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))m_accessor[index]; \ + oob = false; \ + } \ + static void ptr_get(const void *base, int64_t index, void *member) { \ + /* avoid ptrconvert for performance*/ \ + const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ + OOB_TEST(index, m_max); \ + PtrToArg<m_elem_type>::encode(v m_accessor[index], member); \ + } \ + static void set(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob) { \ + if (value->get_type() != GetTypeInfo<m_elem_type>::VARIANT_TYPE) { \ + oob = false; \ + valid = false; \ + } \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + valid = false; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base)) m_accessor[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \ + oob = false; \ + valid = true; \ + } \ + static void validated_set(Variant *base, int64_t index, const Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base)) m_accessor[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \ + oob = false; \ + } \ + static void ptr_set(void *base, int64_t index, const void *member) { \ + /* avoid ptrconvert for performance*/ \ + m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ + OOB_TEST(index, m_max); \ + v m_accessor[index] = PtrToArg<m_elem_type>::convert(member); \ + } \ + static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ + }; + +#define INDEXED_SETGET_STRUCT_BULTIN_FUNC(m_base_type, m_elem_type, m_set, m_get, m_max) \ + struct VariantIndexedSetGet_##m_base_type { \ + static void get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + *value = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_get(index); \ + oob = false; \ + } \ + static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + *VariantGetInternalPtr<m_elem_type>::get_ptr(value) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_get(index); \ + oob = false; \ + } \ + static void ptr_get(const void *base, int64_t index, void *member) { \ + /* avoid ptrconvert for performance*/ \ + const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ + OOB_TEST(index, m_max); \ + PtrToArg<m_elem_type>::encode(v.m_get(index), member); \ + } \ + static void set(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob) { \ + if (value->get_type() != GetTypeInfo<m_elem_type>::VARIANT_TYPE) { \ + oob = false; \ + valid = false; \ + } \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + valid = false; \ + return; \ + } \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_set(index, *VariantGetInternalPtr<m_elem_type>::get_ptr(value)); \ + oob = false; \ + valid = true; \ + } \ + static void validated_set(Variant *base, int64_t index, const Variant *value, bool &oob) { \ + if (index < 0 || index >= m_max) { \ + oob = true; \ + return; \ + } \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_set(index, *VariantGetInternalPtr<m_elem_type>::get_ptr(value)); \ + oob = false; \ + } \ + static void ptr_set(void *base, int64_t index, const void *member) { \ + /* avoid ptrconvert for performance*/ \ + m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ + OOB_TEST(index, m_max); \ + v.m_set(index, PtrToArg<m_elem_type>::convert(member)); \ + } \ + static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ + }; + +#define INDEXED_SETGET_STRUCT_VARIANT(m_base_type) \ + struct VariantIndexedSetGet_##m_base_type { \ + static void get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ + oob = false; \ + } \ + static void ptr_get(const void *base, int64_t index, void *member) { \ + /* avoid ptrconvert for performance*/ \ + const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ + if (index < 0) \ + index += v.size(); \ + OOB_TEST(index, v.size()); \ + PtrToArg<Variant>::encode(v[index], member); \ + } \ + static void set(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + valid = false; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ + oob = false; \ + valid = true; \ + } \ + static void validated_set(Variant *base, int64_t index, const Variant *value, bool &oob) { \ + int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ + if (index < 0) { \ + index += size; \ + } \ + if (index < 0 || index >= size) { \ + oob = true; \ + return; \ + } \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ + oob = false; \ + } \ + static void ptr_set(void *base, int64_t index, const void *member) { \ + /* avoid ptrconvert for performance*/ \ + m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ + if (index < 0) \ + index += v.size(); \ + OOB_TEST(index, v.size()); \ + v[index] = PtrToArg<Variant>::convert(member); \ + } \ + static Variant::Type get_index_type() { return Variant::NIL; } \ + static uint64_t get_indexed_size(const Variant *base) { return 0; } \ + }; + +#define INDEXED_SETGET_STRUCT_DICT(m_base_type) \ + struct VariantIndexedSetGet_##m_base_type { \ + static void get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + const Variant *ptr = VariantGetInternalPtr<m_base_type>::get_ptr(base)->getptr(index); \ + if (!ptr) { \ + oob = true; \ + return; \ + } \ + *value = *ptr; \ + oob = false; \ + } \ + static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \ + const Variant *ptr = VariantGetInternalPtr<m_base_type>::get_ptr(base)->getptr(index); \ + if (!ptr) { \ + oob = true; \ + return; \ + } \ + *value = *ptr; \ + oob = false; \ + } \ + static void ptr_get(const void *base, int64_t index, void *member) { \ + /* avoid ptrconvert for performance*/ \ + const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ + const Variant *ptr = v.getptr(index); \ + NULL_TEST(ptr); \ + PtrToArg<Variant>::encode(*ptr, member); \ + } \ + static void set(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob) { \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ + oob = false; \ + valid = true; \ + } \ + static void validated_set(Variant *base, int64_t index, const Variant *value, bool &oob) { \ + (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ + oob = false; \ + } \ + static void ptr_set(void *base, int64_t index, const void *member) { \ + m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ + v[index] = PtrToArg<Variant>::convert(member); \ + } \ + static Variant::Type get_index_type() { return Variant::NIL; } \ + static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ + }; + +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2, double, real_t, 2) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2i, int64_t, int32_t, 2) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3, double, real_t, 3) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quat, double, real_t, 4) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) + +INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .elements, 3) +INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_axis, get_axis, 3) + +INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t) +INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t) +INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt64Array, int64_t, int64_t) +INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedFloat32Array, double, float) +INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedFloat64Array, double, double) +INDEXED_SETGET_STRUCT_TYPED(PackedVector2Array, Vector2) +INDEXED_SETGET_STRUCT_TYPED(PackedVector3Array, Vector3) +INDEXED_SETGET_STRUCT_TYPED(PackedStringArray, String) +INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color) + +INDEXED_SETGET_STRUCT_VARIANT(Array) +INDEXED_SETGET_STRUCT_DICT(Dictionary) + +struct VariantIndexedSetterGetterInfo { + void (*setter)(Variant *base, int64_t index, const Variant *value, bool &valid, bool &oob); + void (*getter)(const Variant *base, int64_t index, Variant *value, bool &oob); + + Variant::ValidatedIndexedSetter validated_setter; + Variant::ValidatedIndexedGetter validated_getter; + + Variant::PTRIndexedSetter ptr_setter; + Variant::PTRIndexedGetter ptr_getter; + + uint64_t (*get_indexed_size)(const Variant *base); + + Variant::Type index_type; + + bool valid = false; +}; + +static VariantIndexedSetterGetterInfo variant_indexed_setters_getters[Variant::VARIANT_MAX]; + +template <class T> +static void register_indexed_member(Variant::Type p_type) { + VariantIndexedSetterGetterInfo &sgi = variant_indexed_setters_getters[p_type]; + + sgi.setter = T::set; + sgi.validated_setter = T::validated_set; + sgi.ptr_setter = T::ptr_set; + + sgi.getter = T::get; + sgi.validated_getter = T::validated_get; + sgi.ptr_getter = T::ptr_get; + + sgi.index_type = T::get_index_type(); + sgi.get_indexed_size = T::get_indexed_size; + + sgi.valid = true; +} + +void register_indexed_setters_getters() { +#define REGISTER_INDEXED_MEMBER(m_base_type) register_indexed_member<VariantIndexedSetGet_##m_base_type>(GetTypeInfo<m_base_type>::VARIANT_TYPE) + + REGISTER_INDEXED_MEMBER(Vector2); + REGISTER_INDEXED_MEMBER(Vector2i); + REGISTER_INDEXED_MEMBER(Vector3); + REGISTER_INDEXED_MEMBER(Vector3i); + REGISTER_INDEXED_MEMBER(Quat); + REGISTER_INDEXED_MEMBER(Color); + REGISTER_INDEXED_MEMBER(Transform2D); + REGISTER_INDEXED_MEMBER(Basis); + + REGISTER_INDEXED_MEMBER(PackedByteArray); + REGISTER_INDEXED_MEMBER(PackedInt32Array); + REGISTER_INDEXED_MEMBER(PackedInt64Array); + REGISTER_INDEXED_MEMBER(PackedFloat64Array); + REGISTER_INDEXED_MEMBER(PackedVector2Array); + REGISTER_INDEXED_MEMBER(PackedVector3Array); + REGISTER_INDEXED_MEMBER(PackedStringArray); + REGISTER_INDEXED_MEMBER(PackedColorArray); + + REGISTER_INDEXED_MEMBER(Array); + REGISTER_INDEXED_MEMBER(Dictionary); +} + +static void unregister_indexed_setters_getters() { +} + +bool Variant::has_indexing(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + return variant_indexed_setters_getters[p_type].valid; +} + +Variant::Type Variant::get_indexed_element_type(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::VARIANT_MAX); + return variant_indexed_setters_getters[p_type].index_type; +} + +Variant::ValidatedIndexedSetter Variant::get_member_validated_indexed_setter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + return variant_indexed_setters_getters[p_type].validated_setter; +} +Variant::ValidatedIndexedGetter Variant::get_member_validated_indexed_getter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + return variant_indexed_setters_getters[p_type].validated_getter; +} + +Variant::PTRIndexedSetter Variant::get_member_ptr_indexed_setter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + return variant_indexed_setters_getters[p_type].ptr_setter; +} +Variant::PTRIndexedGetter Variant::get_member_ptr_indexed_getter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + return variant_indexed_setters_getters[p_type].ptr_getter; +} + +void Variant::set_indexed(int64_t p_index, const Variant &p_value, bool &r_valid, bool &r_oob) { + if (likely(variant_indexed_setters_getters[type].valid)) { + variant_indexed_setters_getters[type].setter(this, p_index, &p_value, r_valid, r_oob); + } else { + r_valid = false; + r_oob = false; + } +} +Variant Variant::get_indexed(int64_t p_index, bool &r_valid, bool &r_oob) const { + if (likely(variant_indexed_setters_getters[type].valid)) { + Variant ret; + variant_indexed_setters_getters[type].getter(this, p_index, &ret, r_oob); + r_valid = !r_oob; + return ret; + } else { + r_valid = false; + r_oob = false; + return Variant(); + } +} + +uint64_t Variant::get_indexed_size() const { + if (likely(variant_indexed_setters_getters[type].valid && variant_indexed_setters_getters[type].get_indexed_size)) { + return variant_indexed_setters_getters[type].get_indexed_size(this); + } else { + return 0; + } +} + +struct VariantKeyedSetGetDictionary { + static void get(const Variant *base, const Variant *key, Variant *value, bool &r_valid) { + const Variant *ptr = VariantGetInternalPtr<Dictionary>::get_ptr(base)->getptr(*key); + if (!ptr) { + r_valid = false; + return; + } + *value = *ptr; + r_valid = true; + } + static void ptr_get(const void *base, const void *key, void *value) { + /* avoid ptrconvert for performance*/ + const Dictionary &v = *reinterpret_cast<const Dictionary *>(base); + const Variant *ptr = v.getptr(PtrToArg<Variant>::convert(key)); + NULL_TEST(ptr); + PtrToArg<Variant>::encode(*ptr, value); + } + static void set(Variant *base, const Variant *key, const Variant *value, bool &r_valid) { + (*VariantGetInternalPtr<Dictionary>::get_ptr(base))[*key] = *value; + r_valid = true; + } + static void ptr_set(void *base, const void *key, const void *value) { + Dictionary &v = *reinterpret_cast<Dictionary *>(base); + v[PtrToArg<Variant>::convert(key)] = PtrToArg<Variant>::convert(value); + } + + static bool has(const Variant *base, const Variant *key, bool &r_valid) { + r_valid = true; + return VariantGetInternalPtr<Dictionary>::get_ptr(base)->has(*key); + } + static bool ptr_has(const void *base, const void *key) { + /* avoid ptrconvert for performance*/ + const Dictionary &v = *reinterpret_cast<const Dictionary *>(base); + return v.has(PtrToArg<Variant>::convert(key)); + } +}; + +struct VariantKeyedSetGetObject { + static void get(const Variant *base, const Variant *key, Variant *value, bool &r_valid) { + Object *obj = base->get_validated_object(); + + if (!obj) { + r_valid = false; + *value = Variant(); + return; + } + *value = obj->getvar(*key, &r_valid); + } + static void ptr_get(const void *base, const void *key, void *value) { + const Object *obj = PtrToArg<Object *>::convert(base); + NULL_TEST(obj); + Variant v = obj->getvar(PtrToArg<Variant>::convert(key)); + PtrToArg<Variant>::encode(v, value); + } + static void set(Variant *base, const Variant *key, const Variant *value, bool &r_valid) { + Object *obj = base->get_validated_object(); + + if (!obj) { + r_valid = false; + return; + } + obj->setvar(*key, *value, &r_valid); + } + static void ptr_set(void *base, const void *key, const void *value) { + Object *obj = PtrToArg<Object *>::convert(base); + NULL_TEST(obj); + obj->setvar(PtrToArg<Variant>::convert(key), PtrToArg<Variant>::convert(value)); + } + + static bool has(const Variant *base, const Variant *key, bool &r_valid) { + Object *obj = base->get_validated_object(); + if (obj != nullptr) { + r_valid = false; + return false; + } + r_valid = true; + bool exists; + obj->getvar(*key, &exists); + return exists; + } + static bool ptr_has(const void *base, const void *key) { + const Object *obj = PtrToArg<Object *>::convert(base); + ERR_FAIL_COND_V(!obj, false); + bool valid; + obj->getvar(PtrToArg<Variant>::convert(key), &valid); + return valid; + } +}; + +/*typedef void (*ValidatedKeyedSetter)(Variant *base, const Variant *key, const Variant *value); +typedef void (*ValidatedKeyedGetter)(const Variant *base, const Variant *key, Variant *value, bool &valid); +typedef bool (*ValidatedKeyedChecker)(const Variant *base, const Variant *key); + +typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value); +typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value); +typedef bool (*PTRKeyedChecker)(const void *base, const void *key);*/ + +struct VariantKeyedSetterGetterInfo { + Variant::ValidatedKeyedSetter validated_setter; + Variant::ValidatedKeyedGetter validated_getter; + Variant::ValidatedKeyedChecker validated_checker; + + Variant::PTRKeyedSetter ptr_setter; + Variant::PTRKeyedGetter ptr_getter; + Variant::PTRKeyedChecker ptr_checker; + + bool valid = false; +}; + +static VariantKeyedSetterGetterInfo variant_keyed_setters_getters[Variant::VARIANT_MAX]; + +template <class T> +static void register_keyed_member(Variant::Type p_type) { + VariantKeyedSetterGetterInfo &sgi = variant_keyed_setters_getters[p_type]; + + sgi.validated_setter = T::set; + sgi.ptr_setter = T::ptr_set; + + sgi.validated_getter = T::get; + sgi.ptr_getter = T::ptr_get; + + sgi.validated_checker = T::has; + sgi.ptr_checker = T::ptr_has; + + sgi.valid = true; +} + +static void register_keyed_setters_getters() { + register_keyed_member<VariantKeyedSetGetDictionary>(Variant::DICTIONARY); + register_keyed_member<VariantKeyedSetGetObject>(Variant::OBJECT); +} +bool Variant::is_keyed(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, false); + return variant_keyed_setters_getters[p_type].valid; +} + +Variant::ValidatedKeyedSetter Variant::get_member_validated_keyed_setter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr); + return variant_keyed_setters_getters[p_type].validated_setter; +} +Variant::ValidatedKeyedGetter Variant::get_member_validated_keyed_getter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr); + return variant_keyed_setters_getters[p_type].validated_getter; +} +Variant::ValidatedKeyedChecker Variant::get_member_validated_keyed_checker(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr); + return variant_keyed_setters_getters[p_type].validated_checker; +} + +Variant::PTRKeyedSetter Variant::get_member_ptr_keyed_setter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr); + return variant_keyed_setters_getters[p_type].ptr_setter; +} +Variant::PTRKeyedGetter Variant::get_member_ptr_keyed_getter(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr); + return variant_keyed_setters_getters[p_type].ptr_getter; +} +Variant::PTRKeyedChecker Variant::get_member_ptr_keyed_checker(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr); + return variant_keyed_setters_getters[p_type].ptr_checker; +} + +void Variant::set_keyed(const Variant &p_key, const Variant &p_value, bool &r_valid) { + if (likely(variant_keyed_setters_getters[type].valid)) { + variant_keyed_setters_getters[type].validated_setter(this, &p_key, &p_value, r_valid); + } else { + r_valid = false; + } +} +Variant Variant::get_keyed(const Variant &p_key, bool &r_valid) const { + if (likely(variant_keyed_setters_getters[type].valid)) { + Variant ret; + variant_keyed_setters_getters[type].validated_getter(this, &p_key, &ret, r_valid); + return ret; + } else { + r_valid = false; + return Variant(); + } +} +bool Variant::has_key(const Variant &p_key, bool &r_valid) const { + if (likely(variant_keyed_setters_getters[type].valid)) { + return variant_keyed_setters_getters[type].validated_checker(this, &p_key, r_valid); + } else { + r_valid = false; + return false; + } +} + +void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) { + if (type == DICTIONARY || type == OBJECT) { + bool valid; + set_keyed(p_index, p_value, valid); + if (r_valid) { + *r_valid = valid; + } + } else { + bool valid = false; + if (p_index.get_type() == STRING_NAME) { + set_named(*VariantGetInternalPtr<StringName>::get_ptr(&p_index), p_value, valid); + } else if (p_index.get_type() == INT) { + bool obb; + set_indexed(*VariantGetInternalPtr<int64_t>::get_ptr(&p_index), p_value, valid, obb); + if (obb) { + valid = false; + } + } else if (p_index.get_type() == STRING) { // less efficient version of named + set_named(*VariantGetInternalPtr<String>::get_ptr(&p_index), p_value, valid); + } else if (p_index.get_type() == FLOAT) { // less efficient version of indexed + bool obb; + set_indexed(*VariantGetInternalPtr<double>::get_ptr(&p_index), p_value, valid, obb); + if (obb) { + valid = false; + } + } + if (r_valid) { + *r_valid = valid; + } + } +} + +Variant Variant::get(const Variant &p_index, bool *r_valid) const { + Variant ret; + if (type == DICTIONARY || type == OBJECT) { + bool valid; + ret = get_keyed(p_index, valid); + if (r_valid) { + *r_valid = valid; + } + } else { + bool valid = false; + if (p_index.get_type() == STRING_NAME) { + ret = get_named(*VariantGetInternalPtr<StringName>::get_ptr(&p_index), valid); + } else if (p_index.get_type() == INT) { + bool obb; + ret = get_indexed(*VariantGetInternalPtr<int64_t>::get_ptr(&p_index), valid, obb); + if (obb) { + valid = false; + } + } else if (p_index.get_type() == STRING) { // less efficient version of named + ret = get_named(*VariantGetInternalPtr<String>::get_ptr(&p_index), valid); + } else if (p_index.get_type() == FLOAT) { // less efficient version of indexed + bool obb; + ret = get_indexed(*VariantGetInternalPtr<double>::get_ptr(&p_index), valid, obb); + if (obb) { + valid = false; + } + } + if (r_valid) { + *r_valid = valid; + } + } + + return ret; +} + +void Variant::get_property_list(List<PropertyInfo> *p_list) const { + if (type == DICTIONARY) { + const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); + List<Variant> keys; + dic->get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + if (E->get().get_type() == Variant::STRING) { + p_list->push_back(PropertyInfo(Variant::STRING, E->get())); + } + } + } else if (type == OBJECT) { + Object *obj = get_validated_object(); + ERR_FAIL_COND(!obj); + obj->get_property_list(p_list); + + } else { + List<StringName> members; + get_member_list(type, &members); + for (List<StringName>::Element *E = members.front(); E; E = E->next()) { + PropertyInfo pi; + pi.name = E->get(); + pi.type = get_member_type(type, E->get()); + p_list->push_back(pi); + } + } +} + +bool Variant::iter_init(Variant &r_iter, bool &valid) const { + valid = true; + switch (type) { + case INT: { + r_iter = 0; + return _data._int > 0; + } break; + case FLOAT: { + r_iter = 0; + return _data._float > 0.0; + } break; + case VECTOR2: { + double from = reinterpret_cast<const Vector2 *>(_data._mem)->x; + double to = reinterpret_cast<const Vector2 *>(_data._mem)->y; + + r_iter = from; + + return from < to; + } break; + case VECTOR2I: { + int64_t from = reinterpret_cast<const Vector2i *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y; + + r_iter = from; + + return from < to; + } break; + case VECTOR3: { + double from = reinterpret_cast<const Vector3 *>(_data._mem)->x; + double to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + double step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + + r_iter = from; + + if (from == to) { + return false; + } else if (from < to) { + return step > 0; + } + return step < 0; + } break; + case VECTOR3I: { + int64_t from = reinterpret_cast<const Vector3i *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z; + + r_iter = from; + + if (from == to) { + return false; + } else if (from < to) { + return step > 0; + } + return step < 0; + } break; + case OBJECT: { + if (!_get_obj().obj) { + valid = false; + return false; + } + +#ifdef DEBUG_ENABLED + + if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + valid = false; + return false; + } + +#endif + Callable::CallError ce; + ce.error = Callable::CallError::CALL_OK; + Array ref; + ref.push_back(r_iter); + Variant vref = ref; + const Variant *refp[] = { &vref }; + Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce); + + if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { + valid = false; + return false; + } + + r_iter = ref[0]; + return ret; + } break; + + case STRING: { + const String *str = reinterpret_cast<const String *>(_data._mem); + if (str->empty()) { + return false; + } + r_iter = 0; + return true; + } break; + case DICTIONARY: { + const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); + if (dic->empty()) { + return false; + } + + const Variant *next = dic->next(nullptr); + r_iter = *next; + return true; + + } break; + case ARRAY: { + const Array *arr = reinterpret_cast<const Array *>(_data._mem); + if (arr->empty()) { + return false; + } + r_iter = 0; + return true; + } break; + case PACKED_BYTE_ARRAY: { + const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + + } break; + case PACKED_INT32_ARRAY: { + const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + + } break; + case PACKED_INT64_ARRAY: { + const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + + } break; + case PACKED_FLOAT32_ARRAY: { + const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + + } break; + case PACKED_FLOAT64_ARRAY: { + const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + + } break; + case PACKED_STRING_ARRAY: { + const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + } break; + case PACKED_VECTOR2_ARRAY: { + const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + } break; + case PACKED_VECTOR3_ARRAY: { + const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + } break; + case PACKED_COLOR_ARRAY: { + const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array); + if (arr->size() == 0) { + return false; + } + r_iter = 0; + return true; + + } break; + default: { + } + } + + valid = false; + return false; +} + +bool Variant::iter_next(Variant &r_iter, bool &valid) const { + valid = true; + switch (type) { + case INT: { + int64_t idx = r_iter; + idx++; + if (idx >= _data._int) { + return false; + } + r_iter = idx; + return true; + } break; + case FLOAT: { + int64_t idx = r_iter; + idx++; + if (idx >= _data._float) { + return false; + } + r_iter = idx; + return true; + } break; + case VECTOR2: { + double to = reinterpret_cast<const Vector2 *>(_data._mem)->y; + + double idx = r_iter; + idx++; + + if (idx >= to) { + return false; + } + + r_iter = idx; + return true; + } break; + case VECTOR2I: { + int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y; + + int64_t idx = r_iter; + idx++; + + if (idx >= to) { + return false; + } + + r_iter = idx; + return true; + } break; + case VECTOR3: { + double to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + double step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + + double idx = r_iter; + idx += step; + + if (step < 0 && idx <= to) { + return false; + } + + if (step > 0 && idx >= to) { + return false; + } + + r_iter = idx; + return true; + } break; + case VECTOR3I: { + int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z; + + int64_t idx = r_iter; + idx += step; + + if (step < 0 && idx <= to) { + return false; + } + + if (step > 0 && idx >= to) { + return false; + } + + r_iter = idx; + return true; + } break; + case OBJECT: { + if (!_get_obj().obj) { + valid = false; + return false; + } + +#ifdef DEBUG_ENABLED + + if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + valid = false; + return false; + } + +#endif + Callable::CallError ce; + ce.error = Callable::CallError::CALL_OK; + Array ref; + ref.push_back(r_iter); + Variant vref = ref; + const Variant *refp[] = { &vref }; + Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce); + + if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { + valid = false; + return false; + } + + r_iter = ref[0]; + + return ret; + } break; + + case STRING: { + const String *str = reinterpret_cast<const String *>(_data._mem); + int idx = r_iter; + idx++; + if (idx >= str->length()) { + return false; + } + r_iter = idx; + return true; + } break; + case DICTIONARY: { + const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); + const Variant *next = dic->next(&r_iter); + if (!next) { + return false; + } + + r_iter = *next; + return true; + + } break; + case ARRAY: { + const Array *arr = reinterpret_cast<const Array *>(_data._mem); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + } break; + case PACKED_BYTE_ARRAY: { + const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + + } break; + case PACKED_INT32_ARRAY: { + const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array); + int32_t idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + + } break; + case PACKED_INT64_ARRAY: { + const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array); + int64_t idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + + } break; + case PACKED_FLOAT32_ARRAY: { + const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + + } break; + case PACKED_FLOAT64_ARRAY: { + const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + + } break; + case PACKED_STRING_ARRAY: { + const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + } break; + case PACKED_VECTOR2_ARRAY: { + const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + } break; + case PACKED_VECTOR3_ARRAY: { + const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + } break; + case PACKED_COLOR_ARRAY: { + const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array); + int idx = r_iter; + idx++; + if (idx >= arr->size()) { + return false; + } + r_iter = idx; + return true; + } break; + default: { + } + } + + valid = false; + return false; +} + +Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { + r_valid = true; + switch (type) { + case INT: { + return r_iter; + } break; + case FLOAT: { + return r_iter; + } break; + case VECTOR2: { + return r_iter; + } break; + case VECTOR2I: { + return r_iter; + } break; + case VECTOR3: { + return r_iter; + } break; + case VECTOR3I: { + return r_iter; + } break; + case OBJECT: { + if (!_get_obj().obj) { + r_valid = false; + return Variant(); + } +#ifdef DEBUG_ENABLED + if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + r_valid = false; + return Variant(); + } + +#endif + Callable::CallError ce; + ce.error = Callable::CallError::CALL_OK; + const Variant *refp[] = { &r_iter }; + Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce); + + if (ce.error != Callable::CallError::CALL_OK) { + r_valid = false; + return Variant(); + } + + //r_iter=ref[0]; + + return ret; + } break; + + case STRING: { + const String *str = reinterpret_cast<const String *>(_data._mem); + return str->substr(r_iter, 1); + } break; + case DICTIONARY: { + return r_iter; //iterator is the same as the key + + } break; + case ARRAY: { + const Array *arr = reinterpret_cast<const Array *>(_data._mem); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_BYTE_ARRAY: { + const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_INT32_ARRAY: { + const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array); + int32_t idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_INT64_ARRAY: { + const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array); + int64_t idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_FLOAT32_ARRAY: { + const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_FLOAT64_ARRAY: { + const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_STRING_ARRAY: { + const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_VECTOR2_ARRAY: { + const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_VECTOR3_ARRAY: { + const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + case PACKED_COLOR_ARRAY: { + const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array); + int idx = r_iter; +#ifdef DEBUG_ENABLED + if (idx < 0 || idx >= arr->size()) { + r_valid = false; + return Variant(); + } +#endif + return arr->get(idx); + } break; + default: { + } + } + + r_valid = false; + return Variant(); +} + +Variant Variant::duplicate(bool deep) const { + switch (type) { + case OBJECT: { + /* breaks stuff :( + if (deep && !_get_obj().ref.is_null()) { + Ref<Resource> resource = _get_obj().ref; + if (resource.is_valid()) { + return resource->duplicate(true); + } + } + */ + return *this; + } break; + case DICTIONARY: + return operator Dictionary().duplicate(deep); + case ARRAY: + return operator Array().duplicate(deep); + default: + return *this; + } +} + +void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) { + if (a.type != b.type) { + if (a.is_num() && b.is_num()) { + real_t va = a; + real_t vb = b; + r_dst = va + vb * c; + } else { + r_dst = a; + } + return; + } + + switch (a.type) { + case NIL: { + r_dst = Variant(); + } + return; + case INT: { + int64_t va = a._data._int; + int64_t vb = b._data._int; + r_dst = int(va + vb * c + 0.5); + } + return; + case FLOAT: { + double ra = a._data._float; + double rb = b._data._float; + r_dst = ra + rb * c; + } + return; + case VECTOR2: { + r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) + *reinterpret_cast<const Vector2 *>(b._data._mem) * c; + } + return; + case VECTOR2I: { + int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x; + int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x; + int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y; + int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y; + r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5)); + } + return; + case RECT2: { + const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem); + const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem); + r_dst = Rect2(ra->position + rb->position * c, ra->size + rb->size * c); + } + return; + case RECT2I: { + const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem); + const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem); + + int32_t vax = ra->position.x; + int32_t vay = ra->position.y; + int32_t vbx = ra->size.x; + int32_t vby = ra->size.y; + int32_t vcx = rb->position.x; + int32_t vcy = rb->position.y; + int32_t vdx = rb->size.x; + int32_t vdy = rb->size.y; + + r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5)); + } + return; + case VECTOR3: { + r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) + *reinterpret_cast<const Vector3 *>(b._data._mem) * c; + } + return; + case VECTOR3I: { + int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x; + int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x; + int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y; + int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y; + int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z; + int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z; + r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5)); + } + return; + case AABB: { + const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem); + const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem); + r_dst = ::AABB(ra->position + rb->position * c, ra->size + rb->size * c); + } + return; + case QUAT: { + Quat empty_rot; + const Quat *qa = reinterpret_cast<const Quat *>(a._data._mem); + const Quat *qb = reinterpret_cast<const Quat *>(b._data._mem); + r_dst = *qa * empty_rot.slerp(*qb, c); + } + return; + case COLOR: { + const Color *ca = reinterpret_cast<const Color *>(a._data._mem); + const Color *cb = reinterpret_cast<const Color *>(b._data._mem); + float new_r = ca->r + cb->r * c; + float new_g = ca->g + cb->g * c; + float new_b = ca->b + cb->b * c; + float new_a = ca->a + cb->a * c; + new_r = new_r > 1.0 ? 1.0 : new_r; + new_g = new_g > 1.0 ? 1.0 : new_g; + new_b = new_b > 1.0 ? 1.0 : new_b; + new_a = new_a > 1.0 ? 1.0 : new_a; + r_dst = Color(new_r, new_g, new_b, new_a); + } + return; + default: { + r_dst = c < 0.5 ? a : b; + } + return; + } +} + +void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst) { + if (a.type != b.type) { + if (a.is_num() && b.is_num()) { + //not as efficient but.. + real_t va = a; + real_t vb = b; + r_dst = va + (vb - va) * c; + + } else { + r_dst = a; + } + return; + } + + switch (a.type) { + case NIL: { + r_dst = Variant(); + } + return; + case BOOL: { + r_dst = a; + } + return; + case INT: { + int64_t va = a._data._int; + int64_t vb = b._data._int; + r_dst = int(va + (vb - va) * c); + } + return; + case FLOAT: { + real_t va = a._data._float; + real_t vb = b._data._float; + r_dst = va + (vb - va) * c; + } + return; + case STRING: { + //this is pretty funny and bizarre, but artists like to use it for typewritter effects + String sa = *reinterpret_cast<const String *>(a._data._mem); + String sb = *reinterpret_cast<const String *>(b._data._mem); + String dst; + int sa_len = sa.length(); + int sb_len = sb.length(); + int csize = sa_len + (sb_len - sa_len) * c; + if (csize == 0) { + r_dst = ""; + return; + } + dst.resize(csize + 1); + dst[csize] = 0; + int split = csize / 2; + + for (int i = 0; i < csize; i++) { + char32_t chr = ' '; + + if (i < split) { + if (i < sa.length()) { + chr = sa[i]; + } else if (i < sb.length()) { + chr = sb[i]; + } + + } else { + if (i < sb.length()) { + chr = sb[i]; + } else if (i < sa.length()) { + chr = sa[i]; + } + } + + dst[i] = chr; + } + + r_dst = dst; + } + return; + case VECTOR2: { + r_dst = reinterpret_cast<const Vector2 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector2 *>(b._data._mem), c); + } + return; + case VECTOR2I: { + int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x; + int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x; + int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y; + int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y; + r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5)); + } + return; + + case RECT2: { + r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c)); + } + return; + case RECT2I: { + const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem); + const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem); + + int32_t vax = ra->position.x; + int32_t vay = ra->position.y; + int32_t vbx = ra->size.x; + int32_t vby = ra->size.y; + int32_t vcx = rb->position.x; + int32_t vcy = rb->position.y; + int32_t vdx = rb->size.x; + int32_t vdy = rb->size.y; + + r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5)); + } + return; + + case VECTOR3: { + r_dst = reinterpret_cast<const Vector3 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector3 *>(b._data._mem), c); + } + return; + case VECTOR3I: { + int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x; + int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x; + int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y; + int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y; + int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z; + int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z; + r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5)); + } + return; + + case TRANSFORM2D: { + r_dst = a._data._transform2d->interpolate_with(*b._data._transform2d, c); + } + return; + case PLANE: { + r_dst = a; + } + return; + case QUAT: { + r_dst = reinterpret_cast<const Quat *>(a._data._mem)->slerp(*reinterpret_cast<const Quat *>(b._data._mem), c); + } + return; + case AABB: { + r_dst = ::AABB(a._data._aabb->position.lerp(b._data._aabb->position, c), a._data._aabb->size.lerp(b._data._aabb->size, c)); + } + return; + case BASIS: { + r_dst = Transform(*a._data._basis).interpolate_with(Transform(*b._data._basis), c).basis; + } + return; + case TRANSFORM: { + r_dst = a._data._transform->interpolate_with(*b._data._transform, c); + } + return; + case COLOR: { + r_dst = reinterpret_cast<const Color *>(a._data._mem)->lerp(*reinterpret_cast<const Color *>(b._data._mem), c); + } + return; + case STRING_NAME: { + r_dst = a; + } + return; + case NODE_PATH: { + r_dst = a; + } + return; + case RID: { + r_dst = a; + } + return; + case OBJECT: { + r_dst = a; + } + return; + case DICTIONARY: { + } + return; + case ARRAY: { + r_dst = a; + } + return; + case PACKED_BYTE_ARRAY: { + r_dst = a; + } + return; + case PACKED_INT32_ARRAY: { + const Vector<int32_t> *arr_a = &PackedArrayRef<int32_t>::get_array(a._data.packed_array); + const Vector<int32_t> *arr_b = &PackedArrayRef<int32_t>::get_array(b._data.packed_array); + int32_t sz = arr_a->size(); + if (sz == 0 || arr_b->size() != sz) { + r_dst = a; + } else { + Vector<int32_t> v; + v.resize(sz); + { + int32_t *vw = v.ptrw(); + const int32_t *ar = arr_a->ptr(); + const int32_t *br = arr_b->ptr(); + + Variant va; + for (int32_t i = 0; i < sz; i++) { + Variant::interpolate(ar[i], br[i], c, va); + vw[i] = va; + } + } + r_dst = v; + } + } + return; + case PACKED_INT64_ARRAY: { + const Vector<int64_t> *arr_a = &PackedArrayRef<int64_t>::get_array(a._data.packed_array); + const Vector<int64_t> *arr_b = &PackedArrayRef<int64_t>::get_array(b._data.packed_array); + int64_t sz = arr_a->size(); + if (sz == 0 || arr_b->size() != sz) { + r_dst = a; + } else { + Vector<int64_t> v; + v.resize(sz); + { + int64_t *vw = v.ptrw(); + const int64_t *ar = arr_a->ptr(); + const int64_t *br = arr_b->ptr(); + + Variant va; + for (int64_t i = 0; i < sz; i++) { + Variant::interpolate(ar[i], br[i], c, va); + vw[i] = va; + } + } + r_dst = v; + } + } + return; + case PACKED_FLOAT32_ARRAY: { + const Vector<float> *arr_a = &PackedArrayRef<float>::get_array(a._data.packed_array); + const Vector<float> *arr_b = &PackedArrayRef<float>::get_array(b._data.packed_array); + int sz = arr_a->size(); + if (sz == 0 || arr_b->size() != sz) { + r_dst = a; + } else { + Vector<float> v; + v.resize(sz); + { + float *vw = v.ptrw(); + const float *ar = arr_a->ptr(); + const float *br = arr_b->ptr(); + + Variant va; + for (int i = 0; i < sz; i++) { + Variant::interpolate(ar[i], br[i], c, va); + vw[i] = va; + } + } + r_dst = v; + } + } + return; + case PACKED_FLOAT64_ARRAY: { + const Vector<double> *arr_a = &PackedArrayRef<double>::get_array(a._data.packed_array); + const Vector<double> *arr_b = &PackedArrayRef<double>::get_array(b._data.packed_array); + int sz = arr_a->size(); + if (sz == 0 || arr_b->size() != sz) { + r_dst = a; + } else { + Vector<double> v; + v.resize(sz); + { + double *vw = v.ptrw(); + const double *ar = arr_a->ptr(); + const double *br = arr_b->ptr(); + + Variant va; + for (int i = 0; i < sz; i++) { + Variant::interpolate(ar[i], br[i], c, va); + vw[i] = va; + } + } + r_dst = v; + } + } + return; + case PACKED_STRING_ARRAY: { + r_dst = a; + } + return; + case PACKED_VECTOR2_ARRAY: { + const Vector<Vector2> *arr_a = &PackedArrayRef<Vector2>::get_array(a._data.packed_array); + const Vector<Vector2> *arr_b = &PackedArrayRef<Vector2>::get_array(b._data.packed_array); + int sz = arr_a->size(); + if (sz == 0 || arr_b->size() != sz) { + r_dst = a; + } else { + Vector<Vector2> v; + v.resize(sz); + { + Vector2 *vw = v.ptrw(); + const Vector2 *ar = arr_a->ptr(); + const Vector2 *br = arr_b->ptr(); + + for (int i = 0; i < sz; i++) { + vw[i] = ar[i].lerp(br[i], c); + } + } + r_dst = v; + } + } + return; + case PACKED_VECTOR3_ARRAY: { + const Vector<Vector3> *arr_a = &PackedArrayRef<Vector3>::get_array(a._data.packed_array); + const Vector<Vector3> *arr_b = &PackedArrayRef<Vector3>::get_array(b._data.packed_array); + int sz = arr_a->size(); + if (sz == 0 || arr_b->size() != sz) { + r_dst = a; + } else { + Vector<Vector3> v; + v.resize(sz); + { + Vector3 *vw = v.ptrw(); + const Vector3 *ar = arr_a->ptr(); + const Vector3 *br = arr_b->ptr(); + + for (int i = 0; i < sz; i++) { + vw[i] = ar[i].lerp(br[i], c); + } + } + r_dst = v; + } + } + return; + case PACKED_COLOR_ARRAY: { + const Vector<Color> *arr_a = &PackedArrayRef<Color>::get_array(a._data.packed_array); + const Vector<Color> *arr_b = &PackedArrayRef<Color>::get_array(b._data.packed_array); + int sz = arr_a->size(); + if (sz == 0 || arr_b->size() != sz) { + r_dst = a; + } else { + Vector<Color> v; + v.resize(sz); + { + Color *vw = v.ptrw(); + const Color *ar = arr_a->ptr(); + const Color *br = arr_b->ptr(); + + for (int i = 0; i < sz; i++) { + vw[i] = ar[i].lerp(br[i], c); + } + } + r_dst = v; + } + } + return; + default: { + r_dst = a; + } + } +} + +void Variant::_register_variant_setters_getters() { + register_named_setters_getters(); + register_indexed_setters_getters(); + register_keyed_setters_getters(); +} +void Variant::_unregister_variant_setters_getters() { + unregister_named_setters_getters(); + unregister_indexed_setters_getters(); +} diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp new file mode 100644 index 0000000000..91a1b0262c --- /dev/null +++ b/core/variant/variant_utility.cpp @@ -0,0 +1,1392 @@ +/*************************************************************************/ +/* variant_utility.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/io/marshalls.h" +#include "core/object/reference.h" +#include "core/os/os.h" +#include "core/templates/oa_hash_map.h" +#include "core/variant/binder_common.h" +#include "core/variant/variant_parser.h" + +struct VariantUtilityFunctions { + // Math + static inline double sin(double arg) { + return Math::sin(arg); + } + static inline double cos(double arg) { + return Math::cos(arg); + } + static inline double tan(double arg) { + return Math::tan(arg); + } + + static inline double sinh(double arg) { + return Math::sinh(arg); + } + static inline double cosh(double arg) { + return Math::cosh(arg); + } + static inline double tanh(double arg) { + return Math::tanh(arg); + } + + static inline double asin(double arg) { + return Math::asin(arg); + } + static inline double acos(double arg) { + return Math::acos(arg); + } + static inline double atan(double arg) { + return Math::atan(arg); + } + + static inline double atan2(double y, double x) { + return Math::atan2(y, x); + } + + static inline double sqrt(double x) { + return Math::sqrt(x); + } + + static inline double fmod(double b, double r) { + return Math::fmod(b, r); + } + + static inline double fposmod(double b, double r) { + return Math::fposmod(b, r); + } + + static inline double floor(double x) { + return Math::floor(x); + } + + static inline double ceil(double x) { + return Math::ceil(x); + } + + static inline double round(double x) { + return Math::round(x); + } + + static inline Variant abs(const Variant &x, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + switch (x.get_type()) { + case Variant::INT: { + return ABS(VariantInternalAccessor<int64_t>::get(&x)); + } break; + case Variant::FLOAT: { + return Math::absd(VariantInternalAccessor<double>::get(&x)); + } break; + case Variant::VECTOR2: { + return VariantInternalAccessor<Vector2>::get(&x).abs(); + } break; + case Variant::VECTOR2I: { + return VariantInternalAccessor<Vector2i>::get(&x).abs(); + } break; + case Variant::VECTOR3: { + return VariantInternalAccessor<Vector3>::get(&x).abs(); + } break; + case Variant::VECTOR3I: { + return VariantInternalAccessor<Vector3i>::get(&x).abs(); + } break; + default: { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + } + } + + static inline double absf(double x) { + return Math::absd(x); + } + + static inline int64_t absi(int64_t x) { + return ABS(x); + } + + static inline Variant sign(const Variant &x, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + switch (x.get_type()) { + case Variant::INT: { + return SGN(VariantInternalAccessor<int64_t>::get(&x)); + } break; + case Variant::FLOAT: { + return SGN(VariantInternalAccessor<double>::get(&x)); + } break; + case Variant::VECTOR2: { + return VariantInternalAccessor<Vector2>::get(&x).sign(); + } break; + case Variant::VECTOR2I: { + return VariantInternalAccessor<Vector2i>::get(&x).sign(); + } break; + case Variant::VECTOR3: { + return VariantInternalAccessor<Vector3>::get(&x).sign(); + } break; + case Variant::VECTOR3I: { + return VariantInternalAccessor<Vector3i>::get(&x).sign(); + } break; + default: { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + } + } + + static inline double signf(double x) { + return SGN(x); + } + + static inline int64_t signi(int64_t x) { + return SGN(x); + } + + static inline double pow(double x, double y) { + return Math::pow(x, y); + } + static inline double log(double x) { + return Math::log(x); + } + + static inline double exp(double x) { + return Math::exp(x); + } + + static inline double is_nan(double x) { + return Math::is_nan(x); + } + + static inline double is_inf(double x) { + return Math::is_inf(x); + } + + static inline double is_equal_approx(double x, double y) { + return Math::is_equal_approx(x, y); + } + + static inline double is_zero_approx(double x) { + return Math::is_zero_approx(x); + } + + static inline double ease(float x, float c) { + return Math::ease(x, c); + } + + static inline int step_decimals(float step) { + return Math::step_decimals(step); + } + + static inline int range_step_decimals(float step) { + return Math::range_step_decimals(step); + } + + static inline double stepify(double value, double step) { + return Math::stepify(value, step); + } + + static inline double lerp(double from, double to, double weight) { + return Math::lerp(from, to, weight); + } + + static inline double lerp_angle(double from, double to, double weight) { + return Math::lerp_angle(from, to, weight); + } + + static inline double inverse_lerp(double from, double to, double weight) { + return Math::inverse_lerp(from, to, weight); + } + + static inline double range_lerp(double value, double istart, double istop, double ostart, double ostop) { + return Math::range_lerp(value, istart, istop, ostart, ostop); + } + + static inline double smoothstep(double from, double to, double val) { + return Math::smoothstep(from, to, val); + } + + static inline double move_toward(double from, double to, double delta) { + return Math::move_toward(from, to, delta); + } + + static inline double dectime(double value, double amount, double step) { + return Math::dectime(value, amount, step); + } + + static inline double deg2rad(double angle_deg) { + return Math::deg2rad(angle_deg); + } + + static inline double rad2deg(double angle_rad) { + return Math::rad2deg(angle_rad); + } + + static inline double linear2db(double linear) { + return Math::linear2db(linear); + } + + static inline double db2linear(double db) { + return Math::db2linear(db); + } + + static inline Vector2 polar2cartesian(double r, double th) { + return Vector2(r * Math::cos(th), r * Math::sin(th)); + } + + static inline Vector2 cartesian2polar(double x, double y) { + return Vector2(Math::sqrt(x * x + y * y), Math::atan2(y, x)); + } + + static inline int64_t wrapi(int64_t value, int64_t min, int64_t max) { + return Math::wrapi(value, min, max); + } + static inline double wrapf(double value, double min, double max) { + return Math::wrapf(value, min, max); + } + + static inline Variant max(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + if (p_argcount < 2) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.expected = 2; + return Variant(); + } + Variant base = *p_args[0]; + Variant ret; + for (int i = 1; i < p_argcount; i++) { + bool valid; + Variant::evaluate(Variant::OP_GREATER, base, *p_args[i], ret, valid); + if (!valid) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.expected = base.get_type(); + r_error.argument = i; + return Variant(); + } + if (ret.booleanize()) { + base = *p_args[i]; + } + } + r_error.error = Callable::CallError::CALL_OK; + return base; + } + + static inline double maxf(double x, double y) { + return MAX(x, y); + } + + static inline int64_t maxi(int64_t x, int64_t y) { + return MAX(x, y); + } + + static inline Variant min(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + if (p_argcount < 2) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.expected = 2; + return Variant(); + } + Variant base = *p_args[0]; + Variant ret; + for (int i = 1; i < p_argcount; i++) { + bool valid; + Variant::evaluate(Variant::OP_LESS, base, *p_args[i], ret, valid); + if (!valid) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.expected = base.get_type(); + r_error.argument = i; + return Variant(); + } + if (ret.booleanize()) { + base = *p_args[i]; + } + } + r_error.error = Callable::CallError::CALL_OK; + return base; + } + + static inline double minf(double x, double y) { + return MIN(x, y); + } + + static inline int64_t mini(int64_t x, int64_t y) { + return MIN(x, y); + } + + static inline Variant clamp(const Variant &x, const Variant &min, const Variant &max, Callable::CallError &r_error) { + Variant value = x; + + Variant ret; + + bool valid; + Variant::evaluate(Variant::OP_LESS, value, min, ret, valid); + if (!valid) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.expected = value.get_type(); + r_error.argument = 1; + return Variant(); + } + if (ret.booleanize()) { + value = min; + } + Variant::evaluate(Variant::OP_GREATER, value, max, ret, valid); + if (!valid) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.expected = value.get_type(); + r_error.argument = 2; + return Variant(); + } + if (ret.booleanize()) { + value = max; + } + + r_error.error = Callable::CallError::CALL_OK; + + return value; + } + + static inline double clampf(double x, double min, double max) { + return CLAMP(x, min, max); + } + + static inline int64_t clampi(int64_t x, int64_t min, int64_t max) { + return CLAMP(x, min, max); + } + + static inline int64_t nearest_po2(int64_t x) { + return nearest_power_of_2_templated(uint64_t(x)); + } + + // Random + + static inline void randomize() { + Math::randomize(); + } + + static inline int64_t randi() { + return Math::rand(); + } + + static inline double randf() { + return Math::randf(); + } + + static inline int64_t randi_range(int64_t from, int64_t to) { + return Math::random((int32_t)from, (int32_t)to); + } + + static inline double randf_range(double from, double to) { + return Math::random(from, to); + } + + static inline void seed(int64_t s) { + return Math::seed(s); + } + + static inline PackedInt64Array rand_from_seed(int64_t seed) { + uint64_t s = seed; + PackedInt64Array arr; + arr.resize(2); + arr.write[0] = Math::rand_from_seed(&s); + arr.write[1] = s; + return arr; + } + + // Utility + + static inline Variant weakref(const Variant &obj, Callable::CallError &r_error) { + if (obj.get_type() == Variant::OBJECT) { + r_error.error = Callable::CallError::CALL_OK; + if (obj.is_ref()) { + Ref<WeakRef> wref = memnew(WeakRef); + REF r = obj; + if (r.is_valid()) { + wref->set_ref(r); + } + return wref; + } else { + Ref<WeakRef> wref = memnew(WeakRef); + Object *o = obj.get_validated_object(); + if (o) { + wref->set_obj(o); + } + return wref; + } + } else if (obj.get_type() == Variant::NIL) { + r_error.error = Callable::CallError::CALL_OK; + Ref<WeakRef> wref = memnew(WeakRef); + return wref; + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return Variant(); + } + } + + static inline int64_t _typeof(const Variant &obj) { + return obj.get_type(); + } + + static inline String str(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + return String(); + } + String str; + for (int i = 0; i < p_arg_count; i++) { + String os = p_args[i]->operator String(); + + if (i == 0) { + str = os; + } else { + str += os; + } + } + + r_error.error = Callable::CallError::CALL_OK; + + return str; + } + + static inline void print(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + } + String str; + for (int i = 0; i < p_arg_count; i++) { + String os = p_args[i]->operator String(); + + if (i == 0) { + str = os; + } else { + str += os; + } + } + + print_line(str); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void printerr(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + } + String str; + for (int i = 0; i < p_arg_count; i++) { + String os = p_args[i]->operator String(); + + if (i == 0) { + str = os; + } else { + str += os; + } + } + + print_error(str); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void printt(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + } + String str; + for (int i = 0; i < p_arg_count; i++) { + if (i) { + str += "\t"; + } + str += p_args[i]->operator String(); + } + + print_error(str); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void prints(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + } + String str; + for (int i = 0; i < p_arg_count; i++) { + if (i) { + str += " "; + } + str += p_args[i]->operator String(); + } + + print_error(str); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void printraw(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + } + String str; + for (int i = 0; i < p_arg_count; i++) { + String os = p_args[i]->operator String(); + + if (i == 0) { + str = os; + } else { + str += os; + } + } + + OS::get_singleton()->print("%s", str.utf8().get_data()); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void push_error(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + } + String str; + for (int i = 0; i < p_arg_count; i++) { + String os = p_args[i]->operator String(); + + if (i == 0) { + str = os; + } else { + str += os; + } + } + + ERR_PRINT(str); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void push_warning(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + if (p_arg_count < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 1; + } + String str; + for (int i = 0; i < p_arg_count; i++) { + String os = p_args[i]->operator String(); + + if (i == 0) { + str = os; + } else { + str += os; + } + } + + WARN_PRINT(str); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline String var2str(const Variant &p_var) { + String vars; + VariantWriter::write_to_string(p_var, vars); + return vars; + } + + static inline Variant str2var(const String &p_var) { + VariantParser::StreamString ss; + ss.s = p_var; + + String errs; + int line; + Variant ret; + (void)VariantParser::parse(&ss, ret, errs, line); + + return ret; + } + + static inline PackedByteArray var2bytes(const Variant &p_var) { + int len; + Error err = encode_variant(p_var, nullptr, len, false); + if (err != OK) { + return PackedByteArray(); + } + + PackedByteArray barr; + barr.resize(len); + { + uint8_t *w = barr.ptrw(); + err = encode_variant(p_var, w, len, false); + if (err != OK) { + return PackedByteArray(); + } + } + + return barr; + } + + static inline PackedByteArray var2bytes_with_objects(const Variant &p_var) { + int len; + Error err = encode_variant(p_var, nullptr, len, true); + if (err != OK) { + return PackedByteArray(); + } + + PackedByteArray barr; + barr.resize(len); + { + uint8_t *w = barr.ptrw(); + err = encode_variant(p_var, w, len, true); + if (err != OK) { + return PackedByteArray(); + } + } + + return barr; + } + + static inline Variant bytes2var(const PackedByteArray &p_arr) { + Variant ret; + { + const uint8_t *r = p_arr.ptr(); + Error err = decode_variant(ret, r, p_arr.size(), nullptr, false); + if (err != OK) { + return Variant(); + } + } + return ret; + } + + static inline Variant bytes2var_with_objects(const PackedByteArray &p_arr) { + Variant ret; + { + const uint8_t *r = p_arr.ptr(); + Error err = decode_variant(ret, r, p_arr.size(), nullptr, true); + if (err != OK) { + return Variant(); + } + } + return ret; + } + + static inline int64_t hash(const Variant &p_arr) { + return p_arr.hash(); + } + + static inline Variant instance_from_id(int64_t p_id) { + ObjectID id = ObjectID((uint64_t)p_id); + Variant ret = ObjectDB::get_instance(id); + return ret; + } + + static inline bool is_instance_id_valid(int64_t p_id) { + return ObjectDB::get_instance(ObjectID((uint64_t)p_id)) != nullptr; + } + + static inline bool is_instance_valid(const Variant &p_instance) { + if (p_instance.get_type() != Variant::OBJECT) { + return false; + } + return p_instance.get_validated_object() != nullptr; + } +}; + +#ifdef DEBUG_METHODS_ENABLED +#define VCALLR *ret = p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...) +#define VCALL p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...) +#else +#define VCALLR *ret = p_func(VariantCaster<P>::cast(*p_args[Is])...) +#define VCALL p_func(VariantCaster<P>::cast(*p_args[Is])...) +#endif + +template <class R, class... P, size_t... Is> +static _FORCE_INLINE_ void call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + VCALLR; + (void)p_args; // avoid gcc warning + (void)r_error; +} + +template <class R, class... P, size_t... Is> +static _FORCE_INLINE_ void validated_call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, IndexSequence<Is...>) { + *ret = p_func(VariantCaster<P>::cast(*p_args[Is])...); + (void)p_args; +} + +template <class R, class... P, size_t... Is> +static _FORCE_INLINE_ void ptr_call_helperpr(R (*p_func)(P...), void *ret, const void **p_args, IndexSequence<Is...>) { + PtrToArg<R>::encode(p_func(PtrToArg<P>::convert(p_args[Is])...), ret); + (void)p_args; +} + +template <class R, class... P> +static _FORCE_INLINE_ void call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error) { + call_helperpr(p_func, ret, p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class R, class... P> +static _FORCE_INLINE_ void validated_call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args) { + validated_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class R, class... P> +static _FORCE_INLINE_ void ptr_call_helperr(R (*p_func)(P...), void *ret, const void **p_args) { + ptr_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class R, class... P> +static _FORCE_INLINE_ int get_arg_count_helperr(R (*p_func)(P...)) { + return sizeof...(P); +} + +template <class R, class... P> +static _FORCE_INLINE_ Variant::Type get_arg_type_helperr(R (*p_func)(P...), int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + +template <class R, class... P> +static _FORCE_INLINE_ Variant::Type get_ret_type_helperr(R (*p_func)(P...)) { + return GetTypeInfo<R>::VARIANT_TYPE; +} + +// WITHOUT RET + +template <class... P, size_t... Is> +static _FORCE_INLINE_ void call_helperp(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + VCALL; + (void)p_args; + (void)r_error; +} + +template <class... P, size_t... Is> +static _FORCE_INLINE_ void validated_call_helperp(void (*p_func)(P...), const Variant **p_args, IndexSequence<Is...>) { + p_func(VariantCaster<P>::cast(*p_args[Is])...); + (void)p_args; +} + +template <class... P, size_t... Is> +static _FORCE_INLINE_ void ptr_call_helperp(void (*p_func)(P...), const void **p_args, IndexSequence<Is...>) { + p_func(PtrToArg<P>::convert(p_args[Is])...); + (void)p_args; +} + +template <class... P> +static _FORCE_INLINE_ void call_helper(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error) { + call_helperp(p_func, p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +static _FORCE_INLINE_ void validated_call_helper(void (*p_func)(P...), const Variant **p_args) { + validated_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +static _FORCE_INLINE_ void ptr_call_helper(void (*p_func)(P...), const void **p_args) { + ptr_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +static _FORCE_INLINE_ int get_arg_count_helper(void (*p_func)(P...)) { + return sizeof...(P); +} + +template <class... P> +static _FORCE_INLINE_ Variant::Type get_arg_type_helper(void (*p_func)(P...), int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + +template <class... P> +static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) { + return Variant::NIL; +} + +#define FUNCBINDR(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args, r_error); \ + } \ + \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + validated_call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + ptr_call_helperr(VariantUtilityFunctions::m_func, ret, p_args); \ + } \ + \ + static int get_argument_count() { \ + return get_arg_count_helperr(VariantUtilityFunctions::m_func); \ + } \ + \ + static Variant::Type get_argument_type(int p_arg) { \ + return get_arg_type_helperr(VariantUtilityFunctions::m_func, p_arg); \ + } \ + \ + static Variant::Type get_return_type() { \ + return get_ret_type_helperr(VariantUtilityFunctions::m_func); \ + } \ + static bool has_return_type() { \ + return true; \ + } \ + static bool is_vararg() { return false; } \ + static Variant::UtilityFunctionType get_type() { return m_category; } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + +#define FUNCBINDVR(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + r_error.error = Callable::CallError::CALL_OK; \ + *r_ret = VariantUtilityFunctions::m_func(*p_args[0], r_error); \ + } \ + \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + Callable::CallError ce; \ + *r_ret = VariantUtilityFunctions::m_func(*p_args[0], ce); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + Callable::CallError ce; \ + PtrToArg<Variant>::encode(VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), ce), ret); \ + } \ + \ + static int get_argument_count() { \ + return 1; \ + } \ + \ + static Variant::Type get_argument_type(int p_arg) { \ + return Variant::NIL; \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::NIL; \ + } \ + static bool has_return_type() { \ + return true; \ + } \ + static bool is_vararg() { return false; } \ + static Variant::UtilityFunctionType get_type() { return m_category; } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + +#define FUNCBINDVR3(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + r_error.error = Callable::CallError::CALL_OK; \ + *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], *p_args[2], r_error); \ + } \ + \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + Callable::CallError ce; \ + *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], *p_args[2], ce); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + Callable::CallError ce; \ + Variant r; \ + r = VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), PtrToArg<Variant>::convert(p_args[1]), PtrToArg<Variant>::convert(p_args[2]), ce); \ + PtrToArg<Variant>::encode(r, ret); \ + } \ + \ + static int get_argument_count() { \ + return 3; \ + } \ + \ + static Variant::Type get_argument_type(int p_arg) { \ + return Variant::NIL; \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::NIL; \ + } \ + static bool has_return_type() { \ + return true; \ + } \ + static bool is_vararg() { return false; } \ + static Variant::UtilityFunctionType get_type() { return m_category; } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + +#define FUNCBINDVARARG(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + r_error.error = Callable::CallError::CALL_OK; \ + *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \ + } \ + \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + Callable::CallError c; \ + *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + Vector<Variant> args; \ + for (int i = 0; i < p_argcount; i++) { \ + args.push_back(PtrToArg<Variant>::convert(p_args[i])); \ + } \ + Vector<const Variant *> argsp; \ + for (int i = 0; i < p_argcount; i++) { \ + argsp.push_back(&args[i]); \ + } \ + Variant r; \ + validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \ + PtrToArg<Variant>::encode(r, ret); \ + } \ + \ + static int get_argument_count() { \ + return 2; \ + } \ + \ + static Variant::Type get_argument_type(int p_arg) { \ + return Variant::NIL; \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::NIL; \ + } \ + static bool has_return_type() { \ + return true; \ + } \ + static bool is_vararg() { \ + return true; \ + } \ + static Variant::UtilityFunctionType get_type() { \ + return m_category; \ + } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + +#define FUNCBINDVARARGS(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + r_error.error = Callable::CallError::CALL_OK; \ + *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \ + } \ + \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + Callable::CallError c; \ + *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + Vector<Variant> args; \ + for (int i = 0; i < p_argcount; i++) { \ + args.push_back(PtrToArg<Variant>::convert(p_args[i])); \ + } \ + Vector<const Variant *> argsp; \ + for (int i = 0; i < p_argcount; i++) { \ + argsp.push_back(&args[i]); \ + } \ + Variant r; \ + validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \ + PtrToArg<String>::encode(r.operator String(), ret); \ + } \ + \ + static int get_argument_count() { \ + return 1; \ + } \ + \ + static Variant::Type get_argument_type(int p_arg) { \ + return Variant::NIL; \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::STRING; \ + } \ + static bool has_return_type() { \ + return true; \ + } \ + static bool is_vararg() { \ + return true; \ + } \ + static Variant::UtilityFunctionType get_type() { \ + return m_category; \ + } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + +#define FUNCBINDVARARGV(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + r_error.error = Callable::CallError::CALL_OK; \ + VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \ + } \ + \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + Callable::CallError c; \ + VariantUtilityFunctions::m_func(p_args, p_argcount, c); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + Vector<Variant> args; \ + for (int i = 0; i < p_argcount; i++) { \ + args.push_back(PtrToArg<Variant>::convert(p_args[i])); \ + } \ + Vector<const Variant *> argsp; \ + for (int i = 0; i < p_argcount; i++) { \ + argsp.push_back(&args[i]); \ + } \ + Variant r; \ + validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \ + } \ + \ + static int get_argument_count() { \ + return 1; \ + } \ + \ + static Variant::Type get_argument_type(int p_arg) { \ + return Variant::NIL; \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::NIL; \ + } \ + static bool has_return_type() { \ + return false; \ + } \ + static bool is_vararg() { \ + return true; \ + } \ + static Variant::UtilityFunctionType get_type() { \ + return m_category; \ + } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + +#define FUNCBIND(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + call_helper(VariantUtilityFunctions::m_func, p_args, r_error); \ + } \ + \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + validated_call_helper(VariantUtilityFunctions::m_func, p_args); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + ptr_call_helper(VariantUtilityFunctions::m_func, p_args); \ + } \ + \ + static int get_argument_count() { \ + return get_arg_count_helper(VariantUtilityFunctions::m_func); \ + } \ + \ + static Variant::Type get_argument_type(int p_arg) { \ + return get_arg_type_helper(VariantUtilityFunctions::m_func, p_arg); \ + } \ + \ + static Variant::Type get_return_type() { \ + return get_ret_type_helper(VariantUtilityFunctions::m_func); \ + } \ + static bool has_return_type() { \ + return false; \ + } \ + static bool is_vararg() { return false; } \ + static Variant::UtilityFunctionType get_type() { return m_category; } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + +struct VariantUtilityFunctionInfo { + void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Variant::ValidatedUtilityFunction validated_call_utility; + Variant::PTRUtilityFunction ptr_call_utility; + Vector<String> argnames; + bool is_vararg; + bool returns_value; + int argcount; + Variant::Type (*get_arg_type)(int); + Variant::Type return_type; + Variant::UtilityFunctionType type; +}; + +static OAHashMap<StringName, VariantUtilityFunctionInfo> utility_function_table; +static List<StringName> utility_function_name_table; + +template <class T> +static void register_utility_function(const String &p_name, const Vector<String> &argnames) { + String name = p_name; + if (name.begins_with("_")) { + name = name.substr(1, name.length() - 1); + } + StringName sname = name; + ERR_FAIL_COND(utility_function_table.has(sname)); + + VariantUtilityFunctionInfo bfi; + bfi.call_utility = T::call; + bfi.validated_call_utility = T::validated_call; + bfi.ptr_call_utility = T::ptrcall; + bfi.is_vararg = T::is_vararg(); + bfi.argnames = argnames; + bfi.argcount = T::get_argument_count(); + if (!bfi.is_vararg) { + ERR_FAIL_COND_MSG(argnames.size() != bfi.argcount, "wrong number of arguments binding utility function: " + name); + } + bfi.get_arg_type = T::get_argument_type; + bfi.return_type = T::get_return_type(); + bfi.type = T::get_type(); + bfi.returns_value = T::has_return_type(); + + utility_function_table.insert(sname, bfi); + utility_function_name_table.push_back(sname); +} + +void Variant::_register_variant_utility_functions() { + // Math + + FUNCBINDR(sin, sarray("angle_rad"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(cos, sarray("angle_rad"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(tan, sarray("angle_rad"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(sinh, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(cosh, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(tanh, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(asin, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(acos, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(atan, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(atan2, sarray("y", "x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(sqrt, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(fmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(fposmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(floor, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(ceil, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(round, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDVR(abs, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(absf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(absi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDVR(sign, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(signf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(signi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(pow, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(log, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(exp, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(is_nan, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(is_inf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(is_equal_approx, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(is_zero_approx, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(ease, sarray("x", "c"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(range_step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(stepify, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(lerp, sarray("from", "to", "c"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(lerp_angle, sarray("from", "to", "c"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(inverse_lerp, sarray("from", "to", "c"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(range_lerp, sarray("value", "istart", "istop", "ostart", "ostop"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(smoothstep, sarray("from", "to", "c"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(move_toward, sarray("from", "to", "delta"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(dectime, sarray("value", "amount", "step"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(deg2rad, sarray("deg"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(rad2deg, sarray("rad"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(linear2db, sarray("lin"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(db2linear, sarray("db"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(polar2cartesian, sarray("r", "th"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(cartesian2polar, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(wrapi, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(wrapf, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDVARARG(max, sarray(), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(maxi, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(maxf, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDVARARG(min, sarray(), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(mini, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(minf, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDVR3(clamp, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(clampi, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(clampf, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); + + FUNCBINDR(nearest_po2, sarray("value"), Variant::UTILITY_FUNC_TYPE_MATH); + + //Random + + FUNCBIND(randomize, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM); + FUNCBINDR(randi, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM); + FUNCBINDR(randf, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM); + FUNCBINDR(randi_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM); + FUNCBINDR(randf_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM); + FUNCBIND(seed, sarray("base"), Variant::UTILITY_FUNC_TYPE_RANDOM); + FUNCBINDR(rand_from_seed, sarray("seed"), Variant::UTILITY_FUNC_TYPE_RANDOM); + + // Utility + FUNCBINDVR(weakref, sarray("from"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(_typeof, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGS(str, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGV(print, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGV(printerr, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGV(printt, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGV(prints, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGV(printraw, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGV(push_error, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDVARARGV(push_warning, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + + FUNCBINDR(var2str, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(str2var, sarray("string"), Variant::UTILITY_FUNC_TYPE_GENERAL); + + FUNCBINDR(var2bytes, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(bytes2var, sarray("bytes"), Variant::UTILITY_FUNC_TYPE_GENERAL); + + FUNCBINDR(var2bytes_with_objects, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(bytes2var_with_objects, sarray("bytes"), Variant::UTILITY_FUNC_TYPE_GENERAL); + + FUNCBINDR(hash, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL); + + FUNCBINDR(instance_from_id, sarray("id"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(is_instance_id_valid, sarray("id"), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(is_instance_valid, sarray("instance"), Variant::UTILITY_FUNC_TYPE_GENERAL); +} +void Variant::_unregister_variant_utility_functions() { + utility_function_table.clear(); + utility_function_name_table.clear(); +} + +void Variant::call_utility_function(const StringName &p_name, Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + r_error.argument = 0; + r_error.expected = 0; + return; + } + + if (unlikely(!bfi->is_vararg && p_argcount < bfi->argcount)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 0; + r_error.expected = bfi->argcount; + return; + } + + if (unlikely(!bfi->is_vararg && p_argcount > bfi->argcount)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = 0; + r_error.expected = bfi->argcount; + return; + } + + bfi->call_utility(r_ret, p_args, p_argcount, r_error); +} + +bool Variant::has_utility_function(const StringName &p_name) { + return utility_function_table.has(p_name); +} + +Variant::ValidatedUtilityFunction Variant::get_validated_utility_function(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return nullptr; + } + + return bfi->validated_call_utility; +} +Variant::PTRUtilityFunction Variant::get_ptr_utility_function(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return nullptr; + } + + return bfi->ptr_call_utility; +} + +Variant::UtilityFunctionType Variant::get_utility_function_type(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return Variant::UTILITY_FUNC_TYPE_MATH; + } + + return bfi->type; +} + +int Variant::get_utility_function_argument_count(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return 0; + } + + return bfi->argcount; +} +Variant::Type Variant::get_utility_function_argument_type(const StringName &p_name, int p_arg) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return Variant::NIL; + } + + return bfi->get_arg_type(p_arg); +} +String Variant::get_utility_function_argument_name(const StringName &p_name, int p_arg) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return String(); + } + ERR_FAIL_COND_V(bfi->is_vararg, String()); + ERR_FAIL_INDEX_V(p_arg, bfi->argnames.size(), String()); + return bfi->argnames[p_arg]; +} +bool Variant::has_utility_function_return_value(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return false; + } + return bfi->returns_value; +} +Variant::Type Variant::get_utility_function_return_type(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return Variant::NIL; + } + + return bfi->return_type; +} +bool Variant::is_utility_function_vararg(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + if (!bfi) { + return false; + } + + return bfi->is_vararg; +} + +void Variant::get_utility_function_list(List<StringName> *r_functions) { + for (List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) { + r_functions->push_back(E->get()); + } +} diff --git a/core/variant_call.cpp b/core/variant_call.cpp deleted file mode 100644 index 6ffefccb67..0000000000 --- a/core/variant_call.cpp +++ /dev/null @@ -1,2099 +0,0 @@ -/*************************************************************************/ -/* variant_call.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "variant.h" - -#include "core/class_db.h" -#include "core/color_names.inc" -#include "core/core_string_names.h" -#include "core/crypto/crypto_core.h" -#include "core/debugger/engine_debugger.h" -#include "core/io/compression.h" -#include "core/oa_hash_map.h" -#include "core/os/os.h" - -_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) { -} - -_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr, const String &p_str) { - arr.push_back(p_str); -} - -template <class... P> -_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr, const String &p_str, P... p_args) { - arr.push_back(p_str); - sarray_add_str(arr, p_args...); -} - -template <class... P> -_FORCE_INLINE_ Vector<String> sarray(P... p_args) { - Vector<String> arr; - sarray_add_str(arr, p_args...); - return arr; -} - -typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args); -typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args); - -struct _VariantCall { - template <class T, class... P> - class InternalMethod : public Variant::InternalMethod { - public: - void (T::*method)(P...); - Vector<Variant> default_values; -#ifdef DEBUG_ENABLED - Vector<String> argument_names; -#endif - - virtual int get_argument_count() const { - return sizeof...(P); - } - virtual Variant::Type get_argument_type(int p_arg) const { - return call_get_argument_type<P...>(p_arg); - } -#ifdef DEBUG_ENABLED - virtual String get_argument_name(int p_arg) const { - ERR_FAIL_INDEX_V(p_arg, argument_names.size(), String()); - return argument_names[p_arg]; - } -#endif - virtual Vector<Variant> get_default_arguments() const { - return default_values; - } - - virtual Variant::Type get_return_type() const { - return Variant::NIL; - } - virtual uint32_t get_flags() const { - return 0; - } - - virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - call_with_variant_args_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, default_values); - } - - virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { - call_with_validated_variant_args(base, method, p_args); - } - -#ifdef PTRCALL_ENABLED - virtual void ptrcall(void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_args<T, P...>(reinterpret_cast<T *>(p_base), method, p_args); - } -#endif - InternalMethod(void (T::*p_method)(P...), const Vector<Variant> &p_default_args -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_arg_names, const StringName &p_method_name, Variant::Type p_base_type -#endif - ) { - method = p_method; - default_values = p_default_args; -#ifdef DEBUG_ENABLED - argument_names = p_arg_names; - method_name = p_method_name; - base_type = p_base_type; -#endif - } - }; - - template <class T, class R, class... P> - class InternalMethodR : public Variant::InternalMethod { - public: - R(T::*method) - (P...); - Vector<Variant> default_values; -#ifdef DEBUG_ENABLED - Vector<String> argument_names; -#endif - - virtual int get_argument_count() const { - return sizeof...(P); - } - virtual Variant::Type get_argument_type(int p_arg) const { - return call_get_argument_type<P...>(p_arg); - return Variant::NIL; - } -#ifdef DEBUG_ENABLED - virtual String get_argument_name(int p_arg) const { - ERR_FAIL_INDEX_V(p_arg, argument_names.size(), String()); - return argument_names[p_arg]; - } -#endif - virtual Vector<Variant> get_default_arguments() const { - return default_values; - } - - virtual Variant::Type get_return_type() const { - return GetTypeInfo<R>::VARIANT_TYPE; - } - virtual uint32_t get_flags() const { - uint32_t f = 0; - if (get_return_type() == Variant::NIL) { - f |= FLAG_RETURNS_VARIANT; - } - return f; - } - - virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, default_values); - } - - virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { - call_with_validated_variant_args_ret(base, method, p_args, r_ret); - } -#ifdef PTRCALL_ENABLED - virtual void ptrcall(void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_args_ret<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret); - } -#endif - InternalMethodR(R (T::*p_method)(P...), const Vector<Variant> &p_default_args -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_arg_names, const StringName &p_method_name, Variant::Type p_base_type -#endif - ) { - method = p_method; - default_values = p_default_args; -#ifdef DEBUG_ENABLED - argument_names = p_arg_names; - method_name = p_method_name; - base_type = p_base_type; -#endif - } - }; - - template <class T, class R, class... P> - class InternalMethodRC : public Variant::InternalMethod { - public: - R(T::*method) - (P...) const; - Vector<Variant> default_values; -#ifdef DEBUG_ENABLED - Vector<String> argument_names; -#endif - - virtual int get_argument_count() const { - return sizeof...(P); - } - virtual Variant::Type get_argument_type(int p_arg) const { - return call_get_argument_type<P...>(p_arg); - } -#ifdef DEBUG_ENABLED - virtual String get_argument_name(int p_arg) const { - ERR_FAIL_INDEX_V(p_arg, argument_names.size(), String()); - return argument_names[p_arg]; - } -#endif - virtual Vector<Variant> get_default_arguments() const { - return default_values; - } - - virtual Variant::Type get_return_type() const { - return GetTypeInfo<R>::VARIANT_TYPE; - } - virtual uint32_t get_flags() const { - uint32_t f = FLAG_IS_CONST; - if (get_return_type() == Variant::NIL) { - f |= FLAG_RETURNS_VARIANT; - } - return f; - } - - virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - call_with_variant_args_retc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, default_values); - } - - virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { - call_with_validated_variant_args_retc(base, method, p_args, r_ret); - } -#ifdef PTRCALL_ENABLED - virtual void ptrcall(void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_args_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret); - } -#endif - InternalMethodRC(R (T::*p_method)(P...) const, const Vector<Variant> &p_default_args -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_arg_names, const StringName &p_method_name, Variant::Type p_base_type -#endif - ) { - method = p_method; - default_values = p_default_args; -#ifdef DEBUG_ENABLED - argument_names = p_arg_names; - method_name = p_method_name; - base_type = p_base_type; -#endif - } - }; - - template <class T, class R, class... P> - class InternalMethodRS : public Variant::InternalMethod { - public: - R(*method) - (T *, P...); - Vector<Variant> default_values; -#ifdef DEBUG_ENABLED - Vector<String> argument_names; -#endif - - virtual int get_argument_count() const { - return sizeof...(P); - } - virtual Variant::Type get_argument_type(int p_arg) const { - return call_get_argument_type<P...>(p_arg); - } -#ifdef DEBUG_ENABLED - virtual String get_argument_name(int p_arg) const { - ERR_FAIL_INDEX_V(p_arg, argument_names.size(), String()); - return argument_names[p_arg]; - } -#endif - virtual Vector<Variant> get_default_arguments() const { - return default_values; - } - - virtual Variant::Type get_return_type() const { - return GetTypeInfo<R>::VARIANT_TYPE; - } - virtual uint32_t get_flags() const { - uint32_t f = 0; - if (get_return_type() == Variant::NIL) { - f |= FLAG_RETURNS_VARIANT; - } - return f; - } - - virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - const Variant **args = p_args; -#ifdef DEBUG_ENABLED - if ((size_t)p_argcount > sizeof...(P)) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; - r_error.argument = sizeof...(P); - return; - } -#endif - if ((size_t)p_argcount < sizeof...(P)) { - size_t missing = sizeof...(P) - (size_t)p_argcount; - if (missing <= (size_t)default_values.size()) { - args = (const Variant **)alloca(sizeof...(P) * sizeof(const Variant *)); - // GCC fails to see that `sizeof...(P)` cannot be 0 here given the previous - // conditions, so it raises a warning on the potential use of `i < 0` as the - // execution condition. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" -#endif - for (size_t i = 0; i < sizeof...(P); i++) { - if (i < (size_t)p_argcount) { - args[i] = p_args[i]; - } else { - args[i] = &default_values[i - p_argcount + (default_values.size() - missing)]; - } - } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - } else { -#ifdef DEBUG_ENABLED - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = sizeof...(P); -#endif - return; - } - } - call_with_variant_args_retc_static_helper(VariantGetInternalPtr<T>::get_ptr(base), method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); - } - - virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { - call_with_validated_variant_args_static_retc(base, method, p_args, r_ret); - } -#ifdef PTRCALL_ENABLED - virtual void ptrcall(void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_args_static_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret); - } -#endif - InternalMethodRS(R (*p_method)(T *, P...), const Vector<Variant> &p_default_args -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_arg_names, const StringName &p_method_name, Variant::Type p_base_type -#endif - ) { - method = p_method; - default_values = p_default_args; -#ifdef DEBUG_ENABLED - argument_names = p_arg_names; - method_name = p_method_name; - base_type = p_base_type; -#endif - } - }; - - class InternalMethodVC : public Variant::InternalMethod { - public: - typedef void (*MethodVC)(Variant *, const Variant **, int, Variant &r_ret, Callable::CallError &); - MethodVC methodvc = nullptr; - uint32_t base_flags = 0; - Vector<String> argument_names; - Vector<Variant::Type> argument_types; - Variant::Type return_type = Variant::NIL; - - virtual int get_argument_count() const { - return argument_names.size(); - } - virtual Variant::Type get_argument_type(int p_arg) const { - ERR_FAIL_INDEX_V(p_arg, argument_types.size(), Variant::NIL); - return argument_types[p_arg]; - } -#ifdef DEBUG_ENABLED - virtual String get_argument_name(int p_arg) const { - ERR_FAIL_INDEX_V(p_arg, argument_names.size(), String()); - return argument_names[p_arg]; - } -#endif - virtual Vector<Variant> get_default_arguments() const { - return Vector<Variant>(); - } - - virtual Variant::Type get_return_type() const { - return return_type; - } - virtual uint32_t get_flags() const { - return base_flags | FLAG_NO_PTRCALL; - } - - virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - methodvc(base, p_args, p_argcount, r_ret, r_error); - } - - virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { - ERR_FAIL_MSG("No support for validated call"); - } -#ifdef PTRCALL_ENABLED - virtual void ptrcall(void *p_base, const void **p_args, void *r_ret) { - ERR_FAIL_MSG("No support for ptrcall call"); - } -#endif - InternalMethodVC(MethodVC p_method, uint32_t p_flags, const Vector<Variant::Type> &p_argument_types, const Variant::Type &p_return_type -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_arg_names, const StringName &p_method_name, Variant::Type p_base_type -#endif - ) { - methodvc = p_method; - argument_types = p_argument_types; - return_type = p_return_type; - base_flags = p_flags; -#ifdef DEBUG_ENABLED - argument_names = p_arg_names; - method_name = p_method_name; - base_type = p_base_type; -#endif - } - }; - - typedef OAHashMap<StringName, Variant::InternalMethod *> MethodMap; - static MethodMap *type_internal_methods; - static List<StringName> *type_internal_method_names; - - template <class T, class... P> - static void _bind_method(const StringName &p_name, void (T::*p_method)(P...), const Vector<Variant> &p_default_args = Vector<Variant>() -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_argument_names = Vector<String>() -#endif - ) { - -#ifdef DEBUG_ENABLED - ERR_FAIL_COND_MSG(p_argument_names.size() != sizeof...(P), "Wrong argument name count supplied for method: " + Variant::get_type_name(GetTypeInfo<T>::VARIANT_TYPE) + "::" + String(p_name)); - ERR_FAIL_COND(type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].has(p_name)); -#endif -#ifdef DEBUG_ENABLED - Variant::InternalMethod *m = memnew((InternalMethod<T, P...>)(p_method, p_default_args, p_argument_names, p_name, GetTypeInfo<T>::VARIANT_TYPE)); -#else - Variant::InternalMethod *m = memnew((InternalMethod<T, P...>)(p_method, p_default_args)); -#endif - - type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); - type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); - } - - template <class T, class R, class... P> - static void _bind_method(const StringName &p_name, R (T::*p_method)(P...) const, const Vector<Variant> &p_default_args = Vector<Variant>() -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_argument_names = Vector<String>() -#endif - ) { -#ifdef DEBUG_ENABLED - ERR_FAIL_COND_MSG(p_argument_names.size() != sizeof...(P), "Wrong argument name count supplied for method: " + Variant::get_type_name(GetTypeInfo<T>::VARIANT_TYPE) + "::" + String(p_name)); - ERR_FAIL_COND_MSG(type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].has(p_name), " Method already registered: " + Variant::get_type_name(GetTypeInfo<T>::VARIANT_TYPE) + "::" + String(p_name)); - -#endif -#ifdef DEBUG_ENABLED - Variant::InternalMethod *m = memnew((InternalMethodRC<T, R, P...>)(p_method, p_default_args, p_argument_names, p_name, GetTypeInfo<T>::VARIANT_TYPE)); -#else - Variant::InternalMethod *m = memnew((InternalMethodRC<T, R, P...>)(p_method, p_default_args)); -#endif - - type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); - type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); - } - - template <class T, class R, class... P> - static void _bind_method(const StringName &p_name, R (T::*p_method)(P...), const Vector<Variant> &p_default_args = Vector<Variant>() -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_argument_names = Vector<String>() -#endif - ) { -#ifdef DEBUG_ENABLED - ERR_FAIL_COND_MSG(p_argument_names.size() != sizeof...(P), "Wrong argument name count supplied for method: " + Variant::get_type_name(GetTypeInfo<T>::VARIANT_TYPE) + "::" + String(p_name)); - ERR_FAIL_COND_MSG(type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].has(p_name), " Method already registered: " + Variant::get_type_name(GetTypeInfo<T>::VARIANT_TYPE) + "::" + String(p_name)); -#endif - -#ifdef DEBUG_ENABLED - Variant::InternalMethod *m = memnew((InternalMethodR<T, R, P...>)(p_method, p_default_args, p_argument_names, p_name, GetTypeInfo<T>::VARIANT_TYPE)); -#else - Variant::InternalMethod *m = memnew((InternalMethodR<T, R, P...>)(p_method, p_default_args)); -#endif - type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); - type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); - } - -#ifdef DEBUG_ENABLED -#define bind_method(m_type, m_method, m_arg_names, m_default_args) _VariantCall::_bind_method(#m_method, &m_type ::m_method, m_default_args, m_arg_names) -#else -#define bind_method(m_type, m_method, m_arg_names, m_default_args) _VariantCall::_bind_method(#m_method, &m_type ::m_method, m_default_args) -#endif - -#ifdef DEBUG_ENABLED -#define bind_methodv(m_name, m_method, m_arg_names, m_default_args) _VariantCall::_bind_method(#m_name, m_method, m_default_args, m_arg_names) -#else -#define bind_methodv(m_name, m_method, m_arg_names, m_default_args) _VariantCall::_bind_method(#m_name, m_method, m_default_args) -#endif - - template <class T, class R, class... P> - static void _bind_function(const StringName &p_name, R (*p_method)(T *, P...), const Vector<Variant> &p_default_args = Vector<Variant>() -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_argument_names = Vector<String>() -#endif - ) { -#ifdef DEBUG_ENABLED - ERR_FAIL_COND_MSG(p_argument_names.size() != sizeof...(P), "Wrong argument name count supplied for method: " + Variant::get_type_name(GetTypeInfo<T>::VARIANT_TYPE) + "::" + String(p_name)); - ERR_FAIL_COND_MSG(type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].has(p_name), " Method already registered: " + Variant::get_type_name(GetTypeInfo<T>::VARIANT_TYPE) + "::" + String(p_name)); -#endif - -#ifdef DEBUG_ENABLED - Variant::InternalMethod *m = memnew((InternalMethodRS<T, R, P...>)(p_method, p_default_args, p_argument_names, p_name, GetTypeInfo<T>::VARIANT_TYPE)); -#else - Variant::InternalMethod *m = memnew((InternalMethodRS<T, R, P...>)(p_method, p_default_args)); -#endif - - type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); - type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); - } - -#ifdef DEBUG_ENABLED -#define bind_function(m_name, m_method, m_arg_names, m_default_args) _VariantCall::_bind_function(m_name, m_method, m_default_args, m_arg_names) -#else -#define bind_function(m_name, m_method, m_arg_names, m_default_args) _VariantCall::_bind_function(m_name, m_method, m_default_args) -#endif - - static void _bind_custom(Variant::Type p_type, const StringName &p_name, InternalMethodVC::MethodVC p_method, uint32_t p_flags, const Vector<Variant::Type> &p_argument_types, const Variant::Type &p_return_type -#ifdef DEBUG_ENABLED - , - const Vector<String> &p_argument_names = Vector<String>() -#endif - ) { - -#ifdef DEBUG_ENABLED - Variant::InternalMethod *m = memnew(InternalMethodVC(p_method, p_flags, p_argument_types, p_return_type, p_argument_names, p_name, p_type)); -#else - Variant::InternalMethod *m = memnew(InternalMethodVC(p_method, p_flags, p_argument_types, p_return_type)); -#endif - - type_internal_methods[p_type].insert(p_name, m); - type_internal_method_names[p_type].push_back(p_name); - } - -#ifdef DEBUG_ENABLED -#define bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type, m_arg_names) _VariantCall::_bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type, m_arg_names) -#else -#define bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type, m_arg_names) _VariantCall::_bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type) -#endif - - static String func_PackedByteArray_get_string_from_ascii(PackedByteArray *p_instance) { - String s; - if (p_instance->size() > 0) { - const uint8_t *r = p_instance->ptr(); - CharString cs; - cs.resize(p_instance->size() + 1); - copymem(cs.ptrw(), r, p_instance->size()); - cs[p_instance->size()] = 0; - - s = cs.get_data(); - } - return s; - } - - static String func_PackedByteArray_get_string_from_utf8(PackedByteArray *p_instance) { - String s; - if (p_instance->size() > 0) { - const uint8_t *r = p_instance->ptr(); - s.parse_utf8((const char *)r, p_instance->size()); - } - return s; - } - - static String func_PackedByteArray_get_string_from_utf16(PackedByteArray *p_instance) { - String s; - if (p_instance->size() > 0) { - const uint8_t *r = p_instance->ptr(); - s.parse_utf16((const char16_t *)r, p_instance->size() / 2); - } - return s; - } - - static String func_PackedByteArray_get_string_from_utf32(PackedByteArray *p_instance) { - String s; - if (p_instance->size() > 0) { - const uint8_t *r = p_instance->ptr(); - s = String((const char32_t *)r, p_instance->size() / 4); - } - return s; - } - - static PackedByteArray func_PackedByteArray_compress(PackedByteArray *p_instance, int p_mode) { - PackedByteArray compressed; - - if (p_instance->size() > 0) { - Compression::Mode mode = (Compression::Mode)(p_mode); - compressed.resize(Compression::get_max_compressed_buffer_size(p_instance->size(), mode)); - int result = Compression::compress(compressed.ptrw(), p_instance->ptr(), p_instance->size(), mode); - - result = result >= 0 ? result : 0; - compressed.resize(result); - } - - return compressed; - } - - static PackedByteArray func_PackedByteArray_decompress(PackedByteArray *p_instance, int64_t p_buffer_size, int p_mode) { - PackedByteArray decompressed; - Compression::Mode mode = (Compression::Mode)(p_mode); - - int64_t buffer_size = p_buffer_size; - - if (buffer_size <= 0) { - ERR_FAIL_V_MSG(decompressed, "Decompression buffer size must be greater than zero."); - } - - decompressed.resize(buffer_size); - int result = Compression::decompress(decompressed.ptrw(), buffer_size, p_instance->ptr(), p_instance->size(), mode); - - result = result >= 0 ? result : 0; - decompressed.resize(result); - - return decompressed; - } - - static PackedByteArray func_PackedByteArray_decompress_dynamic(PackedByteArray *p_instance, int64_t p_buffer_size, int p_mode) { - PackedByteArray decompressed; - int64_t max_output_size = p_buffer_size; - Compression::Mode mode = (Compression::Mode)(p_mode); - - int result = Compression::decompress_dynamic(&decompressed, max_output_size, p_instance->ptr(), p_instance->size(), mode); - - if (result == OK) { - return decompressed; - } else { - decompressed.clear(); - ERR_FAIL_V_MSG(decompressed, "Decompression failed."); - } - } - - static String func_PackedByteArray_hex_encode(PackedByteArray *p_instance) { - if (p_instance->size() == 0) { - return String(); - } - const uint8_t *r = p_instance->ptr(); - String s = String::hex_encode_buffer(&r[0], p_instance->size()); - return s; - } - - static void func_Callable_call(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - callable->call(p_args, p_argcount, r_ret, r_error); - } - - static void func_Callable_call_deferred(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - callable->call_deferred(p_args, p_argcount); - } - - static void func_Callable_bind(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); - r_ret = callable->bind(p_args, p_argcount); - } - - static void func_Signal_emit(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { - Signal *signal = VariantGetInternalPtr<Signal>::get_ptr(v); - signal->emit(p_args, p_argcount); - } - - struct ConstructData { - int arg_count; - Vector<Variant::Type> arg_types; - Vector<String> arg_names; - VariantConstructFunc func; - }; - - struct ConstructFunc { - List<ConstructData> constructors; - }; - - static ConstructFunc *construct_funcs; - - static void Vector2_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector2(*p_args[0], *p_args[1]); - } - - static void Vector2i_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector2i(*p_args[0], *p_args[1]); - } - - static void Rect2_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2(*p_args[0], *p_args[1]); - } - - static void Rect2_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Rect2i_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2i(*p_args[0], *p_args[1]); - } - - static void Rect2i_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2i(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Transform2D_init2(Variant &r_ret, const Variant **p_args) { - Transform2D m(*p_args[0], *p_args[1]); - r_ret = m; - } - - static void Transform2D_init3(Variant &r_ret, const Variant **p_args) { - Transform2D m; - m[0] = *p_args[0]; - m[1] = *p_args[1]; - m[2] = *p_args[2]; - r_ret = m; - } - - static void Vector3_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector3(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Vector3i_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector3i(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Plane_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Plane_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Plane_init3(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(p_args[0]->operator Vector3(), p_args[1]->operator real_t()); - } - static void Plane_init4(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(p_args[0]->operator Vector3(), p_args[1]->operator Vector3()); - } - - static void Quat_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Quat(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Quat_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Quat(((Vector3)(*p_args[0])), ((real_t)(*p_args[1]))); - } - - static void Quat_init3(Variant &r_ret, const Variant **p_args) { - r_ret = Quat(((Vector3)(*p_args[0]))); - } - - static void Color_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Color(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Color_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Color(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Color_init3(Variant &r_ret, const Variant **p_args) { - r_ret = Color::html(*p_args[0]); - } - - static void Color_init4(Variant &r_ret, const Variant **p_args) { - r_ret = Color::hex(*p_args[0]); - } - - static void Color_init5(Variant &r_ret, const Variant **p_args) { - r_ret = Color(((Color)(*p_args[0])), *p_args[1]); - } - - static void AABB_init1(Variant &r_ret, const Variant **p_args) { - r_ret = ::AABB(*p_args[0], *p_args[1]); - } - - static void Basis_init1(Variant &r_ret, const Variant **p_args) { - Basis m; - m.set_axis(0, *p_args[0]); - m.set_axis(1, *p_args[1]); - m.set_axis(2, *p_args[2]); - r_ret = m; - } - - static void Basis_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Basis(p_args[0]->operator Vector3(), p_args[1]->operator real_t()); - } - - static void Transform_init1(Variant &r_ret, const Variant **p_args) { - Transform t; - t.basis.set_axis(0, *p_args[0]); - t.basis.set_axis(1, *p_args[1]); - t.basis.set_axis(2, *p_args[2]); - t.origin = *p_args[3]; - r_ret = t; - } - - static void Transform_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Transform(p_args[0]->operator Basis(), p_args[1]->operator Vector3()); - } - - static void Callable_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Callable(p_args[0]->operator ObjectID(), p_args[1]->operator String()); - } - - static void Signal_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Signal(p_args[0]->operator ObjectID(), p_args[1]->operator String()); - } - - static void add_constructor(VariantConstructFunc p_func, const Variant::Type p_type, - const String &p_name1 = "", const Variant::Type p_type1 = Variant::NIL, - const String &p_name2 = "", const Variant::Type p_type2 = Variant::NIL, - const String &p_name3 = "", const Variant::Type p_type3 = Variant::NIL, - const String &p_name4 = "", const Variant::Type p_type4 = Variant::NIL) { - ConstructData cd; - cd.func = p_func; - cd.arg_count = 0; - - if (p_name1 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name1); - cd.arg_types.push_back(p_type1); - - if (p_name2 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name2); - cd.arg_types.push_back(p_type2); - - if (p_name3 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name3); - cd.arg_types.push_back(p_type3); - - if (p_name4 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name4); - cd.arg_types.push_back(p_type4); - - end: - - construct_funcs[p_type].constructors.push_back(cd); - } - - struct ConstantData { - Map<StringName, int> value; -#ifdef DEBUG_ENABLED - List<StringName> value_ordered; -#endif - Map<StringName, Variant> variant_value; -#ifdef DEBUG_ENABLED - List<StringName> variant_value_ordered; -#endif - }; - - static ConstantData *constant_data; - - static void add_constant(int p_type, StringName p_constant_name, int p_constant_value) { - constant_data[p_type].value[p_constant_name] = p_constant_value; -#ifdef DEBUG_ENABLED - constant_data[p_type].value_ordered.push_back(p_constant_name); -#endif - } - - static void add_variant_constant(int p_type, StringName p_constant_name, const Variant &p_constant_value) { - constant_data[p_type].variant_value[p_constant_name] = p_constant_value; -#ifdef DEBUG_ENABLED - constant_data[p_type].variant_value_ordered.push_back(p_constant_name); -#endif - } -}; - -_VariantCall::ConstructFunc *_VariantCall::construct_funcs = nullptr; -_VariantCall::ConstantData *_VariantCall::constant_data = nullptr; -_VariantCall::MethodMap *_VariantCall::type_internal_methods = nullptr; -List<StringName> *_VariantCall::type_internal_method_names = nullptr; - -Variant Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - Variant ret; - call_ptr(p_method, p_args, p_argcount, &ret, r_error); - return ret; -} - -void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, Callable::CallError &r_error) { - Variant ret; - - if (type == Variant::OBJECT) { - //call object - Object *obj = _get_obj().obj; - if (!obj) { - r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return; - } -#ifdef DEBUG_ENABLED - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return; - } - -#endif - ret = _get_obj().obj->call(p_method, p_args, p_argcount, r_error); - - //else if (type==Variant::METHOD) { - - } else { - r_error.error = Callable::CallError::CALL_OK; - - Variant::InternalMethod **m = _VariantCall::type_internal_methods[type].lookup_ptr(p_method); - - if (m) { - (*m)->call((Variant *)this, p_args, p_argcount, ret, r_error); - } else { - //ok fail because not found - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return; - } - } - - if (r_error.error == Callable::CallError::CALL_OK && r_ret) { - *r_ret = ret; - } -} - -#define VCALL(m_type, m_method) _VariantCall::_call_##m_type##_##m_method - -Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, Variant()); - - r_error.error = Callable::CallError::CALL_OK; - if (p_argcount == 0) { //generic construct - - switch (p_type) { - case NIL: - return Variant(); - - // atomic types - case BOOL: - return Variant(false); - case INT: - return 0; - case FLOAT: - return 0.0f; - case STRING: - return String(); - - // math types - case VECTOR2: - return Vector2(); - case VECTOR2I: - return Vector2i(); - case RECT2: - return Rect2(); - case RECT2I: - return Rect2i(); - case VECTOR3: - return Vector3(); - case VECTOR3I: - return Vector3i(); - case TRANSFORM2D: - return Transform2D(); - case PLANE: - return Plane(); - case QUAT: - return Quat(); - case AABB: - return ::AABB(); - case BASIS: - return Basis(); - case TRANSFORM: - return Transform(); - - // misc types - case COLOR: - return Color(); - case STRING_NAME: - return StringName(); - case NODE_PATH: - return NodePath(); - case _RID: - return RID(); - case OBJECT: - return (Object *)nullptr; - case CALLABLE: - return Callable(); - case SIGNAL: - return Signal(); - case DICTIONARY: - return Dictionary(); - case ARRAY: - return Array(); - case PACKED_BYTE_ARRAY: - return PackedByteArray(); - case PACKED_INT32_ARRAY: - return PackedInt32Array(); - case PACKED_INT64_ARRAY: - return PackedInt64Array(); - case PACKED_FLOAT32_ARRAY: - return PackedFloat32Array(); - case PACKED_FLOAT64_ARRAY: - return PackedFloat64Array(); - case PACKED_STRING_ARRAY: - return PackedStringArray(); - case PACKED_VECTOR2_ARRAY: - return PackedVector2Array(); - case PACKED_VECTOR3_ARRAY: - return PackedVector3Array(); - case PACKED_COLOR_ARRAY: - return PackedColorArray(); - default: - return Variant(); - } - - } else if (p_argcount == 1 && p_args[0]->type == p_type) { - return *p_args[0]; //copy construct - } else if (p_argcount == 1 && (!p_strict || Variant::can_convert(p_args[0]->type, p_type))) { - //near match construct - - switch (p_type) { - case NIL: { - return Variant(); - } break; - case BOOL: { - return Variant(bool(*p_args[0])); - } - case INT: { - return (int64_t(*p_args[0])); - } - case FLOAT: { - return double(*p_args[0]); - } - case STRING: { - return String(*p_args[0]); - } - case VECTOR2: { - return Vector2(*p_args[0]); - } - case VECTOR2I: { - return Vector2i(*p_args[0]); - } - case RECT2: - return (Rect2(*p_args[0])); - case RECT2I: - return (Rect2i(*p_args[0])); - case VECTOR3: - return (Vector3(*p_args[0])); - case VECTOR3I: - return (Vector3i(*p_args[0])); - case TRANSFORM2D: - return (Transform2D(p_args[0]->operator Transform2D())); - case PLANE: - return (Plane(*p_args[0])); - case QUAT: - return (p_args[0]->operator Quat()); - case AABB: - return (::AABB(*p_args[0])); - case BASIS: - return (Basis(p_args[0]->operator Basis())); - case TRANSFORM: - return (Transform(p_args[0]->operator Transform())); - - // misc types - case COLOR: - return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]); - case STRING_NAME: - return (StringName(p_args[0]->operator StringName())); - case NODE_PATH: - return (NodePath(p_args[0]->operator NodePath())); - case _RID: - return (RID(*p_args[0])); - case OBJECT: - return ((Object *)(p_args[0]->operator Object *())); - case CALLABLE: - return ((Callable)(p_args[0]->operator Callable())); - case SIGNAL: - return ((Signal)(p_args[0]->operator Signal())); - case DICTIONARY: - return p_args[0]->operator Dictionary(); - case ARRAY: - return p_args[0]->operator Array(); - - // arrays - case PACKED_BYTE_ARRAY: - return (PackedByteArray(*p_args[0])); - case PACKED_INT32_ARRAY: - return (PackedInt32Array(*p_args[0])); - case PACKED_INT64_ARRAY: - return (PackedInt64Array(*p_args[0])); - case PACKED_FLOAT32_ARRAY: - return (PackedFloat32Array(*p_args[0])); - case PACKED_FLOAT64_ARRAY: - return (PackedFloat64Array(*p_args[0])); - case PACKED_STRING_ARRAY: - return (PackedStringArray(*p_args[0])); - case PACKED_VECTOR2_ARRAY: - return (PackedVector2Array(*p_args[0])); - case PACKED_VECTOR3_ARRAY: - return (PackedVector3Array(*p_args[0])); - case PACKED_COLOR_ARRAY: - return (PackedColorArray(*p_args[0])); - default: - return Variant(); - } - } else if (p_argcount >= 1) { - _VariantCall::ConstructFunc &c = _VariantCall::construct_funcs[p_type]; - - for (List<_VariantCall::ConstructData>::Element *E = c.constructors.front(); E; E = E->next()) { - const _VariantCall::ConstructData &cd = E->get(); - - if (cd.arg_count != p_argcount) { - continue; - } - - //validate parameters - for (int i = 0; i < cd.arg_count; i++) { - if (!Variant::can_convert(p_args[i]->type, cd.arg_types[i])) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor - r_error.argument = i; - r_error.expected = cd.arg_types[i]; - return Variant(); - } - } - - Variant v; - cd.func(v, p_args); - return v; - } - } - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; //no such constructor - return Variant(); -} - -bool Variant::has_method(const StringName &p_method) const { - if (type == OBJECT) { - Object *obj = get_validated_object(); - if (!obj) { - return false; - } - - return obj->has_method(p_method); - } - - return _VariantCall::type_internal_methods[type].has(p_method); -} - -Vector<Variant::Type> Variant::get_method_argument_types(Variant::Type p_type, const StringName &p_method) { - Vector<Variant::Type> types; - - Variant::InternalMethod **m = _VariantCall::type_internal_methods[p_type].lookup_ptr(p_method); - if (*m) { - types.resize((*m)->get_argument_count()); - for (int i = 0; i < (*m)->get_argument_count(); i++) { - types.write[i] = (*m)->get_argument_type(i); - } - } - - return types; -} - -bool Variant::is_method_const(Variant::Type p_type, const StringName &p_method) { - Variant::InternalMethod **m = _VariantCall::type_internal_methods[p_type].lookup_ptr(p_method); - if (*m) { - return (*m)->get_flags() & Variant::InternalMethod::FLAG_IS_CONST; - } - return false; -} - -Vector<StringName> Variant::get_method_argument_names(Variant::Type p_type, const StringName &p_method) { - Vector<StringName> argnames; - -#ifdef DEBUG_ENABLED - Variant::InternalMethod **m = _VariantCall::type_internal_methods[p_type].lookup_ptr(p_method); - if (*m) { - argnames.resize((*m)->get_argument_count()); - for (int i = 0; i < (*m)->get_argument_count(); i++) { - argnames.write[i] = (*m)->get_argument_name(i); - } - } -#endif - return argnames; -} - -Variant::Type Variant::get_method_return_type(Variant::Type p_type, const StringName &p_method, bool *r_has_return) { - Variant::Type rt = Variant::NIL; - Variant::InternalMethod **m = _VariantCall::type_internal_methods[p_type].lookup_ptr(p_method); - if (*m) { - rt = (*m)->get_return_type(); - if (r_has_return) { - *r_has_return = ((*m)->get_flags() & Variant::InternalMethod::FLAG_RETURNS_VARIANT) || rt != Variant::NIL; - } - } - return rt; -} - -Vector<Variant> Variant::get_method_default_arguments(Variant::Type p_type, const StringName &p_method) { - Variant::InternalMethod **m = _VariantCall::type_internal_methods[p_type].lookup_ptr(p_method); - if (*m) { - return (*m)->get_default_arguments(); - } - return Vector<Variant>(); -} - -void Variant::get_method_list(List<MethodInfo> *p_list) const { - for (List<StringName>::Element *E = _VariantCall::type_internal_method_names[type].front(); E; E = E->next()) { - Variant::InternalMethod **m = _VariantCall::type_internal_methods[type].lookup_ptr(E->get()); - ERR_CONTINUE(!*m); - - MethodInfo mi; - mi.name = E->get(); - mi.return_val.type = (*m)->get_return_type(); - if ((*m)->get_flags() & Variant::InternalMethod::FLAG_RETURNS_VARIANT) { - mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; - } - if ((*m)->get_flags() & Variant::InternalMethod::FLAG_IS_CONST) { - mi.flags |= METHOD_FLAG_CONST; - } - if ((*m)->get_flags() & Variant::InternalMethod::FLAG_VARARGS) { - mi.flags |= METHOD_FLAG_VARARG; - } - - for (int i = 0; i < (*m)->get_argument_count(); i++) { - PropertyInfo arg; -#ifdef DEBUG_ENABLED - arg.name = (*m)->get_argument_name(i); -#else - arg.name = "arg" + itos(i + 1); -#endif - arg.type = (*m)->get_argument_type(i); - mi.arguments.push_back(arg); - } - - mi.default_arguments = (*m)->get_default_arguments(); - p_list->push_back(mi); - } -} - -void Variant::get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list) { - ERR_FAIL_INDEX(p_type, VARIANT_MAX); - - //custom constructors - for (const List<_VariantCall::ConstructData>::Element *E = _VariantCall::construct_funcs[p_type].constructors.front(); E; E = E->next()) { - const _VariantCall::ConstructData &cd = E->get(); - MethodInfo mi; - mi.name = Variant::get_type_name(p_type); - mi.return_val.type = p_type; - for (int i = 0; i < cd.arg_count; i++) { - PropertyInfo pi; - pi.name = cd.arg_names[i]; - pi.type = cd.arg_types[i]; - mi.arguments.push_back(pi); - } - p_list->push_back(mi); - } - //default constructors - for (int i = 0; i < VARIANT_MAX; i++) { - if (i == p_type) { - continue; - } - if (!Variant::can_convert(Variant::Type(i), p_type)) { - continue; - } - - MethodInfo mi; - mi.name = Variant::get_type_name(p_type); - PropertyInfo pi; - pi.name = "from"; - pi.type = Variant::Type(i); - mi.arguments.push_back(pi); - mi.return_val.type = p_type; - p_list->push_back(mi); - } -} - -void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants) { - ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); - - _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; - -#ifdef DEBUG_ENABLED - for (List<StringName>::Element *E = cd.value_ordered.front(); E; E = E->next()) { - p_constants->push_back(E->get()); -#else - for (Map<StringName, int>::Element *E = cd.value.front(); E; E = E->next()) { - p_constants->push_back(E->key()); -#endif - } - -#ifdef DEBUG_ENABLED - for (List<StringName>::Element *E = cd.variant_value_ordered.front(); E; E = E->next()) { - p_constants->push_back(E->get()); -#else - for (Map<StringName, Variant>::Element *E = cd.variant_value.front(); E; E = E->next()) { - p_constants->push_back(E->key()); -#endif - } -} - -bool Variant::has_constant(Variant::Type p_type, const StringName &p_value) { - ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); - _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; - return cd.value.has(p_value) || cd.variant_value.has(p_value); -} - -Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid) { - if (r_valid) { - *r_valid = false; - } - - ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0); - _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; - - Map<StringName, int>::Element *E = cd.value.find(p_value); - if (!E) { - Map<StringName, Variant>::Element *F = cd.variant_value.find(p_value); - if (F) { - if (r_valid) { - *r_valid = true; - } - return F->get(); - } else { - return -1; - } - } - if (r_valid) { - *r_valid = true; - } - - return E->get(); -} - -Variant::InternalMethod *Variant::get_internal_method(Type p_type, const StringName &p_method_name) { - ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr); - - Variant::InternalMethod **m = _VariantCall::type_internal_methods[p_type].lookup_ptr(p_method_name); - if (*m) { - return *m; - } - return nullptr; -} - -void register_variant_methods() { - _VariantCall::type_internal_methods = memnew_arr(_VariantCall::MethodMap, Variant::VARIANT_MAX); - _VariantCall::type_internal_method_names = memnew_arr(List<StringName>, Variant::VARIANT_MAX); - _VariantCall::construct_funcs = memnew_arr(_VariantCall::ConstructFunc, Variant::VARIANT_MAX); - _VariantCall::constant_data = memnew_arr(_VariantCall::ConstantData, Variant::VARIANT_MAX); - - /* STRING */ - - bind_method(String, casecmp_to, sarray("to"), varray()); - bind_method(String, nocasecmp_to, sarray("to"), varray()); - bind_method(String, naturalnocasecmp_to, sarray("to"), varray()); - bind_method(String, length, sarray(), varray()); - bind_method(String, substr, sarray("from", "len"), varray(-1)); - bind_methodv(find, static_cast<int (String::*)(const String &, int) const>(&String::find), sarray("what", "from"), varray(0)); - bind_method(String, count, sarray("what", "from", "to"), varray(0, 0)); - bind_method(String, countn, sarray("what", "from", "to"), varray(0, 0)); - bind_method(String, findn, sarray("what", "from"), varray(0)); - bind_method(String, rfind, sarray("what", "from"), varray(-1)); - bind_method(String, rfindn, sarray("what", "from"), varray(-1)); - bind_method(String, match, sarray("expr"), varray()); - bind_method(String, matchn, sarray("expr"), varray()); - bind_methodv(begins_with, static_cast<bool (String::*)(const String &) const>(&String::begins_with), sarray("text"), varray()); - bind_method(String, ends_with, sarray("text"), varray()); - bind_method(String, is_subsequence_of, sarray("text"), varray()); - bind_method(String, is_subsequence_ofi, sarray("text"), varray()); - bind_method(String, bigrams, sarray(), varray()); - bind_method(String, similarity, sarray("text"), varray()); - - bind_method(String, format, sarray("values", "placeholder"), varray("{_}")); - bind_methodv(replace, static_cast<String (String::*)(const String &, const String &) const>(&String::replace), sarray("what", "forwhat"), varray()); - bind_method(String, replacen, sarray("what", "forwhat"), varray()); - bind_method(String, repeat, sarray("count"), varray()); - bind_method(String, insert, sarray("position", "what"), varray()); - bind_method(String, capitalize, sarray(), varray()); - bind_method(String, split, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0)); - bind_method(String, rsplit, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0)); - bind_method(String, split_floats, sarray("delimiter", "allow_empty"), varray(true)); - bind_method(String, join, sarray("parts"), varray()); - - bind_method(String, to_upper, sarray(), varray()); - bind_method(String, to_lower, sarray(), varray()); - - bind_method(String, left, sarray("position"), varray()); - bind_method(String, right, sarray("position"), varray()); - - bind_method(String, strip_edges, sarray("left", "right"), varray(true, true)); - bind_method(String, strip_escapes, sarray(), varray()); - bind_method(String, lstrip, sarray("chars"), varray()); - bind_method(String, rstrip, sarray("chars"), varray()); - bind_method(String, get_extension, sarray(), varray()); - bind_method(String, get_basename, sarray(), varray()); - bind_method(String, plus_file, sarray("file"), varray()); - bind_method(String, ord_at, sarray("at"), varray()); - bind_method(String, dedent, sarray(), varray()); - //string needs to be immutable when binding - //bind_method(String, erase, sarray("position", "chars"), varray()); - bind_method(String, hash, sarray(), varray()); - bind_method(String, md5_text, sarray(), varray()); - bind_method(String, sha1_text, sarray(), varray()); - bind_method(String, sha256_text, sarray(), varray()); - bind_method(String, md5_buffer, sarray(), varray()); - bind_method(String, sha1_buffer, sarray(), varray()); - bind_method(String, sha256_buffer, sarray(), varray()); - bind_method(String, empty, sarray(), varray()); - //static function, not sure how to bind - //bind_method(String, humanize_size, sarray("size"), varray()); - - bind_method(String, is_abs_path, sarray(), varray()); - bind_method(String, is_rel_path, sarray(), varray()); - bind_method(String, get_base_dir, sarray(), varray()); - bind_method(String, get_file, sarray(), varray()); - bind_method(String, xml_escape, sarray("escape_quotes"), varray(false)); - bind_method(String, xml_unescape, sarray(), varray()); - bind_method(String, http_escape, sarray(), varray()); - bind_method(String, http_unescape, sarray(), varray()); - bind_method(String, c_escape, sarray(), varray()); - bind_method(String, c_unescape, sarray(), varray()); - bind_method(String, json_escape, sarray(), varray()); - bind_method(String, percent_encode, sarray(), varray()); - bind_method(String, percent_decode, sarray(), varray()); - - bind_method(String, is_valid_identifier, sarray(), varray()); - bind_method(String, is_valid_integer, sarray(), varray()); - bind_method(String, is_valid_float, sarray(), varray()); - bind_method(String, is_valid_hex_number, sarray("with_prefix"), varray(false)); - bind_method(String, is_valid_html_color, sarray(), varray()); - bind_method(String, is_valid_ip_address, sarray(), varray()); - bind_method(String, is_valid_filename, sarray(), varray()); - - bind_method(String, to_int, sarray(), varray()); - bind_method(String, to_float, sarray(), varray()); - bind_method(String, hex_to_int, sarray("with_prefix"), varray(true)); - bind_method(String, bin_to_int, sarray("with_prefix"), varray(true)); - - bind_method(String, lpad, sarray("min_length", "character"), varray(" ")); - bind_method(String, rpad, sarray("min_length", "character"), varray(" ")); - bind_method(String, pad_decimals, sarray("digits"), varray()); - bind_method(String, pad_zeros, sarray("digits"), varray()); - bind_method(String, trim_prefix, sarray("prefix"), varray()); - bind_method(String, trim_suffix, sarray("suffix"), varray()); - - bind_method(String, to_ascii_buffer, sarray(), varray()); - bind_method(String, to_utf8_buffer, sarray(), varray()); - bind_method(String, to_utf16_buffer, sarray(), varray()); - bind_method(String, to_utf32_buffer, sarray(), varray()); - - /* VECTOR2 */ - - bind_method(Vector2, angle, sarray(), varray()); - bind_method(Vector2, angle_to, sarray("to"), varray()); - bind_method(Vector2, angle_to_point, sarray("to"), varray()); - bind_method(Vector2, direction_to, sarray("b"), varray()); - bind_method(Vector2, distance_to, sarray("to"), varray()); - bind_method(Vector2, distance_squared_to, sarray("to"), varray()); - bind_method(Vector2, length, sarray(), varray()); - bind_method(Vector2, length_squared, sarray(), varray()); - bind_method(Vector2, normalized, sarray(), varray()); - bind_method(Vector2, is_normalized, sarray(), varray()); - bind_method(Vector2, is_equal_approx, sarray("to"), varray()); - bind_method(Vector2, posmod, sarray("mod"), varray()); - bind_method(Vector2, posmodv, sarray("modv"), varray()); - bind_method(Vector2, project, sarray("b"), varray()); - bind_method(Vector2, lerp, sarray("with", "t"), varray()); - bind_method(Vector2, slerp, sarray("with", "t"), varray()); - bind_method(Vector2, cubic_interpolate, sarray("b", "pre_a", "post_b", "t"), varray()); - bind_method(Vector2, move_toward, sarray("to", "delta"), varray()); - bind_method(Vector2, rotated, sarray("phi"), varray()); - bind_method(Vector2, tangent, sarray(), varray()); - bind_method(Vector2, floor, sarray(), varray()); - bind_method(Vector2, ceil, sarray(), varray()); - bind_method(Vector2, round, sarray(), varray()); - bind_method(Vector2, aspect, sarray(), varray()); - bind_method(Vector2, dot, sarray("with"), varray()); - bind_method(Vector2, slide, sarray("n"), varray()); - bind_method(Vector2, bounce, sarray("n"), varray()); - bind_method(Vector2, reflect, sarray("n"), varray()); - bind_method(Vector2, cross, sarray("with"), varray()); - bind_method(Vector2, abs, sarray(), varray()); - bind_method(Vector2, sign, sarray(), varray()); - bind_method(Vector2, clamped, sarray("length"), varray()); - - /* VECTOR2I */ - - bind_method(Vector2i, aspect, sarray(), varray()); - bind_method(Vector2i, sign, sarray(), varray()); - bind_method(Vector2i, abs, sarray(), varray()); - - /* RECT2 */ - - bind_method(Rect2, get_area, sarray(), varray()); - bind_method(Rect2, has_no_area, sarray(), varray()); - bind_method(Rect2, has_point, sarray("point"), varray()); - bind_method(Rect2, is_equal_approx, sarray("rect"), varray()); - bind_method(Rect2, intersects, sarray("b", "include_borders"), varray(false)); - bind_method(Rect2, encloses, sarray("b"), varray()); - bind_method(Rect2, clip, sarray("b"), varray()); - bind_method(Rect2, merge, sarray("b"), varray()); - bind_method(Rect2, expand, sarray("to"), varray()); - bind_method(Rect2, grow, sarray("by"), varray()); - bind_methodv(grow_margin, &Rect2::grow_margin_bind, sarray("margin", "by"), varray()); - bind_method(Rect2, grow_individual, sarray("left", "top", "right", "bottom"), varray()); - bind_method(Rect2, abs, sarray(), varray()); - - /* Rect2i */ - - bind_method(Rect2i, get_area, sarray(), varray()); - bind_method(Rect2i, has_no_area, sarray(), varray()); - bind_method(Rect2i, has_point, sarray("point"), varray()); - bind_method(Rect2i, intersects, sarray("b"), varray()); - bind_method(Rect2i, encloses, sarray("b"), varray()); - bind_method(Rect2i, clip, sarray("b"), varray()); - bind_method(Rect2i, merge, sarray("b"), varray()); - bind_method(Rect2i, expand, sarray("to"), varray()); - bind_method(Rect2i, grow, sarray("by"), varray()); - bind_methodv(grow_margin, &Rect2i::grow_margin_bind, sarray("margin", "by"), varray()); - bind_method(Rect2i, grow_individual, sarray("left", "top", "right", "bottom"), varray()); - bind_method(Rect2i, abs, sarray(), varray()); - - /* Vector3 */ - - bind_method(Vector3, min_axis, sarray(), varray()); - bind_method(Vector3, max_axis, sarray(), varray()); - bind_method(Vector3, angle_to, sarray("to"), varray()); - bind_method(Vector3, direction_to, sarray("b"), varray()); - bind_method(Vector3, distance_to, sarray("b"), varray()); - bind_method(Vector3, distance_squared_to, sarray("b"), varray()); - bind_method(Vector3, length, sarray(), varray()); - bind_method(Vector3, length_squared, sarray(), varray()); - bind_method(Vector3, normalized, sarray(), varray()); - bind_method(Vector3, is_normalized, sarray(), varray()); - bind_method(Vector3, is_equal_approx, sarray("to"), varray()); - bind_method(Vector3, inverse, sarray(), varray()); - bind_method(Vector3, snapped, sarray("by"), varray()); - bind_method(Vector3, rotated, sarray("by_axis", "phi"), varray()); - bind_method(Vector3, lerp, sarray("b", "t"), varray()); - bind_method(Vector3, slerp, sarray("b", "t"), varray()); - bind_method(Vector3, cubic_interpolate, sarray("b", "pre_a", "post_b", "t"), varray()); - bind_method(Vector3, move_toward, sarray("to", "delta"), varray()); - bind_method(Vector3, dot, sarray("with"), varray()); - bind_method(Vector3, cross, sarray("with"), varray()); - bind_method(Vector3, outer, sarray("with"), varray()); - bind_method(Vector3, to_diagonal_matrix, sarray(), varray()); - bind_method(Vector3, abs, sarray(), varray()); - bind_method(Vector3, floor, sarray(), varray()); - bind_method(Vector3, ceil, sarray(), varray()); - bind_method(Vector3, round, sarray(), varray()); - bind_method(Vector3, posmod, sarray("mod"), varray()); - bind_method(Vector3, posmodv, sarray("modv"), varray()); - bind_method(Vector3, project, sarray("b"), varray()); - bind_method(Vector3, slide, sarray("n"), varray()); - bind_method(Vector3, bounce, sarray("n"), varray()); - bind_method(Vector3, reflect, sarray("n"), varray()); - bind_method(Vector3, sign, sarray(), varray()); - - /* Vector3i */ - - bind_method(Vector3i, min_axis, sarray(), varray()); - bind_method(Vector3i, max_axis, sarray(), varray()); - bind_method(Vector3i, sign, sarray(), varray()); - bind_method(Vector3i, abs, sarray(), varray()); - - /* Plane */ - - bind_method(Plane, normalized, sarray(), varray()); - bind_method(Plane, center, sarray(), varray()); - bind_method(Plane, is_equal_approx, sarray("to_plane"), varray()); - bind_method(Plane, is_point_over, sarray("plane"), varray()); - bind_method(Plane, distance_to, sarray("point"), varray()); - bind_method(Plane, has_point, sarray("point", "epsilon"), varray(CMP_EPSILON)); - bind_method(Plane, project, sarray("point"), varray()); - bind_methodv(intersect_3, &Plane::intersect_3_bind, sarray("b", "c"), varray()); - bind_methodv(intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray()); - bind_methodv(intersects_segment, &Plane::intersects_segment_bind, sarray("from", "to"), varray()); - - /* Quaternion */ - - bind_method(Quat, length, sarray(), varray()); - bind_method(Quat, length_squared, sarray(), varray()); - bind_method(Quat, normalized, sarray(), varray()); - bind_method(Quat, is_normalized, sarray(), varray()); - bind_method(Quat, is_equal_approx, sarray("to"), varray()); - bind_method(Quat, inverse, sarray(), varray()); - bind_method(Quat, dot, sarray("with"), varray()); - bind_method(Quat, xform, sarray("v3"), varray()); - bind_method(Quat, slerp, sarray("b", "t"), varray()); - bind_method(Quat, slerpni, sarray("b", "t"), varray()); - bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "t"), varray()); - bind_method(Quat, get_euler, sarray(), varray()); - - //Quat is atomic, this should be done via construcror - //ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray()); - //ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", FLOAT, "angle", varray()); - - /* Color */ - - bind_method(Color, to_argb32, sarray(), varray()); - bind_method(Color, to_abgr32, sarray(), varray()); - bind_method(Color, to_rgba32, sarray(), varray()); - bind_method(Color, to_argb64, sarray(), varray()); - bind_method(Color, to_abgr64, sarray(), varray()); - bind_method(Color, to_rgba64, sarray(), varray()); - - bind_method(Color, inverted, sarray(), varray()); - bind_method(Color, contrasted, sarray(), varray()); - bind_method(Color, lerp, sarray("b", "t"), varray()); - bind_method(Color, lightened, sarray("amount"), varray()); - bind_method(Color, darkened, sarray("amount"), varray()); - bind_method(Color, to_html, sarray("with_alpha"), varray(true)); - bind_method(Color, blend, sarray("over"), varray()); - - //Color is immutable, need to probably find a way to do this via constructor - //ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0)); - bind_method(Color, is_equal_approx, sarray("to"), varray()); - - /* RID */ - - bind_method(RID, get_id, sarray(), varray()); - - /* NodePath */ - - bind_method(NodePath, is_absolute, sarray(), varray()); - bind_method(NodePath, get_name_count, sarray(), varray()); - bind_method(NodePath, get_name, sarray("idx"), varray()); - bind_method(NodePath, get_subname_count, sarray(), varray()); - bind_method(NodePath, get_subname, sarray("idx"), varray()); - bind_method(NodePath, get_concatenated_subnames, sarray(), varray()); - bind_method(NodePath, get_as_property_path, sarray(), varray()); - bind_method(NodePath, is_empty, sarray(), varray()); - - /* Callable */ - - bind_method(Callable, is_null, sarray(), varray()); - bind_method(Callable, is_custom, sarray(), varray()); - bind_method(Callable, is_standard, sarray(), varray()); - bind_method(Callable, get_object, sarray(), varray()); - bind_method(Callable, get_object_id, sarray(), varray()); - bind_method(Callable, get_method, sarray(), varray()); - bind_method(Callable, hash, sarray(), varray()); - bind_method(Callable, unbind, sarray("argcount"), varray()); - - //#define bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type, m_arg_names) _VariantCall::_bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type) - - bind_custom(Variant::CALLABLE, "call", _VariantCall::func_Callable_call, Variant::InternalMethod::FLAG_VARARGS | Variant::InternalMethod::FLAG_RETURNS_VARIANT, Vector<Variant::Type>(), Variant::NIL, sarray()); - bind_custom(Variant::CALLABLE, "call_deferred", _VariantCall::func_Callable_call_deferred, Variant::InternalMethod::FLAG_VARARGS, Vector<Variant::Type>(), Variant::NIL, sarray()); - bind_custom(Variant::CALLABLE, "bind", _VariantCall::func_Callable_bind, Variant::InternalMethod::FLAG_VARARGS, Vector<Variant::Type>(), Variant::CALLABLE, sarray()); - - /* Signal */ - - bind_method(Signal, is_null, sarray(), varray()); - bind_method(Signal, get_object, sarray(), varray()); - bind_method(Signal, get_object_id, sarray(), varray()); - bind_method(Signal, get_name, sarray(), varray()); - - bind_method(Signal, connect, sarray("callable", "binds", "flags"), varray(Array(), 0)); - bind_method(Signal, disconnect, sarray("callable"), varray()); - bind_method(Signal, is_connected, sarray("callable"), varray()); - bind_method(Signal, get_connections, sarray(), varray()); - - bind_custom(Variant::SIGNAL, "emit", _VariantCall::func_Signal_emit, Variant::InternalMethod::FLAG_VARARGS, Vector<Variant::Type>(), Variant::NIL, sarray()); - - /* Transform2D */ - - bind_method(Transform2D, inverse, sarray(), varray()); - bind_method(Transform2D, affine_inverse, sarray(), varray()); - bind_method(Transform2D, get_rotation, sarray(), varray()); - bind_method(Transform2D, get_origin, sarray(), varray()); - bind_method(Transform2D, get_scale, sarray(), varray()); - bind_method(Transform2D, orthonormalized, sarray(), varray()); - bind_method(Transform2D, rotated, sarray("phi"), varray()); - bind_method(Transform2D, scaled, sarray("scale"), varray()); - bind_method(Transform2D, translated, sarray("offset"), varray()); - //too complex to bind this, operator * should be used instead - //ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform, NIL, "v", varray()); - //ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform_inv, NIL, "v", varray()); - bind_method(Transform2D, basis_xform, sarray("v"), varray()); - bind_method(Transform2D, basis_xform_inv, sarray("v"), varray()); - bind_method(Transform2D, interpolate_with, sarray("xform", "t"), varray()); - bind_method(Transform2D, is_equal_approx, sarray("xform"), varray()); - - /* Basis */ - - bind_method(Basis, inverse, sarray(), varray()); - bind_method(Basis, transposed, sarray(), varray()); - bind_method(Basis, orthonormalized, sarray(), varray()); - bind_method(Basis, determinant, sarray(), varray()); - bind_methodv(rotated, static_cast<Basis (Basis::*)(const Vector3 &, float) const>(&Basis::rotated), sarray("axis", "phi"), varray()); - bind_method(Basis, scaled, sarray("scale"), varray()); - bind_method(Basis, get_scale, sarray(), varray()); - bind_method(Basis, get_euler, sarray(), varray()); - bind_method(Basis, tdotx, sarray("with"), varray()); - bind_method(Basis, tdoty, sarray("with"), varray()); - bind_method(Basis, tdotz, sarray("with"), varray()); - //use the operators instead - //ADDFUNC1R(BASIS, VECTOR3, Basis, xform, VECTOR3, "v", varray()); - //ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, VECTOR3, "v", varray()); - bind_method(Basis, get_orthogonal_index, sarray(), varray()); - bind_method(Basis, slerp, sarray("b", "t"), varray()); - bind_method(Basis, is_equal_approx, sarray("b"), varray()); - bind_method(Basis, get_rotation_quat, sarray(), varray()); - - /* AABB */ - - bind_method(::AABB, abs, sarray(), varray()); - bind_method(::AABB, get_area, sarray(), varray()); - bind_method(::AABB, has_no_area, sarray(), varray()); - bind_method(::AABB, has_no_surface, sarray(), varray()); - bind_method(::AABB, has_point, sarray("point"), varray()); - bind_method(::AABB, is_equal_approx, sarray("aabb"), varray()); - bind_method(::AABB, intersects, sarray("with"), varray()); - bind_method(::AABB, encloses, sarray("with"), varray()); - bind_method(::AABB, intersects_plane, sarray("plane"), varray()); - bind_method(::AABB, intersection, sarray("with"), varray()); - bind_method(::AABB, merge, sarray("with"), varray()); - bind_method(::AABB, expand, sarray("to_point"), varray()); - bind_method(::AABB, grow, sarray("by"), varray()); - bind_method(::AABB, get_support, sarray("dir"), varray()); - bind_method(::AABB, get_longest_axis, sarray(), varray()); - bind_method(::AABB, get_longest_axis_index, sarray(), varray()); - bind_method(::AABB, get_longest_axis_size, sarray(), varray()); - bind_method(::AABB, get_shortest_axis, sarray(), varray()); - bind_method(::AABB, get_shortest_axis_index, sarray(), varray()); - bind_method(::AABB, get_shortest_axis_size, sarray(), varray()); - bind_method(::AABB, get_endpoint, sarray("idx"), varray()); - bind_methodv(intersects_segment, &AABB::intersects_segment_bind, sarray("from", "to"), varray()); - bind_methodv(intersects_ray, &AABB::intersects_ray_bind, sarray("from", "dir"), varray()); - - /* Transform */ - - bind_method(Transform, inverse, sarray(), varray()); - bind_method(Transform, affine_inverse, sarray(), varray()); - bind_method(Transform, orthonormalized, sarray(), varray()); - bind_method(Transform, rotated, sarray("axis", "phi"), varray()); - bind_method(Transform, scaled, sarray("scale"), varray()); - bind_method(Transform, translated, sarray("offset"), varray()); - bind_method(Transform, looking_at, sarray("target", "up"), varray()); - bind_method(Transform, interpolate_with, sarray("xform", "weight"), varray()); - bind_method(Transform, is_equal_approx, sarray("xform"), varray()); - //use the operators instead - //ADDFUNC1R(TRANSFORM, NIL, Transform, xform, NIL, "v", varray()); - //ADDFUNC1R(TRANSFORM, NIL, Transform, xform_inv, NIL, "v", varray()); - - /* Dictionary */ - - bind_method(Dictionary, size, sarray(), varray()); - bind_method(Dictionary, empty, sarray(), varray()); - bind_method(Dictionary, clear, sarray(), varray()); - bind_method(Dictionary, has, sarray("key"), varray()); - bind_method(Dictionary, has_all, sarray("keys"), varray()); - bind_method(Dictionary, erase, sarray("key"), varray()); - bind_method(Dictionary, hash, sarray(), varray()); - bind_method(Dictionary, keys, sarray(), varray()); - bind_method(Dictionary, values, sarray(), varray()); - bind_method(Dictionary, duplicate, sarray("deep"), varray(false)); - bind_method(Dictionary, get, sarray("key", "default"), varray(Variant())); - - /* Array */ - - bind_method(Array, size, sarray(), varray()); - bind_method(Array, empty, sarray(), varray()); - bind_method(Array, clear, sarray(), varray()); - bind_method(Array, hash, sarray(), varray()); - bind_method(Array, push_back, sarray("value"), varray()); - bind_method(Array, push_front, sarray("value"), varray()); - bind_method(Array, append, sarray("value"), varray()); - bind_method(Array, resize, sarray("size"), varray()); - bind_method(Array, insert, sarray("position", "value"), varray()); - bind_method(Array, remove, sarray("position"), varray()); - bind_method(Array, erase, sarray("value"), varray()); - bind_method(Array, front, sarray(), varray()); - bind_method(Array, back, sarray(), varray()); - bind_method(Array, find, sarray("what", "from"), varray(0)); - bind_method(Array, rfind, sarray("what", "from"), varray(-1)); - bind_method(Array, find_last, sarray("value"), varray()); - bind_method(Array, count, sarray("value"), varray()); - bind_method(Array, has, sarray("value"), varray()); - bind_method(Array, pop_back, sarray(), varray()); - bind_method(Array, pop_front, sarray(), varray()); - bind_method(Array, sort, sarray(), varray()); - bind_method(Array, sort_custom, sarray("obj", "func"), varray()); - bind_method(Array, shuffle, sarray(), varray()); - bind_method(Array, bsearch, sarray("value", "before"), varray(true)); - bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true)); - bind_method(Array, invert, sarray(), varray()); - bind_method(Array, duplicate, sarray("deep"), varray(false)); - bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); - bind_method(Array, max, sarray(), varray()); - bind_method(Array, min, sarray(), varray()); - - /* Byte Array */ - bind_method(PackedByteArray, size, sarray(), varray()); - bind_method(PackedByteArray, empty, sarray(), varray()); - bind_method(PackedByteArray, set, sarray("index", "value"), varray()); - bind_method(PackedByteArray, push_back, sarray("value"), varray()); - bind_method(PackedByteArray, append, sarray("value"), varray()); - bind_method(PackedByteArray, append_array, sarray("array"), varray()); - bind_method(PackedByteArray, remove, sarray("index"), varray()); - bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray()); - bind_method(PackedByteArray, resize, sarray("new_size"), varray()); - bind_method(PackedByteArray, has, sarray("value"), varray()); - bind_method(PackedByteArray, invert, sarray(), varray()); - bind_method(PackedByteArray, subarray, sarray("from", "to"), varray()); - bind_method(PackedByteArray, sort, sarray(), varray()); - - bind_function("get_string_from_ascii", _VariantCall::func_PackedByteArray_get_string_from_ascii, sarray(), varray()); - bind_function("get_string_from_utf8", _VariantCall::func_PackedByteArray_get_string_from_utf8, sarray(), varray()); - bind_function("get_string_from_utf16", _VariantCall::func_PackedByteArray_get_string_from_utf16, sarray(), varray()); - bind_function("get_string_from_utf32", _VariantCall::func_PackedByteArray_get_string_from_utf32, sarray(), varray()); - bind_function("hex_encode", _VariantCall::func_PackedByteArray_hex_encode, sarray(), varray()); - bind_function("compress", _VariantCall::func_PackedByteArray_compress, sarray("compression_mode"), varray(0)); - bind_function("decompress", _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray(0)); - bind_function("decompress_dynamic", _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray(0)); - - /* Int32 Array */ - - bind_method(PackedInt32Array, size, sarray(), varray()); - bind_method(PackedInt32Array, empty, sarray(), varray()); - bind_method(PackedInt32Array, set, sarray("index", "value"), varray()); - bind_method(PackedInt32Array, push_back, sarray("value"), varray()); - bind_method(PackedInt32Array, append, sarray("value"), varray()); - bind_method(PackedInt32Array, append_array, sarray("array"), varray()); - bind_method(PackedInt32Array, remove, sarray("index"), varray()); - bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray()); - bind_method(PackedInt32Array, resize, sarray("new_size"), varray()); - bind_method(PackedInt32Array, has, sarray("value"), varray()); - bind_method(PackedInt32Array, invert, sarray(), varray()); - bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray()); - bind_method(PackedInt32Array, to_byte_array, sarray(), varray()); - bind_method(PackedInt32Array, sort, sarray(), varray()); - - /* Int64 Array */ - - bind_method(PackedInt64Array, size, sarray(), varray()); - bind_method(PackedInt64Array, empty, sarray(), varray()); - bind_method(PackedInt64Array, set, sarray("index", "value"), varray()); - bind_method(PackedInt64Array, push_back, sarray("value"), varray()); - bind_method(PackedInt64Array, append, sarray("value"), varray()); - bind_method(PackedInt64Array, append_array, sarray("array"), varray()); - bind_method(PackedInt64Array, remove, sarray("index"), varray()); - bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray()); - bind_method(PackedInt64Array, resize, sarray("new_size"), varray()); - bind_method(PackedInt64Array, has, sarray("value"), varray()); - bind_method(PackedInt64Array, invert, sarray(), varray()); - bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray()); - bind_method(PackedInt64Array, to_byte_array, sarray(), varray()); - bind_method(PackedInt64Array, sort, sarray(), varray()); - - /* Float32 Array */ - - bind_method(PackedFloat32Array, size, sarray(), varray()); - bind_method(PackedFloat32Array, empty, sarray(), varray()); - bind_method(PackedFloat32Array, set, sarray("index", "value"), varray()); - bind_method(PackedFloat32Array, push_back, sarray("value"), varray()); - bind_method(PackedFloat32Array, append, sarray("value"), varray()); - bind_method(PackedFloat32Array, append_array, sarray("array"), varray()); - bind_method(PackedFloat32Array, remove, sarray("index"), varray()); - bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray()); - bind_method(PackedFloat32Array, resize, sarray("new_size"), varray()); - bind_method(PackedFloat32Array, has, sarray("value"), varray()); - bind_method(PackedFloat32Array, invert, sarray(), varray()); - bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray()); - bind_method(PackedFloat32Array, to_byte_array, sarray(), varray()); - bind_method(PackedFloat32Array, sort, sarray(), varray()); - - /* Float64 Array */ - - bind_method(PackedFloat64Array, size, sarray(), varray()); - bind_method(PackedFloat64Array, empty, sarray(), varray()); - bind_method(PackedFloat64Array, set, sarray("index", "value"), varray()); - bind_method(PackedFloat64Array, push_back, sarray("value"), varray()); - bind_method(PackedFloat64Array, append, sarray("value"), varray()); - bind_method(PackedFloat64Array, append_array, sarray("array"), varray()); - bind_method(PackedFloat64Array, remove, sarray("index"), varray()); - bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray()); - bind_method(PackedFloat64Array, resize, sarray("new_size"), varray()); - bind_method(PackedFloat64Array, has, sarray("value"), varray()); - bind_method(PackedFloat64Array, invert, sarray(), varray()); - bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray()); - bind_method(PackedFloat64Array, to_byte_array, sarray(), varray()); - bind_method(PackedFloat64Array, sort, sarray(), varray()); - - /* String Array */ - - bind_method(PackedStringArray, size, sarray(), varray()); - bind_method(PackedStringArray, empty, sarray(), varray()); - bind_method(PackedStringArray, set, sarray("index", "value"), varray()); - bind_method(PackedStringArray, push_back, sarray("value"), varray()); - bind_method(PackedStringArray, append, sarray("value"), varray()); - bind_method(PackedStringArray, append_array, sarray("array"), varray()); - bind_method(PackedStringArray, remove, sarray("index"), varray()); - bind_method(PackedStringArray, insert, sarray("at_index", "value"), varray()); - bind_method(PackedStringArray, resize, sarray("new_size"), varray()); - bind_method(PackedStringArray, has, sarray("value"), varray()); - bind_method(PackedStringArray, invert, sarray(), varray()); - bind_method(PackedStringArray, subarray, sarray("from", "to"), varray()); - bind_method(PackedStringArray, to_byte_array, sarray(), varray()); - bind_method(PackedStringArray, sort, sarray(), varray()); - - /* Vector2 Array */ - - bind_method(PackedVector2Array, size, sarray(), varray()); - bind_method(PackedVector2Array, empty, sarray(), varray()); - bind_method(PackedVector2Array, set, sarray("index", "value"), varray()); - bind_method(PackedVector2Array, push_back, sarray("value"), varray()); - bind_method(PackedVector2Array, append, sarray("value"), varray()); - bind_method(PackedVector2Array, append_array, sarray("array"), varray()); - bind_method(PackedVector2Array, remove, sarray("index"), varray()); - bind_method(PackedVector2Array, insert, sarray("at_index", "value"), varray()); - bind_method(PackedVector2Array, resize, sarray("new_size"), varray()); - bind_method(PackedVector2Array, has, sarray("value"), varray()); - bind_method(PackedVector2Array, invert, sarray(), varray()); - bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray()); - bind_method(PackedVector2Array, to_byte_array, sarray(), varray()); - - /* Vector3 Array */ - - bind_method(PackedVector3Array, size, sarray(), varray()); - bind_method(PackedVector3Array, empty, sarray(), varray()); - bind_method(PackedVector3Array, set, sarray("index", "value"), varray()); - bind_method(PackedVector3Array, push_back, sarray("value"), varray()); - bind_method(PackedVector3Array, append, sarray("value"), varray()); - bind_method(PackedVector3Array, append_array, sarray("array"), varray()); - bind_method(PackedVector3Array, remove, sarray("index"), varray()); - bind_method(PackedVector3Array, insert, sarray("at_index", "value"), varray()); - bind_method(PackedVector3Array, resize, sarray("new_size"), varray()); - bind_method(PackedVector3Array, has, sarray("value"), varray()); - bind_method(PackedVector3Array, invert, sarray(), varray()); - bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray()); - bind_method(PackedVector3Array, to_byte_array, sarray(), varray()); - - /* Color Array */ - - bind_method(PackedColorArray, size, sarray(), varray()); - bind_method(PackedColorArray, empty, sarray(), varray()); - bind_method(PackedColorArray, set, sarray("index", "value"), varray()); - bind_method(PackedColorArray, push_back, sarray("value"), varray()); - bind_method(PackedColorArray, append, sarray("value"), varray()); - bind_method(PackedColorArray, append_array, sarray("array"), varray()); - bind_method(PackedColorArray, remove, sarray("index"), varray()); - bind_method(PackedColorArray, insert, sarray("at_index", "value"), varray()); - bind_method(PackedColorArray, resize, sarray("new_size"), varray()); - bind_method(PackedColorArray, has, sarray("value"), varray()); - bind_method(PackedColorArray, invert, sarray(), varray()); - bind_method(PackedColorArray, subarray, sarray("from", "to"), varray()); - bind_method(PackedColorArray, to_byte_array, sarray(), varray()); - - /* REGISTER CONSTRUCTORS */ - - _VariantCall::add_constructor(_VariantCall::Vector2_init1, Variant::VECTOR2, "x", Variant::FLOAT, "y", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Vector2i_init1, Variant::VECTOR2I, "x", Variant::INT, "y", Variant::INT); - - _VariantCall::add_constructor(_VariantCall::Rect2_init1, Variant::RECT2, "position", Variant::VECTOR2, "size", Variant::VECTOR2); - _VariantCall::add_constructor(_VariantCall::Rect2_init2, Variant::RECT2, "x", Variant::FLOAT, "y", Variant::FLOAT, "width", Variant::FLOAT, "height", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::Rect2i_init1, Variant::RECT2I, "position", Variant::VECTOR2, "size", Variant::VECTOR2); - _VariantCall::add_constructor(_VariantCall::Rect2i_init2, Variant::RECT2I, "x", Variant::INT, "y", Variant::INT, "width", Variant::INT, "height", Variant::INT); - - _VariantCall::add_constructor(_VariantCall::Transform2D_init2, Variant::TRANSFORM2D, "rotation", Variant::FLOAT, "position", Variant::VECTOR2); - _VariantCall::add_constructor(_VariantCall::Transform2D_init3, Variant::TRANSFORM2D, "x_axis", Variant::VECTOR2, "y_axis", Variant::VECTOR2, "origin", Variant::VECTOR2); - - _VariantCall::add_constructor(_VariantCall::Vector3_init1, Variant::VECTOR3, "x", Variant::FLOAT, "y", Variant::FLOAT, "z", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Vector3i_init1, Variant::VECTOR3I, "x", Variant::INT, "y", Variant::INT, "z", Variant::INT); - - _VariantCall::add_constructor(_VariantCall::Plane_init1, Variant::PLANE, "a", Variant::FLOAT, "b", Variant::FLOAT, "c", Variant::FLOAT, "d", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Plane_init2, Variant::PLANE, "v1", Variant::VECTOR3, "v2", Variant::VECTOR3, "v3", Variant::VECTOR3); - _VariantCall::add_constructor(_VariantCall::Plane_init3, Variant::PLANE, "normal", Variant::VECTOR3, "d", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::Quat_init1, Variant::QUAT, "x", Variant::FLOAT, "y", Variant::FLOAT, "z", Variant::FLOAT, "w", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Quat_init2, Variant::QUAT, "axis", Variant::VECTOR3, "angle", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Quat_init3, Variant::QUAT, "euler", Variant::VECTOR3); - - _VariantCall::add_constructor(_VariantCall::Color_init1, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT, "a", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Color_init2, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT); - // init3 and init4 are the constructors for HTML hex strings and integers respectively which don't need binding here, so we skip to init5. - _VariantCall::add_constructor(_VariantCall::Color_init5, Variant::COLOR, "c", Variant::COLOR, "a", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::AABB_init1, Variant::AABB, "position", Variant::VECTOR3, "size", Variant::VECTOR3); - - _VariantCall::add_constructor(_VariantCall::Basis_init1, Variant::BASIS, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3); - _VariantCall::add_constructor(_VariantCall::Basis_init2, Variant::BASIS, "axis", Variant::VECTOR3, "phi", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::Transform_init1, Variant::TRANSFORM, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3, "origin", Variant::VECTOR3); - _VariantCall::add_constructor(_VariantCall::Transform_init2, Variant::TRANSFORM, "basis", Variant::BASIS, "origin", Variant::VECTOR3); - - _VariantCall::add_constructor(_VariantCall::Callable_init2, Variant::CALLABLE, "object", Variant::OBJECT, "method_name", Variant::STRING_NAME); - _VariantCall::add_constructor(_VariantCall::Signal_init2, Variant::SIGNAL, "object", Variant::OBJECT, "signal_name", Variant::STRING_NAME); - - /* REGISTER CONSTANTS */ - - _populate_named_colors(); - for (Map<String, Color>::Element *color = _named_colors.front(); color; color = color->next()) { - _VariantCall::add_variant_constant(Variant::COLOR, color->key(), color->value()); - } - - _VariantCall::add_constant(Variant::VECTOR3, "AXIS_X", Vector3::AXIS_X); - _VariantCall::add_constant(Variant::VECTOR3, "AXIS_Y", Vector3::AXIS_Y); - _VariantCall::add_constant(Variant::VECTOR3, "AXIS_Z", Vector3::AXIS_Z); - - _VariantCall::add_variant_constant(Variant::VECTOR3, "ZERO", Vector3(0, 0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "ONE", Vector3(1, 1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(Math_INF, Math_INF, Math_INF)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "LEFT", Vector3(-1, 0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "RIGHT", Vector3(1, 0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "UP", Vector3(0, 1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "DOWN", Vector3(0, -1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1)); - - _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3i::AXIS_X); - _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3i::AXIS_Y); - _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3i::AXIS_Z); - - _VariantCall::add_variant_constant(Variant::VECTOR3I, "ZERO", Vector3i(0, 0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3I, "ONE", Vector3i(1, 1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR3I, "LEFT", Vector3i(-1, 0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3I, "RIGHT", Vector3i(1, 0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3I, "UP", Vector3i(0, 1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3I, "DOWN", Vector3i(0, -1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR3I, "FORWARD", Vector3i(0, 0, -1)); - _VariantCall::add_variant_constant(Variant::VECTOR3I, "BACK", Vector3i(0, 0, 1)); - - _VariantCall::add_constant(Variant::VECTOR2, "AXIS_X", Vector2::AXIS_X); - _VariantCall::add_constant(Variant::VECTOR2, "AXIS_Y", Vector2::AXIS_Y); - - _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_X", Vector2i::AXIS_X); - _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_Y", Vector2i::AXIS_Y); - - _VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "LEFT", Vector2(-1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "RIGHT", Vector2(1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "DOWN", Vector2(0, 1)); - - _VariantCall::add_variant_constant(Variant::VECTOR2I, "ZERO", Vector2i(0, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR2I, "ONE", Vector2i(1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR2I, "LEFT", Vector2i(-1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR2I, "RIGHT", Vector2i(1, 0)); - _VariantCall::add_variant_constant(Variant::VECTOR2I, "UP", Vector2i(0, -1)); - _VariantCall::add_variant_constant(Variant::VECTOR2I, "DOWN", Vector2i(0, 1)); - - _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D()); - _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0)); - _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0)); - - Transform identity_transform = Transform(); - Transform flip_x_transform = Transform(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); - Transform flip_y_transform = Transform(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0); - Transform flip_z_transform = Transform(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "IDENTITY", identity_transform); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", flip_x_transform); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", flip_y_transform); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", flip_z_transform); - - Basis identity_basis = Basis(); - Basis flip_x_basis = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1); - Basis flip_y_basis = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1); - Basis flip_z_basis = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1); - _VariantCall::add_variant_constant(Variant::BASIS, "IDENTITY", identity_basis); - _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_X", flip_x_basis); - _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Y", flip_y_basis); - _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Z", flip_z_basis); - - _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_YZ", Plane(Vector3(1, 0, 0), 0)); - _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XZ", Plane(Vector3(0, 1, 0), 0)); - _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0)); - - _VariantCall::add_variant_constant(Variant::QUAT, "IDENTITY", Quat(0, 0, 0, 1)); -} - -void unregister_variant_methods() { - //clear methods - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - for (List<StringName>::Element *E = _VariantCall::type_internal_method_names[i].front(); E; E = E->next()) { - Variant::InternalMethod **m = _VariantCall::type_internal_methods[i].lookup_ptr(E->get()); - if (*m) { - memdelete(*m); - } - } - } - - memdelete_arr(_VariantCall::type_internal_methods); - memdelete_arr(_VariantCall::type_internal_method_names); - memdelete_arr(_VariantCall::construct_funcs); - memdelete_arr(_VariantCall::constant_data); -} diff --git a/core/variant_op.cpp b/core/variant_op.cpp deleted file mode 100644 index 47539df856..0000000000 --- a/core/variant_op.cpp +++ /dev/null @@ -1,4608 +0,0 @@ -/*************************************************************************/ -/* variant_op.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "variant.h" - -#include "core/class_db.h" -#include "core/core_string_names.h" -#include "core/debugger/engine_debugger.h" - -#define CASE_TYPE_ALL(PREFIX, OP) \ - CASE_TYPE(PREFIX, OP, INT) \ - CASE_TYPE_ALL_BUT_INT(PREFIX, OP) - -#define CASE_TYPE_ALL_BUT_INT(PREFIX, OP) \ - CASE_TYPE(PREFIX, OP, NIL) \ - CASE_TYPE(PREFIX, OP, BOOL) \ - CASE_TYPE(PREFIX, OP, FLOAT) \ - CASE_TYPE(PREFIX, OP, STRING) \ - CASE_TYPE(PREFIX, OP, VECTOR2) \ - CASE_TYPE(PREFIX, OP, VECTOR2I) \ - CASE_TYPE(PREFIX, OP, RECT2) \ - CASE_TYPE(PREFIX, OP, RECT2I) \ - CASE_TYPE(PREFIX, OP, VECTOR3) \ - CASE_TYPE(PREFIX, OP, VECTOR3I) \ - CASE_TYPE(PREFIX, OP, TRANSFORM2D) \ - CASE_TYPE(PREFIX, OP, PLANE) \ - CASE_TYPE(PREFIX, OP, QUAT) \ - CASE_TYPE(PREFIX, OP, AABB) \ - CASE_TYPE(PREFIX, OP, BASIS) \ - CASE_TYPE(PREFIX, OP, TRANSFORM) \ - CASE_TYPE(PREFIX, OP, COLOR) \ - CASE_TYPE(PREFIX, OP, STRING_NAME) \ - CASE_TYPE(PREFIX, OP, NODE_PATH) \ - CASE_TYPE(PREFIX, OP, _RID) \ - CASE_TYPE(PREFIX, OP, OBJECT) \ - CASE_TYPE(PREFIX, OP, CALLABLE) \ - CASE_TYPE(PREFIX, OP, SIGNAL) \ - CASE_TYPE(PREFIX, OP, DICTIONARY) \ - CASE_TYPE(PREFIX, OP, ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_BYTE_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_INT32_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_INT64_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_STRING_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_VECTOR2_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_VECTOR3_ARRAY) \ - CASE_TYPE(PREFIX, OP, PACKED_COLOR_ARRAY) - -#ifdef __GNUC__ -#define TYPE(PREFIX, OP, TYPE) &&PREFIX##_##OP##_##TYPE - -/* clang-format off */ -#define TYPES(PREFIX, OP) { \ - TYPE(PREFIX, OP, NIL), \ - TYPE(PREFIX, OP, BOOL), \ - TYPE(PREFIX, OP, INT), \ - TYPE(PREFIX, OP, FLOAT), \ - TYPE(PREFIX, OP, STRING), \ - TYPE(PREFIX, OP, VECTOR2), \ - TYPE(PREFIX, OP, VECTOR2I), \ - TYPE(PREFIX, OP, RECT2), \ - TYPE(PREFIX, OP, RECT2I), \ - TYPE(PREFIX, OP, VECTOR3), \ - TYPE(PREFIX, OP, VECTOR3I), \ - TYPE(PREFIX, OP, TRANSFORM2D), \ - TYPE(PREFIX, OP, PLANE), \ - TYPE(PREFIX, OP, QUAT), \ - TYPE(PREFIX, OP, AABB), \ - TYPE(PREFIX, OP, BASIS), \ - TYPE(PREFIX, OP, TRANSFORM), \ - TYPE(PREFIX, OP, COLOR), \ - TYPE(PREFIX, OP, STRING_NAME), \ - TYPE(PREFIX, OP, NODE_PATH), \ - TYPE(PREFIX, OP, _RID), \ - TYPE(PREFIX, OP, OBJECT), \ - TYPE(PREFIX, OP, CALLABLE), \ - TYPE(PREFIX, OP, SIGNAL), \ - TYPE(PREFIX, OP, DICTIONARY), \ - TYPE(PREFIX, OP, ARRAY), \ - TYPE(PREFIX, OP, PACKED_BYTE_ARRAY), \ - TYPE(PREFIX, OP, PACKED_INT32_ARRAY), \ - TYPE(PREFIX, OP, PACKED_INT64_ARRAY), \ - TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY), \ - TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY), \ - TYPE(PREFIX, OP, PACKED_STRING_ARRAY), \ - TYPE(PREFIX, OP, PACKED_VECTOR2_ARRAY), \ - TYPE(PREFIX, OP, PACKED_VECTOR3_ARRAY), \ - TYPE(PREFIX, OP, PACKED_COLOR_ARRAY), \ -} - -/* clang-format on */ - -#define CASES(PREFIX) static const void *switch_table_##PREFIX[Variant::OP_MAX][Variant::VARIANT_MAX] = { \ - TYPES(PREFIX, OP_EQUAL), \ - TYPES(PREFIX, OP_NOT_EQUAL), \ - TYPES(PREFIX, OP_LESS), \ - TYPES(PREFIX, OP_LESS_EQUAL), \ - TYPES(PREFIX, OP_GREATER), \ - TYPES(PREFIX, OP_GREATER_EQUAL), \ - TYPES(PREFIX, OP_ADD), \ - TYPES(PREFIX, OP_SUBTRACT), \ - TYPES(PREFIX, OP_MULTIPLY), \ - TYPES(PREFIX, OP_DIVIDE), \ - TYPES(PREFIX, OP_NEGATE), \ - TYPES(PREFIX, OP_POSITIVE), \ - TYPES(PREFIX, OP_MODULE), \ - TYPES(PREFIX, OP_STRING_CONCAT), \ - TYPES(PREFIX, OP_SHIFT_LEFT), \ - TYPES(PREFIX, OP_SHIFT_RIGHT), \ - TYPES(PREFIX, OP_BIT_AND), \ - TYPES(PREFIX, OP_BIT_OR), \ - TYPES(PREFIX, OP_BIT_XOR), \ - TYPES(PREFIX, OP_BIT_NEGATE), \ - TYPES(PREFIX, OP_AND), \ - TYPES(PREFIX, OP_OR), \ - TYPES(PREFIX, OP_XOR), \ - TYPES(PREFIX, OP_NOT), \ - TYPES(PREFIX, OP_IN), \ -} - -#define SWITCH(PREFIX, op, val) goto *switch_table_##PREFIX[op][val]; -#define SWITCH_OP(PREFIX, OP, val) -#define CASE_TYPE(PREFIX, OP, TYPE) PREFIX##_##OP##_##TYPE: - -#else -#define CASES(PREFIX) -#define SWITCH(PREFIX, op, val) switch (op) -#define SWITCH_OP(PREFIX, OP, val) \ - case OP: \ - switch (val) -#define CASE_TYPE(PREFIX, OP, TYPE) case TYPE: -#endif - -Variant::operator bool() const { - return booleanize(); -} - -// We consider all uninitialized or empty types to be false based on the type's -// zeroiness. -bool Variant::booleanize() const { - return !is_zero(); -} - -#define _RETURN(m_what) \ - { \ - r_ret = m_what; \ - return; \ - } - -#define _RETURN_FAIL \ - { \ - r_valid = false; \ - return; \ - } - -#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == INT) \ - _RETURN(p_a._data.m_type m_op p_b._data._int); \ - if (p_b.type == FLOAT) \ - _RETURN(p_a._data.m_type m_op p_b._data._float); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == INT) \ - _RETURN(p_a._data.m_type m_op p_b._data._int); \ - if (p_b.type == FLOAT) \ - _RETURN(p_a._data.m_type m_op p_b._data._float); \ - if (p_b.type == NIL) \ - _RETURN(!(p_b.type m_op NIL)); \ - \ - _RETURN_FAIL \ - } - -#ifdef DEBUG_ENABLED -#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == INT) { \ - if (p_b._data._int == 0) { \ - r_valid = false; \ - _RETURN("Division By Zero"); \ - } \ - _RETURN(p_a._data.m_type / p_b._data._int); \ - } \ - if (p_b.type == FLOAT) { \ - if (p_b._data._float == 0) { \ - r_valid = false; \ - _RETURN("Division By Zero"); \ - } \ - _RETURN(p_a._data.m_type / p_b._data._float); \ - } \ - \ - _RETURN_FAIL \ - } -#else -#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == INT) \ - _RETURN(p_a._data.m_type / p_b._data._int); \ - if (p_b.type == FLOAT) \ - _RETURN(p_a._data.m_type / p_b._data._float); \ - \ - _RETURN_FAIL \ - } -#endif - -#define DEFAULT_OP_NUM_NEG(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - _RETURN(-p_a._data.m_type); \ - } - -#define DEFAULT_OP_NUM_POS(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - _RETURN(p_a._data.m_type); \ - } - -#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == INT) \ - _RETURN(p_a._data.m_type m_op p_b._data._int); \ - if (p_b.type == FLOAT) \ - _RETURN(p_a._data.m_type m_op p_b._data._float); \ - if (p_b.type == VECTOR2) \ - _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \ - if (p_b.type == VECTOR3) \ - _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \ - if (p_b.type == VECTOR2I) \ - _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2i *>(p_b._data._mem)); \ - if (p_b.type == VECTOR3I) \ - _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3i *>(p_b._data._mem)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == STRING) \ - _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \ - if (p_b.type == STRING_NAME) \ - _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const StringName *>(p_a._data._mem)); \ - if (p_b.type == NODE_PATH) \ - _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == STRING) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ - if (p_b.type == STRING_NAME) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \ - if (p_b.type == NODE_PATH) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == STRING) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ - if (p_b.type == STRING_NAME) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \ - if (p_b.type == NODE_PATH) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \ - if (p_b.type == NIL) \ - _RETURN(!(p_b.type m_op NIL)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == STRING) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ - if (p_b.type == NODE_PATH) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \ - if (p_b.type == NIL) \ - _RETURN(!(p_b.type m_op NIL)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_STR_NULL_SN(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == STRING) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ - if (p_b.type == STRING_NAME) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \ - if (p_b.type == NIL) \ - _RETURN(!(p_b.type m_op NIL)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_LOCALMEM_REV(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == m_name) \ - _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const m_type *>(p_a._data._mem)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_LOCALMEM(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == m_name) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_LOCALMEM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == m_name) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ - if (p_b.type == NIL) \ - _RETURN(!(p_b.type m_op NIL)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_LOCALMEM_NEG(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - _RETURN(-*reinterpret_cast<const m_type *>(p_a._data._mem)); \ - } - -#define DEFAULT_OP_LOCALMEM_POS(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem)); \ - } - -#define DEFAULT_OP_LOCALMEM_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == m_name) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ - if (p_b.type == INT) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \ - if (p_b.type == FLOAT) \ - _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._float); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_PTR(m_op, m_name, m_sub) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == m_name) \ - _RETURN(p_a._data.m_sub m_op p_b._data.m_sub); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_PTRREF(m_prefix, m_op_name, m_name, m_op, m_sub) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == m_name) \ - _RETURN(*p_a._data.m_sub m_op *p_b._data.m_sub); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_PTRREF_NULL(m_prefix, m_op_name, m_name, m_op, m_sub) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == m_name) \ - _RETURN(*p_a._data.m_sub m_op *p_b._data.m_sub); \ - if (p_b.type == NIL) \ - _RETURN(!(p_b.type m_op NIL)); \ - \ - _RETURN_FAIL \ - } - -#define DEFAULT_OP_ARRAY_EQ(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == NIL) \ - _RETURN(false) \ - DEFAULT_OP_ARRAY_OP_BODY(m_prefix, m_op_name, m_name, m_type, !=, !=, true, false, false) \ - } - -#define DEFAULT_OP_ARRAY_NEQ(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_b.type == NIL) \ - _RETURN(true) \ - DEFAULT_OP_ARRAY_OP_BODY(m_prefix, m_op_name, m_name, m_type, !=, !=, false, true, true) \ - } - -#define DEFAULT_OP_ARRAY_LT(m_prefix, m_op_name, m_name, m_type) \ - DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, <, !=, false, a_len < array_b.size(), true) - -#define DEFAULT_OP_ARRAY_GT(m_prefix, m_op_name, m_name, m_type) \ - DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, >, !=, false, a_len < array_b.size(), true) - -#define DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, m_opa, m_opb, m_ret_def, m_ret_s, m_ret_f) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - DEFAULT_OP_ARRAY_OP_BODY(m_prefix, m_op_name, m_name, m_type, m_opa, m_opb, m_ret_def, m_ret_s, m_ret_f) \ - } - -#define DEFAULT_OP_ARRAY_OP_BODY(m_prefix, m_op_name, m_name, m_type, m_opa, m_opb, m_ret_def, m_ret_s, m_ret_f) \ - if (p_a.type != p_b.type) \ - _RETURN_FAIL \ - \ - const Vector<m_type> &array_a = PackedArrayRef<m_type>::get_array(p_a._data.packed_array); \ - const Vector<m_type> &array_b = PackedArrayRef<m_type>::get_array(p_b._data.packed_array); \ - \ - int a_len = array_a.size(); \ - if (a_len m_opa array_b.size()) { \ - _RETURN(m_ret_s); \ - } else { \ - const m_type *ra = array_a.ptr(); \ - const m_type *rb = array_b.ptr(); \ - \ - for (int i = 0; i < a_len; i++) { \ - if (ra[i] m_opb rb[i]) \ - _RETURN(m_ret_f); \ - } \ - \ - _RETURN(m_ret_def); \ - } - -#define DEFAULT_OP_ARRAY_ADD(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_a.type != p_b.type) \ - _RETURN_FAIL; \ - \ - const Vector<m_type> &array_a = PackedArrayRef<m_type>::get_array(p_a._data.packed_array); \ - const Vector<m_type> &array_b = PackedArrayRef<m_type>::get_array(p_b._data.packed_array); \ - Vector<m_type> sum = array_a; \ - sum.append_array(array_b); \ - _RETURN(sum); \ - } - -void Variant::evaluate(const Operator &p_op, const Variant &p_a, - const Variant &p_b, Variant &r_ret, bool &r_valid) { - CASES(math); - r_valid = true; - - SWITCH(math, p_op, p_a.type) { - SWITCH_OP(math, OP_EQUAL, p_a.type) { - CASE_TYPE(math, OP_EQUAL, NIL) { - if (p_b.type == NIL) - _RETURN(true); - if (p_b.type == OBJECT) - _RETURN(p_b._get_obj().obj == nullptr); - - _RETURN(false); - } - - CASE_TYPE(math, OP_EQUAL, BOOL) { - if (p_b.type != BOOL) { - if (p_b.type == NIL) - _RETURN(false); - _RETURN_FAIL; - } - - _RETURN(p_a._data._bool == p_b._data._bool); - } - - CASE_TYPE(math, OP_EQUAL, OBJECT) { - if (p_b.type == OBJECT) - _RETURN((p_a._get_obj().obj == p_b._get_obj().obj)); - if (p_b.type == NIL) - _RETURN(p_a._get_obj().obj == nullptr); - - _RETURN_FAIL; - } - - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, CALLABLE, ==, Callable); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, SIGNAL, ==, Signal); - - CASE_TYPE(math, OP_EQUAL, DICTIONARY) { - if (p_b.type != DICTIONARY) { - if (p_b.type == NIL) - _RETURN(false); - _RETURN_FAIL; - } - - const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem); - const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem); - - _RETURN(*arr_a == *arr_b); - } - - CASE_TYPE(math, OP_EQUAL, ARRAY) { - if (p_b.type != ARRAY) { - if (p_b.type == NIL) - _RETURN(false); - _RETURN_FAIL; - } - const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem); - const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem); - - int l = arr_a->size(); - if (arr_b->size() != l) - _RETURN(false); - for (int i = 0; i < l; i++) { - if (!((*arr_a)[i] == (*arr_b)[i])) { - _RETURN(false); - } - } - - _RETURN(true); - } - - DEFAULT_OP_NUM_NULL(math, OP_EQUAL, INT, ==, _int); - DEFAULT_OP_NUM_NULL(math, OP_EQUAL, FLOAT, ==, _float); - DEFAULT_OP_STR_NULL(math, OP_EQUAL, STRING, ==, String); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR2, ==, Vector2); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR2I, ==, Vector2i); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, RECT2, ==, Rect2); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, RECT2I, ==, Rect2i); - DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM2D, ==, _transform2d); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR3, ==, Vector3); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR3I, ==, Vector3i); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, PLANE, ==, Plane); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, QUAT, ==, Quat); - DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, AABB, ==, _aabb); - DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, BASIS, ==, _basis); - DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM, ==, _transform); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, COLOR, ==, Color); - DEFAULT_OP_STR_NULL_SN(math, OP_EQUAL, STRING_NAME, ==, StringName); - DEFAULT_OP_STR_NULL_NP(math, OP_EQUAL, NODE_PATH, ==, NodePath); - DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, _RID, ==, RID); - - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_BYTE_ARRAY, uint8_t); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_INT32_ARRAY, int32_t); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_INT64_ARRAY, int64_t); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_FLOAT32_ARRAY, float); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_FLOAT64_ARRAY, double); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_STRING_ARRAY, String); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_VECTOR2_ARRAY, Vector2); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_VECTOR3_ARRAY, Vector3); - DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_COLOR_ARRAY, Color); - } - - SWITCH_OP(math, OP_NOT_EQUAL, p_a.type) { - CASE_TYPE(math, OP_NOT_EQUAL, NIL) { - if (p_b.type == NIL) - _RETURN(false); - if (p_b.type == OBJECT) - _RETURN(p_b._get_obj().obj != nullptr); - - _RETURN(true); - } - - CASE_TYPE(math, OP_NOT_EQUAL, BOOL) { - if (p_b.type != BOOL) { - if (p_b.type == NIL) - _RETURN(true); - - _RETURN_FAIL; - } - - _RETURN(p_a._data._bool != p_b._data._bool); - } - - CASE_TYPE(math, OP_NOT_EQUAL, OBJECT) { - if (p_b.type == OBJECT) - _RETURN((p_a._get_obj().obj != p_b._get_obj().obj)); - if (p_b.type == NIL) - _RETURN(p_a._get_obj().obj != nullptr); - - _RETURN_FAIL; - } - - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, CALLABLE, !=, Callable); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, SIGNAL, !=, Signal); - - CASE_TYPE(math, OP_NOT_EQUAL, DICTIONARY) { - if (p_b.type != DICTIONARY) { - if (p_b.type == NIL) - _RETURN(true); - _RETURN_FAIL; - } - - const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem); - const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem); - - _RETURN(*arr_a != *arr_b); - } - - CASE_TYPE(math, OP_NOT_EQUAL, ARRAY) { - if (p_b.type != ARRAY) { - if (p_b.type == NIL) - _RETURN(true); - - _RETURN_FAIL; - } - - const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem); - const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem); - - int l = arr_a->size(); - if (arr_b->size() != l) - _RETURN(true); - for (int i = 0; i < l; i++) { - if (((*arr_a)[i] != (*arr_b)[i])) { - _RETURN(true); - } - } - - _RETURN(false); - } - - DEFAULT_OP_NUM_NULL(math, OP_NOT_EQUAL, INT, !=, _int); - DEFAULT_OP_NUM_NULL(math, OP_NOT_EQUAL, FLOAT, !=, _float); - DEFAULT_OP_STR_NULL(math, OP_NOT_EQUAL, STRING, !=, String); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR2, !=, Vector2); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR2I, !=, Vector2i); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, RECT2, !=, Rect2); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, RECT2I, !=, Rect2i); - DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM2D, !=, _transform2d); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR3, !=, Vector3); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR3I, !=, Vector3i); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, PLANE, !=, Plane); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, QUAT, !=, Quat); - DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, AABB, !=, _aabb); - DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, BASIS, !=, _basis); - DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM, !=, _transform); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, COLOR, !=, Color); - DEFAULT_OP_STR_NULL_SN(math, OP_NOT_EQUAL, STRING_NAME, !=, StringName); - DEFAULT_OP_STR_NULL_NP(math, OP_NOT_EQUAL, NODE_PATH, !=, NodePath); - DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, _RID, !=, RID); - - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_BYTE_ARRAY, uint8_t); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_INT32_ARRAY, int32_t); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_INT64_ARRAY, int64_t); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_FLOAT32_ARRAY, float); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_FLOAT64_ARRAY, double); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_STRING_ARRAY, String); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_VECTOR2_ARRAY, Vector2); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_VECTOR3_ARRAY, Vector3); - DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_COLOR_ARRAY, Color); - } - - SWITCH_OP(math, OP_LESS, p_a.type) { - CASE_TYPE(math, OP_LESS, BOOL) { - if (p_b.type != BOOL) - _RETURN_FAIL; - - if (p_a._data._bool == p_b._data._bool) - _RETURN(false); - - if (p_a._data._bool && !p_b._data._bool) - _RETURN(false); - - _RETURN(true); - } - - CASE_TYPE(math, OP_LESS, OBJECT) { - if (p_b.type != OBJECT) - _RETURN_FAIL; - _RETURN((p_a._get_obj().obj < p_b._get_obj().obj)); - } - - DEFAULT_OP_LOCALMEM_NULL(math, OP_LESS, CALLABLE, <, Callable); - DEFAULT_OP_LOCALMEM_NULL(math, OP_LESS, SIGNAL, <, Signal); - - CASE_TYPE(math, OP_LESS, ARRAY) { - if (p_b.type != ARRAY) - _RETURN_FAIL; - - const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem); - const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem); - - int l = arr_a->size(); - if (arr_b->size() < l) - _RETURN(false); - for (int i = 0; i < l; i++) { - if (!((*arr_a)[i] < (*arr_b)[i])) { - _RETURN(true); - } - } - - _RETURN(false); - } - - DEFAULT_OP_NUM(math, OP_LESS, INT, <, _int); - DEFAULT_OP_NUM(math, OP_LESS, FLOAT, <, _float); - DEFAULT_OP_STR(math, OP_LESS, STRING, <, String); - DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR2, <, Vector2); - DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR2I, <, Vector2i); - DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR3, <, Vector3); - DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR3I, <, Vector3i); - DEFAULT_OP_LOCALMEM(math, OP_LESS, _RID, <, RID); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_BYTE_ARRAY, uint8_t); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_INT32_ARRAY, int32_t); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_INT64_ARRAY, int64_t); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_FLOAT32_ARRAY, float); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_FLOAT64_ARRAY, double); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_STRING_ARRAY, String); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_VECTOR2_ARRAY, Vector3); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_VECTOR3_ARRAY, Vector3); - DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_COLOR_ARRAY, Color); - - CASE_TYPE(math, OP_LESS, NIL) - CASE_TYPE(math, OP_LESS, RECT2) - CASE_TYPE(math, OP_LESS, RECT2I) - CASE_TYPE(math, OP_LESS, TRANSFORM2D) - CASE_TYPE(math, OP_LESS, PLANE) - CASE_TYPE(math, OP_LESS, QUAT) - CASE_TYPE(math, OP_LESS, AABB) - CASE_TYPE(math, OP_LESS, BASIS) - CASE_TYPE(math, OP_LESS, TRANSFORM) - CASE_TYPE(math, OP_LESS, COLOR) - CASE_TYPE(math, OP_LESS, STRING_NAME) - CASE_TYPE(math, OP_LESS, NODE_PATH) - CASE_TYPE(math, OP_LESS, DICTIONARY) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_LESS_EQUAL, p_a.type) { - CASE_TYPE(math, OP_LESS_EQUAL, OBJECT) { - if (p_b.type != OBJECT) - _RETURN_FAIL; - _RETURN((p_a._get_obj().obj <= p_b._get_obj().obj)); - } - - DEFAULT_OP_NUM(math, OP_LESS_EQUAL, INT, <=, _int); - DEFAULT_OP_NUM(math, OP_LESS_EQUAL, FLOAT, <=, _float); - DEFAULT_OP_STR(math, OP_LESS_EQUAL, STRING, <=, String); - DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR2, <=, Vector2); - DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR2I, <=, Vector2i); - DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR3, <=, Vector3); - DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR3I, <=, Vector3i); - DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, _RID, <=, RID); - - CASE_TYPE(math, OP_LESS_EQUAL, NIL) - CASE_TYPE(math, OP_LESS_EQUAL, BOOL) - CASE_TYPE(math, OP_LESS_EQUAL, RECT2) - CASE_TYPE(math, OP_LESS_EQUAL, RECT2I) - CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM2D) - CASE_TYPE(math, OP_LESS_EQUAL, PLANE) - CASE_TYPE(math, OP_LESS_EQUAL, QUAT) - CASE_TYPE(math, OP_LESS_EQUAL, AABB) - CASE_TYPE(math, OP_LESS_EQUAL, BASIS) - CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM) - CASE_TYPE(math, OP_LESS_EQUAL, COLOR) - CASE_TYPE(math, OP_LESS_EQUAL, STRING_NAME) - CASE_TYPE(math, OP_LESS_EQUAL, NODE_PATH) - CASE_TYPE(math, OP_LESS_EQUAL, CALLABLE) - CASE_TYPE(math, OP_LESS_EQUAL, SIGNAL) - - CASE_TYPE(math, OP_LESS_EQUAL, DICTIONARY) - CASE_TYPE(math, OP_LESS_EQUAL, ARRAY) - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_BYTE_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_INT32_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_INT64_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_FLOAT32_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_FLOAT64_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_STRING_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_VECTOR2_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_VECTOR3_ARRAY); - CASE_TYPE(math, OP_LESS_EQUAL, PACKED_COLOR_ARRAY); - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_GREATER, p_a.type) { - CASE_TYPE(math, OP_GREATER, BOOL) { - if (p_b.type != BOOL) - _RETURN_FAIL; - - if (p_a._data._bool == p_b._data._bool) - _RETURN(false); - - if (!p_a._data._bool && p_b._data._bool) - _RETURN(false); - - _RETURN(true); - } - - CASE_TYPE(math, OP_GREATER, OBJECT) { - if (p_b.type != OBJECT) - _RETURN_FAIL; - _RETURN((p_a._get_obj().obj > p_b._get_obj().obj)); - } - - CASE_TYPE(math, OP_GREATER, ARRAY) { - if (p_b.type != ARRAY) - _RETURN_FAIL; - - const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem); - const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem); - - int l = arr_a->size(); - if (arr_b->size() > l) - _RETURN(false); - for (int i = 0; i < l; i++) { - if (((*arr_a)[i] < (*arr_b)[i])) { - _RETURN(false); - } - } - - _RETURN(true); - } - - DEFAULT_OP_NUM(math, OP_GREATER, INT, >, _int); - DEFAULT_OP_NUM(math, OP_GREATER, FLOAT, >, _float); - DEFAULT_OP_STR_REV(math, OP_GREATER, STRING, <, String); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR2, <, Vector2); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR2I, <, Vector2i); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR3, <, Vector3); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR3I, <, Vector3i); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, _RID, <, RID); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_BYTE_ARRAY, uint8_t); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_INT32_ARRAY, int32_t); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_INT64_ARRAY, int64_t); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_FLOAT32_ARRAY, float); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_FLOAT64_ARRAY, double); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_STRING_ARRAY, String); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_VECTOR2_ARRAY, Vector3); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_VECTOR3_ARRAY, Vector3); - DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_COLOR_ARRAY, Color); - - CASE_TYPE(math, OP_GREATER, NIL) - CASE_TYPE(math, OP_GREATER, RECT2) - CASE_TYPE(math, OP_GREATER, RECT2I) - CASE_TYPE(math, OP_GREATER, TRANSFORM2D) - CASE_TYPE(math, OP_GREATER, PLANE) - CASE_TYPE(math, OP_GREATER, QUAT) - CASE_TYPE(math, OP_GREATER, AABB) - CASE_TYPE(math, OP_GREATER, BASIS) - CASE_TYPE(math, OP_GREATER, TRANSFORM) - CASE_TYPE(math, OP_GREATER, COLOR) - CASE_TYPE(math, OP_GREATER, STRING_NAME) - CASE_TYPE(math, OP_GREATER, NODE_PATH) - CASE_TYPE(math, OP_GREATER, DICTIONARY) - CASE_TYPE(math, OP_GREATER, CALLABLE) - CASE_TYPE(math, OP_GREATER, SIGNAL) - - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_GREATER_EQUAL, p_a.type) { - CASE_TYPE(math, OP_GREATER_EQUAL, OBJECT) { - if (p_b.type != OBJECT) - _RETURN_FAIL; - _RETURN((p_a._get_obj().obj >= p_b._get_obj().obj)); - } - - DEFAULT_OP_NUM(math, OP_GREATER_EQUAL, INT, >=, _int); - DEFAULT_OP_NUM(math, OP_GREATER_EQUAL, FLOAT, >=, _float); - DEFAULT_OP_STR_REV(math, OP_GREATER_EQUAL, STRING, <=, String); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR2, <=, Vector2); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR2I, <=, Vector2i); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR3, <=, Vector3); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR3I, <=, Vector3i); - DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, _RID, <=, RID); - - CASE_TYPE(math, OP_GREATER_EQUAL, NIL) - CASE_TYPE(math, OP_GREATER_EQUAL, BOOL) - CASE_TYPE(math, OP_GREATER_EQUAL, RECT2) - CASE_TYPE(math, OP_GREATER_EQUAL, RECT2I) - CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM2D) - CASE_TYPE(math, OP_GREATER_EQUAL, PLANE) - CASE_TYPE(math, OP_GREATER_EQUAL, QUAT) - CASE_TYPE(math, OP_GREATER_EQUAL, AABB) - CASE_TYPE(math, OP_GREATER_EQUAL, BASIS) - CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM) - CASE_TYPE(math, OP_GREATER_EQUAL, COLOR) - CASE_TYPE(math, OP_GREATER_EQUAL, STRING_NAME) - CASE_TYPE(math, OP_GREATER_EQUAL, NODE_PATH) - CASE_TYPE(math, OP_GREATER_EQUAL, CALLABLE) - CASE_TYPE(math, OP_GREATER_EQUAL, SIGNAL) - - CASE_TYPE(math, OP_GREATER_EQUAL, DICTIONARY) - CASE_TYPE(math, OP_GREATER_EQUAL, ARRAY) - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_BYTE_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_INT32_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_INT64_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_FLOAT32_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_FLOAT64_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_STRING_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_VECTOR2_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_VECTOR3_ARRAY); - CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_COLOR_ARRAY); - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_ADD, p_a.type) { - CASE_TYPE(math, OP_ADD, ARRAY) { - if (p_a.type != p_b.type) - _RETURN_FAIL; - - const Array &array_a = *reinterpret_cast<const Array *>(p_a._data._mem); - const Array &array_b = *reinterpret_cast<const Array *>(p_b._data._mem); - Array sum; - int asize = array_a.size(); - int bsize = array_b.size(); - sum.resize(asize + bsize); - for (int i = 0; i < asize; i++) { - sum[i] = array_a[i]; - } - for (int i = 0; i < bsize; i++) { - sum[i + asize] = array_b[i]; - } - _RETURN(sum); - } - - DEFAULT_OP_NUM(math, OP_ADD, INT, +, _int); - DEFAULT_OP_NUM(math, OP_ADD, FLOAT, +, _float); - DEFAULT_OP_STR(math, OP_ADD, STRING, +, String); - DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR2, +, Vector2); - DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR2I, +, Vector2i); - DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR3, +, Vector3); - DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR3I, +, Vector3i); - DEFAULT_OP_LOCALMEM(math, OP_ADD, QUAT, +, Quat); - DEFAULT_OP_LOCALMEM(math, OP_ADD, COLOR, +, Color); - - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_BYTE_ARRAY, uint8_t); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_INT32_ARRAY, int32_t); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_INT64_ARRAY, int64_t); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_FLOAT32_ARRAY, float); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_FLOAT64_ARRAY, double); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_STRING_ARRAY, String); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_VECTOR2_ARRAY, Vector2); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_VECTOR3_ARRAY, Vector3); - DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_COLOR_ARRAY, Color); - - CASE_TYPE(math, OP_ADD, NIL) - CASE_TYPE(math, OP_ADD, BOOL) - CASE_TYPE(math, OP_ADD, RECT2) - CASE_TYPE(math, OP_ADD, RECT2I) - CASE_TYPE(math, OP_ADD, TRANSFORM2D) - CASE_TYPE(math, OP_ADD, PLANE) - CASE_TYPE(math, OP_ADD, AABB) - CASE_TYPE(math, OP_ADD, BASIS) - CASE_TYPE(math, OP_ADD, TRANSFORM) - CASE_TYPE(math, OP_ADD, STRING_NAME) - CASE_TYPE(math, OP_ADD, NODE_PATH) - CASE_TYPE(math, OP_ADD, _RID) - CASE_TYPE(math, OP_ADD, OBJECT) - CASE_TYPE(math, OP_ADD, CALLABLE) - CASE_TYPE(math, OP_ADD, SIGNAL) - - CASE_TYPE(math, OP_ADD, DICTIONARY) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_SUBTRACT, p_a.type) { - DEFAULT_OP_NUM(math, OP_SUBTRACT, INT, -, _int); - DEFAULT_OP_NUM(math, OP_SUBTRACT, FLOAT, -, _float); - DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR2, -, Vector2); - DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR2I, -, Vector2i); - DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR3, -, Vector3); - DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR3I, -, Vector3i); - DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, QUAT, -, Quat); - DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, COLOR, -, Color); - - CASE_TYPE(math, OP_SUBTRACT, NIL) - CASE_TYPE(math, OP_SUBTRACT, BOOL) - CASE_TYPE(math, OP_SUBTRACT, STRING) - CASE_TYPE(math, OP_SUBTRACT, RECT2) - CASE_TYPE(math, OP_SUBTRACT, RECT2I) - CASE_TYPE(math, OP_SUBTRACT, TRANSFORM2D) - CASE_TYPE(math, OP_SUBTRACT, PLANE) - CASE_TYPE(math, OP_SUBTRACT, AABB) - CASE_TYPE(math, OP_SUBTRACT, BASIS) - CASE_TYPE(math, OP_SUBTRACT, TRANSFORM) - CASE_TYPE(math, OP_SUBTRACT, STRING_NAME) - CASE_TYPE(math, OP_SUBTRACT, NODE_PATH) - CASE_TYPE(math, OP_SUBTRACT, _RID) - CASE_TYPE(math, OP_SUBTRACT, OBJECT) - CASE_TYPE(math, OP_SUBTRACT, CALLABLE) - CASE_TYPE(math, OP_SUBTRACT, SIGNAL) - - CASE_TYPE(math, OP_SUBTRACT, DICTIONARY) - CASE_TYPE(math, OP_SUBTRACT, ARRAY) - CASE_TYPE(math, OP_SUBTRACT, PACKED_BYTE_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_INT32_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_INT64_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_FLOAT32_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_FLOAT64_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_STRING_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_VECTOR2_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_VECTOR3_ARRAY); - CASE_TYPE(math, OP_SUBTRACT, PACKED_COLOR_ARRAY); - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_MULTIPLY, p_a.type) { - CASE_TYPE(math, OP_MULTIPLY, TRANSFORM2D) { - switch (p_b.type) { - case TRANSFORM2D: { - _RETURN(*p_a._data._transform2d * *p_b._data._transform2d); - } - case VECTOR2: { - _RETURN(p_a._data._transform2d->xform(*(const Vector2 *)p_b._data._mem)); - } - default: - _RETURN_FAIL; - } - } - - CASE_TYPE(math, OP_MULTIPLY, QUAT) { - switch (p_b.type) { - case VECTOR3: { - _RETURN(reinterpret_cast<const Quat *>(p_a._data._mem)->xform(*(const Vector3 *)p_b._data._mem)); - } - case QUAT: { - _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * *reinterpret_cast<const Quat *>(p_b._data._mem)); - } - case FLOAT: { - _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._float); - } - case INT: { - _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._int); - } - default: - _RETURN_FAIL; - } - } - - CASE_TYPE(math, OP_MULTIPLY, BASIS) { - switch (p_b.type) { - case VECTOR3: { - _RETURN(p_a._data._basis->xform(*(const Vector3 *)p_b._data._mem)); - } - case BASIS: { - _RETURN(*p_a._data._basis * *p_b._data._basis); - } - default: - _RETURN_FAIL; - } - } - - CASE_TYPE(math, OP_MULTIPLY, TRANSFORM) { - switch (p_b.type) { - case VECTOR3: { - _RETURN(p_a._data._transform->xform(*(const Vector3 *)p_b._data._mem)); - } - case TRANSFORM: { - _RETURN(*p_a._data._transform * *p_b._data._transform); - } - default: - _RETURN_FAIL; - } - } - - CASE_TYPE(math, OP_MULTIPLY, INT) { - if (p_b.type == INT) { - _RETURN(p_a._data._int * p_b._data._int); - } - if (p_b.type == FLOAT) { - _RETURN(p_a._data._int * p_b._data._float); - } - if (p_b.type == VECTOR2) { - _RETURN(p_a._data._int * *reinterpret_cast<const Vector2 *>(p_b._data._mem)); - } - if (p_b.type == VECTOR3) { - _RETURN(p_a._data._int * *reinterpret_cast<const Vector3 *>(p_b._data._mem)); - } - if (p_b.type == VECTOR2I) { - _RETURN(p_a._data._int * *reinterpret_cast<const Vector2i *>(p_b._data._mem)); - } - if (p_b.type == VECTOR3I) { - _RETURN(p_a._data._int * *reinterpret_cast<const Vector3i *>(p_b._data._mem)); - } - if (p_b.type == QUAT) { - _RETURN(p_a._data._int * *reinterpret_cast<const Quat *>(p_b._data._mem)); - } - if (p_b.type == COLOR) { - _RETURN(p_a._data._int * *reinterpret_cast<const Color *>(p_b._data._mem)); - } - - _RETURN_FAIL - } - - CASE_TYPE(math, OP_MULTIPLY, FLOAT) { - if (p_b.type == INT) { - _RETURN(p_a._data._float * p_b._data._int); - } - if (p_b.type == FLOAT) { - _RETURN(p_a._data._float * p_b._data._float); - } - if (p_b.type == VECTOR2) { - _RETURN(p_a._data._float * *reinterpret_cast<const Vector2 *>(p_b._data._mem)); - } - if (p_b.type == VECTOR3) { - _RETURN(p_a._data._float * *reinterpret_cast<const Vector3 *>(p_b._data._mem)); - } - if (p_b.type == VECTOR2I) { - _RETURN(p_a._data._float * *reinterpret_cast<const Vector2i *>(p_b._data._mem)); - } - if (p_b.type == VECTOR3I) { - _RETURN(p_a._data._float * *reinterpret_cast<const Vector3i *>(p_b._data._mem)); - } - if (p_b.type == QUAT) { - _RETURN(p_a._data._float * *reinterpret_cast<const Quat *>(p_b._data._mem)); - } - if (p_b.type == COLOR) { - _RETURN(p_a._data._float * *reinterpret_cast<const Color *>(p_b._data._mem)); - } - - _RETURN_FAIL - } - - DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR2, *, Vector2); - DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR2I, *, Vector2i); - DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR3, *, Vector3); - DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR3I, *, Vector3i); - DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, COLOR, *, Color); - - CASE_TYPE(math, OP_MULTIPLY, NIL) - CASE_TYPE(math, OP_MULTIPLY, BOOL) - CASE_TYPE(math, OP_MULTIPLY, STRING) - CASE_TYPE(math, OP_MULTIPLY, RECT2) - CASE_TYPE(math, OP_MULTIPLY, RECT2I) - CASE_TYPE(math, OP_MULTIPLY, PLANE) - CASE_TYPE(math, OP_MULTIPLY, AABB) - CASE_TYPE(math, OP_MULTIPLY, STRING_NAME) - CASE_TYPE(math, OP_MULTIPLY, NODE_PATH) - CASE_TYPE(math, OP_MULTIPLY, _RID) - CASE_TYPE(math, OP_MULTIPLY, OBJECT) - CASE_TYPE(math, OP_MULTIPLY, CALLABLE) - CASE_TYPE(math, OP_MULTIPLY, SIGNAL) - - CASE_TYPE(math, OP_MULTIPLY, DICTIONARY) - CASE_TYPE(math, OP_MULTIPLY, ARRAY) - CASE_TYPE(math, OP_MULTIPLY, PACKED_BYTE_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_INT32_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_INT64_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_FLOAT32_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_FLOAT64_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_STRING_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_VECTOR2_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_VECTOR3_ARRAY); - CASE_TYPE(math, OP_MULTIPLY, PACKED_COLOR_ARRAY); - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_DIVIDE, p_a.type) { - CASE_TYPE(math, OP_DIVIDE, QUAT) { - if (p_b.type != FLOAT) - _RETURN_FAIL; -#ifdef DEBUG_ENABLED - if (p_b._data._float == 0) { - r_valid = false; - _RETURN("Division By Zero"); - } -#endif - _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) / p_b._data._float); - } - - DEFAULT_OP_NUM_DIV(math, OP_DIVIDE, INT, _int); - DEFAULT_OP_NUM_DIV(math, OP_DIVIDE, FLOAT, _float); - DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR2, /, Vector2); - DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR2I, /, Vector2i); - DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR3, /, Vector3); - DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR3I, /, Vector3i); - DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, COLOR, /, Color); - - CASE_TYPE(math, OP_DIVIDE, NIL) - CASE_TYPE(math, OP_DIVIDE, BOOL) - CASE_TYPE(math, OP_DIVIDE, STRING) - CASE_TYPE(math, OP_DIVIDE, RECT2) - CASE_TYPE(math, OP_DIVIDE, RECT2I) - CASE_TYPE(math, OP_DIVIDE, TRANSFORM2D) - CASE_TYPE(math, OP_DIVIDE, PLANE) - CASE_TYPE(math, OP_DIVIDE, AABB) - CASE_TYPE(math, OP_DIVIDE, BASIS) - CASE_TYPE(math, OP_DIVIDE, TRANSFORM) - CASE_TYPE(math, OP_DIVIDE, STRING_NAME) - CASE_TYPE(math, OP_DIVIDE, NODE_PATH) - CASE_TYPE(math, OP_DIVIDE, _RID) - CASE_TYPE(math, OP_DIVIDE, OBJECT) - CASE_TYPE(math, OP_DIVIDE, CALLABLE) - CASE_TYPE(math, OP_DIVIDE, SIGNAL) - - CASE_TYPE(math, OP_DIVIDE, DICTIONARY) - CASE_TYPE(math, OP_DIVIDE, ARRAY) - CASE_TYPE(math, OP_DIVIDE, PACKED_BYTE_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_INT32_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_INT64_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_FLOAT32_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_FLOAT64_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_STRING_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_VECTOR2_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_VECTOR3_ARRAY); - CASE_TYPE(math, OP_DIVIDE, PACKED_COLOR_ARRAY); - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_POSITIVE, p_a.type) { - DEFAULT_OP_NUM_POS(math, OP_POSITIVE, INT, _int); - DEFAULT_OP_NUM_POS(math, OP_POSITIVE, FLOAT, _float); - DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR3, Vector3); - DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR3I, Vector3i); - DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, PLANE, Plane); - DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, QUAT, Quat); - DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR2, Vector2); - DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR2I, Vector2i); - - CASE_TYPE(math, OP_POSITIVE, NIL) - CASE_TYPE(math, OP_POSITIVE, BOOL) - CASE_TYPE(math, OP_POSITIVE, STRING) - CASE_TYPE(math, OP_POSITIVE, RECT2) - CASE_TYPE(math, OP_POSITIVE, RECT2I) - CASE_TYPE(math, OP_POSITIVE, TRANSFORM2D) - CASE_TYPE(math, OP_POSITIVE, AABB) - CASE_TYPE(math, OP_POSITIVE, BASIS) - CASE_TYPE(math, OP_POSITIVE, TRANSFORM) - CASE_TYPE(math, OP_POSITIVE, COLOR) - CASE_TYPE(math, OP_POSITIVE, STRING_NAME) - CASE_TYPE(math, OP_POSITIVE, NODE_PATH) - CASE_TYPE(math, OP_POSITIVE, _RID) - CASE_TYPE(math, OP_POSITIVE, OBJECT) - CASE_TYPE(math, OP_POSITIVE, CALLABLE) - CASE_TYPE(math, OP_POSITIVE, SIGNAL) - - CASE_TYPE(math, OP_POSITIVE, DICTIONARY) - CASE_TYPE(math, OP_POSITIVE, ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_BYTE_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_INT32_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_INT64_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_FLOAT32_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_FLOAT64_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_STRING_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_VECTOR2_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_VECTOR3_ARRAY) - CASE_TYPE(math, OP_POSITIVE, PACKED_COLOR_ARRAY) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_NEGATE, p_a.type) { - DEFAULT_OP_NUM_NEG(math, OP_NEGATE, INT, _int); - DEFAULT_OP_NUM_NEG(math, OP_NEGATE, FLOAT, _float); - - DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR2, Vector2); - DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR2I, Vector2i); - DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR3, Vector3); - DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR3I, Vector3i); - DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, PLANE, Plane); - DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, QUAT, Quat); - DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, COLOR, Color); - - CASE_TYPE(math, OP_NEGATE, NIL) - CASE_TYPE(math, OP_NEGATE, BOOL) - CASE_TYPE(math, OP_NEGATE, STRING) - CASE_TYPE(math, OP_NEGATE, RECT2) - CASE_TYPE(math, OP_NEGATE, RECT2I) - CASE_TYPE(math, OP_NEGATE, TRANSFORM2D) - CASE_TYPE(math, OP_NEGATE, AABB) - CASE_TYPE(math, OP_NEGATE, BASIS) - CASE_TYPE(math, OP_NEGATE, TRANSFORM) - CASE_TYPE(math, OP_NEGATE, STRING_NAME) - CASE_TYPE(math, OP_NEGATE, NODE_PATH) - CASE_TYPE(math, OP_NEGATE, _RID) - CASE_TYPE(math, OP_NEGATE, OBJECT) - CASE_TYPE(math, OP_NEGATE, CALLABLE) - CASE_TYPE(math, OP_NEGATE, SIGNAL) - - CASE_TYPE(math, OP_NEGATE, DICTIONARY) - CASE_TYPE(math, OP_NEGATE, ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_BYTE_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_INT32_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_INT64_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_FLOAT32_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_FLOAT64_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_STRING_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_VECTOR2_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_VECTOR3_ARRAY) - CASE_TYPE(math, OP_NEGATE, PACKED_COLOR_ARRAY) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_MODULE, p_a.type) { - CASE_TYPE(math, OP_MODULE, INT) { - if (p_b.type != INT) - _RETURN_FAIL; -#ifdef DEBUG_ENABLED - if (p_b._data._int == 0) { - r_valid = false; - _RETURN("Division By Zero"); - } -#endif - _RETURN(p_a._data._int % p_b._data._int); - } - - CASE_TYPE(math, OP_MODULE, STRING) { - const String *format = reinterpret_cast<const String *>(p_a._data._mem); - - String result; - bool error; - if (p_b.type == ARRAY) { - // e.g. "frog %s %d" % ["fish", 12] - const Array *args = reinterpret_cast<const Array *>(p_b._data._mem); - result = format->sprintf(*args, &error); - } else { - // e.g. "frog %d" % 12 - Array args; - args.push_back(p_b); - result = format->sprintf(args, &error); - } - r_valid = !error; - _RETURN(result); - } - - CASE_TYPE(math, OP_MODULE, NIL) - CASE_TYPE(math, OP_MODULE, BOOL) - CASE_TYPE(math, OP_MODULE, FLOAT) - CASE_TYPE(math, OP_MODULE, VECTOR2) - CASE_TYPE(math, OP_MODULE, VECTOR2I) - CASE_TYPE(math, OP_MODULE, RECT2) - CASE_TYPE(math, OP_MODULE, RECT2I) - CASE_TYPE(math, OP_MODULE, VECTOR3) - CASE_TYPE(math, OP_MODULE, VECTOR3I) - CASE_TYPE(math, OP_MODULE, TRANSFORM2D) - CASE_TYPE(math, OP_MODULE, PLANE) - CASE_TYPE(math, OP_MODULE, QUAT) - CASE_TYPE(math, OP_MODULE, AABB) - CASE_TYPE(math, OP_MODULE, BASIS) - CASE_TYPE(math, OP_MODULE, TRANSFORM) - CASE_TYPE(math, OP_MODULE, COLOR) - CASE_TYPE(math, OP_MODULE, STRING_NAME) - CASE_TYPE(math, OP_MODULE, NODE_PATH) - CASE_TYPE(math, OP_MODULE, _RID) - CASE_TYPE(math, OP_MODULE, OBJECT) - CASE_TYPE(math, OP_MODULE, CALLABLE) - CASE_TYPE(math, OP_MODULE, SIGNAL) - - CASE_TYPE(math, OP_MODULE, DICTIONARY) - CASE_TYPE(math, OP_MODULE, ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_BYTE_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_INT32_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_INT64_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_FLOAT32_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_FLOAT64_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_STRING_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_VECTOR2_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_VECTOR3_ARRAY) - CASE_TYPE(math, OP_MODULE, PACKED_COLOR_ARRAY) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_STRING_CONCAT, p_a.type) { - CASE_TYPE_ALL(math, OP_STRING_CONCAT) - - _RETURN(p_a.operator String() + p_b.operator String()); - } - - SWITCH_OP(math, OP_SHIFT_LEFT, p_a.type) { - CASE_TYPE(math, OP_SHIFT_LEFT, INT) { - if (p_b.type != INT) - _RETURN_FAIL; - if (p_b._data._int < 0 || p_b._data._int >= 64) - _RETURN_FAIL; - _RETURN(p_a._data._int << p_b._data._int); - } - - CASE_TYPE_ALL_BUT_INT(math, OP_SHIFT_LEFT) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_SHIFT_RIGHT, p_a.type) { - CASE_TYPE(math, OP_SHIFT_RIGHT, INT) { - if (p_b.type != INT) - _RETURN_FAIL; - if (p_b._data._int < 0 || p_b._data._int >= 64) - _RETURN_FAIL; - _RETURN(p_a._data._int >> p_b._data._int); - } - - CASE_TYPE_ALL_BUT_INT(math, OP_SHIFT_RIGHT) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_BIT_AND, p_a.type) { - CASE_TYPE(math, OP_BIT_AND, INT) { - if (p_b.type != INT) - _RETURN_FAIL; - _RETURN(p_a._data._int & p_b._data._int); - } - - CASE_TYPE_ALL_BUT_INT(math, OP_BIT_AND) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_BIT_OR, p_a.type) { - CASE_TYPE(math, OP_BIT_OR, INT) { - if (p_b.type != INT) - _RETURN_FAIL; - _RETURN(p_a._data._int | p_b._data._int); - } - - CASE_TYPE_ALL_BUT_INT(math, OP_BIT_OR) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_BIT_XOR, p_a.type) { - CASE_TYPE(math, OP_BIT_XOR, INT) { - if (p_b.type != INT) - _RETURN_FAIL; - _RETURN(p_a._data._int ^ p_b._data._int); - } - - CASE_TYPE_ALL_BUT_INT(math, OP_BIT_XOR) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_BIT_NEGATE, p_a.type) { - CASE_TYPE(math, OP_BIT_NEGATE, INT) { - _RETURN(~p_a._data._int); - } - - CASE_TYPE_ALL_BUT_INT(math, OP_BIT_NEGATE) - _RETURN_FAIL; - } - - SWITCH_OP(math, OP_AND, p_a.type) { - CASE_TYPE_ALL(math, OP_AND) { - bool l = p_a.booleanize(); - bool r = p_b.booleanize(); - - _RETURN(l && r); - } - } - - SWITCH_OP(math, OP_OR, p_a.type) { - CASE_TYPE_ALL(math, OP_OR) { - bool l = p_a.booleanize(); - bool r = p_b.booleanize(); - - _RETURN(l || r); - } - } - - SWITCH_OP(math, OP_XOR, p_a.type) { - CASE_TYPE_ALL(math, OP_XOR) { - bool l = p_a.booleanize(); - bool r = p_b.booleanize(); - - _RETURN((l || r) && !(l && r)); - } - } - - SWITCH_OP(math, OP_NOT, p_a.type) { - CASE_TYPE_ALL(math, OP_NOT) { - bool l = p_a.booleanize(); - _RETURN(!l); - } - } - - SWITCH_OP(math, OP_IN, p_a.type) { - CASE_TYPE_ALL(math, OP_IN) - _RETURN(p_b.in(p_a, &r_valid)); - } - } -} - -void Variant::set_named(const StringName &p_index, const Variant &p_value, bool *r_valid) { - bool valid = false; - switch (type) { - case VECTOR2: { - if (p_value.type == Variant::INT) { - Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._int; - valid = true; - } - } else if (p_value.type == Variant::FLOAT) { - Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._float; - valid = true; - } - } - - } break; - case VECTOR2I: { - if (p_value.type == Variant::INT) { - Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._int; - valid = true; - } - } else if (p_value.type == Variant::FLOAT) { - Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._float; - valid = true; - } - } - - } break; - case RECT2: { - if (p_value.type == Variant::VECTOR2) { - Rect2 *v = reinterpret_cast<Rect2 *>(_data._mem); - //scalar name - if (p_index == CoreStringNames::singleton->position) { - v->position = *reinterpret_cast<const Vector2 *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->size) { - v->size = *reinterpret_cast<const Vector2 *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->end) { - v->size = *reinterpret_cast<const Vector2 *>(p_value._data._mem) - v->position; - valid = true; - } - } - } break; - case RECT2I: { - if (p_value.type == Variant::VECTOR2I) { - Rect2i *v = reinterpret_cast<Rect2i *>(_data._mem); - //scalar name - if (p_index == CoreStringNames::singleton->position) { - v->position = *reinterpret_cast<const Vector2i *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->size) { - v->size = *reinterpret_cast<const Vector2i *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->end) { - v->size = *reinterpret_cast<const Vector2i *>(p_value._data._mem) - v->position; - valid = true; - } - } - } break; - case TRANSFORM2D: { - if (p_value.type == Variant::VECTOR2) { - Transform2D *v = _data._transform2d; - if (p_index == CoreStringNames::singleton->x) { - v->elements[0] = *reinterpret_cast<const Vector2 *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->elements[1] = *reinterpret_cast<const Vector2 *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->origin) { - v->elements[2] = *reinterpret_cast<const Vector2 *>(p_value._data._mem); - valid = true; - } - } - - } break; - case VECTOR3: { - if (p_value.type == Variant::INT) { - Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->z = p_value._data._int; - valid = true; - } - } else if (p_value.type == Variant::FLOAT) { - Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->z = p_value._data._float; - valid = true; - } - } - - } break; - case VECTOR3I: { - if (p_value.type == Variant::INT) { - Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->z = p_value._data._int; - valid = true; - } - } else if (p_value.type == Variant::FLOAT) { - Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->z = p_value._data._float; - valid = true; - } - } - - } break; - case PLANE: { - if (p_value.type == Variant::INT) { - Plane *v = reinterpret_cast<Plane *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->normal.x = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->normal.y = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->normal.z = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->d) { - v->d = p_value._data._int; - valid = true; - } - } else if (p_value.type == Variant::FLOAT) { - Plane *v = reinterpret_cast<Plane *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->normal.x = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->normal.y = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->normal.z = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->d) { - v->d = p_value._data._float; - valid = true; - } - - } else if (p_value.type == Variant::VECTOR3) { - Plane *v = reinterpret_cast<Plane *>(_data._mem); - if (p_index == CoreStringNames::singleton->normal) { - v->normal = *reinterpret_cast<const Vector3 *>(p_value._data._mem); - valid = true; - } - } - - } break; - case QUAT: { - if (p_value.type == Variant::INT) { - Quat *v = reinterpret_cast<Quat *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->z = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->w) { - v->w = p_value._data._int; - valid = true; - } - } else if (p_value.type == Variant::FLOAT) { - Quat *v = reinterpret_cast<Quat *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - v->x = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->y = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->z = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->w) { - v->w = p_value._data._float; - valid = true; - } - } - - } break; - case AABB: { - if (p_value.type == Variant::VECTOR3) { - ::AABB *v = _data._aabb; - //scalar name - if (p_index == CoreStringNames::singleton->position) { - v->position = *reinterpret_cast<const Vector3 *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->size) { - v->size = *reinterpret_cast<const Vector3 *>(p_value._data._mem); - valid = true; - } else if (p_index == CoreStringNames::singleton->end) { - v->size = *reinterpret_cast<const Vector3 *>(p_value._data._mem) - v->position; - valid = true; - } - } - } break; - case BASIS: { - if (p_value.type == Variant::VECTOR3) { - Basis *v = _data._basis; - //scalar name - if (p_index == CoreStringNames::singleton->x) { - v->set_axis(0, *reinterpret_cast<const Vector3 *>(p_value._data._mem)); - valid = true; - } else if (p_index == CoreStringNames::singleton->y) { - v->set_axis(1, *reinterpret_cast<const Vector3 *>(p_value._data._mem)); - valid = true; - } else if (p_index == CoreStringNames::singleton->z) { - v->set_axis(2, *reinterpret_cast<const Vector3 *>(p_value._data._mem)); - valid = true; - } - } - } break; - case TRANSFORM: { - if (p_value.type == Variant::BASIS && p_index == CoreStringNames::singleton->basis) { - _data._transform->basis = *p_value._data._basis; - valid = true; - } else if (p_value.type == Variant::VECTOR3 && p_index == CoreStringNames::singleton->origin) { - _data._transform->origin = *reinterpret_cast<const Vector3 *>(p_value._data._mem); - valid = true; - } - - } break; - case COLOR: { - if (p_value.type == Variant::INT) { - Color *v = reinterpret_cast<Color *>(_data._mem); - if (p_index == CoreStringNames::singleton->r) { - v->r = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->g) { - v->g = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->b) { - v->b = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->a) { - v->a = p_value._data._int; - valid = true; - } else if (p_index == CoreStringNames::singleton->r8) { - v->r = p_value._data._int / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->g8) { - v->g = p_value._data._int / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->b8) { - v->b = p_value._data._int / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->a8) { - v->a = p_value._data._int / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->h) { - v->set_hsv(p_value._data._int, v->get_s(), v->get_v(), v->a); - valid = true; - } else if (p_index == CoreStringNames::singleton->s) { - v->set_hsv(v->get_h(), p_value._data._int, v->get_v(), v->a); - valid = true; - } else if (p_index == CoreStringNames::singleton->v) { - v->set_hsv(v->get_h(), v->get_v(), p_value._data._int, v->a); - valid = true; - } - } else if (p_value.type == Variant::FLOAT) { - Color *v = reinterpret_cast<Color *>(_data._mem); - if (p_index == CoreStringNames::singleton->r) { - v->r = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->g) { - v->g = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->b) { - v->b = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->a) { - v->a = p_value._data._float; - valid = true; - } else if (p_index == CoreStringNames::singleton->r8) { - v->r = p_value._data._float / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->g8) { - v->g = p_value._data._float / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->b8) { - v->b = p_value._data._float / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->a8) { - v->a = p_value._data._float / 255.0; - valid = true; - } else if (p_index == CoreStringNames::singleton->h) { - v->set_hsv(p_value._data._float, v->get_s(), v->get_v(), v->a); - valid = true; - } else if (p_index == CoreStringNames::singleton->s) { - v->set_hsv(v->get_h(), p_value._data._float, v->get_v(), v->a); - valid = true; - } else if (p_index == CoreStringNames::singleton->v) { - v->set_hsv(v->get_h(), v->get_s(), p_value._data._float, v->a); - valid = true; - } - } - } break; - case OBJECT: { -#ifdef DEBUG_ENABLED - if (!_get_obj().obj) { - break; - } else if (EngineDebugger::is_active() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - break; - } - -#endif - _get_obj().obj->set(p_index, p_value, &valid); - - } break; - default: { - set(p_index.operator String(), p_value, &valid); - } break; - } - - if (r_valid) { - *r_valid = valid; - } -} - -Variant Variant::get_named(const StringName &p_index, bool *r_valid) const { - if (r_valid) { - *r_valid = true; - } - - switch (type) { - case VECTOR2: { - const Vector2 *v = reinterpret_cast<const Vector2 *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - return v->x; - } else if (p_index == CoreStringNames::singleton->y) { - return v->y; - } - - } break; - case VECTOR2I: { - const Vector2i *v = reinterpret_cast<const Vector2i *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - return v->x; - } else if (p_index == CoreStringNames::singleton->y) { - return v->y; - } - - } break; - case RECT2: { - const Rect2 *v = reinterpret_cast<const Rect2 *>(_data._mem); - //scalar name - if (p_index == CoreStringNames::singleton->position) { - return v->position; - } else if (p_index == CoreStringNames::singleton->size) { - return v->size; - } else if (p_index == CoreStringNames::singleton->end) { - return v->size + v->position; - } - } break; - case RECT2I: { - const Rect2i *v = reinterpret_cast<const Rect2i *>(_data._mem); - //scalar name - if (p_index == CoreStringNames::singleton->position) { - return v->position; - } else if (p_index == CoreStringNames::singleton->size) { - return v->size; - } else if (p_index == CoreStringNames::singleton->end) { - return v->size + v->position; - } - } break; - case TRANSFORM2D: { - const Transform2D *v = _data._transform2d; - if (p_index == CoreStringNames::singleton->x) { - return v->elements[0]; - } else if (p_index == CoreStringNames::singleton->y) { - return v->elements[1]; - } else if (p_index == CoreStringNames::singleton->origin) { - return v->elements[2]; - } - - } break; - case VECTOR3: { - const Vector3 *v = reinterpret_cast<const Vector3 *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - return v->x; - } else if (p_index == CoreStringNames::singleton->y) { - return v->y; - } else if (p_index == CoreStringNames::singleton->z) { - return v->z; - } - - } break; - case VECTOR3I: { - const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - return v->x; - } else if (p_index == CoreStringNames::singleton->y) { - return v->y; - } else if (p_index == CoreStringNames::singleton->z) { - return v->z; - } - - } break; - case PLANE: { - const Plane *v = reinterpret_cast<const Plane *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - return v->normal.x; - } else if (p_index == CoreStringNames::singleton->y) { - return v->normal.y; - } else if (p_index == CoreStringNames::singleton->z) { - return v->normal.z; - } else if (p_index == CoreStringNames::singleton->d) { - return v->d; - } else if (p_index == CoreStringNames::singleton->normal) { - return v->normal; - } - - } break; - case QUAT: { - const Quat *v = reinterpret_cast<const Quat *>(_data._mem); - if (p_index == CoreStringNames::singleton->x) { - return v->x; - } else if (p_index == CoreStringNames::singleton->y) { - return v->y; - } else if (p_index == CoreStringNames::singleton->z) { - return v->z; - } else if (p_index == CoreStringNames::singleton->w) { - return v->w; - } - - } break; - case AABB: { - const ::AABB *v = _data._aabb; - //scalar name - if (p_index == CoreStringNames::singleton->position) { - return v->position; - } else if (p_index == CoreStringNames::singleton->size) { - return v->size; - } else if (p_index == CoreStringNames::singleton->end) { - return v->size + v->position; - } - } break; - case BASIS: { - const Basis *v = _data._basis; - //scalar name - if (p_index == CoreStringNames::singleton->x) { - return v->get_axis(0); - } else if (p_index == CoreStringNames::singleton->y) { - return v->get_axis(1); - } else if (p_index == CoreStringNames::singleton->z) { - return v->get_axis(2); - } - - } break; - case TRANSFORM: { - if (p_index == CoreStringNames::singleton->basis) { - return _data._transform->basis; - } else if (p_index == CoreStringNames::singleton->origin) { - return _data._transform->origin; - } - - } break; - case COLOR: { - const Color *v = reinterpret_cast<const Color *>(_data._mem); - if (p_index == CoreStringNames::singleton->r) { - return v->r; - } else if (p_index == CoreStringNames::singleton->g) { - return v->g; - } else if (p_index == CoreStringNames::singleton->b) { - return v->b; - } else if (p_index == CoreStringNames::singleton->a) { - return v->a; - } else if (p_index == CoreStringNames::singleton->r8) { - return int(Math::round(v->r * 255.0)); - } else if (p_index == CoreStringNames::singleton->g8) { - return int(Math::round(v->g * 255.0)); - } else if (p_index == CoreStringNames::singleton->b8) { - return int(Math::round(v->b * 255.0)); - } else if (p_index == CoreStringNames::singleton->a8) { - return int(Math::round(v->a * 255.0)); - } else if (p_index == CoreStringNames::singleton->h) { - return v->get_h(); - } else if (p_index == CoreStringNames::singleton->s) { - return v->get_s(); - } else if (p_index == CoreStringNames::singleton->v) { - return v->get_v(); - } - } break; - case OBJECT: { -#ifdef DEBUG_ENABLED - if (!_get_obj().obj) { - if (r_valid) { - *r_valid = false; - } - return "Instance base is null."; - } else { - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - if (r_valid) { - *r_valid = false; - } - return "Attempted use of stray pointer object."; - } - } - -#endif - - return _get_obj().obj->get(p_index, r_valid); - - } break; - default: { - return get(p_index.operator String(), r_valid); - } - } - - if (r_valid) { - *r_valid = false; - } - return Variant(); -} - -#define DEFAULT_OP_ARRAY_CMD(m_name, m_type, skip_test, cmd) \ - case m_name: { \ - skip_test; \ - \ - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \ - int index = p_index; \ - m_type *arr = reinterpret_cast<m_type *>(_data._mem); \ - \ - if (index < 0) \ - index += arr->size(); \ - if (index >= 0 && index < arr->size()) { \ - valid = true; \ - cmd; \ - } \ - } \ - } break; - -#define DEFAULT_OP_DVECTOR_SET(m_name, m_type, skip_cond) \ - case m_name: { \ - if (skip_cond) \ - return; \ - \ - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \ - int index = p_index; \ - Vector<m_type> *arr = PackedArrayRef<m_type>::get_array_ptr(_data.packed_array); \ - \ - if (index < 0) \ - index += arr->size(); \ - if (index >= 0 && index < arr->size()) { \ - valid = true; \ - arr->set(index, p_value); \ - } \ - } \ - } break; - -#define DEFAULT_OP_DVECTOR_GET(m_name, m_type) \ - case m_name: { \ - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \ - int index = p_index; \ - const Vector<m_type> *arr = &PackedArrayRef<m_type>::get_array(_data.packed_array); \ - \ - if (index < 0) \ - index += arr->size(); \ - if (index >= 0 && index < arr->size()) { \ - valid = true; \ - return arr->get(index); \ - } \ - } \ - } break; - -void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) { - static bool _dummy = false; - - bool &valid = r_valid ? *r_valid : _dummy; - valid = false; - - switch (type) { - case NIL: { - return; - } break; - case BOOL: { - return; - } break; - case INT: { - return; - } break; - case FLOAT: { - return; - } break; - case STRING: { - if (p_index.type != Variant::INT && p_index.type != Variant::FLOAT) { - return; - } - - int idx = p_index; - String *str = reinterpret_cast<String *>(_data._mem); - int len = str->length(); - if (idx < 0) { - idx += len; - } - if (idx < 0 || idx >= len) { - return; - } - - String chr; - if (p_value.type == Variant::INT || p_value.type == Variant::FLOAT) { - chr = String::chr(p_value); - } else if (p_value.type == Variant::STRING) { - chr = p_value; - } else { - return; - } - - *str = str->substr(0, idx) + chr + str->substr(idx + 1, len); - valid = true; - return; - - } break; - case VECTOR2: { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - // scalar index - int idx = p_index; - - if (idx < 0) { - idx += 2; - } - if (idx >= 0 && idx < 2) { - Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem); - valid = true; - (*v)[idx] = p_value; - return; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem); - if (*str == "x") { - valid = true; - v->x = p_value; - return; - } else if (*str == "y") { - valid = true; - v->y = p_value; - return; - } - } - - } break; - case VECTOR2I: { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - // scalar index - int idx = p_index; - - if (idx < 0) { - idx += 2; - } - if (idx >= 0 && idx < 2) { - Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem); - valid = true; - (*v)[idx] = p_value; - return; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem); - if (*str == "x") { - valid = true; - v->x = p_value; - return; - } else if (*str == "y") { - valid = true; - v->y = p_value; - return; - } - } - - } break; - case RECT2: { - if (p_value.type != Variant::VECTOR2) { - return; - } - - if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Rect2 *v = reinterpret_cast<Rect2 *>(_data._mem); - if (*str == "position") { - valid = true; - v->position = p_value; - return; - } else if (*str == "size") { - valid = true; - v->size = p_value; - return; - } else if (*str == "end") { - valid = true; - v->size = Vector2(p_value) - v->position; - return; - } - } - } break; - case RECT2I: { - if (p_value.type != Variant::VECTOR2I) { - return; - } - - if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Rect2i *v = reinterpret_cast<Rect2i *>(_data._mem); - if (*str == "position") { - valid = true; - v->position = p_value; - return; - } else if (*str == "size") { - valid = true; - v->size = p_value; - return; - } else if (*str == "end") { - valid = true; - v->size = Vector2i(p_value) - v->position; - return; - } - } - } break; - case TRANSFORM2D: { - if (p_value.type != Variant::VECTOR2) { - return; - } - - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int index = p_index; - - if (index < 0) { - index += 3; - } - if (index >= 0 && index < 3) { - Transform2D *v = _data._transform2d; - - valid = true; - v->elements[index] = p_value; - return; - } - } else if (p_index.get_type() == Variant::STRING && p_value.get_type() == Variant::VECTOR2) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Transform2D *v = _data._transform2d; - if (*str == "x") { - valid = true; - v->elements[0] = p_value; - return; - } else if (*str == "y") { - valid = true; - v->elements[1] = p_value; - return; - } else if (*str == "origin") { - valid = true; - v->elements[2] = p_value; - return; - } - } - - } break; - case VECTOR3: { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - //scalar index - int idx = p_index; - if (idx < 0) { - idx += 3; - } - if (idx >= 0 && idx < 3) { - Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem); - valid = true; - (*v)[idx] = p_value; - return; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem); - if (*str == "x") { - valid = true; - v->x = p_value; - return; - } else if (*str == "y") { - valid = true; - v->y = p_value; - return; - } else if (*str == "z") { - valid = true; - v->z = p_value; - return; - } - } - - } break; - case VECTOR3I: { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - //scalar index - int idx = p_index; - if (idx < 0) { - idx += 3; - } - if (idx >= 0 && idx < 3) { - Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem); - valid = true; - (*v)[idx] = p_value; - return; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem); - if (*str == "x") { - valid = true; - v->x = p_value; - return; - } else if (*str == "y") { - valid = true; - v->y = p_value; - return; - } else if (*str == "z") { - valid = true; - v->z = p_value; - return; - } - } - - } break; - case PLANE: { - if (p_index.get_type() == Variant::STRING) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Plane *v = reinterpret_cast<Plane *>(_data._mem); - if (*str == "x") { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - valid = true; - v->normal.x = p_value; - return; - } else if (*str == "y") { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - valid = true; - v->normal.y = p_value; - return; - } else if (*str == "z") { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - valid = true; - v->normal.z = p_value; - return; - } else if (*str == "normal") { - if (p_value.type != Variant::VECTOR3) { - return; - } - - valid = true; - v->normal = p_value; - return; - } else if (*str == "d") { - valid = true; - v->d = p_value; - return; - } - } - - } break; - case QUAT: { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - if (p_index.get_type() == Variant::STRING) { - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Quat *v = reinterpret_cast<Quat *>(_data._mem); - if (*str == "x") { - valid = true; - v->x = p_value; - return; - } else if (*str == "y") { - valid = true; - v->y = p_value; - return; - } else if (*str == "z") { - valid = true; - v->z = p_value; - return; - } else if (*str == "w") { - valid = true; - v->w = p_value; - return; - } - } - - } break; - case AABB: { - if (p_value.type != Variant::VECTOR3) { - return; - } - - if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - ::AABB *v = _data._aabb; - if (*str == "position") { - valid = true; - v->position = p_value; - return; - } else if (*str == "size") { - valid = true; - v->size = p_value; - return; - } else if (*str == "end") { - valid = true; - v->size = Vector3(p_value) - v->position; - return; - } - } - } break; - case BASIS: { - if (p_value.type != Variant::VECTOR3) { - return; - } - - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int index = p_index; - - if (index < 0) { - index += 3; - } - if (index >= 0 && index < 3) { - Basis *v = _data._basis; - - valid = true; - v->set_axis(index, p_value); - return; - } - } else if (p_index.get_type() == Variant::STRING) { - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Basis *v = _data._basis; - - if (*str == "x") { - valid = true; - v->set_axis(0, p_value); - return; - } else if (*str == "y") { - valid = true; - v->set_axis(1, p_value); - return; - } else if (*str == "z") { - valid = true; - v->set_axis(2, p_value); - return; - } - } - - } break; - case TRANSFORM: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - if (p_value.type != Variant::VECTOR3) { - return; - } - - int index = p_index; - - if (index < 0) { - index += 4; - } - if (index >= 0 && index < 4) { - Transform *v = _data._transform; - valid = true; - if (index == 3) { - v->origin = p_value; - } else { - v->basis.set_axis(index, p_value); - } - return; - } - } else if (p_index.get_type() == Variant::STRING) { - Transform *v = _data._transform; - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - - if (*str == "basis") { - if (p_value.type != Variant::BASIS) { - return; - } - valid = true; - v->basis = p_value; - return; - } - if (*str == "origin") { - if (p_value.type != Variant::VECTOR3) { - return; - } - valid = true; - v->origin = p_value; - return; - } - } - - } break; - case COLOR: { - if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) { - return; - } - - if (p_index.get_type() == Variant::STRING) { - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Color *v = reinterpret_cast<Color *>(_data._mem); - if (*str == "r") { - valid = true; - v->r = p_value; - return; - } else if (*str == "g") { - valid = true; - v->g = p_value; - return; - } else if (*str == "b") { - valid = true; - v->b = p_value; - return; - } else if (*str == "a") { - valid = true; - v->a = p_value; - return; - } else if (*str == "h") { - valid = true; - v->set_hsv(p_value, v->get_s(), v->get_v(), v->a); - return; - } else if (*str == "s") { - valid = true; - v->set_hsv(v->get_h(), p_value, v->get_v(), v->a); - return; - } else if (*str == "v") { - valid = true; - v->set_hsv(v->get_h(), v->get_s(), p_value, v->a); - return; - } else if (*str == "r8") { - valid = true; - v->r = float(p_value) / 255.0; - return; - } else if (*str == "g8") { - valid = true; - v->g = float(p_value) / 255.0; - return; - } else if (*str == "b8") { - valid = true; - v->b = float(p_value) / 255.0; - return; - } else if (*str == "a8") { - valid = true; - v->a = float(p_value) / 255.0; - return; - } - } else if (p_index.get_type() == Variant::INT) { - int idx = p_index; - if (idx < 0) { - idx += 4; - } - if (idx >= 0 && idx < 4) { - Color *v = reinterpret_cast<Color *>(_data._mem); - (*v)[idx] = p_value; - valid = true; - } - } - - } break; - case STRING_NAME: { - } break; - case NODE_PATH: { - } break; - case _RID: { - } break; - case OBJECT: { - Object *obj = _get_obj().obj; - //only if debugging! - - if (obj) { -#ifdef DEBUG_ENABLED - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - WARN_PRINT("Attempted use of previously freed pointer object."); - valid = false; - return; - } -#endif - - if (p_index.get_type() != Variant::STRING_NAME && p_index.get_type() != Variant::STRING) { - obj->setvar(p_index, p_value, r_valid); - return; - } - - obj->set(p_index, p_value, r_valid); - return; - } - } break; - case DICTIONARY: { - Dictionary *dic = reinterpret_cast<Dictionary *>(_data._mem); - dic->operator[](p_index) = p_value; - valid = true; //always valid, i guess? should this really be ok? - return; - } break; - DEFAULT_OP_ARRAY_CMD(ARRAY, Array, ;, (*arr)[index] = p_value; return ) - DEFAULT_OP_DVECTOR_SET(PACKED_BYTE_ARRAY, uint8_t, p_value.type != Variant::FLOAT && p_value.type != Variant::INT) - DEFAULT_OP_DVECTOR_SET(PACKED_INT32_ARRAY, int32_t, p_value.type != Variant::FLOAT && p_value.type != Variant::INT) - DEFAULT_OP_DVECTOR_SET(PACKED_INT64_ARRAY, int64_t, p_value.type != Variant::FLOAT && p_value.type != Variant::INT) - DEFAULT_OP_DVECTOR_SET(PACKED_FLOAT32_ARRAY, float, p_value.type != Variant::FLOAT && p_value.type != Variant::INT) - DEFAULT_OP_DVECTOR_SET(PACKED_FLOAT64_ARRAY, double, p_value.type != Variant::FLOAT && p_value.type != Variant::INT) - DEFAULT_OP_DVECTOR_SET(PACKED_STRING_ARRAY, String, p_value.type != Variant::STRING) - DEFAULT_OP_DVECTOR_SET(PACKED_VECTOR2_ARRAY, Vector2, p_value.type != Variant::VECTOR2) - DEFAULT_OP_DVECTOR_SET(PACKED_VECTOR3_ARRAY, Vector3, p_value.type != Variant::VECTOR3) - DEFAULT_OP_DVECTOR_SET(PACKED_COLOR_ARRAY, Color, p_value.type != Variant::COLOR) - default: - return; - } -} - -Variant Variant::get(const Variant &p_index, bool *r_valid) const { - static bool _dummy = false; - - bool &valid = r_valid ? *r_valid : _dummy; - - valid = false; - - switch (type) { - case NIL: { - return Variant(); - } break; - case BOOL: { - return Variant(); - } break; - case INT: { - return Variant(); - } break; - case FLOAT: { - return Variant(); - } break; - case STRING: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - //string index - - int idx = p_index; - const String *str = reinterpret_cast<const String *>(_data._mem); - if (idx < 0) { - idx += str->length(); - } - if (idx >= 0 && idx < str->length()) { - valid = true; - return str->substr(idx, 1); - } - } - - } break; - case VECTOR2: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - // scalar index - int idx = p_index; - if (idx < 0) { - idx += 2; - } - if (idx >= 0 && idx < 2) { - const Vector2 *v = reinterpret_cast<const Vector2 *>(_data._mem); - valid = true; - return (*v)[idx]; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Vector2 *v = reinterpret_cast<const Vector2 *>(_data._mem); - if (*str == "x") { - valid = true; - return v->x; - } else if (*str == "y") { - valid = true; - return v->y; - } - } - - } break; - case VECTOR2I: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - // scalar index - int idx = p_index; - if (idx < 0) { - idx += 2; - } - if (idx >= 0 && idx < 2) { - const Vector2i *v = reinterpret_cast<const Vector2i *>(_data._mem); - valid = true; - return (*v)[idx]; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Vector2i *v = reinterpret_cast<const Vector2i *>(_data._mem); - if (*str == "x") { - valid = true; - return v->x; - } else if (*str == "y") { - valid = true; - return v->y; - } - } - - } break; - case RECT2: { - if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Rect2 *v = reinterpret_cast<const Rect2 *>(_data._mem); - if (*str == "position") { - valid = true; - return v->position; - } else if (*str == "size") { - valid = true; - return v->size; - } else if (*str == "end") { - valid = true; - return v->size + v->position; - } - } - } break; - case RECT2I: { - if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Rect2i *v = reinterpret_cast<const Rect2i *>(_data._mem); - if (*str == "position") { - valid = true; - return v->position; - } else if (*str == "size") { - valid = true; - return v->size; - } else if (*str == "end") { - valid = true; - return v->size + v->position; - } - } - } break; - case VECTOR3: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - //scalar index - int idx = p_index; - if (idx < 0) { - idx += 3; - } - if (idx >= 0 && idx < 3) { - const Vector3 *v = reinterpret_cast<const Vector3 *>(_data._mem); - valid = true; - return (*v)[idx]; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Vector3 *v = reinterpret_cast<const Vector3 *>(_data._mem); - if (*str == "x") { - valid = true; - return v->x; - } else if (*str == "y") { - valid = true; - return v->y; - } else if (*str == "z") { - valid = true; - return v->z; - } - } - - } break; - case VECTOR3I: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - //scalar index - int idx = p_index; - if (idx < 0) { - idx += 3; - } - if (idx >= 0 && idx < 3) { - const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem); - valid = true; - return (*v)[idx]; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem); - if (*str == "x") { - valid = true; - return v->x; - } else if (*str == "y") { - valid = true; - return v->y; - } else if (*str == "z") { - valid = true; - return v->z; - } - } - - } break; - case TRANSFORM2D: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int index = p_index; - - if (index < 0) { - index += 3; - } - if (index >= 0 && index < 3) { - const Transform2D *v = _data._transform2d; - - valid = true; - return v->elements[index]; - } - } else if (p_index.get_type() == Variant::STRING) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Transform2D *v = _data._transform2d; - if (*str == "x") { - valid = true; - return v->elements[0]; - } else if (*str == "y") { - valid = true; - return v->elements[1]; - } else if (*str == "origin") { - valid = true; - return v->elements[2]; - } - } - - } break; - case PLANE: { - if (p_index.get_type() == Variant::STRING) { - //scalar name - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Plane *v = reinterpret_cast<const Plane *>(_data._mem); - if (*str == "x") { - valid = true; - return v->normal.x; - } else if (*str == "y") { - valid = true; - return v->normal.y; - } else if (*str == "z") { - valid = true; - return v->normal.z; - } else if (*str == "normal") { - valid = true; - return v->normal; - } else if (*str == "d") { - valid = true; - return v->d; - } - } - - } break; - case QUAT: { - if (p_index.get_type() == Variant::STRING) { - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Quat *v = reinterpret_cast<const Quat *>(_data._mem); - if (*str == "x") { - valid = true; - return v->x; - } else if (*str == "y") { - valid = true; - return v->y; - } else if (*str == "z") { - valid = true; - return v->z; - } else if (*str == "w") { - valid = true; - return v->w; - } - } - - } break; - case AABB: { - if (p_index.get_type() == Variant::STRING) { - //scalar name - - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const ::AABB *v = _data._aabb; - if (*str == "position") { - valid = true; - return v->position; - } else if (*str == "size") { - valid = true; - return v->size; - } else if (*str == "end") { - valid = true; - return v->size + v->position; - } - } - } break; - case BASIS: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int index = p_index; - if (index < 0) { - index += 3; - } - if (index >= 0 && index < 3) { - const Basis *v = _data._basis; - - valid = true; - return v->get_axis(index); - } - } else if (p_index.get_type() == Variant::STRING) { - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Basis *v = _data._basis; - - if (*str == "x") { - valid = true; - return v->get_axis(0); - } else if (*str == "y") { - valid = true; - return v->get_axis(1); - } else if (*str == "z") { - valid = true; - return v->get_axis(2); - } - } - - } break; - case TRANSFORM: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int index = p_index; - if (index < 0) { - index += 4; - } - if (index >= 0 && index < 4) { - const Transform *v = _data._transform; - valid = true; - return index == 3 ? v->origin : v->basis.get_axis(index); - } - } else if (p_index.get_type() == Variant::STRING) { - const Transform *v = _data._transform; - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - - if (*str == "basis") { - valid = true; - return v->basis; - } - if (*str == "origin") { - valid = true; - return v->origin; - } - } - - } break; - case COLOR: { - if (p_index.get_type() == Variant::STRING) { - const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Color *v = reinterpret_cast<const Color *>(_data._mem); - if (*str == "r") { - valid = true; - return v->r; - } else if (*str == "g") { - valid = true; - return v->g; - } else if (*str == "b") { - valid = true; - return v->b; - } else if (*str == "a") { - valid = true; - return v->a; - } else if (*str == "h") { - valid = true; - return v->get_h(); - } else if (*str == "s") { - valid = true; - return v->get_s(); - } else if (*str == "v") { - valid = true; - return v->get_v(); - } else if (*str == "r8") { - valid = true; - return (int)Math::round(v->r * 255.0); - } else if (*str == "g8") { - valid = true; - return (int)Math::round(v->g * 255.0); - } else if (*str == "b8") { - valid = true; - return (int)Math::round(v->b * 255.0); - } else if (*str == "a8") { - valid = true; - return (int)Math::round(v->a * 255.0); - } - } else if (p_index.get_type() == Variant::INT) { - int idx = p_index; - if (idx < 0) { - idx += 4; - } - if (idx >= 0 && idx < 4) { - const Color *v = reinterpret_cast<const Color *>(_data._mem); - valid = true; - return (*v)[idx]; - } - } - - } break; - case STRING_NAME: { - } break; - case NODE_PATH: { - } break; - case _RID: { - } break; - case OBJECT: { - Object *obj = _get_obj().obj; - if (obj) { -#ifdef DEBUG_ENABLED - - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - valid = false; - return "Attempted get on previously freed instance."; - } -#endif - - if (p_index.get_type() != Variant::STRING) { - return obj->getvar(p_index, r_valid); - } - - return obj->get(p_index, r_valid); - } - - } break; - case DICTIONARY: { - const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); - const Variant *res = dic->getptr(p_index); - if (res) { - valid = true; - return *res; - } - } break; - DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, ;, return (*arr)[index]) - DEFAULT_OP_DVECTOR_GET(PACKED_BYTE_ARRAY, uint8_t) - DEFAULT_OP_DVECTOR_GET(PACKED_INT32_ARRAY, int32_t) - DEFAULT_OP_DVECTOR_GET(PACKED_INT64_ARRAY, int64_t) - DEFAULT_OP_DVECTOR_GET(PACKED_FLOAT32_ARRAY, float) - DEFAULT_OP_DVECTOR_GET(PACKED_FLOAT64_ARRAY, double) - DEFAULT_OP_DVECTOR_GET(PACKED_STRING_ARRAY, String) - DEFAULT_OP_DVECTOR_GET(PACKED_VECTOR2_ARRAY, Vector2) - DEFAULT_OP_DVECTOR_GET(PACKED_VECTOR3_ARRAY, Vector3) - DEFAULT_OP_DVECTOR_GET(PACKED_COLOR_ARRAY, Color) - default: - return Variant(); - } - - return Variant(); -} - -bool Variant::in(const Variant &p_index, bool *r_valid) const { - if (r_valid) { - *r_valid = true; - } - - switch (type) { - case STRING: { - if (p_index.get_type() == Variant::STRING) { - //string index - String idx = p_index; - const String *str = reinterpret_cast<const String *>(_data._mem); - - return str->find(idx) != -1; - } - - } break; - case OBJECT: { - Object *obj = _get_obj().obj; - if (obj) { - bool valid = false; -#ifdef DEBUG_ENABLED - - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - if (r_valid) { - *r_valid = false; - } - return true; // Attempted get on stray pointer. - } - -#endif - - if (p_index.get_type() != Variant::STRING) { - obj->getvar(p_index, &valid); - } else { - obj->get(p_index, &valid); - } - - return valid; - } else { - if (r_valid) { - *r_valid = false; - } - } - return false; - } break; - case DICTIONARY: { - const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); - return dic->has(p_index); - - } break; - case ARRAY: { - const Array *arr = reinterpret_cast<const Array *>(_data._mem); - int l = arr->size(); - if (l) { - for (int i = 0; i < l; i++) { - if (evaluate(OP_EQUAL, (*arr)[i], p_index)) { - return true; - } - } - } - - return false; - - } break; - case PACKED_BYTE_ARRAY: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int index = p_index; - const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array); - int l = arr->size(); - if (l) { - const uint8_t *r = arr->ptr(); - for (int i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - - } break; - case PACKED_INT32_ARRAY: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int32_t index = p_index; - const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array); - int32_t l = arr->size(); - if (l) { - const int32_t *r = arr->ptr(); - for (int32_t i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - } break; - case PACKED_INT64_ARRAY: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - int64_t index = p_index; - const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array); - int64_t l = arr->size(); - if (l) { - const int64_t *r = arr->ptr(); - for (int64_t i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - } break; - case PACKED_FLOAT32_ARRAY: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - real_t index = p_index; - const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array); - int l = arr->size(); - if (l) { - const float *r = arr->ptr(); - for (int i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - - } break; - case PACKED_FLOAT64_ARRAY: { - if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { - real_t index = p_index; - const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array); - int l = arr->size(); - if (l) { - const double *r = arr->ptr(); - for (int i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - - } break; - case PACKED_STRING_ARRAY: { - if (p_index.get_type() == Variant::STRING) { - String index = p_index; - const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array); - - int l = arr->size(); - if (l) { - const String *r = arr->ptr(); - for (int i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - - } break; //25 - case PACKED_VECTOR2_ARRAY: { - if (p_index.get_type() == Variant::VECTOR2) { - Vector2 index = p_index; - const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array); - - int l = arr->size(); - if (l) { - const Vector2 *r = arr->ptr(); - for (int i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - - } break; - case PACKED_VECTOR3_ARRAY: { - if (p_index.get_type() == Variant::VECTOR3) { - Vector3 index = p_index; - const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array); - - int l = arr->size(); - if (l) { - const Vector3 *r = arr->ptr(); - for (int i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - - } break; - case PACKED_COLOR_ARRAY: { - if (p_index.get_type() == Variant::COLOR) { - Color index = p_index; - const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array); - - int l = arr->size(); - if (l) { - const Color *r = arr->ptr(); - for (int i = 0; i < l; i++) { - if (r[i] == index) { - return true; - } - } - } - - return false; - } - } break; - default: { - } - } - - if (r_valid) { - *r_valid = false; - } - return false; -} - -void Variant::get_property_list(List<PropertyInfo> *p_list) const { - switch (type) { - case VECTOR2: { - p_list->push_back(PropertyInfo(Variant::FLOAT, "x")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "y")); - - } break; - case VECTOR2I: { - p_list->push_back(PropertyInfo(Variant::INT, "x")); - p_list->push_back(PropertyInfo(Variant::INT, "y")); - - } break; - case RECT2: { - p_list->push_back(PropertyInfo(Variant::VECTOR2, "position")); - p_list->push_back(PropertyInfo(Variant::VECTOR2, "size")); - p_list->push_back(PropertyInfo(Variant::VECTOR2, "end")); - - } break; - case RECT2I: { - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "position")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "size")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "end")); - - } break; - case VECTOR3: { - p_list->push_back(PropertyInfo(Variant::FLOAT, "x")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "y")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "z")); - - } break; - case VECTOR3I: { - p_list->push_back(PropertyInfo(Variant::INT, "x")); - p_list->push_back(PropertyInfo(Variant::INT, "y")); - p_list->push_back(PropertyInfo(Variant::INT, "z")); - - } break; - case TRANSFORM2D: { - p_list->push_back(PropertyInfo(Variant::VECTOR2, "x")); - p_list->push_back(PropertyInfo(Variant::VECTOR2, "y")); - p_list->push_back(PropertyInfo(Variant::VECTOR2, "origin")); - - } break; - case PLANE: { - p_list->push_back(PropertyInfo(Variant::VECTOR3, "normal")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "x")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "y")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "z")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "d")); - - } break; - case QUAT: { - p_list->push_back(PropertyInfo(Variant::FLOAT, "x")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "y")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "z")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "w")); - - } break; - case AABB: { - p_list->push_back(PropertyInfo(Variant::VECTOR3, "position")); - p_list->push_back(PropertyInfo(Variant::VECTOR3, "size")); - p_list->push_back(PropertyInfo(Variant::VECTOR3, "end")); - } break; - case BASIS: { - p_list->push_back(PropertyInfo(Variant::VECTOR3, "x")); - p_list->push_back(PropertyInfo(Variant::VECTOR3, "y")); - p_list->push_back(PropertyInfo(Variant::VECTOR3, "z")); - - } break; - case TRANSFORM: { - p_list->push_back(PropertyInfo(Variant::BASIS, "basis")); - p_list->push_back(PropertyInfo(Variant::VECTOR3, "origin")); - - } break; - case COLOR: { - p_list->push_back(PropertyInfo(Variant::FLOAT, "r")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "g")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "b")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "a")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "h")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "s")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "v")); - p_list->push_back(PropertyInfo(Variant::INT, "r8")); - p_list->push_back(PropertyInfo(Variant::INT, "g8")); - p_list->push_back(PropertyInfo(Variant::INT, "b8")); - p_list->push_back(PropertyInfo(Variant::INT, "a8")); - - } break; - case STRING_NAME: { - } break; - case NODE_PATH: { - } break; - case _RID: { - } break; - case OBJECT: { - Object *obj = _get_obj().obj; - if (obj) { -#ifdef DEBUG_ENABLED - - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - WARN_PRINT("Attempted get_property list on previously freed instance."); - return; - } - -#endif - - obj->get_property_list(p_list); - } - - } break; - case DICTIONARY: { - const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); - List<Variant> keys; - dic->get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - if (E->get().get_type() == Variant::STRING) { - p_list->push_back(PropertyInfo(Variant::STRING, E->get())); - } - } - } break; - case ARRAY: - case PACKED_BYTE_ARRAY: - case PACKED_INT32_ARRAY: - case PACKED_INT64_ARRAY: - case PACKED_FLOAT32_ARRAY: - case PACKED_FLOAT64_ARRAY: - case PACKED_STRING_ARRAY: - case PACKED_VECTOR2_ARRAY: - case PACKED_VECTOR3_ARRAY: - case PACKED_COLOR_ARRAY: { - //nothing - } break; - default: { - } - } -} - -bool Variant::iter_init(Variant &r_iter, bool &valid) const { - valid = true; - switch (type) { - case INT: { - r_iter = 0; - return _data._int > 0; - } break; - case FLOAT: { - r_iter = 0; - return _data._float > 0.0; - } break; - case VECTOR2: { - double from = reinterpret_cast<const Vector2 *>(_data._mem)->x; - double to = reinterpret_cast<const Vector2 *>(_data._mem)->y; - - r_iter = from; - - return from < to; - } break; - case VECTOR2I: { - int64_t from = reinterpret_cast<const Vector2i *>(_data._mem)->x; - int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y; - - r_iter = from; - - return from < to; - } break; - case VECTOR3: { - double from = reinterpret_cast<const Vector3 *>(_data._mem)->x; - double to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - double step = reinterpret_cast<const Vector3 *>(_data._mem)->z; - - r_iter = from; - - if (from == to) { - return false; - } else if (from < to) { - return step > 0; - } - return step < 0; - } break; - case VECTOR3I: { - int64_t from = reinterpret_cast<const Vector3i *>(_data._mem)->x; - int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y; - int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z; - - r_iter = from; - - if (from == to) { - return false; - } else if (from < to) { - return step > 0; - } - return step < 0; - } break; - case OBJECT: { - if (!_get_obj().obj) { - valid = false; - return false; - } - -#ifdef DEBUG_ENABLED - - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - valid = false; - return false; - } - -#endif - Callable::CallError ce; - ce.error = Callable::CallError::CALL_OK; - Array ref; - ref.push_back(r_iter); - Variant vref = ref; - const Variant *refp[] = { &vref }; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce); - - if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { - valid = false; - return false; - } - - r_iter = ref[0]; - return ret; - } break; - - case STRING: { - const String *str = reinterpret_cast<const String *>(_data._mem); - if (str->empty()) { - return false; - } - r_iter = 0; - return true; - } break; - case DICTIONARY: { - const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); - if (dic->empty()) { - return false; - } - - const Variant *next = dic->next(nullptr); - r_iter = *next; - return true; - - } break; - case ARRAY: { - const Array *arr = reinterpret_cast<const Array *>(_data._mem); - if (arr->empty()) { - return false; - } - r_iter = 0; - return true; - } break; - case PACKED_BYTE_ARRAY: { - const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - - } break; - case PACKED_INT32_ARRAY: { - const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - - } break; - case PACKED_INT64_ARRAY: { - const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - - } break; - case PACKED_FLOAT32_ARRAY: { - const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - - } break; - case PACKED_FLOAT64_ARRAY: { - const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - - } break; - case PACKED_STRING_ARRAY: { - const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - } break; - case PACKED_VECTOR2_ARRAY: { - const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - } break; - case PACKED_VECTOR3_ARRAY: { - const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - } break; - case PACKED_COLOR_ARRAY: { - const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array); - if (arr->size() == 0) { - return false; - } - r_iter = 0; - return true; - - } break; - default: { - } - } - - valid = false; - return false; -} - -bool Variant::iter_next(Variant &r_iter, bool &valid) const { - valid = true; - switch (type) { - case INT: { - int64_t idx = r_iter; - idx++; - if (idx >= _data._int) { - return false; - } - r_iter = idx; - return true; - } break; - case FLOAT: { - int64_t idx = r_iter; - idx++; - if (idx >= _data._float) { - return false; - } - r_iter = idx; - return true; - } break; - case VECTOR2: { - double to = reinterpret_cast<const Vector2 *>(_data._mem)->y; - - double idx = r_iter; - idx++; - - if (idx >= to) { - return false; - } - - r_iter = idx; - return true; - } break; - case VECTOR2I: { - int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y; - - int64_t idx = r_iter; - idx++; - - if (idx >= to) { - return false; - } - - r_iter = idx; - return true; - } break; - case VECTOR3: { - double to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - double step = reinterpret_cast<const Vector3 *>(_data._mem)->z; - - double idx = r_iter; - idx += step; - - if (step < 0 && idx <= to) { - return false; - } - - if (step > 0 && idx >= to) { - return false; - } - - r_iter = idx; - return true; - } break; - case VECTOR3I: { - int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y; - int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z; - - int64_t idx = r_iter; - idx += step; - - if (step < 0 && idx <= to) { - return false; - } - - if (step > 0 && idx >= to) { - return false; - } - - r_iter = idx; - return true; - } break; - case OBJECT: { - if (!_get_obj().obj) { - valid = false; - return false; - } - -#ifdef DEBUG_ENABLED - - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - valid = false; - return false; - } - -#endif - Callable::CallError ce; - ce.error = Callable::CallError::CALL_OK; - Array ref; - ref.push_back(r_iter); - Variant vref = ref; - const Variant *refp[] = { &vref }; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce); - - if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { - valid = false; - return false; - } - - r_iter = ref[0]; - - return ret; - } break; - - case STRING: { - const String *str = reinterpret_cast<const String *>(_data._mem); - int idx = r_iter; - idx++; - if (idx >= str->length()) { - return false; - } - r_iter = idx; - return true; - } break; - case DICTIONARY: { - const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); - const Variant *next = dic->next(&r_iter); - if (!next) { - return false; - } - - r_iter = *next; - return true; - - } break; - case ARRAY: { - const Array *arr = reinterpret_cast<const Array *>(_data._mem); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - } break; - case PACKED_BYTE_ARRAY: { - const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - - } break; - case PACKED_INT32_ARRAY: { - const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array); - int32_t idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - - } break; - case PACKED_INT64_ARRAY: { - const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array); - int64_t idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - - } break; - case PACKED_FLOAT32_ARRAY: { - const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - - } break; - case PACKED_FLOAT64_ARRAY: { - const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - - } break; - case PACKED_STRING_ARRAY: { - const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - } break; - case PACKED_VECTOR2_ARRAY: { - const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - } break; - case PACKED_VECTOR3_ARRAY: { - const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - } break; - case PACKED_COLOR_ARRAY: { - const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array); - int idx = r_iter; - idx++; - if (idx >= arr->size()) { - return false; - } - r_iter = idx; - return true; - } break; - default: { - } - } - - valid = false; - return false; -} - -Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { - r_valid = true; - switch (type) { - case INT: { - return r_iter; - } break; - case FLOAT: { - return r_iter; - } break; - case VECTOR2: { - return r_iter; - } break; - case VECTOR2I: { - return r_iter; - } break; - case VECTOR3: { - return r_iter; - } break; - case VECTOR3I: { - return r_iter; - } break; - case OBJECT: { - if (!_get_obj().obj) { - r_valid = false; - return Variant(); - } -#ifdef DEBUG_ENABLED - if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - r_valid = false; - return Variant(); - } - -#endif - Callable::CallError ce; - ce.error = Callable::CallError::CALL_OK; - const Variant *refp[] = { &r_iter }; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce); - - if (ce.error != Callable::CallError::CALL_OK) { - r_valid = false; - return Variant(); - } - - //r_iter=ref[0]; - - return ret; - } break; - - case STRING: { - const String *str = reinterpret_cast<const String *>(_data._mem); - return str->substr(r_iter, 1); - } break; - case DICTIONARY: { - return r_iter; //iterator is the same as the key - - } break; - case ARRAY: { - const Array *arr = reinterpret_cast<const Array *>(_data._mem); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_BYTE_ARRAY: { - const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_INT32_ARRAY: { - const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array); - int32_t idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_INT64_ARRAY: { - const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array); - int64_t idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_FLOAT32_ARRAY: { - const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_FLOAT64_ARRAY: { - const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_STRING_ARRAY: { - const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_VECTOR2_ARRAY: { - const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_VECTOR3_ARRAY: { - const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - case PACKED_COLOR_ARRAY: { - const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array); - int idx = r_iter; -#ifdef DEBUG_ENABLED - if (idx < 0 || idx >= arr->size()) { - r_valid = false; - return Variant(); - } -#endif - return arr->get(idx); - } break; - default: { - } - } - - r_valid = false; - return Variant(); -} - -Variant Variant::duplicate(bool deep) const { - switch (type) { - case OBJECT: { - /* breaks stuff :( - if (deep && !_get_obj().ref.is_null()) { - Ref<Resource> resource = _get_obj().ref; - if (resource.is_valid()) { - return resource->duplicate(true); - } - } - */ - return *this; - } break; - case DICTIONARY: - return operator Dictionary().duplicate(deep); - case ARRAY: - return operator Array().duplicate(deep); - default: - return *this; - } -} - -void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) { - if (a.type != b.type) { - if (a.is_num() && b.is_num()) { - real_t va = a; - real_t vb = b; - r_dst = va + vb * c; - } else { - r_dst = a; - } - return; - } - - switch (a.type) { - case NIL: { - r_dst = Variant(); - } - return; - case INT: { - int64_t va = a._data._int; - int64_t vb = b._data._int; - r_dst = int(va + vb * c + 0.5); - } - return; - case FLOAT: { - double ra = a._data._float; - double rb = b._data._float; - r_dst = ra + rb * c; - } - return; - case VECTOR2: { - r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) + *reinterpret_cast<const Vector2 *>(b._data._mem) * c; - } - return; - case VECTOR2I: { - int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x; - int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x; - int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y; - int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y; - r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5)); - } - return; - case RECT2: { - const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem); - const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem); - r_dst = Rect2(ra->position + rb->position * c, ra->size + rb->size * c); - } - return; - case RECT2I: { - const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem); - const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem); - - int32_t vax = ra->position.x; - int32_t vay = ra->position.y; - int32_t vbx = ra->size.x; - int32_t vby = ra->size.y; - int32_t vcx = rb->position.x; - int32_t vcy = rb->position.y; - int32_t vdx = rb->size.x; - int32_t vdy = rb->size.y; - - r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5)); - } - return; - case VECTOR3: { - r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) + *reinterpret_cast<const Vector3 *>(b._data._mem) * c; - } - return; - case VECTOR3I: { - int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x; - int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x; - int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y; - int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y; - int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z; - int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z; - r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5)); - } - return; - case AABB: { - const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem); - const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem); - r_dst = ::AABB(ra->position + rb->position * c, ra->size + rb->size * c); - } - return; - case QUAT: { - Quat empty_rot; - const Quat *qa = reinterpret_cast<const Quat *>(a._data._mem); - const Quat *qb = reinterpret_cast<const Quat *>(b._data._mem); - r_dst = *qa * empty_rot.slerp(*qb, c); - } - return; - case COLOR: { - const Color *ca = reinterpret_cast<const Color *>(a._data._mem); - const Color *cb = reinterpret_cast<const Color *>(b._data._mem); - float new_r = ca->r + cb->r * c; - float new_g = ca->g + cb->g * c; - float new_b = ca->b + cb->b * c; - float new_a = ca->a + cb->a * c; - new_r = new_r > 1.0 ? 1.0 : new_r; - new_g = new_g > 1.0 ? 1.0 : new_g; - new_b = new_b > 1.0 ? 1.0 : new_b; - new_a = new_a > 1.0 ? 1.0 : new_a; - r_dst = Color(new_r, new_g, new_b, new_a); - } - return; - default: { - r_dst = c < 0.5 ? a : b; - } - return; - } -} - -void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst) { - if (a.type != b.type) { - if (a.is_num() && b.is_num()) { - //not as efficient but.. - real_t va = a; - real_t vb = b; - r_dst = va + (vb - va) * c; - - } else { - r_dst = a; - } - return; - } - - switch (a.type) { - case NIL: { - r_dst = Variant(); - } - return; - case BOOL: { - r_dst = a; - } - return; - case INT: { - int64_t va = a._data._int; - int64_t vb = b._data._int; - r_dst = int(va + (vb - va) * c); - } - return; - case FLOAT: { - real_t va = a._data._float; - real_t vb = b._data._float; - r_dst = va + (vb - va) * c; - } - return; - case STRING: { - //this is pretty funny and bizarre, but artists like to use it for typewritter effects - String sa = *reinterpret_cast<const String *>(a._data._mem); - String sb = *reinterpret_cast<const String *>(b._data._mem); - String dst; - int sa_len = sa.length(); - int sb_len = sb.length(); - int csize = sa_len + (sb_len - sa_len) * c; - if (csize == 0) { - r_dst = ""; - return; - } - dst.resize(csize + 1); - dst[csize] = 0; - int split = csize / 2; - - for (int i = 0; i < csize; i++) { - char32_t chr = ' '; - - if (i < split) { - if (i < sa.length()) { - chr = sa[i]; - } else if (i < sb.length()) { - chr = sb[i]; - } - - } else { - if (i < sb.length()) { - chr = sb[i]; - } else if (i < sa.length()) { - chr = sa[i]; - } - } - - dst[i] = chr; - } - - r_dst = dst; - } - return; - case VECTOR2: { - r_dst = reinterpret_cast<const Vector2 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector2 *>(b._data._mem), c); - } - return; - case VECTOR2I: { - int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x; - int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x; - int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y; - int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y; - r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5)); - } - return; - - case RECT2: { - r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c)); - } - return; - case RECT2I: { - const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem); - const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem); - - int32_t vax = ra->position.x; - int32_t vay = ra->position.y; - int32_t vbx = ra->size.x; - int32_t vby = ra->size.y; - int32_t vcx = rb->position.x; - int32_t vcy = rb->position.y; - int32_t vdx = rb->size.x; - int32_t vdy = rb->size.y; - - r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5)); - } - return; - - case VECTOR3: { - r_dst = reinterpret_cast<const Vector3 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector3 *>(b._data._mem), c); - } - return; - case VECTOR3I: { - int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x; - int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x; - int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y; - int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y; - int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z; - int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z; - r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5)); - } - return; - - case TRANSFORM2D: { - r_dst = a._data._transform2d->interpolate_with(*b._data._transform2d, c); - } - return; - case PLANE: { - r_dst = a; - } - return; - case QUAT: { - r_dst = reinterpret_cast<const Quat *>(a._data._mem)->slerp(*reinterpret_cast<const Quat *>(b._data._mem), c); - } - return; - case AABB: { - r_dst = ::AABB(a._data._aabb->position.lerp(b._data._aabb->position, c), a._data._aabb->size.lerp(b._data._aabb->size, c)); - } - return; - case BASIS: { - r_dst = Transform(*a._data._basis).interpolate_with(Transform(*b._data._basis), c).basis; - } - return; - case TRANSFORM: { - r_dst = a._data._transform->interpolate_with(*b._data._transform, c); - } - return; - case COLOR: { - r_dst = reinterpret_cast<const Color *>(a._data._mem)->lerp(*reinterpret_cast<const Color *>(b._data._mem), c); - } - return; - case STRING_NAME: { - r_dst = a; - } - return; - case NODE_PATH: { - r_dst = a; - } - return; - case _RID: { - r_dst = a; - } - return; - case OBJECT: { - r_dst = a; - } - return; - case DICTIONARY: { - } - return; - case ARRAY: { - r_dst = a; - } - return; - case PACKED_BYTE_ARRAY: { - r_dst = a; - } - return; - case PACKED_INT32_ARRAY: { - const Vector<int32_t> *arr_a = &PackedArrayRef<int32_t>::get_array(a._data.packed_array); - const Vector<int32_t> *arr_b = &PackedArrayRef<int32_t>::get_array(b._data.packed_array); - int32_t sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { - r_dst = a; - } else { - Vector<int32_t> v; - v.resize(sz); - { - int32_t *vw = v.ptrw(); - const int32_t *ar = arr_a->ptr(); - const int32_t *br = arr_b->ptr(); - - Variant va; - for (int32_t i = 0; i < sz; i++) { - Variant::interpolate(ar[i], br[i], c, va); - vw[i] = va; - } - } - r_dst = v; - } - } - return; - case PACKED_INT64_ARRAY: { - const Vector<int64_t> *arr_a = &PackedArrayRef<int64_t>::get_array(a._data.packed_array); - const Vector<int64_t> *arr_b = &PackedArrayRef<int64_t>::get_array(b._data.packed_array); - int64_t sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { - r_dst = a; - } else { - Vector<int64_t> v; - v.resize(sz); - { - int64_t *vw = v.ptrw(); - const int64_t *ar = arr_a->ptr(); - const int64_t *br = arr_b->ptr(); - - Variant va; - for (int64_t i = 0; i < sz; i++) { - Variant::interpolate(ar[i], br[i], c, va); - vw[i] = va; - } - } - r_dst = v; - } - } - return; - case PACKED_FLOAT32_ARRAY: { - const Vector<float> *arr_a = &PackedArrayRef<float>::get_array(a._data.packed_array); - const Vector<float> *arr_b = &PackedArrayRef<float>::get_array(b._data.packed_array); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { - r_dst = a; - } else { - Vector<float> v; - v.resize(sz); - { - float *vw = v.ptrw(); - const float *ar = arr_a->ptr(); - const float *br = arr_b->ptr(); - - Variant va; - for (int i = 0; i < sz; i++) { - Variant::interpolate(ar[i], br[i], c, va); - vw[i] = va; - } - } - r_dst = v; - } - } - return; - case PACKED_FLOAT64_ARRAY: { - const Vector<double> *arr_a = &PackedArrayRef<double>::get_array(a._data.packed_array); - const Vector<double> *arr_b = &PackedArrayRef<double>::get_array(b._data.packed_array); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { - r_dst = a; - } else { - Vector<double> v; - v.resize(sz); - { - double *vw = v.ptrw(); - const double *ar = arr_a->ptr(); - const double *br = arr_b->ptr(); - - Variant va; - for (int i = 0; i < sz; i++) { - Variant::interpolate(ar[i], br[i], c, va); - vw[i] = va; - } - } - r_dst = v; - } - } - return; - case PACKED_STRING_ARRAY: { - r_dst = a; - } - return; - case PACKED_VECTOR2_ARRAY: { - const Vector<Vector2> *arr_a = &PackedArrayRef<Vector2>::get_array(a._data.packed_array); - const Vector<Vector2> *arr_b = &PackedArrayRef<Vector2>::get_array(b._data.packed_array); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { - r_dst = a; - } else { - Vector<Vector2> v; - v.resize(sz); - { - Vector2 *vw = v.ptrw(); - const Vector2 *ar = arr_a->ptr(); - const Vector2 *br = arr_b->ptr(); - - for (int i = 0; i < sz; i++) { - vw[i] = ar[i].lerp(br[i], c); - } - } - r_dst = v; - } - } - return; - case PACKED_VECTOR3_ARRAY: { - const Vector<Vector3> *arr_a = &PackedArrayRef<Vector3>::get_array(a._data.packed_array); - const Vector<Vector3> *arr_b = &PackedArrayRef<Vector3>::get_array(b._data.packed_array); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { - r_dst = a; - } else { - Vector<Vector3> v; - v.resize(sz); - { - Vector3 *vw = v.ptrw(); - const Vector3 *ar = arr_a->ptr(); - const Vector3 *br = arr_b->ptr(); - - for (int i = 0; i < sz; i++) { - vw[i] = ar[i].lerp(br[i], c); - } - } - r_dst = v; - } - } - return; - case PACKED_COLOR_ARRAY: { - const Vector<Color> *arr_a = &PackedArrayRef<Color>::get_array(a._data.packed_array); - const Vector<Color> *arr_b = &PackedArrayRef<Color>::get_array(b._data.packed_array); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { - r_dst = a; - } else { - Vector<Color> v; - v.resize(sz); - { - Color *vw = v.ptrw(); - const Color *ar = arr_a->ptr(); - const Color *br = arr_b->ptr(); - - for (int i = 0; i < sz; i++) { - vw[i] = ar[i].lerp(br[i], c); - } - } - r_dst = v; - } - } - return; - default: { - r_dst = a; - } - } -} - -static const char *_op_names[Variant::OP_MAX] = { - "==", - "!=", - "<", - "<=", - ">", - ">=", - "+", - "-", - "*", - "/", - "- (negation)", - "+ (positive)", - "%", - "+ (concatenation)", - "<<", - ">>", - "&", - "|", - "^", - "~", - "and", - "or", - "xor", - "not", - "in" - -}; - -String Variant::get_operator_name(Operator p_op) { - ERR_FAIL_INDEX_V(p_op, OP_MAX, ""); - return _op_names[p_op]; -} diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 2b1770f12b..ee65bbc07e 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1594,43 +1594,40 @@ <constant name="OP_MODULE" value="12" enum="Variant.Operator"> Remainder/modulo operator ([code]%[/code]). </constant> - <constant name="OP_STRING_CONCAT" value="13" enum="Variant.Operator"> - String concatenation operator ([code]+[/code]). - </constant> - <constant name="OP_SHIFT_LEFT" value="14" enum="Variant.Operator"> + <constant name="OP_SHIFT_LEFT" value="13" enum="Variant.Operator"> Left shift operator ([code]<<[/code]). </constant> - <constant name="OP_SHIFT_RIGHT" value="15" enum="Variant.Operator"> + <constant name="OP_SHIFT_RIGHT" value="14" enum="Variant.Operator"> Right shift operator ([code]>>[/code]). </constant> - <constant name="OP_BIT_AND" value="16" enum="Variant.Operator"> + <constant name="OP_BIT_AND" value="15" enum="Variant.Operator"> Bitwise AND operator ([code]&[/code]). </constant> - <constant name="OP_BIT_OR" value="17" enum="Variant.Operator"> + <constant name="OP_BIT_OR" value="16" enum="Variant.Operator"> Bitwise OR operator ([code]|[/code]). </constant> - <constant name="OP_BIT_XOR" value="18" enum="Variant.Operator"> + <constant name="OP_BIT_XOR" value="17" enum="Variant.Operator"> Bitwise XOR operator ([code]^[/code]). </constant> - <constant name="OP_BIT_NEGATE" value="19" enum="Variant.Operator"> + <constant name="OP_BIT_NEGATE" value="18" enum="Variant.Operator"> Bitwise NOT operator ([code]~[/code]). </constant> - <constant name="OP_AND" value="20" enum="Variant.Operator"> + <constant name="OP_AND" value="19" enum="Variant.Operator"> Logical AND operator ([code]and[/code] or [code]&&[/code]). </constant> - <constant name="OP_OR" value="21" enum="Variant.Operator"> + <constant name="OP_OR" value="20" enum="Variant.Operator"> Logical OR operator ([code]or[/code] or [code]||[/code]). </constant> - <constant name="OP_XOR" value="22" enum="Variant.Operator"> + <constant name="OP_XOR" value="21" enum="Variant.Operator"> Logical XOR operator (not implemented in GDScript). </constant> - <constant name="OP_NOT" value="23" enum="Variant.Operator"> + <constant name="OP_NOT" value="22" enum="Variant.Operator"> Logical NOT operator ([code]not[/code] or [code]![/code]). </constant> - <constant name="OP_IN" value="24" enum="Variant.Operator"> + <constant name="OP_IN" value="23" enum="Variant.Operator"> Logical IN operator ([code]in[/code]). </constant> - <constant name="OP_MAX" value="25" enum="Variant.Operator"> + <constant name="OP_MAX" value="24" enum="Variant.Operator"> Represents the size of the [enum Variant.Operator] enum. </constant> </constants> diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index c547563a6e..baea84df65 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -14,7 +14,23 @@ <link title="Advanced vector math">https://docs.godotengine.org/en/latest/tutorials/math/vectors_advanced.html</link> </tutorials> <methods> - <method name="AABB"> + <method name="AABB" qualifiers="constructor"> + <return type="AABB"> + </return> + <description> + Constructs a default-initialized [AABB] with default (zero) values of [member position] and [member size]. + </description> + </method> + <method name="AABB" qualifiers="constructor"> + <return type="AABB"> + </return> + <argument index="0" name="from" type="AABB"> + </argument> + <description> + Constructs an [AABB] as a copy of the given [AABB]. + </description> + </method> + <method name="AABB" qualifiers="constructor"> <return type="AABB"> </return> <argument index="0" name="position" type="Vector3"> @@ -176,8 +192,18 @@ Returns [code]true[/code] if the [AABB] is on both sides of a plane. </description> </method> + <method name="intersects_ray"> + <return type="Variant"> + </return> + <argument index="0" name="from" type="Vector3"> + </argument> + <argument index="1" name="dir" type="Vector3"> + </argument> + <description> + </description> + </method> <method name="intersects_segment"> - <return type="bool"> + <return type="Variant"> </return> <argument index="0" name="from" type="Vector3"> </argument> @@ -205,6 +231,30 @@ Returns a larger [AABB] that contains both this [AABB] and [code]with[/code]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="AABB"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="AABB"> + </return> + <argument index="0" name="right" type="Transform"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="AABB"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="end" type="Vector3" setter="" getter="" default="Vector3( 0, 0, 0 )"> diff --git a/doc/classes/AnimatedSprite2D.xml b/doc/classes/AnimatedSprite2D.xml index 39228eab79..969e9cc85b 100644 --- a/doc/classes/AnimatedSprite2D.xml +++ b/doc/classes/AnimatedSprite2D.xml @@ -63,12 +63,6 @@ <member name="playing" type="bool" setter="_set_playing" getter="_is_playing" default="false"> If [code]true[/code], the [member animation] is currently playing. </member> - <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> - Strength of the specular light effect of this [AnimatedSprite2D]. - </member> - <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> - The color of the specular light effect. - </member> <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0"> The animation speed is multiplied by this value. </member> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 87b7443a8a..0ad5960d4a 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -38,48 +38,56 @@ GD.Print(array1 + array2); // Prints [One, 2, 3, Four] [/csharp] [/codeblocks] + Note that concatenating with [code]+=[/code] operator will create a new array. If you want to append another array to an existing array, [method append_array] is more efficient. [b]Note:[/b] Arrays are always passed by reference. To get a copy of an array which can be modified independently of the original array, use [method duplicate]. </description> <tutorials> </tutorials> <methods> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> - <argument index="0" name="from" type="PackedColorArray"> + <description> + Constructs an empty [Array]. + </description> + </method> + <method name="Array" qualifiers="constructor"> + <return type="Array"> + </return> + <argument index="0" name="from" type="Array"> </argument> <description> - Constructs an array from a [PackedColorArray]. + Constructs an [Array] as a copy of the given [Array]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> - <argument index="0" name="from" type="PackedVector3Array"> + <argument index="0" name="from" type="PackedByteArray"> </argument> <description> - Constructs an array from a [PackedVector3Array]. + Constructs an array from a [PackedByteArray]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> - <argument index="0" name="from" type="PackedVector2Array"> + <argument index="0" name="from" type="PackedColorArray"> </argument> <description> - Constructs an array from a [PackedVector2Array]. + Constructs an array from a [PackedColorArray]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> - <argument index="0" name="from" type="PackedStringArray"> + <argument index="0" name="from" type="PackedFloat32Array"> </argument> <description> - Constructs an array from a [PackedStringArray]. + Constructs an array from a [PackedFloat32Array]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> <argument index="0" name="from" type="PackedFloat64Array"> @@ -88,16 +96,16 @@ Constructs an array from a [PackedFloat64Array]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> - <argument index="0" name="from" type="PackedFloat32Array"> + <argument index="0" name="from" type="PackedInt32Array"> </argument> <description> - Constructs an array from a [PackedFloat32Array]. + Constructs an array from a [PackedInt32Array]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> <argument index="0" name="from" type="PackedInt64Array"> @@ -106,22 +114,31 @@ Constructs an array from a [PackedInt64Array]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> - <argument index="0" name="from" type="PackedInt32Array"> + <argument index="0" name="from" type="PackedStringArray"> </argument> <description> - Constructs an array from a [PackedInt32Array]. + Constructs an array from a [PackedStringArray]. </description> </method> - <method name="Array"> + <method name="Array" qualifiers="constructor"> <return type="Array"> </return> - <argument index="0" name="from" type="PackedByteArray"> + <argument index="0" name="from" type="PackedVector2Array"> </argument> <description> - Constructs an array from a [PackedByteArray]. + Constructs an array from a [PackedVector2Array]. + </description> + </method> + <method name="Array" qualifiers="constructor"> + <return type="Array"> + </return> + <argument index="0" name="from" type="PackedVector3Array"> + </argument> + <description> + Constructs an array from a [PackedVector3Array]. </description> </method> <method name="append"> @@ -133,6 +150,21 @@ Appends an element at the end of the array (alias of [method push_back]). </description> </method> + <method name="append_array"> + <return type="void"> + </return> + <argument index="0" name="array" type="Array"> + </argument> + <description> + Appends another array at the end of this array. + [codeblock] + var array1 = [1, 2, 3] + var array2 = [4, 5, 6] + array1.append_array(array2) + print(array1) # Prints [1, 2, 3, 4, 5, 6]. + [/codeblock] + </description> + </method> <method name="back"> <return type="Variant"> </return> @@ -160,7 +192,7 @@ </argument> <argument index="1" name="obj" type="Object"> </argument> - <argument index="2" name="func" type="String"> + <argument index="2" name="func" type="StringName"> </argument> <argument index="3" name="before" type="bool" default="true"> </argument> @@ -320,6 +352,70 @@ Returns the minimum value contained in the array if all elements are of comparable types. If the elements can't be compared, [code]null[/code] is returned. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Array"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Array"> + </return> + <argument index="0" name="right" type="Array"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Array"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Array"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Array"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Array"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="void"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="pop_back"> <return type="Variant"> </return> @@ -362,7 +458,7 @@ </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> <argument index="0" name="size" type="int"> </argument> @@ -433,7 +529,7 @@ </return> <argument index="0" name="obj" type="Object"> </argument> - <argument index="1" name="func" type="String"> + <argument index="1" name="func" type="StringName"> </argument> <description> Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 8c92975b9c..31e6ea5e54 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -81,6 +81,15 @@ <member name="albedo_texture" type="Texture2D" setter="set_texture" getter="get_texture"> Texture to multiply by [member albedo_color]. Used for basic texturing of objects. </member> + <member name="alpha_antialiasing_edge" type="float" setter="set_alpha_antialiasing_edge" getter="get_alpha_antialiasing_edge"> + Threshold at which antialiasing will by applied on the alpha channel. + </member> + <member name="alpha_antialiasing_mode" type="int" setter="set_alpha_antialiasing" getter="get_alpha_antialiasing" enum="BaseMaterial3D.AlphaAntiAliasing"> + The type of alpha antialiasing to apply. See [enum AlphaAntiAliasing]. + </member> + <member name="alpha_hash_scale" type="float" setter="set_alpha_hash_scale" getter="get_alpha_hash_scale"> + The hashing scale for Alpha Hash. Recommended values between [code]0[/code] and [code]2[/code]. + </member> <member name="alpha_scissor_threshold" type="float" setter="set_alpha_scissor_threshold" getter="get_alpha_scissor_threshold"> Threshold at which the alpha scissor will discard values. </member> @@ -486,10 +495,13 @@ <constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="Transparency"> The material will cut off all values below a threshold, the rest will remain opaque. </constant> - <constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="3" enum="Transparency"> + <constant name="TRANSPARENCY_ALPHA_HASH" value="3" enum="Transparency"> + The material will cut off all values below a spatially-deterministic threshold, the rest will remain opaque. + </constant> + <constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="4" enum="Transparency"> The material will use the texture's alpha value for transparency, but will still be rendered in the pre-pass. </constant> - <constant name="TRANSPARENCY_MAX" value="4" enum="Transparency"> + <constant name="TRANSPARENCY_MAX" value="5" enum="Transparency"> Represents the size of the [enum Transparency] enum. </constant> <constant name="SHADING_MODE_UNSHADED" value="0" enum="ShadingMode"> @@ -555,6 +567,15 @@ <constant name="BLEND_MODE_MUL" value="3" enum="BlendMode"> The color of the object is multiplied by the background. </constant> + <constant name="ALPHA_ANTIALIASING_OFF" value="0" enum="AlphaAntiAliasing"> + Disables Alpha AntiAliasing for the material. + </constant> + <constant name="ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE" value="1" enum="AlphaAntiAliasing"> + Enables AlphaToCoverage. Alpha values in the material are passed to the AntiAliasing sample mask. + </constant> + <constant name="ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE" value="2" enum="AlphaAntiAliasing"> + Enables AlphaToCoverage and forces all non-zero alpha values to [code]1[/code]. Alpha values in the material are passed to the AntiAliasing sample mask. + </constant> <constant name="DEPTH_DRAW_OPAQUE_ONLY" value="0" enum="DepthDrawMode"> Default depth draw mode. Depth is drawn only for opaque objects. </constant> diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 42ca3ad24b..877d3ca85a 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -19,26 +19,23 @@ <link title="2.5D Demo">https://godotengine.org/asset-library/asset/583</link> </tutorials> <methods> - <method name="Basis"> + <method name="Basis" qualifiers="constructor"> <return type="Basis"> </return> - <argument index="0" name="from" type="Quat"> - </argument> <description> - Constructs a pure rotation basis matrix from the given quaternion. + Constructs a default-initialized [Basis] set to [constant IDENTITY]. </description> </method> - <method name="Basis"> + <method name="Basis" qualifiers="constructor"> <return type="Basis"> </return> - <argument index="0" name="from" type="Vector3"> + <argument index="0" name="from" type="Basis"> </argument> <description> - Constructs a pure rotation basis matrix from the given Euler angles (in the YXZ convention: when *composing*, first Y, then X, and Z last), given in the vector format as (X angle, Y angle, Z angle). - Consider using the [Quat] constructor instead, which uses a quaternion instead of Euler angles. + Constructs a [Basis] as a copy of the given [Basis]. </description> </method> - <method name="Basis"> + <method name="Basis" qualifiers="constructor"> <return type="Basis"> </return> <argument index="0" name="axis" type="Vector3"> @@ -49,7 +46,26 @@ Constructs a pure rotation basis matrix, rotated around the given [code]axis[/code] by [code]phi[/code], in radians. The axis must be a normalized vector. </description> </method> - <method name="Basis"> + <method name="Basis" qualifiers="constructor"> + <return type="Basis"> + </return> + <argument index="0" name="euler" type="Vector3"> + </argument> + <description> + Constructs a pure rotation basis matrix from the given Euler angles (in the YXZ convention: when *composing*, first Y, then X, and Z last), given in the vector format as (X angle, Y angle, Z angle). + Consider using the [Quat] constructor instead, which uses a quaternion instead of Euler angles. + </description> + </method> + <method name="Basis" qualifiers="constructor"> + <return type="Basis"> + </return> + <argument index="0" name="from" type="Quat"> + </argument> + <description> + Constructs a pure rotation basis matrix from the given quaternion. + </description> + </method> + <method name="Basis" qualifiers="constructor"> <return type="Basis"> </return> <argument index="0" name="x_axis" type="Vector3"> @@ -115,6 +131,46 @@ Returns [code]true[/code] if this basis and [code]b[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Basis"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Basis"> + </return> + <argument index="0" name="right" type="Basis"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Basis"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="orthonormalized"> <return type="Basis"> </return> @@ -187,25 +243,6 @@ Returns the transposed version of the matrix. </description> </method> - <method name="xform"> - <return type="Vector3"> - </return> - <argument index="0" name="v" type="Vector3"> - </argument> - <description> - Returns a vector transformed (multiplied) by the matrix. - </description> - </method> - <method name="xform_inv"> - <return type="Vector3"> - </return> - <argument index="0" name="v" type="Vector3"> - </argument> - <description> - Returns a vector transformed (multiplied) by the transposed basis matrix. - [b]Note:[/b] This results in a multiplication by the inverse of the matrix only if it represents a rotation-reflection. - </description> - </method> </methods> <members> <member name="x" type="Vector3" setter="" getter="" default="Vector3( 1, 0, 0 )"> diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index 7244da56ca..fcf2feb3b9 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -238,10 +238,6 @@ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. </member> - <member name="normalmap" type="Texture2D" setter="set_normalmap" getter="get_normalmap"> - Normal map to be used for the [member texture] property. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. </member> diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml index ad5c549fee..f137ede90f 100644 --- a/doc/classes/Callable.xml +++ b/doc/classes/Callable.xml @@ -36,19 +36,35 @@ <tutorials> </tutorials> <methods> - <method name="Callable"> + <method name="Callable" qualifiers="constructor"> + <return type="Callable"> + </return> + <description> + Constructs a null [Callable] with no object nor method bound. + </description> + </method> + <method name="Callable" qualifiers="constructor"> + <return type="Callable"> + </return> + <argument index="0" name="from" type="Callable"> + </argument> + <description> + Constructs a [Callable] as a copy of the given [Callable]. + </description> + </method> + <method name="Callable" qualifiers="constructor"> <return type="Callable"> </return> <argument index="0" name="object" type="Object"> </argument> - <argument index="1" name="method_name" type="StringName"> + <argument index="1" name="method" type="StringName"> </argument> <description> - Creates a new [Callable] for the method called [code]method_name[/code] in the specified [code]object[/code]. + Creates a new [Callable] for the method called [code]method[/code] in the specified [code]object[/code]. </description> </method> <method name="bind" qualifiers="vararg"> - <return type="void"> + <return type="Callable"> </return> <description> </description> @@ -112,6 +128,22 @@ <description> </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Callable"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Callable"> + </argument> + <description> + </description> + </method> <method name="unbind"> <return type="Callable"> </return> diff --git a/doc/classes/CanvasGroup.xml b/doc/classes/CanvasGroup.xml new file mode 100644 index 0000000000..ceeda6c3f5 --- /dev/null +++ b/doc/classes/CanvasGroup.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="CanvasGroup" inherits="Node2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="clear_margin" type="float" setter="set_clear_margin" getter="get_clear_margin" default="10.0"> + </member> + <member name="fit_margin" type="float" setter="set_fit_margin" getter="get_fit_margin" default="10.0"> + </member> + <member name="use_mipmaps" type="bool" setter="set_use_mipmaps" getter="is_using_mipmaps" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 9f6baae8a3..8efa1adae8 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -86,16 +86,6 @@ </argument> <argument index="3" name="texture" type="Texture2D" default="null"> </argument> - <argument index="4" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a colored polygon of any amount of points, convex or concave. </description> @@ -122,19 +112,9 @@ </argument> <argument index="1" name="texture" type="Texture2D"> </argument> - <argument index="2" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="3" name="specular_map" type="Texture2D" default="null"> + <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> </argument> - <argument index="4" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="5" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> - </argument> - <argument index="6" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> + <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> <description> Draws a [Mesh] in 2D, using the provided texture. See [MeshInstance2D] for related documentation. @@ -173,16 +153,6 @@ </argument> <argument index="1" name="texture" type="Texture2D"> </argument> - <argument index="2" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="3" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="4" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="5" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="6" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a [MultiMesh] in 2D with the provided texture. See [MultiMeshInstance2D] for related documentation. </description> @@ -198,16 +168,6 @@ </argument> <argument index="3" name="texture" type="Texture2D" default="null"> </argument> - <argument index="4" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a polygon of any amount of points, convex or concave. </description> @@ -251,16 +211,6 @@ </argument> <argument index="4" name="width" type="float" default="1.0"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a custom primitive. 1 point for a point, 2 points for a line, 3 points for a triangle, and 4 points for a quad. </description> @@ -358,16 +308,6 @@ </argument> <argument index="2" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="3" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="4" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="6" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="7" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a texture at a given position. </description> @@ -385,16 +325,6 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a textured rectangle at a given position, optionally modulated by a color. If [code]transpose[/code] is [code]true[/code], the texture will have its X and Y coordinates swapped. </description> @@ -412,17 +342,7 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="clip_uv" type="bool" default="true"> - </argument> - <argument index="9" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="10" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> + <argument index="5" name="clip_uv" type="bool" default="true"> </argument> <description> Draws a textured rectangle region at a given position, optionally modulated by a color. If [code]transpose[/code] is [code]true[/code], the texture will have its X and Y coordinates swapped. @@ -592,6 +512,8 @@ </method> </methods> <members> + <member name="clip_children" type="bool" setter="set_clip_children" getter="is_clipping_children" default="false"> + </member> <member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" default="1"> The rendering layers in which this [CanvasItem] responds to [Light2D] nodes. </member> diff --git a/doc/classes/CanvasTexture.xml b/doc/classes/CanvasTexture.xml new file mode 100644 index 0000000000..0ca132746b --- /dev/null +++ b/doc/classes/CanvasTexture.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="CanvasTexture" inherits="Texture2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="diffuse_texture" type="Texture2D" setter="set_diffuse_texture" getter="get_diffuse_texture"> + </member> + <member name="normal_texture" type="Texture2D" setter="set_normal_texture" getter="get_normal_texture"> + </member> + <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> + </member> + <member name="specular_shininess" type="float" setter="set_specular_shininess" getter="get_specular_shininess" default="1.0"> + </member> + <member name="specular_texture" type="Texture2D" setter="set_specular_texture" getter="get_specular_texture"> + </member> + <member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="CanvasItem.TextureFilter" default="0"> + </member> + <member name="texture_repeat" type="int" setter="set_texture_repeat" getter="get_texture_repeat" enum="CanvasItem.TextureRepeat" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index ef438e422a..ae8703c837 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -16,74 +16,31 @@ <link title="GUI Drag And Drop Demo">https://godotengine.org/asset-library/asset/133</link> </tutorials> <methods> - <method name="Color"> + <method name="Color" qualifiers="constructor"> <return type="Color"> </return> - <argument index="0" name="from" type="String"> - </argument> <description> - Constructs a color from an HTML hexadecimal color string in RGB or RGBA format. See also [method @GDScript.ColorN]. - [codeblocks] - [gdscript] - # Each of the following creates the same color RGBA(178, 217, 10, 255). - var c3 = Color("#b2d90a") # RGB format with "#". - var c4 = Color("b2d90a") # RGB format. - var c1 = Color("#b2d90aff") # RGBA format with "#". - var c2 = Color("b2d90aff") # RGBA format. - [/gdscript] - [csharp] - // Each of the following creates the same color RGBA(178, 217, 10, 255). - var c3 = new Color("#b2d90a"); - var c4 = new Color("b2d90a"); // RGB format. - var c1 = new Color("#b2d90aff"); - var c2 = new Color("b2d90aff"); // RGBA format. - [/csharp] - [/codeblocks] - You can also use the "web color" short-hand form by only using 3 or 4 digits. - [codeblocks] - [gdscript] - # Each of the following creates the same color RGBA(17, 34, 51, 255). - var c3 = Color("#123") # RGB format with "#". - var c4 = Color("123") # RGB format. - var c1 = Color("#123f") # RGBA format with "#". - var c2 = Color("123f") # RGBA format. - [/gdscript] - [csharp] - // Each of the following creates the same color RGBA(17, 34, 51, 255). - var c3 = new Color("#123"); - var c4 = new Color("123"); // RGB format. - var c1 = new Color("#123f"); - var c2 = new Color("123f"); // RGBA format. - [/csharp] - [/codeblocks] + Constructs a default-initialized [Color] with all components set to [code]0[/code]. </description> </method> - <method name="Color"> + <method name="Color" qualifiers="constructor"> <return type="Color"> </return> - <argument index="0" name="from" type="int"> + <argument index="0" name="from" type="Color"> </argument> <description> - Constructs a color from a 32-bit integer (each byte represents a component of the RGBA profile). - [codeblocks] - [gdscript] - var c = Color(274) # Equivalent to RGBA(0, 0, 1, 18) - [/gdscript] - [csharp] - var c = new Color(274); // Equivalent to RGBA(0, 0, 1, 18) - [/csharp] - [/codeblocks] + Constructs a [Color] as a copy of the given [Color]. </description> </method> - <method name="Color"> + <method name="Color" qualifiers="constructor"> <return type="Color"> </return> - <argument index="0" name="c" type="Color"> + <argument index="0" name="from" type="Color"> </argument> - <argument index="1" name="a" type="float"> + <argument index="1" name="alpha" type="float"> </argument> <description> - Constructs a color from an existing color, but with a custom alpha value. + Constructs a [Color] from an existing color, but with a custom alpha value. [codeblocks] [gdscript] var red = Color(Color.red, 0.5) # 50% transparent red. @@ -94,7 +51,7 @@ [/codeblocks] </description> </method> - <method name="Color"> + <method name="Color" qualifiers="constructor"> <return type="Color"> </return> <argument index="0" name="r" type="float"> @@ -103,19 +60,21 @@ </argument> <argument index="2" name="b" type="float"> </argument> + <argument index="3" name="a" type="float"> + </argument> <description> - Constructs a color from an RGB profile using values between 0 and 1. Alpha will always be 1. + Constructs a [Color] from an RGBA profile using values between 0 and 1. [codeblocks] [gdscript] - var color = Color(0.2, 1.0, 0.7) # Equivalent to RGBA(51, 255, 178, 255) + var color = Color(0.2, 1.0, 0.7, 0.8) # Equivalent to RGBA(51, 255, 178, 204) [/gdscript] [csharp] - var color = new Color(0.2f, 1.0f, 0.7f); // Equivalent to RGBA(51, 255, 178, 255) + var color = new Color(0.2f, 1.0f, 0.7f, 0.8f); // Equivalent to RGBA(51, 255, 178, 255, 204) [/csharp] [/codeblocks] </description> </method> - <method name="Color"> + <method name="Color" qualifiers="constructor"> <return type="Color"> </return> <argument index="0" name="r" type="float"> @@ -124,16 +83,14 @@ </argument> <argument index="2" name="b" type="float"> </argument> - <argument index="3" name="a" type="float"> - </argument> <description> - Constructs a color from an RGBA profile using values between 0 and 1. + Constructs a color from an RGB profile using values between 0 and 1. Alpha will always be 1. [codeblocks] [gdscript] - var color = Color(0.2, 1.0, 0.7, 0.8) # Equivalent to RGBA(51, 255, 178, 204) + var color = Color(0.2, 1.0, 0.7) # Equivalent to RGBA(51, 255, 178, 255) [/gdscript] [csharp] - var color = new Color(0.2f, 1.0f, 0.7f, 0.8f); // Equivalent to RGBA(51, 255, 178, 255, 204) + var color = new Color(0.2f, 1.0f, 0.7f); // Equivalent to RGBA(51, 255, 178, 255) [/csharp] [/codeblocks] </description> @@ -159,23 +116,6 @@ [/codeblocks] </description> </method> - <method name="contrasted"> - <return type="Color"> - </return> - <description> - Returns the most contrasting color. - [codeblocks] - [gdscript] - var color = Color(0.3, 0.4, 0.9) - var contrasted_color = color.contrasted() # Equivalent to RGBA(204, 229, 102, 255) - [/gdscript] - [csharp] - var color = new Color(0.3f, 0.4f, 0.9f); - Color contrastedColor = color.Contrasted(); // Equivalent to RGBA(204, 229, 102, 255) - [/csharp] - [/codeblocks] - </description> - </method> <method name="darkened"> <return type="Color"> </return> @@ -195,29 +135,6 @@ [/codeblocks] </description> </method> - <method name="from_hsv"> - <return type="Color"> - </return> - <argument index="0" name="h" type="float"> - </argument> - <argument index="1" name="s" type="float"> - </argument> - <argument index="2" name="v" type="float"> - </argument> - <argument index="3" name="a" type="float" default="1.0"> - </argument> - <description> - Constructs a color from an HSV profile. [code]h[/code], [code]s[/code], and [code]v[/code] are values between 0 and 1. - [codeblocks] - [gdscript] - var color = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8) - [/gdscript] - [csharp] - Color color = Color.FromHsv(0.58f, 0.5f, 0.79f, 0.8f); // Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8) - [/csharp] - [/codeblocks] - </description> - </method> <method name="inverted"> <return type="Color"> </return> @@ -238,7 +155,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="color" type="Color"> + <argument index="0" name="to" type="Color"> </argument> <description> Returns [code]true[/code] if this color and [code]color[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -286,6 +203,98 @@ [/codeblocks] </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Color"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Color"> + </return> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="to_abgr32"> <return type="int"> </return> diff --git a/doc/classes/ColorRect.xml b/doc/classes/ColorRect.xml index 7c0cd981e4..09ba4c8b26 100644 --- a/doc/classes/ColorRect.xml +++ b/doc/classes/ColorRect.xml @@ -12,7 +12,7 @@ <methods> </methods> <members> - <member name="color" type="Color" setter="set_frame_color" getter="get_frame_color" default="Color( 1, 1, 1, 1 )"> + <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )"> The fill color. [codeblocks] [gdscript] diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index f495bfe894..6ea7b79dff 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -75,15 +75,17 @@ </description> </method> <method name="_make_custom_tooltip" qualifiers="virtual"> - <return type="Object"> + <return type="Control"> </return> <argument index="0" name="for_text" type="String"> </argument> <description> - Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. Use [code]for_text[/code] parameter to determine what text the tooltip should contain (likely the contents of [member hint_tooltip]). - The returned node must be of type [Control] or Control-derieved. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance, not e.g. a node from scene. When [code]null[/code] or non-Control node is returned, the default tooltip will be used instead. + Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. The [code]for_text[/code] includes the contents of the [member hint_tooltip] property. + The returned node must be of type [Control] or Control-derived. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance (if you want to use a pre-existing node from your scene tree, you can duplicate it and pass the duplicated instance).When [code]null[/code] or a non-Control node is returned, the default tooltip will be used instead. + The returned node will be added as child to a [PopupPanel], so you should only provide the contents of that panel. That [PopupPanel] can be themed using [method Theme.set_stylebox] for the type [code]"TooltipPanel"[/code] (see [member hint_tooltip] for an example). [b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member rect_min_size] to some non-zero value. - Example of usage with custom-constructed node: + [b]Note:[/b] The node (and any relevant children) should be [member CanvasItem.visible] when returned, otherwise the viewport that instantiates it will not be able to calculate its minimum size reliably. + Example of usage with a custom-constructed node: [codeblocks] [gdscript] func _make_custom_tooltip(for_text): @@ -92,7 +94,7 @@ return label [/gdscript] [csharp] - public override Godot.Object _MakeCustomTooltip(String forText) + public override Godot.Control _MakeCustomTooltip(String forText) { var label = new Label(); label.Text = forText; @@ -100,18 +102,18 @@ } [/csharp] [/codeblocks] - Example of usage with custom scene instance: + Example of usage with a custom scene instance: [codeblocks] [gdscript] func _make_custom_tooltip(for_text): - var tooltip = preload("SomeTooltipScene.tscn").instance() + var tooltip = preload("res://SomeTooltipScene.tscn").instance() tooltip.get_node("Label").text = for_text return tooltip [/gdscript] [csharp] - public override Godot.Object _MakeCustomTooltip(String forText) + public override Godot.Control _MakeCustomTooltip(String forText) { - Node tooltip = ResourceLoader.Load<PackedScene>("SomeTooltipScene.tscn").Instance(); + Node tooltip = ResourceLoader.Load<PackedScene>("res://SomeTooltipScene.tscn").Instance(); tooltip.GetNode<Label>("Label").Text = forText; return tooltip; } @@ -993,6 +995,25 @@ </member> <member name="hint_tooltip" type="String" setter="set_tooltip" getter="_get_tooltip" default=""""> Changes the tooltip text. The tooltip appears when the user's mouse cursor stays idle over this control for a few moments, provided that the [member mouse_filter] property is not [constant MOUSE_FILTER_IGNORE]. You can change the time required for the tooltip to appear with [code]gui/timers/tooltip_delay_sec[/code] option in Project Settings. + The tooltip popup will use either a default implementation, or a custom one that you can provide by overriding [method _make_custom_tooltip]. The default tooltip includes a [PopupPanel] and [Label] whose theme properties can be customized using [Theme] methods with the [code]"TooltipPanel"[/code] and [code]"TooltipLabel"[/code] respectively. For example: + [codeblocks] + [gdscript] + var style_box = StyleBoxFlat.new() + style_box.set_bg_color(Color(1, 1, 0)) + style_box.set_border_width_all(2) + # We assume here that the `theme` property has been assigned a custom Theme beforehand. + theme.set_stylebox("panel", "TooltipPanel", style_box) + theme.set_color("font_color", "TooltipLabel", Color(0, 1, 1)) + [/gdscript] + [csharp] + var styleBox = new StyleBoxFlat(); + styleBox.SetBgColor(new Color(1, 1, 0)); + styleBox.SetBorderWidthAll(2); + // We assume here that the `Theme` property has been assigned a custom Theme beforehand. + Theme.SetStyleBox("panel", "TooltipPanel", styleBox); + Theme.SetColor("font_color", "TooltipLabel", new Color(0, 1, 1)); + [/csharp] + [/codeblocks] </member> <member name="margin_bottom" type="float" setter="set_margin" getter="get_margin" default="0.0"> Distance between the node's bottom edge and its parent control, based on [member anchor_bottom]. diff --git a/doc/classes/DTLSServer.xml b/doc/classes/DTLSServer.xml index 8c71b61553..91a04b1f28 100644 --- a/doc/classes/DTLSServer.xml +++ b/doc/classes/DTLSServer.xml @@ -6,8 +6,9 @@ <description> This class is used to store the state of a DTLS server. Upon [method setup] it converts connected [PacketPeerUDP] to [PacketPeerDTLS] accepting them via [method take_connection] as DTLS clients. Under the hood, this class is used to store the DTLS state and cookies of the server. The reason of why the state and cookies are needed is outside of the scope of this documentation. Below a small example of how to use it: - [codeblock] - # server.gd + [codeblocks] + [gdscript] + # ServerNode.gd extends Node var dtls := DTLSServer.new() @@ -28,15 +29,64 @@ continue # It is normal that 50% of the connections fails due to cookie exchange. print("Peer connected!") peers.append(dtls_peer) + for p in peers: p.poll() # Must poll to update the state. if p.get_status() == PacketPeerDTLS.STATUS_CONNECTED: while p.get_available_packet_count() > 0: print("Received message from client: %s" % p.get_packet().get_string_from_utf8()) p.put_packet("Hello DTLS client".to_utf8()) - [/codeblock] - [codeblock] - # client.gd + [/gdscript] + [csharp] + using Godot; + using System; + // ServerNode.cs + public class ServerNode : Node + { + public DTLSServer Dtls = new DTLSServer(); + public UDPServer Server = new UDPServer(); + public Godot.Collections.Array<PacketPeerDTLS> Peers = new Godot.Collections.Array<PacketPeerDTLS>(); + public override void _Ready() + { + Server.Listen(4242); + var key = GD.Load<CryptoKey>("key.key"); // Your private key. + var cert = GD.Load<X509Certificate>("cert.crt"); // Your X509 certificate. + Dtls.Setup(key, cert); + } + + public override void _Process(float delta) + { + while (Server.IsConnectionAvailable()) + { + PacketPeerUDP peer = Server.TakeConnection(); + PacketPeerDTLS dtlsPeer = Dtls.TakeConnection(peer); + if (dtlsPeer.GetStatus() != PacketPeerDTLS.Status.Handshaking) + { + continue; // It is normal that 50% of the connections fails due to cookie exchange. + } + GD.Print("Peer connected!"); + Peers.Add(dtlsPeer); + } + + foreach (var p in Peers) + { + p.Poll(); // Must poll to update the state. + if (p.GetStatus() == PacketPeerDTLS.Status.Connected) + { + while (p.GetAvailablePacketCount() > 0) + { + GD.Print("Received Message From Client: " + p.GetPacket().GetStringFromUTF8()); + p.PutPacket("Hello Dtls Client".ToUTF8()); + } + } + } + } + } + [/csharp] + [/codeblocks] + [codeblocks] + [gdscript] + # ClientNode.gd extends Node var dtls := PacketPeerDTLS.new() @@ -56,7 +106,42 @@ while dtls.get_available_packet_count() > 0: print("Connected: %s" % dtls.get_packet().get_string_from_utf8()) connected = true - [/codeblock] + [/gdscript] + [csharp] + using Godot; + using System.Text; + // ClientNode.cs + public class ClientNode : Node + { + public PacketPeerDTLS Dtls = new PacketPeerDTLS(); + public PacketPeerUDP Udp = new PacketPeerUDP(); + public bool Connected = false; + public override void _Ready() + { + Udp.ConnectToHost("127.0.0.1", 4242); + Dtls.ConnectToPeer(Udp, false); // Use true in production for certificate validation! + } + + public override void _Process(float delta) + { + Dtls.Poll(); + if (Dtls.GetStatus() == PacketPeerDTLS.Status.Connected) + { + if (!Connected) + { + // Try to contact server + Dtls.PutPacket("The Answer Is..42!".ToUTF8()); + } + while (Dtls.GetAvailablePacketCount() > 0) + { + GD.Print("Connected: " + Dtls.GetPacket().GetStringFromUTF8()); + Connected = true; + } + } + } + } + [/csharp] + [/codeblocks] </description> <tutorials> </tutorials> diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml index f9baa3b09a..8107d97b67 100644 --- a/doc/classes/Decal.xml +++ b/doc/classes/Decal.xml @@ -20,10 +20,18 @@ Returns the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly. For example, instead of [code]albedo_tex = $Decal.get_texture(Decal.TEXTURE_ALBEDO)[/code], use [code]albedo_tex = $Decal.texture_albedo[/code]. One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example: - [codeblock] + [codeblocks] + [gdscript] for i in Decal.TEXTURE_MAX: $NewDecal.set_texture(i, $OldDecal.get_texture(i)) - [/codeblock] + [/gdscript] + [csharp] + for (int i = 0; i < (int)Decal.DecalTexture.Max; i++) + { + GetNode<Decal>("NewDecal").SetTexture(i, GetNode<Decal>("OldDecal").GetTexture(i)); + } + [/csharp] + [/codeblocks] </description> </method> <method name="set_texture"> @@ -37,10 +45,18 @@ Sets the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly. For example, instead of [code]$Decal.set_texture(Decal.TEXTURE_ALBEDO, albedo_tex)[/code], use [code]$Decal.texture_albedo = albedo_tex[/code]. One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example: - [codeblock] + [codeblocks] + [gdscript] for i in Decal.TEXTURE_MAX: $NewDecal.set_texture(i, $OldDecal.get_texture(i)) - [/codeblock] + [/gdscript] + [csharp] + for (int i = 0; i < (int)Decal.DecalTexture.Max; i++) + { + GetNode<Decal>("NewDecal").SetTexture(i, GetNode<Decal>("OldDecal").GetTexture(i)); + } + [/csharp] + [/codeblocks] </description> </method> </methods> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index cb60d6e621..dc38fdf0e8 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -9,7 +9,8 @@ Erasing elements while iterating over them [b]is not supported[/b] and will result in undefined behavior. [b]Note:[/b] Dictionaries are always passed by reference. To get a copy of a dictionary which can be modified independently of the original dictionary, use [method duplicate]. Creating a dictionary: - [codeblock] + [codeblocks] + [gdscript] var my_dir = {} # Creates an empty dictionary. var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} var another_dir = { @@ -17,28 +18,74 @@ key2: value2, key3: value3, } - [/codeblock] + [/gdscript] + [csharp] + var myDir = new Godot.Collections.Dictionary(); // Creates an empty dictionary. + var pointsDir = new Godot.Collections.Dictionary + { + {"White", 50}, + {"Yellow", 75}, + {"Orange", 100} + }; + [/csharp] + [/codeblocks] You can access a dictionary's values by referencing the appropriate key. In the above example, [code]points_dir["White"][/code] will return [code]50[/code]. You can also write [code]points_dir.White[/code], which is equivalent. However, you'll have to use the bracket syntax if the key you're accessing the dictionary with isn't a fixed string (such as a number or variable). - [codeblock] - export(String, "White", "Yellow", "Orange") var my_color + [codeblocks] + [gdscript] + export(string, "White", "Yellow", "Orange") var my_color var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} - func _ready(): # We can't use dot syntax here as `my_color` is a variable. var points = points_dir[my_color] - [/codeblock] + [/gdscript] + [csharp] + [Export(PropertyHint.Enum, "White,Yellow,Orange")] + public string MyColor { get; set; } + public Godot.Collections.Dictionary pointsDir = new Godot.Collections.Dictionary + { + {"White", 50}, + {"Yellow", 75}, + {"Orange", 100} + }; + + public override void _Ready() + { + int points = (int)pointsDir[MyColor]; + } + [/csharp] + [/codeblocks] In the above code, [code]points[/code] will be assigned the value that is paired with the appropriate color selected in [code]my_color[/code]. Dictionaries can contain more complex data: - [codeblock] + [codeblocks] + [gdscript] my_dir = {"First Array": [1, 2, 3, 4]} # Assigns an Array to a String key. - [/codeblock] + [/gdscript] + [csharp] + var myDir = new Godot.Collections.Dictionary + { + {"First Array", new Godot.Collections.Array{1, 2, 3, 4}} + }; + [/csharp] + [/codeblocks] To add a key to an existing dictionary, access it like an existing key and assign to it: - [codeblock] + [codeblocks] + [gdscript] var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} points_dir["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value. - [/codeblock] + [/gdscript] + [csharp] + var pointsDir = new Godot.Collections.Dictionary + { + {"White", 50}, + {"Yellow", 75}, + {"Orange", 100} + }; + pointsDir["blue"] = 150; // Add "Blue" as a key and assign 150 as its value. + [/csharp] + [/codeblocks] Finally, dictionaries can contain different types of keys and values in the same dictionary: - [codeblock] + [codeblocks] + [gdscript] # This is a valid dictionary. # To access the string "Nested value" below, use `my_dir.sub_dir.sub_key` or `my_dir["sub_dir"]["sub_key"]`. # Indexing styles can be mixed and matched depending on your needs. @@ -48,29 +95,75 @@ 7: "Hello", "sub_dir": {"sub_key": "Nested value"}, } - [/codeblock] + [/gdscript] + [csharp] + // This is a valid dictionary. + // To access the string "Nested value" below, use `my_dir.sub_dir.sub_key` or `my_dir["sub_dir"]["sub_key"]`. + // Indexing styles can be mixed and matched depending on your needs. + var myDir = new Godot.Collections.Dictionary { + {"String Key", 5}, + {4, new Godot.Collections.Array{1,2,3}}, + {7, "Hello"}, + {"sub_dir", new Godot.Collections.Dictionary{{"sub_key", "Nested value"}}} + }; + [/csharp] + [/codeblocks] [b]Note:[/b] Unlike [Array]s, you can't compare dictionaries directly: - [codeblock] - array1 = [1, 2, 3] - array2 = [1, 2, 3] + [codeblocks] + [gdscript] + var array1 = [1, 2, 3] + var array2 = [1, 2, 3] func compare_arrays(): print(array1 == array2) # Will print true. - dir1 = {"a": 1, "b": 2, "c": 3} - dir2 = {"a": 1, "b": 2, "c": 3} + var dir1 = {"a": 1, "b": 2, "c": 3} + var dir2 = {"a": 1, "b": 2, "c": 3} func compare_dictionaries(): print(dir1 == dir2) # Will NOT print true. - [/codeblock] + [/gdscript] + [csharp] + // You have to use GD.Hash(). + + public Godot.Collections.Array array1 = new Godot.Collections.Array{1, 2, 3}; + public Godot.Collections.Array array2 = new Godot.Collections.Array{1, 2, 3}; + + public void CompareArrays() + { + GD.Print(array1 == array2); // Will print FALSE!! + GD.Print(GD.Hash(array1) == GD.Hash(array2)); // Will print true. + } + + public Godot.Collections.Dictionary dir1 = new Godot.Collections.Dictionary{{"a", 1}, {"b", 2}, {"c", 3}}; + public Godot.Collections.Dictionary dir2 = new Godot.Collections.Dictionary{{"a", 1}, {"b", 2}, {"c", 3}}; + + public void CompareDictionaries() + { + GD.Print(dir1 == dir2); // Will NOT print true. + } + [/csharp] + [/codeblocks] You need to first calculate the dictionary's hash with [method hash] before you can compare them: - [codeblock] - dir1 = {"a": 1, "b": 2, "c": 3} - dir2 = {"a": 1, "b": 2, "c": 3} + [codeblocks] + [gdscript] + var dir1 = {"a": 1, "b": 2, "c": 3} + var dir2 = {"a": 1, "b": 2, "c": 3} func compare_dictionaries(): print(dir1.hash() == dir2.hash()) # Will print true. - [/codeblock] + [/gdscript] + [csharp] + // You have to use GD.Hash(). + public Godot.Collections.Dictionary dir1 = new Godot.Collections.Dictionary{{"a", 1}, {"b", 2}, {"c", 3}}; + public Godot.Collections.Dictionary dir2 = new Godot.Collections.Dictionary{{"a", 1}, {"b", 2}, {"c", 3}}; + + public void CompareDictionaries() + { + GD.Print(GD.Hash(dir1) == GD.Hash(dir2)); // Will print true. + } + [/csharp] + [/codeblocks] </description> <tutorials> <link title="GDScript basics: Dictionary">https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_basics.html#dictionary</link> @@ -78,6 +171,22 @@ <link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link> </tutorials> <methods> + <method name="Dictionary" qualifiers="constructor"> + <return type="Dictionary"> + </return> + <description> + Constructs an empty [Dictionary]. + </description> + </method> + <method name="Dictionary" qualifiers="constructor"> + <return type="Dictionary"> + </return> + <argument index="0" name="from" type="Dictionary"> + </argument> + <description> + Constructs a [Dictionary] as a copy of the given [Dictionary]. + </description> + </method> <method name="clear"> <return type="void"> </return> @@ -129,11 +238,20 @@ <description> Returns [code]true[/code] if the dictionary has a given key. [b]Note:[/b] This is equivalent to using the [code]in[/code] operator as follows: - [codeblock] + [codeblocks] + [gdscript] # Will evaluate to `true`. if "godot" in {"godot": "engine"}: pass - [/codeblock] + [/gdscript] + [csharp] + // You have to use Contains() here as an alternative to GDScript's `in` operator. + if (new Godot.Collections.Dictionary{{"godot", "engine"}}.Contains("godot")) + { + // I am executed. + } + [/csharp] + [/codeblocks] This method (like the [code]in[/code] operator) will evaluate to [code]true[/code] as long as the key exists, even if the associated value is [code]null[/code]. </description> </method> @@ -151,12 +269,21 @@ </return> <description> Returns a hashed integer value representing the dictionary contents. This can be used to compare dictionaries by value: - [codeblock] + [codeblocks] + [gdscript] var dict1 = {0: 10} var dict2 = {0: 10} # The line below prints `true`, whereas it would have printed `false` if both variables were compared directly. print(dict1.hash() == dict2.hash()) - [/codeblock] + [/gdscript] + [csharp] + var dict1 = new Godot.Collections.Dictionary{{0, 10}}; + var dict2 = new Godot.Collections.Dictionary{{0, 10}}; + // The line below prints `true`, whereas it would have printed `false` if both variables were compared directly. + // Dictionary has no Hash() method. Use GD.Hash() instead. + GD.Print(GD.Hash(dict1) == GD.Hash(dict2)); + [/csharp] + [/codeblocks] [b]Note:[/b] Dictionaries with the same keys/values but in a different order will have a different hash. </description> </method> @@ -167,6 +294,30 @@ Returns the list of keys in the [Dictionary]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Dictionary"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Dictionary"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="Variant"> + </return> + <argument index="0" name="key" type="Variant"> + </argument> + <description> + </description> + </method> <method name="size"> <return type="int"> </return> diff --git a/doc/classes/DirectionalLight2D.xml b/doc/classes/DirectionalLight2D.xml new file mode 100644 index 0000000000..a6eb780159 --- /dev/null +++ b/doc/classes/DirectionalLight2D.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="DirectionalLight2D" inherits="Light2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="height" type="float" setter="set_height" getter="get_height" default="0.0"> + The height of the light. Used with 2D normal mapping. + </member> + <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="10000.0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml index bcdadcd970..2d7292717d 100644 --- a/doc/classes/Directory.xml +++ b/doc/classes/Directory.xml @@ -7,7 +7,8 @@ Directory type. It is used to manage directories and their content (not restricted to the project folder). When creating a new [Directory], it must be explicitly opened using [method open] before most methods can be used. However, [method file_exists] and [method dir_exists] can be used without opening a directory. If so, they use a path relative to [code]res://[/code]. Here is an example on how to iterate through the files of a directory: - [codeblock] + [codeblocks] + [gdscript] func dir_contents(path): var dir = Directory.new() if dir.open(path) == OK: @@ -21,7 +22,35 @@ file_name = dir.get_next() else: print("An error occurred when trying to access the path.") - [/codeblock] + [/gdscript] + [csharp] + public void DirContents(string path) + { + var dir = new Directory(); + if (dir.Open(path) == Error.Ok) + { + dir.ListDirBegin(); + string fileName = dir.GetNext(); + while (fileName != "") + { + if (dir.CurrentIsDir()) + { + GD.Print("Found directory: " + fileName); + } + else + { + GD.Print("Found file: " + fileName); + } + fileName = dir.GetNext(); + } + } + else + { + GD.Print("An error occurred when trying to access the path."); + } + } + [/csharp] + [/codeblocks] </description> <tutorials> <link title="File system">https://docs.godotengine.org/en/latest/getting_started/step_by_step/filesystem.html</link> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 53776b7752..d91ea6528a 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -923,7 +923,8 @@ <description> Sets a polygonal region of the window which accepts mouse events. Mouse events outside the region will be passed through. Passing an empty array will disable passthrough support (all mouse events will be intercepted by the window, which is the default behavior). - [codeblock] + [codeblocks] + [gdscript] # Set region, using Path2D node. DisplayServer.window_set_mouse_passthrough($Path2D.curve.get_baked_points()) @@ -932,7 +933,18 @@ # Reset region to default. DisplayServer.window_set_mouse_passthrough([]) - [/codeblock] + [/gdscript] + [csharp] + // Set region, using Path2D node. + DisplayServer.WindowSetMousePassthrough(GetNode<Path2D>("Path2D").Curve.GetBakedPoints()); + + // Set region, using Polygon2D node. + DisplayServer.WindowSetMousePassthrough(GetNode<Polygon2D>("Polygon2D").Polygon); + + // Reset region to default. + DisplayServer.WindowSetMousePassthrough(new Vector2[] {}); + [/csharp] + [/codeblocks] [b]Note:[/b] On Windows, the portion of a window that lies outside the region is not drawn, while on Linux and macOS it is. [b]Note:[/b] This method is implemented on Linux, macOS and Windows. </description> @@ -1108,6 +1120,8 @@ <constant name="WINDOW_MODE_MAXIMIZED" value="2" enum="WindowMode"> </constant> <constant name="WINDOW_MODE_FULLSCREEN" value="3" enum="WindowMode"> + Fullscreen window mode. Note that this is not [i]exclusive[/i] fullscreen. On Windows and Linux, a borderless window is used to emulate fullscreen. On macOS, a new desktop is used to display the running project. + Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=https://docs.godotengine.org/en/latest/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode. </constant> <constant name="WINDOW_FLAG_RESIZE_DISABLED" value="0" enum="WindowFlags"> </constant> diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml index f687937e27..d2d0c54761 100644 --- a/doc/classes/DynamicFont.xml +++ b/doc/classes/DynamicFont.xml @@ -6,12 +6,20 @@ <description> DynamicFont renders vector font files (such as TTF or OTF) dynamically at runtime instead of using a prerendered texture atlas like [BitmapFont]. This trades the faster loading time of [BitmapFont]s for the ability to change font parameters like size and spacing during runtime. [DynamicFontData] is used for referencing the font file paths. DynamicFont also supports defining one or more fallback fonts, which will be used when displaying a character not supported by the main font. DynamicFont uses the [url=https://www.freetype.org/]FreeType[/url] library for rasterization. - [codeblock] + [codeblocks] + [gdscript] var dynamic_font = DynamicFont.new() dynamic_font.font_data = load("res://BarlowCondensed-Bold.ttf") dynamic_font.size = 64 $"Label".set("custom_fonts/font", dynamic_font) - [/codeblock] + [/gdscript] + [csharp] + var dynamicFont = new DynamicFont(); + dynamicFont.FontData = ResourceLoader.Load<DynamicFontData>("res://BarlowCondensed-Bold.ttf"); + dynamicFont.Size = 64; + GetNode("Label").Set("custom_fonts/font", dynamicFont); + [/csharp] + [/codeblocks] [b]Note:[/b] DynamicFont doesn't support features such as kerning, right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. In FontForge, use [b]File > Generate Fonts[/b], click [b]Options[/b], choose the desired features then generate the font. </description> <tutorials> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index 2a7f27ef55..e5401134bf 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -7,7 +7,8 @@ EditorImportPlugins provide a way to extend the editor's resource import functionality. Use them to import resources from custom files or to provide alternatives to the editor's existing importers. Register your [EditorPlugin] with [method EditorPlugin.add_import_plugin]. EditorImportPlugins work by associating with specific file extensions and a resource type. See [method get_recognized_extensions] and [method get_resource_type]. They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].godot/imported[/code] directory. Below is an example EditorImportPlugin that imports a [Mesh] from a file with the extension ".special" or ".spec": - [codeblock] + [codeblocks] + [gdscript] tool extends EditorImportPlugin @@ -39,14 +40,76 @@ var file = File.new() if file.open(source_file, File.READ) != OK: return FAILED - - var mesh = Mesh.new() - # Fill the Mesh with data read in "file", left as an exercise to the reader + var mesh = ArrayMesh.new() + # Fill the Mesh with data read in "file", left as an exercise to the reader. var filename = save_path + "." + get_save_extension() ResourceSaver.save(filename, mesh) return OK - [/codeblock] + [/gdscript] + [csharp] + using Godot; + using System; + + public class MySpecialPlugin : EditorImportPlugin + { + public override String GetImporterName() + { + return "my.special.plugin"; + } + + public override String GetVisibleName() + { + return "Special Mesh Importer"; + } + + public override Godot.Collections.Array GetRecognizedExtensions() + { + return new Godot.Collections.Array{"special", "spec"}; + } + + public override String GetSaveExtension() + { + return "mesh"; + } + + public override String GetResourceType() + { + return "Mesh"; + } + + public override int GetPresetCount() + { + return 1; + } + + public override String GetPresetName(int i) + { + return "Default"; + } + + public override Godot.Collections.Array GetImportOptions(int i) + { + return new Godot.Collections.Array{new Godot.Collections.Dictionary{{"name", "myOption"}, {"defaultValue", false}}}; + } + + public override int Import(String sourceFile, String savePath, Godot.Collections.Dictionary options, Godot.Collections.Array platformVariants, Godot.Collections.Array genFiles) + { + var file = new File(); + if (file.Open(sourceFile, File.ModeFlags.Read) != Error.Ok) + { + return (int)Error.Failed; + } + + var mesh = new ArrayMesh(); + // Fill the Mesh with data read in "file", left as an exercise to the reader. + String filename = savePath + "." + GetSaveExtension(); + ResourceSaver.Save(filename, mesh); + return (int)Error.Ok; + } + } + [/csharp] + [/codeblocks] </description> <tutorials> <link title="Import plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/import_plugins.html</link> @@ -84,14 +147,28 @@ </argument> <description> This method can be overridden to hide specific import options if conditions are met. This is mainly useful for hiding options that depend on others if one of them is disabled. For example: - [codeblock] + [codeblocks] + [gdscript] func get_option_visibility(option, options): # Only show the lossy quality setting if the compression mode is set to "Lossy". if option == "compress/lossy_quality" and options.has("compress/mode"): - return int(options["compress/mode"]) == COMPRESS_LOSSY + return int(options["compress/mode"]) == COMPRESS_LOSSY # This is a constant that you set return true - [/codeblock] + [/gdscript] + [csharp] + public void GetOptionVisibility(string option, Godot.Collections.Dictionary options) + { + // Only show the lossy quality setting if the compression mode is set to "Lossy". + if (option == "compress/lossyQuality" && options.Contains("compress/mode")) + { + return (int)options["compress/mode"] == COMPRESS_LOSSY; // This is a constant you set + } + + return true; + } + [/csharp] + [/codeblocks] Return [code]true[/code] to make all options always visible. </description> </method> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index 6a64a7aa55..ca011abb36 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -210,6 +210,38 @@ <argument index="0" name="overlay" type="Control"> </argument> <description> + Called by the engine when the 2D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays]. + [codeblocks] + [gdscript] + func forward_canvas_draw_over_viewport(overlay): + # Draw a circle at cursor position. + overlay.draw_circle(overlay.get_local_mouse_position(), 64) + + func forward_canvas_gui_input(event): + if event is InputEventMouseMotion: + # Redraw viewport when cursor is moved. + update_overlays() + return true + return false + [/gdscript] + [csharp] + public override void ForwardCanvasDrawOverViewport(Godot.Control overlay) + { + // Draw a circle at cursor position. + overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White); + } + + public override bool ForwardCanvasGuiInput(InputEvent @event) + { + if (@event is InputEventMouseMotion) + { + // Redraw viewport when cursor is moved. + UpdateOverlays(); + return true; + } + return false; + [/csharp] + [/codeblocks] </description> </method> <method name="forward_canvas_force_draw_over_viewport" qualifiers="virtual"> @@ -218,6 +250,8 @@ <argument index="0" name="overlay" type="Control"> </argument> <description> + This method is the same as [method forward_canvas_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else. + You need to enable calling of this method by using [method set_force_draw_over_forwarding_enabled]. </description> </method> <method name="forward_canvas_gui_input" qualifiers="virtual"> @@ -227,21 +261,85 @@ </argument> <description> Called when there is a root node in the current edited scene, [method handles] is implemented and an [InputEvent] happens in the 2D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example: - [codeblock] + [codeblocks] + [gdscript] # Prevents the InputEvent to reach other Editor classes func forward_canvas_gui_input(event): - var forward = true - return forward - [/codeblock] + return true + [/gdscript] + [csharp] + // Prevents the InputEvent to reach other Editor classes + public override bool ForwardCanvasGuiInput(InputEvent @event) + { + return true; + } + [/csharp] + [/codeblocks] Must [code]return false[/code] in order to forward the [InputEvent] to other Editor classes. Example: - [codeblock] - # Consumes InputEventMouseMotion and forwards other InputEvent types + [codeblocks] + [gdscript] + # Consumes InputEventMouseMotion and forwards other InputEvent types. func forward_canvas_gui_input(event): - var forward = false + return event is InputEventMouseMotion + [/gdscript] + [csharp] + // Consumes InputEventMouseMotion and forwards other InputEvent types. + public override bool ForwardCanvasGuiInput(InputEvent @event) + { + return @event is InputEventMouseMotion; + } + [/csharp] + [/codeblocks] + </description> + </method> + <method name="forward_spatial_draw_over_viewport" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="overlay" type="Control"> + </argument> + <description> + Called by the engine when the 3D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays]. + [codeblocks] + [gdscript] + func forward_spatial_draw_over_viewport(overlay): + # Draw a circle at cursor position. + overlay.draw_circle(overlay.get_local_mouse_position(), 64) + + func forward_spatial_gui_input(camera, event): if event is InputEventMouseMotion: - forward = true - return forward - [/codeblock] + # Redraw viewport when cursor is moved. + update_overlays() + return true + return false + [/gdscript] + [csharp] + public override void ForwardSpatialDrawOverViewport(Godot.Control overlay) + { + // Draw a circle at cursor position. + overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White); + } + + public override bool ForwardSpatialGuiInput(Godot.Camera3D camera, InputEvent @event) + { + if (@event is InputEventMouseMotion) + { + // Redraw viewport when cursor is moved. + UpdateOverlays(); + return true; + } + return false; + [/csharp] + [/codeblocks] + </description> + </method> + <method name="forward_spatial_force_draw_over_viewport" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="overlay" type="Control"> + </argument> + <description> + This method is the same as [method forward_spatial_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else. + You need to enable calling of this method by using [method set_force_draw_over_forwarding_enabled]. </description> </method> <method name="forward_spatial_gui_input" qualifiers="virtual"> @@ -253,21 +351,35 @@ </argument> <description> Called when there is a root node in the current edited scene, [method handles] is implemented and an [InputEvent] happens in the 3D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example: - [codeblock] - # Prevents the InputEvent to reach other Editor classes + [codeblocks] + [gdscript] + # Prevents the InputEvent to reach other Editor classes. func forward_spatial_gui_input(camera, event): - var forward = true - return forward - [/codeblock] + return true + [/gdscript] + [csharp] + // Prevents the InputEvent to reach other Editor classes. + public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event) + { + return true; + } + [/csharp] + [/codeblocks] Must [code]return false[/code] in order to forward the [InputEvent] to other Editor classes. Example: - [codeblock] - # Consumes InputEventMouseMotion and forwards other InputEvent types + [codeblocks] + [gdscript] + # Consumes InputEventMouseMotion and forwards other InputEvent types. func forward_spatial_gui_input(camera, event): - var forward = false - if event is InputEventMouseMotion: - forward = true - return forward - [/codeblock] + return event is InputEventMouseMotion + [/gdscript] + [csharp] + // Consumes InputEventMouseMotion and forwards other InputEvent types. + public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event) + { + return @event is InputEventMouseMotion; + } + [/csharp] + [/codeblocks] </description> </method> <method name="get_breakpoints" qualifiers="virtual"> @@ -291,13 +403,24 @@ Override this method in your plugin to return a [Texture2D] in order to give it an icon. For main screen plugins, this appears at the top of the screen, to the right of the "2D", "3D", "Script", and "AssetLib" buttons. Ideally, the plugin icon should be white with a transparent background and 16x16 pixels in size. - [codeblock] + [codeblocks] + [gdscript] func get_plugin_icon(): # You can use a custom icon: return preload("res://addons/my_plugin/my_plugin_icon.svg") # Or use a built-in icon: return get_editor_interface().get_base_control().get_icon("Node", "EditorIcons") - [/codeblock] + [/gdscript] + [csharp] + public override Texture2D GetPluginIcon() + { + // You can use a custom icon: + return ResourceLoader.Load<Texture2D>("res://addons/my_plugin/my_plugin_icon.svg"); + // Or use a built-in icon: + return GetEditorInterface().GetBaseControl().GetIcon("Node", "EditorIcons"); + } + [/csharp] + [/codeblocks] </description> </method> <method name="get_plugin_name" qualifiers="virtual"> @@ -379,7 +502,7 @@ Remember that you have to manage the visibility of all your editor controls manually. </description> </method> - <method name="queue_save_layout" qualifiers="const"> + <method name="queue_save_layout"> <return type="void"> </return> <description> @@ -511,6 +634,7 @@ <return type="void"> </return> <description> + Enables calling of [method forward_canvas_force_draw_over_viewport] for the 2D editor and [method forward_spatial_force_draw_over_viewport] for the 3D editor when their viewports are updated. You need to call this method only once and it will work permanently for this plugin. </description> </method> <method name="set_input_event_forwarding_always_enabled"> @@ -542,7 +666,7 @@ <return type="int"> </return> <description> - Updates the overlays of the editor (2D/3D) viewport. + Updates the overlays of the 2D and 3D editor viewport. Causes methods [method forward_canvas_draw_over_viewport], [method forward_canvas_force_draw_over_viewport], [method forward_spatial_draw_over_viewport] and [method forward_spatial_force_draw_over_viewport] to be called. </description> </method> </methods> diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml index cb1f5d2e77..5cddecffa8 100644 --- a/doc/classes/EditorScenePostImport.xml +++ b/doc/classes/EditorScenePostImport.xml @@ -6,24 +6,50 @@ <description> Imported scenes can be automatically modified right after import by setting their [b]Custom Script[/b] Import property to a [code]tool[/code] script that inherits from this class. The [method post_import] callback receives the imported scene's root node and returns the modified version of the scene. Usage example: - [codeblock] - tool # Needed so it runs in editor + [codeblocks] + [gdscript] + tool # Needed so it runs in editor. extends EditorScenePostImport - - # This sample changes all node names - - # Called right after the scene is imported and gets the root node + # This sample changes all node names. + # Called right after the scene is imported and gets the root node. func post_import(scene): # Change all node names to "modified_[oldnodename]" iterate(scene) return scene # Remember to return the imported scene - func iterate(node): if node != null: node.name = "modified_" + node.name for child in node.get_children(): iterate(child) - [/codeblock] + [/gdscript] + [csharp] + using Godot; + + // This sample changes all node names. + // Called right after the scene is imported and gets the root node. + [Tool] + public class NodeRenamer : EditorScenePostImport + { + public override Object PostImport(Object scene) + { + // Change all node names to "modified_[oldnodename]" + Iterate(scene as Node); + return scene; // Remember to return the imported scene + } + public void Iterate(Node node) + { + if (node != null) + { + node.Name = "modified_" + node.Name; + foreach (Node child in node.GetChildren()) + { + Iterate(child); + } + } + } + } + [/csharp] + [/codeblocks] </description> <tutorials> <link title="Importing 3D scenes: Custom script">https://docs.godotengine.org/en/latest/getting_started/workflow/assets/importing_scenes.html#custom-script</link> diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml index e96044bf48..60ccf451b8 100644 --- a/doc/classes/EditorScript.xml +++ b/doc/classes/EditorScript.xml @@ -7,13 +7,28 @@ Scripts extending this class and implementing its [method _run] method can be executed from the Script Editor's [b]File > Run[/b] menu option (or by pressing [kbd]Ctrl + Shift + X[/kbd]) while the editor is running. This is useful for adding custom in-editor functionality to Godot. For more complex additions, consider using [EditorPlugin]s instead. [b]Note:[/b] Extending scripts need to have [code]tool[/code] mode enabled. [b]Example script:[/b] - [codeblock] + [codeblocks] + [gdscript] tool extends EditorScript func _run(): print("Hello from the Godot Editor!") - [/codeblock] + [/gdscript] + [csharp] + using Godot; + using System; + + [Tool] + public class HelloEditor : EditorScript + { + public override void _Run() + { + GD.Print("Hello from the Godot Editor!"); + } + } + [/csharp] + [/codeblocks] [b]Note:[/b] The script is run in the Editor context, which means the output is visible in the console window started with the Editor (stdout) instead of the usual Godot [b]Output[/b] dock. </description> <tutorials> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 0c6a2d61cd..6088ae7a43 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -7,15 +7,24 @@ Object that holds the project-independent editor settings. These settings are generally visible in the [b]Editor > Editor Settings[/b] menu. Property names use slash delimiters to distinguish sections. Setting values can be of any [Variant] type. It's recommended to use [code]snake_case[/code] for editor settings to be consistent with the Godot editor itself. Accessing the settings can be done using the following methods, such as: - [codeblock] - # `settings.set("some/property", value)` also works as this class overrides `_set()` internally. - settings.set_setting("some/property",value) - - # `settings.get("some/property", value)` also works as this class overrides `_get()` internally. + [codeblocks] + [gdscript] + var settings = EditorInterface.get_editor_settings() + # `settings.set("some/property", 10)` also works as this class overrides `_set()` internally. + settings.set_setting("some/property", 10) + # `settings.get("some/property")` also works as this class overrides `_get()` internally. settings.get_setting("some/property") - var list_of_settings = settings.get_property_list() - [/codeblock] + [/gdscript] + [csharp] + EditorSettings settings = GetEditorInterface().GetEditorSettings(); + // `settings.set("some/property", value)` also works as this class overrides `_set()` internally. + settings.SetSetting("some/property", Value); + // `settings.get("some/property", value)` also works as this class overrides `_get()` internally. + settings.GetSetting("some/property"); + Godot.Collections.Array listOfSettings = settings.GetPropertyList(); + [/csharp] + [/codeblocks] [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_editor_settings]. </description> <tutorials> @@ -32,8 +41,10 @@ - [code]type[/code]: [int] (see [enum Variant.Type]) - optionally [code]hint[/code]: [int] (see [enum PropertyHint]) and [code]hint_string[/code]: [String] [b]Example:[/b] - [codeblock] - editor_settings.set("category/property_name", 0) + [codeblocks] + [gdscript] + var settings = EditorInterface.get_editor_settings() + settings.set("category/property_name", 0) var property_info = { "name": "category/property_name", @@ -42,8 +53,23 @@ "hint_string": "one,two,three" } - editor_settings.add_property_info(property_info) - [/codeblock] + settings.add_property_info(property_info) + [/gdscript] + [csharp] + var settings = GetEditorInterface().GetEditorSettings(); + settings.Set("category/property_name", 0); + + var propertyInfo = new Godot.Collections.Dictionary + { + {"name", "category/propertyName"}, + {"type", Variant.Type.Int}, + {"hint", PropertyHint.Enum}, + {"hint_string", "one,two,three"} + }; + + settings.AddPropertyInfo(propertyInfo); + [/csharp] + [/codeblocks] </description> </method> <method name="erase"> diff --git a/doc/classes/EditorTranslationParserPlugin.xml b/doc/classes/EditorTranslationParserPlugin.xml index f5204e7bab..c97459d9dc 100644 --- a/doc/classes/EditorTranslationParserPlugin.xml +++ b/doc/classes/EditorTranslationParserPlugin.xml @@ -9,45 +9,95 @@ When adding to [code]msgids_context_plural[/code], you must add the data using the format [code]["A", "B", "C"][/code], where [code]A[/code] represents the extracted string, [code]B[/code] represents the context, and [code]C[/code] represents the plural version of the extracted string. If you want to add only context but not plural, put [code]""[/code] for the plural slot. The idea is the same if you only want to add plural but not context. See the code below for concrete examples. The extracted strings will be written into a POT file selected by user under "POT Generation" in "Localization" tab in "Project Settings" menu. Below shows an example of a custom parser that extracts strings from a CSV file to write into a POT. - [codeblock] + [codeblocks] + [gdscript] tool extends EditorTranslationParserPlugin - func parse_file(path, msgids, msgids_context_plural): var file = File.new() file.open(path, File.READ) var text = file.get_as_text() - var split_strs = text.split(",", false, 0) + var split_strs = text.split(",", false) for s in split_strs: msgids.append(s) #print("Extracted string: " + s) - func get_recognized_extensions(): return ["csv"] - [/codeblock] + [/gdscript] + [csharp] + using Godot; + using System; + + [Tool] + public class CustomParser : EditorTranslationParserPlugin + { + public override void ParseFile(string path, Godot.Collections.Array msgids, Godot.Collections.Array msgidsContextPlural) + { + var file = new File(); + file.Open(path, File.ModeFlags.Read); + string text = file.GetAsText(); + string[] splitStrs = text.Split(",", false); + foreach (var s in splitStrs) + { + msgids.Add(s); + //GD.Print("Extracted string: " + s) + } + } + + public override Godot.Collections.Array GetRecognizedExtensions() + { + return new Godot.Collections.Array{"csv"}; + } + } + [/csharp] + [/codeblocks] To add a translatable string associated with context or plural, add it to [code]msgids_context_plural[/code]: - [codeblock] + [codeblocks] + [gdscript] # This will add a message with msgid "Test 1", msgctxt "context", and msgid_plural "test 1 plurals". msgids_context_plural.append(["Test 1", "context", "test 1 plurals"]) # This will add a message with msgid "A test without context" and msgid_plural "plurals". msgids_context_plural.append(["A test without context", "", "plurals"]) # This will add a message with msgid "Only with context" and msgctxt "a friendly context". msgids_context_plural.append(["Only with context", "a friendly context", ""]) - [/codeblock] + [/gdscript] + [csharp] + // This will add a message with msgid "Test 1", msgctxt "context", and msgid_plural "test 1 plurals". + msgidsContextPlural.Add(new Godot.Collections.Array{"Test 1", "context", "test 1 Plurals"}); + // This will add a message with msgid "A test without context" and msgid_plural "plurals". + msgidsContextPlural.Add(new Godot.Collections.Array{"A test without context", "", "plurals"}); + // This will add a message with msgid "Only with context" and msgctxt "a friendly context". + msgidsContextPlural.Add(new Godot.Collections.Array{"Only with context", "a friendly context", ""}); + [/csharp] + [/codeblocks] [b]Note:[/b] If you override parsing logic for standard script types (GDScript, C#, etc.), it would be better to load the [code]path[/code] argument using [method ResourceLoader.load]. This is because built-in scripts are loaded as [Resource] type, not [File] type. For example: - [codeblock] + [codeblocks] + [gdscript] func parse_file(path, msgids, msgids_context_plural): var res = ResourceLoader.load(path, "Script") - var text = res.get_source_code() + var text = res.source_code # Parsing logic. - func get_recognized_extensions(): return ["gd"] - [/codeblock] + [/gdscript] + [csharp] + public override void ParseFile(string path, Godot.Collections.Array msgids, Godot.Collections.Array msgidsContextPlural) + { + var res = ResourceLoader.Load<Script>(path, "Script"); + string text = res.SourceCode; + // Parsing logic. + } + + public override Godot.Collections.Array GetRecognizedExtensions() + { + return new Godot.Collections.Array{"gd"}; + } + [/csharp] + [/codeblocks] </description> <tutorials> </tutorials> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 297cccaaac..fab8512e4a 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -117,12 +117,24 @@ [code]year[/code] - Holds the year the version was released in as an int [code]string[/code] - [code]major[/code] + [code]minor[/code] + [code]patch[/code] + [code]status[/code] + [code]build[/code] in a single String The [code]hex[/code] value is encoded as follows, from left to right: one byte for the major, one byte for the minor, one byte for the patch version. For example, "3.1.12" would be [code]0x03010C[/code]. [b]Note:[/b] It's still an int internally, and printing it will give you its decimal representation, which is not particularly meaningful. Use hexadecimal literals for easy version comparisons from code: - [codeblock] + [codeblocks] + [gdscript] if Engine.get_version_info().hex >= 0x030200: # Do things specific to version 3.2 or later else: # Do things specific to versions before 3.2 - [/codeblock] + [/gdscript] + [csharp] + if ((int)Engine.GetVersionInfo()["hex"] >= 0x030200) + { + // Do things specific to version 3.2 or later + } + else + { + // Do things specific to versions before 3.2 + } + [/csharp] + [/codeblocks] </description> </method> <method name="has_singleton" qualifiers="const"> diff --git a/doc/classes/Expression.xml b/doc/classes/Expression.xml index f2611dc850..d777c6fd9d 100644 --- a/doc/classes/Expression.xml +++ b/doc/classes/Expression.xml @@ -7,21 +7,46 @@ An expression can be made of any arithmetic operation, built-in math function call, method call of a passed instance, or built-in type construction call. An example expression text using the built-in math functions could be [code]sqrt(pow(3, 2) + pow(4, 2))[/code]. In the following example we use a [LineEdit] node to write our expression and show the result. - [codeblock] - onready var expression = Expression.new() + [codeblocks] + [gdscript] + var expression = Expression.new() func _ready(): $LineEdit.connect("text_entered", self, "_on_text_entered") func _on_text_entered(command): - var error = expression.parse(command, []) + var error = expression.parse(command) if error != OK: print(expression.get_error_text()) return - var result = expression.execute([], null, true) + var result = expression.execute() if not expression.has_execute_failed(): $LineEdit.text = str(result) - [/codeblock] + [/gdscript] + [csharp] + public Expression expression = new Expression(); + + public override void _Ready() + { + GetNode("LineEdit").Connect("text_entered", this, nameof(OnTextEntered)); + } + + private void OnTextEntered(string command) + { + Error error = expression.Parse(command); + if (error != Error.Ok) + { + GD.Print(expression.GetErrorText()); + return; + } + object result = expression.Execute(); + if (!expression.HasExecuteFailed()) + { + GetNode<LineEdit>("LineEdit").Text = result.ToString(); + } + } + [/csharp] + [/codeblocks] </description> <tutorials> </tutorials> diff --git a/doc/classes/FuncRef.xml b/doc/classes/FuncRef.xml deleted file mode 100644 index dc9246ad35..0000000000 --- a/doc/classes/FuncRef.xml +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="FuncRef" inherits="Reference" version="4.0"> - <brief_description> - Reference to a function in an object. - </brief_description> - <description> - In GDScript, functions are not [i]first-class objects[/i]. This means it is impossible to store them directly as variables, return them from another function, or pass them as arguments. - However, by creating a [FuncRef] using the [method @GDScript.funcref] function, a reference to a function in a given object can be created, passed around and called. - </description> - <tutorials> - </tutorials> - <methods> - <method name="call_func" qualifiers="vararg"> - <return type="Variant"> - </return> - <description> - Calls the referenced function previously set in [member function] or [method @GDScript.funcref]. - </description> - </method> - <method name="call_funcv"> - <return type="Variant"> - </return> - <argument index="0" name="arg_array" type="Array"> - </argument> - <description> - Calls the referenced function previously set in [member function] or [method @GDScript.funcref]. Contrarily to [method call_func], this method does not support a variable number of arguments but expects all parameters to be passed via a single [Array]. - </description> - </method> - <method name="is_valid" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns whether the object still exists and has the function assigned. - </description> - </method> - <method name="set_instance"> - <return type="void"> - </return> - <argument index="0" name="instance" type="Object"> - </argument> - <description> - The object containing the referenced function. This object must be of a type actually inheriting from [Object], not a built-in type such as [int], [Vector2] or [Dictionary]. - </description> - </method> - </methods> - <members> - <member name="function" type="StringName" setter="set_function" getter="get_function" default="@"""> - The name of the referenced function. - </member> - </members> - <constants> - </constants> -</class> diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index ba201af5db..c09151405a 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -52,10 +52,6 @@ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - Normal map to be used for the [member texture] property. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. </member> diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml index 86dc8e864a..a6bcc1301b 100644 --- a/doc/classes/Geometry2D.xml +++ b/doc/classes/Geometry2D.xml @@ -200,11 +200,11 @@ Inflates or deflates [code]polygon[/code] by [code]delta[/code] units (pixels). If [code]delta[/code] is positive, makes the polygon grow outward. If [code]delta[/code] is negative, shrinks the polygon inward. Returns an array of polygons because inflating/deflating may result in multiple discrete polygons. Returns an empty array if [code]delta[/code] is negative and the absolute value of it approximately exceeds the minimum bounding rectangle dimensions of the polygon. Each polygon's vertices will be rounded as determined by [code]join_type[/code], see [enum PolyJoinType]. The operation may result in an outer polygon (boundary) and inner polygon (hole) produced which could be distinguished by calling [method is_polygon_clockwise]. - [b]Note:[/b] To translate the polygon's vertices specifically, use the [method Transform2D.xform] method: + [b]Note:[/b] To translate the polygon's vertices specifically, multiply them to a [Transform2D]: [codeblock] var polygon = PackedVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(100, 100), Vector2(0, 100)]) var offset = Vector2(50, 50) - polygon = Transform2D(0, offset).xform(polygon) + polygon = Transform2D(0, offset) * polygon print(polygon) # prints [Vector2(50, 50), Vector2(150, 50), Vector2(150, 150), Vector2(50, 150)] [/codeblock] </description> diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index 9dc38b018a..ec8ca7456a 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -9,6 +9,7 @@ A [HTTPClient] should be reused between multiple requests or to connect to different hosts instead of creating one client per request. Supports SSL and SSL server certificate verification. HTTP status codes in the 2xx range indicate success, 3xx redirection (i.e. "try again, but over here"), 4xx something was wrong with the request, and 5xx something went wrong on the server's side. For more information on HTTP, see https://developer.mozilla.org/en-US/docs/Web/HTTP (or read RFC 2616 to get it straight from the source: https://tools.ietf.org/html/rfc2616). [b]Note:[/b] When performing HTTP requests from a project exported to HTML5, keep in mind the remote server may not allow requests from foreign origins due to [url=https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS]CORS[/url]. If you host the server in question, you should modify its backend to allow requests from foreign origins by adding the [code]Access-Control-Allow-Origin: *[/code] HTTP header. + [b]Note:[/b] SSL/TLS support is currently limited to TLS 1.0, TLS 1.1, and TLS 1.2. Attempting to connect to a TLS 1.3-only server will return an error. </description> <tutorials> <link title="HTTP client class">https://docs.godotengine.org/en/latest/tutorials/networking/http_client_class.html</link> @@ -180,7 +181,7 @@ <member name="connection" type="StreamPeer" setter="set_connection" getter="get_connection"> The connection to use for this client. </member> - <member name="read_chunk_size" type="int" setter="set_read_chunk_size" getter="get_read_chunk_size" default="4096"> + <member name="read_chunk_size" type="int" setter="set_read_chunk_size" getter="get_read_chunk_size" default="65536"> The size of the buffer used and maximum bytes to read per iteration. See [method read_response_body_chunk]. </member> </members> diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index 8cc7ecfbe3..6eae881ffe 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -23,7 +23,7 @@ # Note: Don't make simultaneous requests using a single HTTPRequest node. # The snippet below is provided for reference only. var body = {"name": "Godette"} - var error = http_request.request("https://httpbin.org/post", [], true, HTTPClient.METHOD_POST, body) + error = http_request.request("https://httpbin.org/post", [], true, HTTPClient.METHOD_POST, body) if error != OK: push_error("An error occurred in the HTTP request.") @@ -65,11 +65,9 @@ texture_rect.texture = texture [/codeblock] - [b]Gzipped response bodies[/b] - HttpRequest will automatically handle decompression of response bodies. - A "Accept-Encoding" header will be automatically added to each of your requests, unless one is already specified. - Any response with a "Content-Encoding: gzip" header will automatically be decompressed and delivered to you as a uncompressed bytes. + [b]Gzipped response bodies[/b]: HTTPRequest will automatically handle decompression of response bodies. A [code]Accept-Encoding[/code] header will be automatically added to each of your requests, unless one is already specified. Any response with a [code]Content-Encoding: gzip[/code] header will automatically be decompressed and delivered to you as uncompressed bytes. [b]Note:[/b] When performing HTTP requests from a project exported to HTML5, keep in mind the remote server may not allow requests from foreign origins due to [url=https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS]CORS[/url]. If you host the server in question, you should modify its backend to allow requests from foreign origins by adding the [code]Access-Control-Allow-Origin: *[/code] HTTP header. + [b]Note:[/b] SSL/TLS support is currently limited to TLS 1.0, TLS 1.1, and TLS 1.2. Attempting to connect to a TLS 1.3-only server will return an error. </description> <tutorials> <link title="Making HTTP requests">https://docs.godotengine.org/en/latest/tutorials/networking/http_request_class.html</link> @@ -153,9 +151,9 @@ <member name="body_size_limit" type="int" setter="set_body_size_limit" getter="get_body_size_limit" default="-1"> Maximum allowed size for response bodies. If the response body is compressed, this will be used as the maximum allowed size for the decompressed body. </member> - <member name="download_chunk_size" type="int" setter="set_download_chunk_size" getter="get_download_chunk_size" default="4096"> + <member name="download_chunk_size" type="int" setter="set_download_chunk_size" getter="get_download_chunk_size" default="65536"> The size of the buffer used and maximum bytes to read per iteration. See [member HTTPClient.read_chunk_size]. - Set this to a higher value (e.g. 65536 for 64 KiB) when downloading large files to achieve better speeds at the cost of memory. + Set this to a lower value (e.g. 4096 for 4 KiB) when downloading small files to decrease memory usage at the cost of download speeds. </member> <member name="download_file" type="String" setter="set_download_file" getter="get_download_file" default=""""> The file to download into. Will output any received file into it. diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 20be20db34..3b108468de 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -346,6 +346,16 @@ Loads an image from file [code]path[/code]. See [url=https://docs.godotengine.org/en/latest/getting_started/workflow/assets/importing_images.html#supported-image-formats]Supported image formats[/url] for a list of supported image formats and limitations. </description> </method> + <method name="load_bmp_from_buffer"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="buffer" type="PackedByteArray"> + </argument> + <description> + Loads an image from the binary contents of a BMP file. + [b]Note:[/b] Godot's BMP module doesn't support 16-bit per pixel images. Only 1-bit, 4-bit, 8-bit, 24-bit, and 32-bit per pixel images are supported. + </description> + </method> <method name="load_jpg_from_buffer"> <return type="int" enum="Error"> </return> diff --git a/doc/classes/InstancePlaceholder.xml b/doc/classes/InstancePlaceholder.xml index 39827f6604..defd23afb1 100644 --- a/doc/classes/InstancePlaceholder.xml +++ b/doc/classes/InstancePlaceholder.xml @@ -18,13 +18,14 @@ <argument index="1" name="custom_scene" type="PackedScene" default="null"> </argument> <description> + Not thread-safe. Use [method Object.call_deferred] if calling from a thread. </description> </method> <method name="get_instance_path" qualifiers="const"> <return type="String"> </return> <description> - Gets the path to the [PackedScene] resource file that is loaded by default when calling [method create_instance]. + Gets the path to the [PackedScene] resource file that is loaded by default when calling [method create_instance]. Not thread-safe. Use [method Object.call_deferred] if calling from a thread. </description> </method> <method name="get_stored_values"> diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml index c5f0c2df8c..f6698352ab 100644 --- a/doc/classes/Light2D.xml +++ b/doc/classes/Light2D.xml @@ -11,8 +11,25 @@ <link title="2D lights and shadows">https://docs.godotengine.org/en/latest/tutorials/2d/2d_lights_and_shadows.html</link> </tutorials> <methods> + <method name="get_height" qualifiers="const"> + <return type="float"> + </return> + <description> + </description> + </method> + <method name="set_height"> + <return type="void"> + </return> + <argument index="0" name="height" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> + <member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" enum="Light2D.BlendMode" default="0"> + The Light2D's blend mode. See [enum BlendMode] constants for values. + </member> <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )"> The Light2D's [Color]. </member> @@ -25,15 +42,6 @@ <member name="energy" type="float" setter="set_energy" getter="get_energy" default="1.0"> The Light2D's energy value. The larger the value, the stronger the light. </member> - <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="Light2D.Mode" default="0"> - The Light2D's mode. See [enum Mode] constants for values. - </member> - <member name="offset" type="Vector2" setter="set_texture_offset" getter="get_texture_offset" default="Vector2( 0, 0 )"> - The offset of the Light2D's [code]texture[/code]. - </member> - <member name="range_height" type="float" setter="set_height" getter="get_height" default="0.0"> - The height of the Light2D. Used with 2D normal mapping. - </member> <member name="range_item_cull_mask" type="int" setter="set_item_cull_mask" getter="get_item_cull_mask" default="1"> The layer mask. Only objects with a matching mask will be affected by the Light2D. </member> @@ -49,9 +57,6 @@ <member name="range_z_min" type="int" setter="set_z_range_min" getter="get_z_range_min" default="-1024"> Minimum [code]z[/code] value of objects that are affected by the Light2D. </member> - <member name="shadow_buffer_size" type="int" setter="set_shadow_buffer_size" getter="get_shadow_buffer_size" default="2048"> - Shadow buffer size. - </member> <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color( 0, 0, 0, 0 )"> [Color] of shadows cast by the Light2D. </member> @@ -67,26 +72,8 @@ <member name="shadow_item_cull_mask" type="int" setter="set_item_shadow_cull_mask" getter="get_item_shadow_cull_mask" default="1"> The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders with a matching light mask will cast shadows. </member> - <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> - [Texture2D] used for the Light2D's appearance. - </member> - <member name="texture_scale" type="float" setter="set_texture_scale" getter="get_texture_scale" default="1.0"> - The [code]texture[/code]'s scale factor. - </member> </members> <constants> - <constant name="MODE_ADD" value="0" enum="Mode"> - Adds the value of pixels corresponding to the Light2D to the values of pixels under it. This is the common behavior of a light. - </constant> - <constant name="MODE_SUB" value="1" enum="Mode"> - Subtracts the value of pixels corresponding to the Light2D to the values of pixels under it, resulting in inversed light effect. - </constant> - <constant name="MODE_MIX" value="2" enum="Mode"> - Mix the value of pixels corresponding to the Light2D to the values of pixels under it by linear interpolation. - </constant> - <constant name="MODE_MASK" value="3" enum="Mode"> - The light texture of the Light2D is used as a mask, hiding or revealing parts of the screen underneath depending on the value of each pixel of the light (mask) texture. - </constant> <constant name="SHADOW_FILTER_NONE" value="0" enum="ShadowFilter"> No filter applies to the shadow map. See [member shadow_filter]. </constant> @@ -96,5 +83,14 @@ <constant name="SHADOW_FILTER_PCF13" value="2" enum="ShadowFilter"> Percentage closer filtering (13 samples) applies to the shadow map. See [member shadow_filter]. </constant> + <constant name="BLEND_MODE_ADD" value="0" enum="BlendMode"> + Adds the value of pixels corresponding to the Light2D to the values of pixels under it. This is the common behavior of a light. + </constant> + <constant name="BLEND_MODE_SUB" value="1" enum="BlendMode"> + Subtracts the value of pixels corresponding to the Light2D to the values of pixels under it, resulting in inversed light effect. + </constant> + <constant name="BLEND_MODE_MIX" value="2" enum="BlendMode"> + Mix the value of pixels corresponding to the Light2D to the values of pixels under it by linear interpolation. + </constant> </constants> </class> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index f08a15d873..5c2dffd538 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -78,6 +78,13 @@ Returns the [PopupMenu] of this [LineEdit]. By default, this menu is displayed when right-clicking on the [LineEdit]. </description> </method> + <method name="get_scroll_offset" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the scroll offset due to [member caret_position], as a number of characters. + </description> + </method> <method name="menu_option"> <return type="void"> </return> diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index 2d475fc449..15307de897 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -12,7 +12,6 @@ <methods> </methods> <members> - <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" /> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="2" /> <member name="text" type="String" setter="set_text" getter="get_text" default=""""> The button's text that will be displayed inside the button's area. diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index 55ae54d12b..3c3cbbfa29 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -78,38 +78,6 @@ If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame. </description> </method> - <method name="finish"> - <return type="void"> - </return> - <description> - Should not be called manually, override [method _finalize] instead. Will be removed in Godot 4.0. - </description> - </method> - <method name="idle"> - <return type="bool"> - </return> - <argument index="0" name="delta" type="float"> - </argument> - <description> - Should not be called manually, override [method _idle] instead. Will be removed in Godot 4.0. - </description> - </method> - <method name="init"> - <return type="void"> - </return> - <description> - Should not be called manually, override [method _initialize] instead. Will be removed in Godot 4.0. - </description> - </method> - <method name="iteration"> - <return type="bool"> - </return> - <argument index="0" name="delta" type="float"> - </argument> - <description> - Should not be called manually, override [method _iteration] instead. Will be removed in Godot 4.0. - </description> - </method> </methods> <signals> <signal name="on_request_permissions_result"> diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index d97e0f0f21..fe38c08280 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -31,7 +31,6 @@ <members> <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" override="true" enum="BaseButton.ActionMode" default="0" /> <member name="flat" type="bool" setter="set_flat" getter="is_flat" override="true" default="true" /> - <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" /> <member name="switch_on_hover" type="bool" setter="set_switch_on_hover" getter="is_switch_on_hover" default="false"> If [code]true[/code], when the cursor hovers above another [MenuButton] within the same parent which also has [code]switch_on_hover[/code] enabled, it will close the current [MenuButton] and open the other one. </member> diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml index 08ab01036c..b2e0442be8 100644 --- a/doc/classes/NinePatchRect.xml +++ b/doc/classes/NinePatchRect.xml @@ -32,10 +32,10 @@ </methods> <members> <member name="axis_stretch_horizontal" type="int" setter="set_h_axis_stretch_mode" getter="get_h_axis_stretch_mode" enum="NinePatchRect.AxisStretchMode" default="0"> - Doesn't do anything at the time of writing. + The stretch mode to use for horizontal stretching/tiling. See [enum NinePatchRect.AxisStretchMode] for possible values. </member> <member name="axis_stretch_vertical" type="int" setter="set_v_axis_stretch_mode" getter="get_v_axis_stretch_mode" enum="NinePatchRect.AxisStretchMode" default="0"> - Doesn't do anything at the time of writing. + The stretch mode to use for vertical stretching/tiling. See [enum NinePatchRect.AxisStretchMode] for possible values. </member> <member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" default="true"> If [code]true[/code], draw the panel's center. Else, only draw the 9-slice's borders. @@ -69,13 +69,15 @@ </signals> <constants> <constant name="AXIS_STRETCH_MODE_STRETCH" value="0" enum="AxisStretchMode"> - Doesn't do anything at the time of writing. + Stretches the center texture across the NinePatchRect. This may cause the texture to be distorted. </constant> <constant name="AXIS_STRETCH_MODE_TILE" value="1" enum="AxisStretchMode"> - Doesn't do anything at the time of writing. + Repeats the center texture across the NinePatchRect. This won't cause any visible distortion. The texture must be seamless for this to work without displaying artifacts between edges. + [b]Note:[/b] Only supported when using the GLES3 renderer. When using the GLES2 renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH]. </constant> <constant name="AXIS_STRETCH_MODE_TILE_FIT" value="2" enum="AxisStretchMode"> - Doesn't do anything at the time of writing. + Repeats the center texture across the NinePatchRect, but will also stretch the texture to make sure each tile is visible in full. This may cause the texture to be distorted, but less than [constant AXIS_STRETCH_MODE_STRETCH]. The texture must be seamless for this to work without displaying artifacts between edges. + [b]Note:[/b] Only supported when using the GLES3 renderer. When using the GLES2 renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH]. </constant> </constants> </class> diff --git a/doc/classes/NodePath.xml b/doc/classes/NodePath.xml index 658f0e6c28..93ede047fd 100644 --- a/doc/classes/NodePath.xml +++ b/doc/classes/NodePath.xml @@ -25,7 +25,23 @@ <link title="2D Role Playing Game Demo">https://godotengine.org/asset-library/asset/520</link> </tutorials> <methods> - <method name="NodePath"> + <method name="NodePath" qualifiers="constructor"> + <return type="NodePath"> + </return> + <description> + Constructs an empty [NodePath]. + </description> + </method> + <method name="NodePath" qualifiers="constructor"> + <return type="NodePath"> + </return> + <argument index="0" name="from" type="NodePath"> + </argument> + <description> + Constructs a [NodePath] as a copy of the given [NodePath]. + </description> + </method> + <method name="NodePath" qualifiers="constructor"> <return type="NodePath"> </return> <argument index="0" name="from" type="String"> @@ -65,7 +81,7 @@ </description> </method> <method name="get_concatenated_subnames"> - <return type="String"> + <return type="StringName"> </return> <description> Returns all subnames concatenated with a colon character ([code]:[/code]) as separator, i.e. the right side of the first colon in a node path. @@ -76,7 +92,7 @@ </description> </method> <method name="get_name"> - <return type="String"> + <return type="StringName"> </return> <argument index="0" name="idx" type="int"> </argument> @@ -99,7 +115,7 @@ </description> </method> <method name="get_subname"> - <return type="String"> + <return type="StringName"> </return> <argument index="0" name="idx" type="int"> </argument> @@ -134,6 +150,22 @@ Returns [code]true[/code] if the node path is empty. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="NodePath"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="NodePath"> + </argument> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index 0b43522bce..4a6893879d 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -10,7 +10,23 @@ <tutorials> </tutorials> <methods> - <method name="PackedByteArray"> + <method name="PackedByteArray" qualifiers="constructor"> + <return type="PackedByteArray"> + </return> + <description> + Constructs an empty [PackedByteArray]. + </description> + </method> + <method name="PackedByteArray" qualifiers="constructor"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="from" type="PackedByteArray"> + </argument> + <description> + Constructs a [PackedByteArray] as a copy of the given [PackedByteArray]. + </description> + </method> + <method name="PackedByteArray" qualifiers="constructor"> <return type="PackedByteArray"> </return> <argument index="0" name="from" type="Array"> @@ -20,9 +36,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="byte" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -128,9 +144,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="byte" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -143,10 +159,42 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedByteArray"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="right" type="PackedByteArray"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedByteArray"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="byte" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array. @@ -155,16 +203,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -173,9 +221,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="byte" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Changes the byte at the given index. diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index ec087e1b39..3065d16945 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -10,7 +10,23 @@ <tutorials> </tutorials> <methods> - <method name="PackedColorArray"> + <method name="PackedColorArray" qualifiers="constructor"> + <return type="PackedColorArray"> + </return> + <description> + Constructs an empty [PackedColorArray]. + </description> + </method> + <method name="PackedColorArray" qualifiers="constructor"> + <return type="PackedColorArray"> + </return> + <argument index="0" name="from" type="PackedColorArray"> + </argument> + <description> + Constructs a [PackedColorArray] as a copy of the given [PackedColorArray]. + </description> + </method> + <method name="PackedColorArray" qualifiers="constructor"> <return type="PackedColorArray"> </return> <argument index="0" name="from" type="Array"> @@ -20,9 +36,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="color" type="Color"> + <argument index="0" name="value" type="Color"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -56,9 +72,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="color" type="Color"> + <argument index="1" name="value" type="Color"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -71,10 +87,42 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedColorArray"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedColorArray"> + </return> + <argument index="0" name="right" type="PackedColorArray"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedColorArray"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="color" type="Color"> + <argument index="0" name="value" type="Color"> </argument> <description> Appends a value to the array. @@ -83,16 +131,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -101,9 +149,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="color" type="Color"> + <argument index="1" name="value" type="Color"> </argument> <description> Changes the [Color] at the given index. @@ -123,6 +171,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedColorArray"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index a6b726944b..ab9594d2e3 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -11,7 +11,23 @@ <tutorials> </tutorials> <methods> - <method name="PackedFloat32Array"> + <method name="PackedFloat32Array" qualifiers="constructor"> + <return type="PackedFloat32Array"> + </return> + <description> + Constructs an empty [PackedFloat32Array]. + </description> + </method> + <method name="PackedFloat32Array" qualifiers="constructor"> + <return type="PackedFloat32Array"> + </return> + <argument index="0" name="from" type="PackedFloat32Array"> + </argument> + <description> + Constructs a [PackedFloat32Array] as a copy of the given [PackedFloat32Array]. + </description> + </method> + <method name="PackedFloat32Array" qualifiers="constructor"> <return type="PackedFloat32Array"> </return> <argument index="0" name="from" type="Array"> @@ -21,7 +37,7 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -57,7 +73,7 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -72,8 +88,32 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedFloat32Array"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedFloat32Array"> + </return> + <argument index="0" name="right" type="PackedFloat32Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedFloat32Array"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -84,16 +124,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,7 +142,7 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -124,6 +164,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedFloat32Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index f867cda3b6..3088aee483 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -11,7 +11,23 @@ <tutorials> </tutorials> <methods> - <method name="PackedFloat64Array"> + <method name="PackedFloat64Array" qualifiers="constructor"> + <return type="PackedFloat64Array"> + </return> + <description> + Constructs an empty [PackedFloat64Array]. + </description> + </method> + <method name="PackedFloat64Array" qualifiers="constructor"> + <return type="PackedFloat64Array"> + </return> + <argument index="0" name="from" type="PackedFloat64Array"> + </argument> + <description> + Constructs a [PackedFloat64Array] as a copy of the given [PackedFloat64Array]. + </description> + </method> + <method name="PackedFloat64Array" qualifiers="constructor"> <return type="PackedFloat64Array"> </return> <argument index="0" name="from" type="Array"> @@ -21,7 +37,7 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -57,7 +73,7 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -72,8 +88,40 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedFloat64Array"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedFloat64Array"> + </return> + <argument index="0" name="right" type="PackedFloat64Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedFloat64Array"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -84,16 +132,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,7 +150,7 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -124,6 +172,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedFloat64Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index b796d9cacb..eded545de8 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -11,7 +11,23 @@ <tutorials> </tutorials> <methods> - <method name="PackedInt32Array"> + <method name="PackedInt32Array" qualifiers="constructor"> + <return type="PackedInt32Array"> + </return> + <description> + Constructs an empty [PackedInt32Array]. + </description> + </method> + <method name="PackedInt32Array" qualifiers="constructor"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="from" type="PackedInt32Array"> + </argument> + <description> + Constructs a [PackedInt32Array] as a copy of the given [PackedInt32Array]. + </description> + </method> + <method name="PackedInt32Array" qualifiers="constructor"> <return type="PackedInt32Array"> </return> <argument index="0" name="from" type="Array"> @@ -21,9 +37,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +73,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Inserts a new integer at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -72,10 +88,42 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedInt32Array"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="right" type="PackedInt32Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedInt32Array"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends a value to the array. @@ -84,16 +132,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +150,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Changes the integer at the given index. @@ -124,6 +172,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 3d0d9a1360..83731b1023 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -11,7 +11,23 @@ <tutorials> </tutorials> <methods> - <method name="PackedInt64Array"> + <method name="PackedInt64Array" qualifiers="constructor"> + <return type="PackedInt64Array"> + </return> + <description> + Constructs an empty [PackedInt64Array]. + </description> + </method> + <method name="PackedInt64Array" qualifiers="constructor"> + <return type="PackedInt64Array"> + </return> + <argument index="0" name="from" type="PackedInt64Array"> + </argument> + <description> + Constructs a [PackedInt64Array] as a copy of the given [PackedInt64Array]. + </description> + </method> + <method name="PackedInt64Array" qualifiers="constructor"> <return type="PackedInt64Array"> </return> <argument index="0" name="from" type="Array"> @@ -21,9 +37,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +73,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Inserts a new integer at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -72,10 +88,42 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedInt64Array"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedInt64Array"> + </return> + <argument index="0" name="right" type="PackedInt64Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedInt64Array"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends a value to the array. @@ -84,16 +132,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +150,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Changes the integer at the given index. @@ -124,6 +172,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedInt64Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 5f3a16ac73..c71f5ffa7e 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -11,7 +11,23 @@ <link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link> </tutorials> <methods> - <method name="PackedStringArray"> + <method name="PackedStringArray" qualifiers="constructor"> + <return type="PackedStringArray"> + </return> + <description> + Constructs an empty [PackedStringArray]. + </description> + </method> + <method name="PackedStringArray" qualifiers="constructor"> + <return type="PackedStringArray"> + </return> + <argument index="0" name="from" type="PackedStringArray"> + </argument> + <description> + Constructs a [PackedStringArray] as a copy of the given [PackedStringArray]. + </description> + </method> + <method name="PackedStringArray" qualifiers="constructor"> <return type="PackedStringArray"> </return> <argument index="0" name="from" type="Array"> @@ -21,9 +37,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="string" type="String"> + <argument index="0" name="value" type="String"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +73,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="string" type="String"> + <argument index="1" name="value" type="String"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -72,10 +88,42 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedStringArray"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedStringArray"> + </return> + <argument index="0" name="right" type="PackedStringArray"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedStringArray"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="String"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="string" type="String"> + <argument index="0" name="value" type="String"> </argument> <description> Appends a string element at end of the array. @@ -84,16 +132,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +150,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="string" type="String"> + <argument index="1" name="value" type="String"> </argument> <description> Changes the [String] at the given index. @@ -124,6 +172,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedStringArray"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index cb62aea95c..5f68d9256d 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -11,7 +11,23 @@ <link title="2D Navigation Astar Demo">https://godotengine.org/asset-library/asset/519</link> </tutorials> <methods> - <method name="PackedVector2Array"> + <method name="PackedVector2Array" qualifiers="constructor"> + <return type="PackedVector2Array"> + </return> + <description> + Constructs an empty [PackedVector2Array]. + </description> + </method> + <method name="PackedVector2Array" qualifiers="constructor"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="from" type="PackedVector2Array"> + </argument> + <description> + Constructs a [PackedVector2Array] as a copy of the given [PackedVector2Array]. + </description> + </method> + <method name="PackedVector2Array" qualifiers="constructor"> <return type="PackedVector2Array"> </return> <argument index="0" name="from" type="Array"> @@ -21,9 +37,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector2" type="Vector2"> + <argument index="0" name="value" type="Vector2"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +73,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="vector2" type="Vector2"> + <argument index="1" name="value" type="Vector2"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -72,10 +88,50 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedVector2Array"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="right" type="Transform2D"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="right" type="PackedVector2Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedVector2Array"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector2" type="Vector2"> + <argument index="0" name="value" type="Vector2"> </argument> <description> Inserts a [Vector2] at the end. @@ -84,16 +140,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +158,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="vector2" type="Vector2"> + <argument index="1" name="value" type="Vector2"> </argument> <description> Changes the [Vector2] at the given index. @@ -124,6 +180,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index f268fbcc83..e681e1deb7 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -10,7 +10,23 @@ <tutorials> </tutorials> <methods> - <method name="PackedVector3Array"> + <method name="PackedVector3Array" qualifiers="constructor"> + <return type="PackedVector3Array"> + </return> + <description> + Constructs an empty [PackedVector3Array]. + </description> + </method> + <method name="PackedVector3Array" qualifiers="constructor"> + <return type="PackedVector3Array"> + </return> + <argument index="0" name="from" type="PackedVector3Array"> + </argument> + <description> + Constructs a [PackedVector3Array] as a copy of the given [PackedVector3Array]. + </description> + </method> + <method name="PackedVector3Array" qualifiers="constructor"> <return type="PackedVector3Array"> </return> <argument index="0" name="from" type="Array"> @@ -20,9 +36,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector3" type="Vector3"> + <argument index="0" name="value" type="Vector3"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -56,9 +72,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="vector3" type="Vector3"> + <argument index="1" name="value" type="Vector3"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -71,10 +87,50 @@ Reverses the order of the elements in the array. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedVector3Array"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="PackedVector3Array"> + </return> + <argument index="0" name="right" type="Transform"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="PackedVector3Array"> + </return> + <argument index="0" name="right" type="PackedVector3Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="PackedVector3Array"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector3" type="Vector3"> + <argument index="0" name="value" type="Vector3"> </argument> <description> Inserts a [Vector3] at the end. @@ -83,16 +139,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -101,9 +157,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="vector3" type="Vector3"> + <argument index="1" name="value" type="Vector3"> </argument> <description> Changes the [Vector3] at the given index. @@ -123,6 +179,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedVector3Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml index d420e6ccdc..e3242512c4 100644 --- a/doc/classes/Plane.xml +++ b/doc/classes/Plane.xml @@ -10,7 +10,23 @@ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link> </tutorials> <methods> - <method name="Plane"> + <method name="Plane" qualifiers="constructor"> + <return type="Plane"> + </return> + <description> + Constructs a default-initialized [Plane] with all components set to [code]0[/code]. + </description> + </method> + <method name="Plane" qualifiers="constructor"> + <return type="Plane"> + </return> + <argument index="0" name="from" type="Plane"> + </argument> + <description> + Constructs a [Plane] as a copy of the given [Plane]. + </description> + </method> + <method name="Plane" qualifiers="constructor"> <return type="Plane"> </return> <argument index="0" name="a" type="float"> @@ -25,28 +41,39 @@ Creates a plane from the four parameters. The three components of the resulting plane's [member normal] are [code]a[/code], [code]b[/code] and [code]c[/code], and the plane has a distance of [code]d[/code] from the origin. </description> </method> - <method name="Plane"> + <method name="Plane" qualifiers="constructor"> <return type="Plane"> </return> - <argument index="0" name="v1" type="Vector3"> + <argument index="0" name="normal" type="Vector3"> </argument> - <argument index="1" name="v2" type="Vector3"> + <argument index="1" name="d" type="float"> </argument> - <argument index="2" name="v3" type="Vector3"> + <description> + Creates a plane from the normal and the plane's distance to the origin. + </description> + </method> + <method name="Plane" qualifiers="constructor"> + <return type="Plane"> + </return> + <argument index="0" name="point" type="Vector3"> + </argument> + <argument index="1" name="normal" type="Vector3"> </argument> <description> - Creates a plane from the three points, given in clockwise order. + Creates a plane from the given position and a plane normal. </description> </method> - <method name="Plane"> + <method name="Plane" qualifiers="constructor"> <return type="Plane"> </return> - <argument index="0" name="normal" type="Vector3"> + <argument index="0" name="point1" type="Vector3"> </argument> - <argument index="1" name="d" type="float"> + <argument index="1" name="point2" type="Vector3"> + </argument> + <argument index="2" name="point3" type="Vector3"> </argument> <description> - Creates a plane from the normal and the plane's distance to the origin. + Creates a plane from the three points, given in clockwise order. </description> </method> <method name="center"> @@ -77,7 +104,7 @@ </description> </method> <method name="intersect_3"> - <return type="Vector3"> + <return type="Variant"> </return> <argument index="0" name="b" type="Plane"> </argument> @@ -88,7 +115,7 @@ </description> </method> <method name="intersects_ray"> - <return type="Vector3"> + <return type="Variant"> </return> <argument index="0" name="from" type="Vector3"> </argument> @@ -99,11 +126,11 @@ </description> </method> <method name="intersects_segment"> - <return type="Vector3"> + <return type="Variant"> </return> - <argument index="0" name="begin" type="Vector3"> + <argument index="0" name="from" type="Vector3"> </argument> - <argument index="1" name="end" type="Vector3"> + <argument index="1" name="to" type="Vector3"> </argument> <description> Returns the intersection point of a segment from position [code]begin[/code] to position [code]end[/code] with this plane. If no intersection is found, [code]null[/code] is returned. @@ -112,7 +139,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="plane" type="Plane"> + <argument index="0" name="to_plane" type="Plane"> </argument> <description> Returns [code]true[/code] if this plane and [code]plane[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -121,7 +148,7 @@ <method name="is_point_over"> <return type="bool"> </return> - <argument index="0" name="point" type="Vector3"> + <argument index="0" name="plane" type="Vector3"> </argument> <description> Returns [code]true[/code] if [code]point[/code] is located above the plane. @@ -134,6 +161,34 @@ Returns a copy of the plane, normalized. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Plane"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Plane"> + </return> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Plane"> + </return> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Plane"> + </argument> + <description> + </description> + </method> <method name="project"> <return type="Vector3"> </return> diff --git a/doc/classes/PointLight2D.xml b/doc/classes/PointLight2D.xml new file mode 100644 index 0000000000..9337bc8351 --- /dev/null +++ b/doc/classes/PointLight2D.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="PointLight2D" inherits="Light2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="height" type="float" setter="set_height" getter="get_height" default="0.0"> + The height of the light. Used with 2D normal mapping. + </member> + <member name="offset" type="Vector2" setter="set_texture_offset" getter="get_texture_offset" default="Vector2( 0, 0 )"> + The offset of the light's [member texture]. + </member> + <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] used for the light's appearance. + </member> + <member name="texture_scale" type="float" setter="set_texture_scale" getter="get_texture_scale" default="1.0"> + The [member texture]'s scale factor. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/Polygon2D.xml b/doc/classes/Polygon2D.xml index 335df1ac3f..3aca83658d 100644 --- a/doc/classes/Polygon2D.xml +++ b/doc/classes/Polygon2D.xml @@ -101,10 +101,6 @@ <member name="invert_enable" type="bool" setter="set_invert" getter="get_invert" default="false"> If [code]true[/code], polygon will be inverted, containing the area outside the defined points and extending to the [code]invert_border[/code]. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - The normal map gives depth to the Polygon2D. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )"> The offset applied to each vertex. </member> @@ -114,14 +110,8 @@ </member> <member name="polygons" type="Array" setter="set_polygons" getter="get_polygons" default="[ ]"> </member> - <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> - </member> <member name="skeleton" type="NodePath" setter="set_skeleton" getter="get_skeleton" default="NodePath("")"> </member> - <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> - </member> - <member name="specular_map" type="Texture2D" setter="set_specular_map" getter="get_specular_map"> - </member> <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> The polygon's fill texture. Use [code]uv[/code] to set texture coordinates. </member> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 91998ead34..7ca2dae4d7 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -435,19 +435,24 @@ If [code]true[/code], the home indicator is hidden automatically. This only affects iOS devices without a physical home button. </member> <member name="display/window/size/always_on_top" type="bool" setter="" getter="" default="false"> - Force the window to be always on top. + Forces the main window to be always on top. + [b]Note:[/b] This setting is ignored on iOS, Android, and HTML5. </member> <member name="display/window/size/borderless" type="bool" setter="" getter="" default="false"> - Force the window to be borderless. + Forces the main window to be borderless. + [b]Note:[/b] This setting is ignored on iOS, Android, and HTML5. </member> <member name="display/window/size/fullscreen" type="bool" setter="" getter="" default="false"> - Sets the window to full screen when it starts. + Sets the main window to full screen when the project starts. Note that this is not [i]exclusive[/i] fullscreen. On Windows and Linux, a borderless window is used to emulate fullscreen. On macOS, a new desktop is used to display the running project. + Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=https://docs.godotengine.org/en/latest/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode. + [b]Note:[/b] This setting is ignored on iOS, Android, and HTML5. </member> <member name="display/window/size/height" type="int" setter="" getter="" default="600"> Sets the game's main viewport height. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled. </member> <member name="display/window/size/resizable" type="bool" setter="" getter="" default="true"> Allows the window to be resizable by default. + [b]Note:[/b] This setting is ignored on iOS and Android. </member> <member name="display/window/size/test_height" type="int" setter="" getter="" default="0"> If greater than zero, overrides the window height when running the game. Useful for testing stretch modes. @@ -818,6 +823,8 @@ <member name="logging/file_logging/max_log_files" type="int" setter="" getter="" default="5"> Specifies the maximum amount of log files allowed (used for rotation). </member> + <member name="memory/limits/command_queue/multithreading_queue_size_kb" type="int" setter="" getter="" default="256"> + </member> <member name="memory/limits/message_queue/max_size_kb" type="int" setter="" getter="" default="4096"> Godot uses a message queue to defer some function calls. If you run out of space on it (you will see an error), you can increase the size here. </member> @@ -1004,8 +1011,11 @@ </member> <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600"> </member> - <member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false"> - If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles. + <member name="rendering/quality/2d/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false"> + </member> + <member name="rendering/quality/2d/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false"> + </member> + <member name="rendering/quality/2d_shadow_atlas/size" type="int" setter="" getter="" default="2048"> </member> <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother. @@ -1102,6 +1112,8 @@ </member> <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_limit" type="float" setter="" getter="" default="0.18"> </member> + <member name="rendering/quality/screen_filters/use_debanding" type="bool" setter="" getter="" default="false"> + </member> <member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1"> Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better. </member> diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml index 6c95e303b8..5932a624f2 100644 --- a/doc/classes/Quat.xml +++ b/doc/classes/Quat.xml @@ -13,25 +13,33 @@ <link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link> </tutorials> <methods> - <method name="Quat"> + <method name="Quat" qualifiers="constructor"> <return type="Quat"> </return> - <argument index="0" name="from" type="Basis"> + <description> + Constructs a default-initialized quaternion with all components set to [code]0[/code]. + </description> + </method> + <method name="Quat" qualifiers="constructor"> + <return type="Quat"> + </return> + <argument index="0" name="from" type="Quat"> </argument> <description> - Constructs a quaternion from the given [Basis]. + Constructs a [Quat] as a copy of the given [Quat]. </description> </method> - <method name="Quat"> + <method name="Quat" qualifiers="constructor"> <return type="Quat"> </return> - <argument index="0" name="euler" type="Vector3"> + <argument index="0" name="arc_from" type="Vector3"> + </argument> + <argument index="1" name="arc_to" type="Vector3"> </argument> <description> - Constructs a quaternion that will perform a rotation specified by Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle, Z angle). </description> </method> - <method name="Quat"> + <method name="Quat" qualifiers="constructor"> <return type="Quat"> </return> <argument index="0" name="axis" type="Vector3"> @@ -42,7 +50,25 @@ Constructs a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector. </description> </method> - <method name="Quat"> + <method name="Quat" qualifiers="constructor"> + <return type="Quat"> + </return> + <argument index="0" name="euler" type="Vector3"> + </argument> + <description> + Constructs a quaternion that will perform a rotation specified by Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle, Z angle). + </description> + </method> + <method name="Quat" qualifiers="constructor"> + <return type="Quat"> + </return> + <argument index="0" name="from" type="Basis"> + </argument> + <description> + Constructs a quaternion from the given [Basis]. + </description> + </method> + <method name="Quat" qualifiers="constructor"> <return type="Quat"> </return> <argument index="0" name="x" type="float"> @@ -75,7 +101,7 @@ <method name="dot"> <return type="float"> </return> - <argument index="0" name="b" type="Quat"> + <argument index="0" name="with" type="Quat"> </argument> <description> Returns the dot product of two quaternions. @@ -98,7 +124,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="quat" type="Quat"> + <argument index="0" name="to" type="Quat"> </argument> <description> Returns [code]true[/code] if this quaterion and [code]quat[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -132,24 +158,96 @@ Returns a copy of the quaternion, normalized to unit length. </description> </method> - <method name="set_axis_angle"> - <return type="void"> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> </return> - <argument index="0" name="axis" type="Vector3"> + <argument index="0" name="right" type="Quat"> </argument> - <argument index="1" name="angle" type="float"> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="Quat"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> </argument> <description> - Sets the quaternion to a rotation which rotates around axis by the specified angle, in radians. The axis must be a normalized vector. </description> </method> - <method name="set_euler"> - <return type="void"> + <method name="operator *" qualifiers="operator"> + <return type="Quat"> </return> - <argument index="0" name="euler" type="Vector3"> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Quat"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="Quat"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Quat"> + </return> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Quat"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="index" type="int"> </argument> <description> - Sets the quaternion to a rotation specified by Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle, Z angle). </description> </method> <method name="slerp"> @@ -175,15 +273,6 @@ Returns the result of the spherical linear interpolation between this quaternion and [code]to[/code] by amount [code]weight[/code], but without checking if the rotation path is not bigger than 90 degrees. </description> </method> - <method name="xform"> - <return type="Vector3"> - </return> - <argument index="0" name="v" type="Vector3"> - </argument> - <description> - Returns a vector transformed (multiplied) by this quaternion. - </description> - </method> </methods> <members> <member name="w" type="float" setter="" getter="" default="1.0"> diff --git a/doc/classes/RID.xml b/doc/classes/RID.xml index 644c427120..0ee34d4194 100644 --- a/doc/classes/RID.xml +++ b/doc/classes/RID.xml @@ -9,13 +9,20 @@ <tutorials> </tutorials> <methods> - <method name="RID"> + <method name="RID" qualifiers="constructor"> <return type="RID"> </return> - <argument index="0" name="from" type="Object"> + <description> + Constructs an empty [RID] with the invalid ID [code]0[/code]. + </description> + </method> + <method name="RID" qualifiers="constructor"> + <return type="RID"> + </return> + <argument index="0" name="from" type="RID"> </argument> <description> - Creates a new RID instance with the ID of a given resource. When not handed a valid resource, silently stores the unused ID 0. + Constructs a [RID] as a copy of the given [RID]. </description> </method> <method name="get_id"> @@ -25,6 +32,54 @@ Returns the ID of the referenced resource. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="RID"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="RID"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="RID"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="RID"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="RID"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="RID"> + </argument> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/RandomNumberGenerator.xml b/doc/classes/RandomNumberGenerator.xml index d4f9517dd1..dcb75dc275 100644 --- a/doc/classes/RandomNumberGenerator.xml +++ b/doc/classes/RandomNumberGenerator.xml @@ -74,9 +74,10 @@ </method> </methods> <members> - <member name="seed" type="int" setter="set_seed" getter="get_seed" default="-6398989897141750821"> + <member name="seed" type="int" setter="set_seed" getter="get_seed" default="0"> The seed used by the random number generator. A given seed will give a reproducible sequence of pseudo-random numbers. [b]Note:[/b] The RNG does not have an avalanche effect, and can output similar random streams given similar seeds. Consider using a hash function to improve your seed quality if they're sourced externally. + [b]Note:[/b] The default value of this property is pseudo-random, and changes when calling [method randomize]. The [code]0[/code] value documented here is a placeholder, and not the actual default seed. </member> </members> <constants> diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml index aaeaa7629d..02a77a0e24 100644 --- a/doc/classes/Rect2.xml +++ b/doc/classes/Rect2.xml @@ -14,7 +14,32 @@ <link title="Advanced vector math">https://docs.godotengine.org/en/latest/tutorials/math/vectors_advanced.html</link> </tutorials> <methods> - <method name="Rect2"> + <method name="Rect2" qualifiers="constructor"> + <return type="Rect2"> + </return> + <description> + Constructs a default-initialized [Rect2] with default (zero) values of [member position] and [member size]. + </description> + </method> + <method name="Rect2" qualifiers="constructor"> + <return type="Rect2"> + </return> + <argument index="0" name="from" type="Rect2"> + </argument> + <description> + Constructs a [Rect2] as a copy of the given [Rect2]. + </description> + </method> + <method name="Rect2" qualifiers="constructor"> + <return type="Rect2"> + </return> + <argument index="0" name="from" type="Rect2i"> + </argument> + <description> + Constructs a [Rect2] from a [Rect2i]. + </description> + </method> + <method name="Rect2" qualifiers="constructor"> <return type="Rect2"> </return> <argument index="0" name="position" type="Vector2"> @@ -25,7 +50,7 @@ Constructs a [Rect2] by position and size. </description> </method> - <method name="Rect2"> + <method name="Rect2" qualifiers="constructor"> <return type="Rect2"> </return> <argument index="0" name="x" type="float"> @@ -40,15 +65,6 @@ Constructs a [Rect2] by x, y, width, and height. </description> </method> - <method name="Rect2"> - <return type="Rect2"> - </return> - <argument index="0" name="from" type="Rect2i"> - </argument> - <description> - Constructs a [Rect2] from a [Rect2i]. - </description> - </method> <method name="abs"> <return type="Rect2"> </return> @@ -108,7 +124,7 @@ </argument> <argument index="2" name="right" type="float"> </argument> - <argument index="3" name=" bottom" type="float"> + <argument index="3" name="bottom" type="float"> </argument> <description> Returns a copy of the [Rect2] grown a given amount of units towards each direction individually. @@ -171,6 +187,30 @@ Returns a larger [Rect2] that contains this [Rect2] and [code]b[/code]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Rect2"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Rect2"> + </return> + <argument index="0" name="right" type="Transform2D"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Rect2"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="end" type="Vector2" setter="" getter="" default="Vector2( 0, 0 )"> diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml index 8b29daa264..e8b75a6ac6 100644 --- a/doc/classes/Rect2i.xml +++ b/doc/classes/Rect2i.xml @@ -12,18 +12,43 @@ <link title="Vector math">https://docs.godotengine.org/en/latest/tutorials/math/vector_math.html</link> </tutorials> <methods> - <method name="Rect2i"> + <method name="Rect2i" qualifiers="constructor"> <return type="Rect2i"> </return> - <argument index="0" name="position" type="Vector2"> + <description> + Constructs a default-initialized [Rect2i] with default (zero) values of [member position] and [member size]. + </description> + </method> + <method name="Rect2i" qualifiers="constructor"> + <return type="Rect2i"> + </return> + <argument index="0" name="from" type="Rect2i"> + </argument> + <description> + Constructs a [Rect2i] as a copy of the given [Rect2i]. + </description> + </method> + <method name="Rect2i" qualifiers="constructor"> + <return type="Rect2i"> + </return> + <argument index="0" name="from" type="Rect2"> + </argument> + <description> + Constructs a new [Rect2i] from [Rect2]. The floating point coordinates will be truncated. + </description> + </method> + <method name="Rect2i" qualifiers="constructor"> + <return type="Rect2i"> + </return> + <argument index="0" name="position" type="Vector2i"> </argument> - <argument index="1" name="size" type="Vector2"> + <argument index="1" name="size" type="Vector2i"> </argument> <description> Constructs a [Rect2i] by position and size. </description> </method> - <method name="Rect2i"> + <method name="Rect2i" qualifiers="constructor"> <return type="Rect2i"> </return> <argument index="0" name="x" type="int"> @@ -38,15 +63,6 @@ Constructs a [Rect2i] by x, y, width, and height. </description> </method> - <method name="Rect2i"> - <return type="Rect2i"> - </return> - <argument index="0" name="from" type="Rect2"> - </argument> - <description> - Constructs a new [Rect2i] from [Rect2]. The floating point coordinates will be truncated. - </description> - </method> <method name="abs"> <return type="Rect2i"> </return> @@ -106,7 +122,7 @@ </argument> <argument index="2" name="right" type="int"> </argument> - <argument index="3" name=" bottom" type="int"> + <argument index="3" name="bottom" type="int"> </argument> <description> Returns a copy of the [Rect2i] grown a given amount of units towards each direction individually. @@ -158,6 +174,22 @@ Returns a larger [Rect2i] that contains this [Rect2i] and [code]b[/code]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Rect2i"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Rect2i"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="end" type="Vector2i" setter="" getter="" default="Vector2i( 0, 0 )"> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 857c13deb5..5830a8452c 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -404,28 +404,6 @@ The mode of the light, see [enum CanvasLightMode] constants. </description> </method> - <method name="canvas_light_set_scale"> - <return type="void"> - </return> - <argument index="0" name="light" type="RID"> - </argument> - <argument index="1" name="scale" type="float"> - </argument> - <description> - Sets the texture's scale factor of the light. Equivalent to [member Light2D.texture_scale]. - </description> - </method> - <method name="canvas_light_set_shadow_buffer_size"> - <return type="void"> - </return> - <argument index="0" name="light" type="RID"> - </argument> - <argument index="1" name="size" type="int"> - </argument> - <description> - Sets the width of the shadow buffer, size gets scaled to the next power of two for this. - </description> - </method> <method name="canvas_light_set_shadow_color"> <return type="void"> </return> @@ -478,7 +456,7 @@ <argument index="1" name="texture" type="RID"> </argument> <description> - Sets texture to be used by light. Equivalent to [member Light2D.texture]. + Sets the texture to be used by a [PointLight2D]. Equivalent to [member PointLight2D.texture]. </description> </method> <method name="canvas_light_set_texture_offset"> @@ -489,7 +467,18 @@ <argument index="1" name="offset" type="Vector2"> </argument> <description> - Sets the offset of the light's texture. Equivalent to [member Light2D.offset]. + Sets the offset of a [PointLight2D]'s texture. Equivalent to [member PointLight2D.offset]. + </description> + </method> + <method name="canvas_light_set_texture_scale"> + <return type="void"> + </return> + <argument index="0" name="light" type="RID"> + </argument> + <argument index="1" name="scale" type="float"> + </argument> + <description> + Sets the scale factor of a [PointLight2D]'s texture. Equivalent to [member PointLight2D.texture_scale]. </description> </method> <method name="canvas_light_set_transform"> @@ -708,6 +697,8 @@ </argument> <argument index="7" name="height_density" type="float"> </argument> + <argument index="8" name="aerial_perspective" type="float"> + </argument> <description> </description> </method> @@ -2965,6 +2956,16 @@ Sets when the viewport should be updated. See [enum ViewportUpdateMode] constants for options. </description> </method> + <method name="viewport_set_use_debanding"> + <return type="void"> + </return> + <argument index="0" name="viewport" type="RID"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> <method name="viewport_set_use_xr"> <return type="void"> </return> @@ -3674,18 +3675,25 @@ <constant name="CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="4" enum="CanvasItemTextureRepeat"> Max value for [enum CanvasItemTextureRepeat] enum. </constant> - <constant name="CANVAS_LIGHT_MODE_ADD" value="0" enum="CanvasLightMode"> + <constant name="CANVAS_GROUP_MODE_DISABLED" value="0" enum="CanvasGroupMode"> + </constant> + <constant name="CANVAS_GROUP_MODE_OPAQUE" value="1" enum="CanvasGroupMode"> + </constant> + <constant name="CANVAS_GROUP_MODE_TRANSPARENT" value="2" enum="CanvasGroupMode"> + </constant> + <constant name="CANVAS_LIGHT_MODE_POINT" value="0" enum="CanvasLightMode"> + </constant> + <constant name="CANVAS_LIGHT_MODE_DIRECTIONAL" value="1" enum="CanvasLightMode"> + </constant> + <constant name="CANVAS_LIGHT_BLEND_MODE_ADD" value="0" enum="CanvasLightBlendMode"> Adds light color additive to the canvas. </constant> - <constant name="CANVAS_LIGHT_MODE_SUB" value="1" enum="CanvasLightMode"> + <constant name="CANVAS_LIGHT_BLEND_MODE_SUB" value="1" enum="CanvasLightBlendMode"> Adds light color subtractive to the canvas. </constant> - <constant name="CANVAS_LIGHT_MODE_MIX" value="2" enum="CanvasLightMode"> + <constant name="CANVAS_LIGHT_BLEND_MODE_MIX" value="2" enum="CanvasLightBlendMode"> The light adds color depending on transparency. </constant> - <constant name="CANVAS_LIGHT_MODE_MASK" value="3" enum="CanvasLightMode"> - The light adds color depending on mask. - </constant> <constant name="CANVAS_LIGHT_FILTER_NONE" value="0" enum="CanvasLightShadowFilter"> Do not apply a filter to canvas light shadows. </constant> diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml index 1a05c02b60..b7a2258fc1 100644 --- a/doc/classes/Signal.xml +++ b/doc/classes/Signal.xml @@ -8,15 +8,31 @@ <tutorials> </tutorials> <methods> - <method name="Signal"> + <method name="Signal" qualifiers="constructor"> + <return type="Signal"> + </return> + <description> + Constructs a null [Signal] with no object nor signal name bound. + </description> + </method> + <method name="Signal" qualifiers="constructor"> + <return type="Signal"> + </return> + <argument index="0" name="from" type="Signal"> + </argument> + <description> + Constructs a [Signal] as a copy of the given [Signal]. + </description> + </method> + <method name="Signal" qualifiers="constructor"> <return type="Signal"> </return> <argument index="0" name="object" type="Object"> </argument> - <argument index="1" name="signal_name" type="StringName"> + <argument index="1" name="signal" type="StringName"> </argument> <description> - Creates a new signal named [code]signal_name[/code] in the given object. + Creates a new [Signal] with the name [code]signal[/code] in the specified [code]object[/code]. </description> </method> <method name="connect"> @@ -33,7 +49,7 @@ </description> </method> <method name="disconnect"> - <return type="Variant"> + <return type="void"> </return> <argument index="0" name="callable" type="Callable"> </argument> @@ -91,6 +107,22 @@ <description> </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Signal"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Signal"> + </argument> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml index 8205889ea7..c56596423d 100644 --- a/doc/classes/Sprite2D.xml +++ b/doc/classes/Sprite2D.xml @@ -53,10 +53,6 @@ <member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1"> The number of columns in the sprite sheet. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - The normal map gives depth to the Sprite2D. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )"> The texture's drawing offset. </member> @@ -69,15 +65,6 @@ <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. </member> - <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> - Strength of the specular light effect of this [Sprite2D]. - </member> - <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> - The color of the specular light effect. - </member> - <member name="specular_map" type="Texture2D" setter="set_specular_map" getter="get_specular_map"> - The specular map is used for more control on the shininess effect. - </member> <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> [Texture2D] object to draw. </member> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 4034a5ee07..4ee9dbf1f9 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -10,160 +10,23 @@ <link title="GDScript format strings">https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_format_string.html</link> </tutorials> <methods> - <method name="String"> + <method name="String" qualifiers="constructor"> <return type="String"> </return> - <argument index="0" name="from" type="bool"> - </argument> <description> - Constructs a new String from the given [bool]. + Constructs an empty [String] ([code]""[/code]). </description> </method> - <method name="String"> + <method name="String" qualifiers="constructor"> <return type="String"> </return> - <argument index="0" name="from" type="int"> + <argument index="0" name="from" type="String"> </argument> <description> - Constructs a new String from the given [int]. + Constructs a [String] as a copy of the given [String]. </description> </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="float"> - </argument> - <description> - Constructs a new String from the given [float]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Vector2"> - </argument> - <description> - Constructs a new String from the given [Vector2]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Vector2i"> - </argument> - <description> - Constructs a new String from the given [Vector2i]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Rect2"> - </argument> - <description> - Constructs a new String from the given [Rect2]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Rect2i"> - </argument> - <description> - Constructs a new String from the given [Rect2i]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Vector3"> - </argument> - <description> - Constructs a new String from the given [Vector3]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Vector3i"> - </argument> - <description> - Constructs a new String from the given [Vector3i]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Transform2D"> - </argument> - <description> - Constructs a new String from the given [Transform2D]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Plane"> - </argument> - <description> - Constructs a new String from the given [Plane]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Quat"> - </argument> - <description> - Constructs a new String from the given [Quat]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="AABB"> - </argument> - <description> - Constructs a new String from the given [AABB]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Basis"> - </argument> - <description> - Constructs a new String from the given [Basis]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Transform"> - </argument> - <description> - Constructs a new String from the given [Transform]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Color"> - </argument> - <description> - Constructs a new String from the given [Color]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="StringName"> - </argument> - <description> - Constructs a new String from the given [StringName]. - </description> - </method> - <method name="String"> + <method name="String" qualifiers="constructor"> <return type="String"> </return> <argument index="0" name="from" type="NodePath"> @@ -172,130 +35,13 @@ Constructs a new String from the given [NodePath]. </description> </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="RID"> - </argument> - <description> - Constructs a new String from the given [RID]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Callable"> - </argument> - <description> - Constructs a new String from the given [Callable]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Signal"> - </argument> - <description> - Constructs a new String from the given [Signal]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Dictionary"> - </argument> - <description> - Constructs a new String from the given [Dictionary]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="Array"> - </argument> - <description> - Constructs a new String from the given [Array]. - </description> - </method> - <method name="String"> + <method name="String" qualifiers="constructor"> <return type="String"> </return> - <argument index="0" name="from" type="PackedByteArray"> - </argument> - <description> - Constructs a new String from the given [PackedByteArray]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedInt32Array"> - </argument> - <description> - Constructs a new String from the given [PackedInt32Array]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedInt64Array"> - </argument> - <description> - Constructs a new String from the given [PackedInt64Array]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedFloat32Array"> - </argument> - <description> - Constructs a new String from the given [PackedFloat32Array]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedFloat64Array"> - </argument> - <description> - Constructs a new String from the given [PackedFloat64Array]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedStringArray"> - </argument> - <description> - Constructs a new String from the given [PackedStringArray]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedVector2Array"> - </argument> - <description> - Constructs a new String from the given [PackedVector2Array]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedVector3Array"> - </argument> - <description> - Constructs a new String from the given [PackedVector3Array]. - </description> - </method> - <method name="String"> - <return type="String"> - </return> - <argument index="0" name="from" type="PackedColorArray"> + <argument index="0" name="from" type="StringName"> </argument> <description> - Constructs a new String from the given [PackedColorArray]. + Constructs a new String from the given [StringName]. </description> </method> <method name="begins_with"> @@ -314,6 +60,14 @@ Returns the bigrams (pairs of consecutive letters) of this string. </description> </method> + <method name="bin_to_int"> + <return type="int"> + </return> + <argument index="0" name="with_prefix" type="bool" default="true"> + </argument> + <description> + </description> + </method> <method name="c_escape"> <return type="String"> </return> @@ -397,17 +151,6 @@ Returns [code]true[/code] if the string ends with the given string. </description> </method> - <method name="erase"> - <return type="void"> - </return> - <argument index="0" name="position" type="int"> - </argument> - <argument index="1" name="chars" type="int"> - </argument> - <description> - Erases [code]chars[/code] characters from the string starting from [code]position[/code]. - </description> - </method> <method name="find"> <return type="int"> </return> @@ -485,10 +228,13 @@ <method name="hex_to_int"> <return type="int"> </return> + <argument index="0" name="with_prefix" type="bool" default="true"> + </argument> <description> - Converts a string containing a hexadecimal number into an integer. Hexadecimal strings are expected to be prefixed with "[code]0x[/code]" otherwise [code]0[/code] is returned. + Converts a string containing a hexadecimal number into a decimal integer. If [code]with_prefix[/code] is [code]true[/code], the hexadecimal string should start with the [code]0x[/code] prefix, otherwise [code]0[/code] is returned. [codeblock] print("0xff".hex_to_int()) # Print "255" + print("ab".hex_to_int(false)) # Print "171" [/codeblock] </description> </method> @@ -512,20 +258,6 @@ [/codeblock] </description> </method> - <method name="humanize_size"> - <return type="String"> - </return> - <argument index="0" name="size" type="int"> - </argument> - <description> - Converts [code]size[/code] represented as number of bytes to human-readable format using internationalized set of data size units, namely: B, KiB, MiB, GiB, TiB, PiB, EiB. Note that the next smallest unit is picked automatically to hold at most 1024 units. - [codeblock] - var bytes = 133790307 - var size = String.humanize_size(bytes) - print(size) # prints "127.5 MiB" - [/codeblock] - </description> - </method> <method name="insert"> <return type="String"> </return> @@ -734,6 +466,86 @@ To get a boolean result from a string comparison, use the [code]==[/code] operator instead. See also [method casecmp_to] and [method naturalnocasecmp_to]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="operator %" qualifiers="operator"> + <return type="String"> + </return> + <argument index="0" name="right" type="Variant"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="String"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> <method name="ord_at"> <return type="int"> </return> @@ -990,11 +802,11 @@ Returns part of the string from the position [code]from[/code] with length [code]len[/code]. Argument [code]len[/code] is optional and using [code]-1[/code] will return remaining characters from given position. </description> </method> - <method name="to_ascii"> + <method name="to_ascii_buffer"> <return type="PackedByteArray"> </return> <description> - Converts the String (which is a character array) to ASCII/Latin-1 encoded [PackedByteArray] (which is an array of bytes). The conversion is faster compared to [method to_utf8], as this method assumes that all the characters in the String are ASCII/Latin-1 characters, unsupported characters are replaced with spaces. + Converts the String (which is a character array) to ASCII/Latin-1 encoded [PackedByteArray] (which is an array of bytes). The conversion is faster compared to [method to_utf8_buffer], as this method assumes that all the characters in the String are ASCII/Latin-1 characters, unsupported characters are replaced with spaces. </description> </method> <method name="to_float"> @@ -1025,25 +837,25 @@ Returns the string converted to uppercase. </description> </method> - <method name="to_utf16"> + <method name="to_utf16_buffer"> <return type="PackedByteArray"> </return> <description> Converts the String (which is an array of characters) to UTF-16 encoded [PackedByteArray] (which is an array of bytes). </description> </method> - <method name="to_utf32"> + <method name="to_utf32_buffer"> <return type="PackedByteArray"> </return> <description> Converts the String (which is an array of characters) to UTF-32 encoded [PackedByteArray] (which is an array of bytes). </description> </method> - <method name="to_utf8"> + <method name="to_utf8_buffer"> <return type="PackedByteArray"> </return> <description> - Converts the String (which is an array of characters) to UTF-8 encode [PackedByteArray] (which is an array of bytes). The conversion is a bit slower than [method to_ascii], but supports all UTF-8 characters. Therefore, you should prefer this function over [method to_ascii]. + Converts the String (which is an array of characters) to UTF-8 encode [PackedByteArray] (which is an array of bytes). The conversion is a bit slower than [method to_ascii_buffer], but supports all UTF-8 characters. Therefore, you should prefer this function over [method to_ascii_buffer]. </description> </method> <method name="trim_prefix"> @@ -1067,8 +879,10 @@ <method name="xml_escape"> <return type="String"> </return> + <argument index="0" name="escape_quotes" type="bool" default="false"> + </argument> <description> - Returns a copy of the string with special characters escaped using the XML standard. + Returns a copy of the string with special characters escaped using the XML standard. If [code]escape_quotes[/code] is [code]true[/code], the single quote ([code]'[/code]) and double quote ([code]"[/code]) characters are also escaped. </description> </method> <method name="xml_unescape"> diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml index 5d8ac6fdcc..af0074f080 100644 --- a/doc/classes/StringName.xml +++ b/doc/classes/StringName.xml @@ -9,7 +9,23 @@ <tutorials> </tutorials> <methods> - <method name="StringName"> + <method name="StringName" qualifiers="constructor"> + <return type="StringName"> + </return> + <description> + Constructs an empty [StringName]. + </description> + </method> + <method name="StringName" qualifiers="constructor"> + <return type="StringName"> + </return> + <argument index="0" name="from" type="StringName"> + </argument> + <description> + Constructs a [StringName] as a copy of the given [StringName]. + </description> + </method> + <method name="StringName" qualifiers="constructor"> <return type="StringName"> </return> <argument index="0" name="from" type="String"> @@ -18,6 +34,38 @@ Creates a new [StringName] from the given [String]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="String"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="StringName"> + </argument> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml index f8aa14cb2b..6f5577b61b 100644 --- a/doc/classes/StyleBoxTexture.xml +++ b/doc/classes/StyleBoxTexture.xml @@ -119,10 +119,6 @@ <member name="modulate_color" type="Color" setter="set_modulate" getter="get_modulate" default="Color( 1, 1, 1, 1 )"> Modulates the color of the texture when this style box is drawn. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - The normal map to use when drawing this style box. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> Species a sub-region of the texture to use. This is equivalent to first wrapping the texture in an [AtlasTexture] with the same region. diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index ef1f370185..15c2d3504c 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -4,7 +4,7 @@ Tabs control. </brief_description> <description> - Simple tabs control, similar to [TabContainer] but is only in charge of drawing tabs, not interact with children. + Simple tabs control, similar to [TabContainer] but is only in charge of drawing tabs, not interacting with children. </description> <tutorials> </tutorials> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index a23a4936f8..53d706db2d 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -213,6 +213,12 @@ Returns the [PopupMenu] of this [TextEdit]. By default, this menu is displayed when right-clicking on the [TextEdit]. </description> </method> + <method name="get_selection_column" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> <method name="get_selection_from_column" qualifiers="const"> <return type="int"> </return> @@ -227,6 +233,18 @@ Returns the selection begin line. </description> </method> + <method name="get_selection_line" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_selection_mode" qualifiers="const"> + <return type="int" enum="TextEdit.SelectionMode"> + </return> + <description> + </description> + </method> <method name="get_selection_text" qualifiers="const"> <return type="String"> </return> @@ -555,6 +573,18 @@ <description> </description> </method> + <method name="set_selection_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="TextEdit.SelectionMode"> + </argument> + <argument index="1" name="line" type="int" default="-1"> + </argument> + <argument index="2" name="column" type="int" default="-1"> + </argument> + <description> + </description> + </method> <method name="toggle_fold_line"> <return type="void"> </return> @@ -732,6 +762,16 @@ <constant name="SEARCH_BACKWARDS" value="4" enum="SearchFlags"> Search from end to beginning. </constant> + <constant name="SELECTION_MODE_NONE" value="0" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_SHIFT" value="1" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_POINTER" value="2" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_WORD" value="3" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_LINE" value="4" enum="SelectionMode"> + </constant> <constant name="GUTTER_TYPE_STRING" value="0" enum="GutterType"> </constant> <constant name="GUTTER_TPYE_ICON" value="1" enum="GutterType"> diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml index f283efdc3d..ff8b439a3d 100644 --- a/doc/classes/Texture2D.xml +++ b/doc/classes/Texture2D.xml @@ -22,16 +22,6 @@ </argument> <argument index="3" name="transpose" type="bool" default="false"> </argument> - <argument index="4" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_color_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="RenderingServer.CanvasItemTextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="RenderingServer.CanvasItemTextureRepeat" default="0"> - </argument> <description> Draws the texture using a [CanvasItem] with the [RenderingServer] API at the specified [code]position[/code]. </description> @@ -49,16 +39,6 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_color_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="RenderingServer.CanvasItemTextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="RenderingServer.CanvasItemTextureRepeat" default="0"> - </argument> <description> Draws the texture using a [CanvasItem] with the [RenderingServer] API. </description> @@ -76,17 +56,7 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_color_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="RenderingServer.CanvasItemTextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="RenderingServer.CanvasItemTextureRepeat" default="0"> - </argument> - <argument index="10" name="clip_uv" type="bool" default="true"> + <argument index="5" name="clip_uv" type="bool" default="true"> </argument> <description> Draws a part of the texture using a [CanvasItem] with the [RenderingServer] API. diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 9ab9d9ca7a..adc5880c71 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -389,15 +389,6 @@ Returns the offset of the tile's navigation polygon. </description> </method> - <method name="tile_get_normal_map" qualifiers="const"> - <return type="Texture2D"> - </return> - <argument index="0" name="id" type="int"> - </argument> - <description> - Returns the tile's normal map texture. - </description> - </method> <method name="tile_get_occluder_offset" qualifiers="const"> <return type="Vector2"> </return> @@ -600,18 +591,6 @@ Sets an offset for the tile's navigation polygon. </description> </method> - <method name="tile_set_normal_map"> - <return type="void"> - </return> - <argument index="0" name="id" type="int"> - </argument> - <argument index="1" name="normal_map" type="Texture2D"> - </argument> - <description> - Sets the tile's normal map texture. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </description> - </method> <method name="tile_set_occluder_offset"> <return type="void"> </return> diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index 52dda75dff..cda69f6a64 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -16,57 +16,46 @@ <link title="2.5D Demo">https://godotengine.org/asset-library/asset/583</link> </tutorials> <methods> - <method name="Transform"> + <method name="Transform" qualifiers="constructor"> <return type="Transform"> </return> - <argument index="0" name="x_axis" type="Vector3"> - </argument> - <argument index="1" name="y_axis" type="Vector3"> - </argument> - <argument index="2" name="z_axis" type="Vector3"> - </argument> - <argument index="3" name="origin" type="Vector3"> - </argument> <description> - Constructs a Transform from four [Vector3] values (matrix columns). Each axis corresponds to local basis vectors (some of which may be scaled). + Constructs a default-initialized [Transform] set to [constant IDENTITY]. </description> </method> - <method name="Transform"> + <method name="Transform" qualifiers="constructor"> <return type="Transform"> </return> - <argument index="0" name="basis" type="Basis"> - </argument> - <argument index="1" name="origin" type="Vector3"> + <argument index="0" name="from" type="Transform"> </argument> <description> - Constructs a Transform from a [Basis] and [Vector3]. + Constructs a [Transform] as a copy of the given [Transform]. </description> </method> - <method name="Transform"> + <method name="Transform" qualifiers="constructor"> <return type="Transform"> </return> - <argument index="0" name="from" type="Transform2D"> + <argument index="0" name="basis" type="Basis"> </argument> - <description> - Constructs a Transform from a [Transform2D]. - </description> - </method> - <method name="Transform"> - <return type="Transform"> - </return> - <argument index="0" name="from" type="Quat"> + <argument index="1" name="origin" type="Vector3"> </argument> <description> - Constructs a Transform from a [Quat]. The origin will be [code]Vector3(0, 0, 0)[/code]. + Constructs a Transform from a [Basis] and [Vector3]. </description> </method> - <method name="Transform"> + <method name="Transform" qualifiers="constructor"> <return type="Transform"> </return> - <argument index="0" name="from" type="Basis"> + <argument index="0" name="x_axis" type="Vector3"> + </argument> + <argument index="1" name="y_axis" type="Vector3"> + </argument> + <argument index="2" name="z_axis" type="Vector3"> + </argument> + <argument index="3" name="origin" type="Vector3"> </argument> <description> - Constructs the Transform from a [Basis]. The origin will be Vector3(0, 0, 0). + Constructs a Transform from four [Vector3] values (matrix columns). Each axis corresponds to local basis vectors (some of which may be scaled). </description> </method> <method name="affine_inverse"> @@ -79,7 +68,7 @@ <method name="interpolate_with"> <return type="Transform"> </return> - <argument index="0" name="transform" type="Transform"> + <argument index="0" name="xform" type="Transform"> </argument> <argument index="1" name="weight" type="float"> </argument> @@ -97,7 +86,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="transform" type="Transform"> + <argument index="0" name="xform" type="Transform"> </argument> <description> Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. @@ -116,6 +105,54 @@ Operations take place in global space. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Transform"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="PackedVector3Array"> + </return> + <argument index="0" name="right" type="PackedVector3Array"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Transform"> + </return> + <argument index="0" name="right" type="Transform"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="AABB"> + </return> + <argument index="0" name="right" type="AABB"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Transform"> + </argument> + <description> + </description> + </method> <method name="orthonormalized"> <return type="Transform"> </return> @@ -153,24 +190,6 @@ Unlike [method rotated] and [method scaled], this does not use matrix multiplication. </description> </method> - <method name="xform"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Transforms the given [Vector3], [Plane], [AABB], or [PackedVector3Array] by this transform. - </description> - </method> - <method name="xform_inv"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Inverse-transforms the given [Vector3], [Plane], [AABB], or [PackedVector3Array] by this transform. - </description> - </method> </methods> <members> <member name="basis" type="Basis" setter="" getter="" default="Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1 )"> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index b23bb4d33b..ff291663fa 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -14,29 +14,23 @@ <link title="2.5D Demo">https://godotengine.org/asset-library/asset/583</link> </tutorials> <methods> - <method name="Transform2D"> + <method name="Transform2D" qualifiers="constructor"> <return type="Transform2D"> </return> - <argument index="0" name="from" type="Transform"> - </argument> <description> - Constructs the transform from a 3D [Transform]. + Constructs a default-initialized [Transform] set to [constant IDENTITY]. </description> </method> - <method name="Transform2D"> + <method name="Transform2D" qualifiers="constructor"> <return type="Transform2D"> </return> - <argument index="0" name="x_axis" type="Vector2"> - </argument> - <argument index="1" name="y_axis" type="Vector2"> - </argument> - <argument index="2" name="origin" type="Vector2"> + <argument index="0" name="from" type="Transform2D"> </argument> <description> - Constructs the transform from 3 [Vector2] values representing [member x], [member y], and the [member origin] (the three column vectors). + Constructs a [Transform2D] as a copy of the given [Transform2D]. </description> </method> - <method name="Transform2D"> + <method name="Transform2D" qualifiers="constructor"> <return type="Transform2D"> </return> <argument index="0" name="rotation" type="float"> @@ -47,6 +41,19 @@ Constructs the transform from a given angle (in radians) and position. </description> </method> + <method name="Transform2D" qualifiers="constructor"> + <return type="Transform2D"> + </return> + <argument index="0" name="x_axis" type="Vector2"> + </argument> + <argument index="1" name="y_axis" type="Vector2"> + </argument> + <argument index="2" name="origin" type="Vector2"> + </argument> + <description> + Constructs the transform from 3 [Vector2] values representing [member x], [member y], and the [member origin] (the three column vectors). + </description> + </method> <method name="affine_inverse"> <return type="Transform2D"> </return> @@ -98,9 +105,9 @@ <method name="interpolate_with"> <return type="Transform2D"> </return> - <argument index="0" name="transform" type="Transform2D"> + <argument index="0" name="xform" type="Transform2D"> </argument> - <argument index="1" name="weight" type="float"> + <argument index="1" name="t" type="float"> </argument> <description> Returns a transform interpolated between this transform and another by a given weight (on the range of 0.0 to 1.0). @@ -116,12 +123,68 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="transform" type="Transform2D"> + <argument index="0" name="xform" type="Transform2D"> </argument> <description> Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Transform2D"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Rect2"> + </return> + <argument index="0" name="right" type="Rect2"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Transform2D"> + </return> + <argument index="0" name="right" type="Transform2D"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="right" type="PackedVector2Array"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Transform2D"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="orthonormalized"> <return type="Transform2D"> </return> @@ -157,24 +220,6 @@ Unlike [method rotated] and [method scaled], this does not use matrix multiplication. </description> </method> - <method name="xform"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Transforms the given [Vector2], [Rect2], or [PackedVector2Array] by this transform. - </description> - </method> - <method name="xform_inv"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Inverse-transforms the given [Vector2], [Rect2], or [PackedVector2Array] by this transform. - </description> - </method> </methods> <members> <member name="origin" type="Vector2" setter="" getter="" default="Vector2( 0, 0 )"> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index 025d6474ee..f99231de39 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -17,7 +17,23 @@ <link title="All 2D Demos">https://github.com/godotengine/godot-demo-projects/tree/master/2d</link> </tutorials> <methods> - <method name="Vector2"> + <method name="Vector2" qualifiers="constructor"> + <return type="Vector2"> + </return> + <description> + Constructs a default-initialized [Vector2] with all components set to [code]0[/code]. + </description> + </method> + <method name="Vector2" qualifiers="constructor"> + <return type="Vector2"> + </return> + <argument index="0" name="from" type="Vector2"> + </argument> + <description> + Constructs a [Vector2] as a copy of the given [Vector2]. + </description> + </method> + <method name="Vector2" qualifiers="constructor"> <return type="Vector2"> </return> <argument index="0" name="from" type="Vector2i"> @@ -26,7 +42,7 @@ Constructs a new [Vector2] from [Vector2i]. </description> </method> - <method name="Vector2"> + <method name="Vector2" qualifiers="constructor"> <return type="Vector2"> </return> <argument index="0" name="x" type="float"> @@ -177,7 +193,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="v" type="Vector2"> + <argument index="0" name="to" type="Vector2"> </argument> <description> Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -208,7 +224,7 @@ <method name="lerp"> <return type="Vector2"> </return> - <argument index="0" name="b" type="Vector2"> + <argument index="0" name="with" type="Vector2"> </argument> <argument index="1" name="t" type="float"> </argument> @@ -234,6 +250,146 @@ Returns the vector scaled to unit length. Equivalent to [code]v / v.length()[/code]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Transform2D"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector2"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector2"> + </return> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="posmod"> <return type="Vector2"> </return> @@ -296,7 +452,7 @@ <method name="slerp"> <return type="Vector2"> </return> - <argument index="0" name="b" type="Vector2"> + <argument index="0" name="with" type="Vector2"> </argument> <argument index="1" name="t" type="float"> </argument> diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml index 75ddc46dab..a4ea5c2742 100644 --- a/doc/classes/Vector2i.xml +++ b/doc/classes/Vector2i.xml @@ -14,18 +14,23 @@ <link title="3Blue1Brown Essence of Linear Algebra">https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab</link> </tutorials> <methods> - <method name="Vector2i"> + <method name="Vector2i" qualifiers="constructor"> <return type="Vector2i"> </return> - <argument index="0" name="x" type="int"> - </argument> - <argument index="1" name="y" type="int"> + <description> + Constructs a default-initialized [Vector2i] with all components set to [code]0[/code]. + </description> + </method> + <method name="Vector2i" qualifiers="constructor"> + <return type="Vector2i"> + </return> + <argument index="0" name="from" type="Vector2i"> </argument> <description> - Constructs a new [Vector2i] from the given [code]x[/code] and [code]y[/code]. + Constructs a [Vector2i] as a copy of the given [Vector2i]. </description> </method> - <method name="Vector2i"> + <method name="Vector2i" qualifiers="constructor"> <return type="Vector2i"> </return> <argument index="0" name="from" type="Vector2"> @@ -34,6 +39,17 @@ Constructs a new [Vector2i] from [Vector2]. The floating point coordinates will be truncated. </description> </method> + <method name="Vector2i" qualifiers="constructor"> + <return type="Vector2i"> + </return> + <argument index="0" name="x" type="int"> + </argument> + <argument index="1" name="y" type="int"> + </argument> + <description> + Constructs a new [Vector2i] from the given [code]x[/code] and [code]y[/code]. + </description> + </method> <method name="abs"> <return type="Vector2i"> </return> @@ -48,6 +64,154 @@ Returns the ratio of [member x] to [member y]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator %" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator %" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector2i"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector2i"> + </return> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="sign"> <return type="Vector2i"> </return> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index b26fe09e91..6ba0d6ab8d 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -17,7 +17,23 @@ <link title="All 3D Demos">https://github.com/godotengine/godot-demo-projects/tree/master/3d</link> </tutorials> <methods> - <method name="Vector3"> + <method name="Vector3" qualifiers="constructor"> + <return type="Vector3"> + </return> + <description> + Constructs a default-initialized [Vector3] with all components set to [code]0[/code]. + </description> + </method> + <method name="Vector3" qualifiers="constructor"> + <return type="Vector3"> + </return> + <argument index="0" name="from" type="Vector3"> + </argument> + <description> + Constructs a [Vector3] as a copy of the given [Vector3]. + </description> + </method> + <method name="Vector3" qualifiers="constructor"> <return type="Vector3"> </return> <argument index="0" name="from" type="Vector3i"> @@ -26,7 +42,7 @@ Constructs a new [Vector3] from [Vector3i]. </description> </method> - <method name="Vector3"> + <method name="Vector3" qualifiers="constructor"> <return type="Vector3"> </return> <argument index="0" name="x" type="float"> @@ -74,7 +90,7 @@ <method name="cross"> <return type="Vector3"> </return> - <argument index="0" name="b" type="Vector3"> + <argument index="0" name="with" type="Vector3"> </argument> <description> Returns the cross product of this vector and [code]b[/code]. @@ -126,7 +142,7 @@ <method name="dot"> <return type="float"> </return> - <argument index="0" name="b" type="Vector3"> + <argument index="0" name="with" type="Vector3"> </argument> <description> Returns the dot product of this vector and [code]b[/code]. This can be used to compare the angle between two vectors. For example, this can be used to determine whether an enemy is facing the player. @@ -152,7 +168,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="v" type="Vector3"> + <argument index="0" name="to" type="Vector3"> </argument> <description> Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -223,10 +239,166 @@ Returns the vector scaled to unit length. Equivalent to [code]v / v.length()[/code]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Basis"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Quat"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Transform"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector3"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector3"> + </return> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="outer"> <return type="Basis"> </return> - <argument index="0" name="b" type="Vector3"> + <argument index="0" name="with" type="Vector3"> </argument> <description> Returns the outer product with [code]b[/code]. @@ -271,7 +443,7 @@ <method name="rotated"> <return type="Vector3"> </return> - <argument index="0" name="axis" type="Vector3"> + <argument index="0" name="by_axis" type="Vector3"> </argument> <argument index="1" name="phi" type="float"> </argument> diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml index f977b81ce7..a1ae2aceab 100644 --- a/doc/classes/Vector3i.xml +++ b/doc/classes/Vector3i.xml @@ -14,7 +14,32 @@ <link title="3Blue1Brown Essence of Linear Algebra">https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab</link> </tutorials> <methods> - <method name="Vector3i"> + <method name="Vector3i" qualifiers="constructor"> + <return type="Vector3i"> + </return> + <description> + Constructs a default-initialized [Vector3i] with all components set to [code]0[/code]. + </description> + </method> + <method name="Vector3i" qualifiers="constructor"> + <return type="Vector3i"> + </return> + <argument index="0" name="from" type="Vector3i"> + </argument> + <description> + Constructs a [Vector3i] as a copy of the given [Vector3i]. + </description> + </method> + <method name="Vector3i" qualifiers="constructor"> + <return type="Vector3i"> + </return> + <argument index="0" name="from" type="Vector3"> + </argument> + <description> + Constructs a new [Vector3i] from [Vector3]. The floating point coordinates will be truncated. + </description> + </method> + <method name="Vector3i" qualifiers="constructor"> <return type="Vector3i"> </return> <argument index="0" name="x" type="int"> @@ -27,13 +52,10 @@ Returns a [Vector3i] with the given components. </description> </method> - <method name="Vector3i"> + <method name="abs"> <return type="Vector3i"> </return> - <argument index="0" name="from" type="Vector3"> - </argument> <description> - Constructs a new [Vector3i] from [Vector3]. The floating point coordinates will be truncated. </description> </method> <method name="max_axis"> @@ -50,6 +72,154 @@ Returns the axis of the vector's smallest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_Z]. </description> </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator %" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator %" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector3i"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector3i"> + </return> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator []" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> <method name="sign"> <return type="Vector3i"> </return> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 84974874de..85dc5e8fd8 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -250,9 +250,15 @@ The shadow atlas' resolution (used for omni and spot lights). The value will be rounded up to the nearest power of 2. [b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-created viewports default to a value of 0, this value must be set above 0 manually. </member> + <member name="snap_2d_transforms_to_pixel" type="bool" setter="set_snap_2d_transforms_to_pixel" getter="is_snap_2d_transforms_to_pixel_enabled" default="false"> + </member> + <member name="snap_2d_vertices_to_pixel" type="bool" setter="set_snap_2d_vertices_to_pixel" getter="is_snap_2d_vertices_to_pixel_enabled" default="false"> + </member> <member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false"> If [code]true[/code], the viewport should render its background as transparent. </member> + <member name="use_debanding" type="bool" setter="set_use_debanding" getter="is_using_debanding" default="false"> + </member> <member name="world_2d" type="World2D" setter="set_world_2d" getter="get_world_2d"> The custom [World2D] which can be used as 2D environment source. </member> diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index c1a991fca1..a0711b4214 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -362,6 +362,8 @@ <constant name="MODE_MAXIMIZED" value="2" enum="Mode"> </constant> <constant name="MODE_FULLSCREEN" value="3" enum="Mode"> + Fullscreen window mode. Note that this is not [i]exclusive[/i] fullscreen. On Windows and Linux, a borderless window is used to emulate fullscreen. On macOS, a new desktop is used to display the running project. + Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=https://docs.godotengine.org/en/latest/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode. </constant> <constant name="FLAG_RESIZE_DISABLED" value="0" enum="Flags"> </constant> diff --git a/doc/classes/bool.xml b/doc/classes/bool.xml index ce4d000a9b..03e8bee7d5 100644 --- a/doc/classes/bool.xml +++ b/doc/classes/bool.xml @@ -91,16 +91,23 @@ <tutorials> </tutorials> <methods> - <method name="bool"> + <method name="bool" qualifiers="constructor"> <return type="bool"> </return> - <argument index="0" name="from" type="int"> + <description> + Constructs a default-initialized [bool] set to [code]false[/code]. + </description> + </method> + <method name="bool" qualifiers="constructor"> + <return type="bool"> + </return> + <argument index="0" name="from" type="bool"> </argument> <description> - Cast an [int] value to a boolean value, this method will return [code]false[/code] if [code]0[/code] is passed in, and [code]true[/code] for all other ints. + Constructs a [bool] as a copy of the given [bool]. </description> </method> - <method name="bool"> + <method name="bool" qualifiers="constructor"> <return type="bool"> </return> <argument index="0" name="from" type="float"> @@ -109,14 +116,45 @@ Cast a [float] value to a boolean value, this method will return [code]false[/code] if [code]0.0[/code] is passed in, and [code]true[/code] for all other floats. </description> </method> - <method name="bool"> + <method name="bool" qualifiers="constructor"> + <return type="bool"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <description> + Cast an [int] value to a boolean value, this method will return [code]false[/code] if [code]0[/code] is passed in, and [code]true[/code] for all other ints. + </description> + </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="bool"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="bool"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="bool"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> <return type="bool"> </return> - <argument index="0" name="from" type="String"> + <argument index="0" name="right" type="bool"> </argument> <description> - Cast a [String] value to a boolean value, this method will return [code]false[/code] if [code]""[/code] is passed in, and [code]true[/code] for all non-empty strings. - Examples: [code]bool("False")[/code] returns [code]true[/code], [code]bool("")[/code] returns [code]false[/code]. </description> </method> </methods> diff --git a/doc/classes/float.xml b/doc/classes/float.xml index 16a696f959..85fe31eec8 100644 --- a/doc/classes/float.xml +++ b/doc/classes/float.xml @@ -9,7 +9,23 @@ <tutorials> </tutorials> <methods> - <method name="float"> + <method name="float" qualifiers="constructor"> + <return type="float"> + </return> + <description> + Constructs a default-initialized [float] set to [code]0.0[/code]. + </description> + </method> + <method name="float" qualifiers="constructor"> + <return type="float"> + </return> + <argument index="0" name="from" type="float"> + </argument> + <description> + Constructs a [float] as a copy of the given [float]. + </description> + </method> + <method name="float" qualifiers="constructor"> <return type="float"> </return> <argument index="0" name="from" type="bool"> @@ -18,22 +34,233 @@ Cast a [bool] value to a floating-point value, [code]float(true)[/code] will be equal to 1.0 and [code]float(false)[/code] will be equal to 0.0. </description> </method> - <method name="float"> + <method name="float" qualifiers="constructor"> <return type="float"> </return> <argument index="0" name="from" type="int"> </argument> <description> - Cast an [int] value to a floating-point value, [code]float(1)[/code] will be equal to 1.0. + Cast an [int] value to a floating-point value, [code]float(1)[/code] will be equal to [code]1.0[/code]. + </description> + </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> </description> </method> - <method name="float"> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> <return type="float"> </return> - <argument index="0" name="from" type="String"> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="Quat"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="float"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="float"> + </return> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> </argument> <description> - Cast a [String] value to a floating-point value. This method accepts float value strings like [code]"1.23"[/code] and exponential notation strings for its parameter so calling [code]float("1e3")[/code] will return 1000.0 and calling [code]float("1e-3")[/code] will return 0.001. Calling this method with an invalid float string will return 0. This method stops parsing at the first invalid character and will return the parsed result so far, so calling [code]float("1a3")[/code] will return 1 while calling [code]float("1e3a2")[/code] will return 1000.0. </description> </method> </methods> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index 2c9f0ad371..5ac9f8405a 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -23,7 +23,23 @@ <tutorials> </tutorials> <methods> - <method name="int"> + <method name="int" qualifiers="constructor"> + <return type="int"> + </return> + <description> + Constructs a default-initialized [int] set to [code]0[/code]. + </description> + </method> + <method name="int" qualifiers="constructor"> + <return type="int"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <description> + Constructs an [int] as a copy of the given [int]. + </description> + </method> + <method name="int" qualifiers="constructor"> <return type="int"> </return> <argument index="0" name="from" type="bool"> @@ -32,7 +48,7 @@ Cast a [bool] value to an integer value, [code]int(true)[/code] will be equals to 1 and [code]int(false)[/code] will be equals to 0. </description> </method> - <method name="int"> + <method name="int" qualifiers="constructor"> <return type="int"> </return> <argument index="0" name="from" type="float"> @@ -41,13 +57,278 @@ Cast a float value to an integer value, this method simply removes the number fractions, so for example [code]int(2.7)[/code] will be equals to 2, [code]int(.1)[/code] will be equals to 0 and [code]int(-2.7)[/code] will be equals to -2. </description> </method> - <method name="int"> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator !=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator %" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator &" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2"> + </return> + <argument index="0" name="right" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector2i"> + </return> + <argument index="0" name="right" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3"> + </return> + <argument index="0" name="right" type="Vector3"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Vector3i"> + </return> + <argument index="0" name="right" type="Vector3i"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Quat"> + </return> + <argument index="0" name="right" type="Quat"> + </argument> + <description> + </description> + </method> + <method name="operator *" qualifiers="operator"> + <return type="Color"> + </return> + <argument index="0" name="right" type="Color"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator +" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator -" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="float"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator /" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator <" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <<" qualifiers="operator"> <return type="int"> </return> - <argument index="0" name="from" type="String"> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator <=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> </argument> <description> - Cast a [String] value to an integer value, this method is an integer parser from a string, so calling this method with an invalid integer string will return 0, a valid string will be something like [code]'1.7'[/code]. This method will ignore all non-number characters, so calling [code]int('1e3')[/code] will return 13. + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator ==" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator >" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="float"> + </argument> + <description> + </description> + </method> + <method name="operator >=" qualifiers="operator"> + <return type="bool"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator >>" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator ^" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator |" qualifiers="operator"> + <return type="int"> + </return> + <argument index="0" name="right" type="int"> + </argument> + <description> + </description> + </method> + <method name="operator ~" qualifiers="operator"> + <return type="int"> + </return> + <description> </description> </method> </methods> diff --git a/doc/tools/doc_merge.py b/doc/tools/doc_merge.py deleted file mode 100755 index f6f52f5d66..0000000000 --- a/doc/tools/doc_merge.py +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import sys -import xml.etree.ElementTree as ET - - -tree = ET.parse(sys.argv[1]) -old_doc = tree.getroot() - -tree = ET.parse(sys.argv[2]) -new_doc = tree.getroot() - -f = file(sys.argv[3], "wb") -tab = 0 - -old_classes = {} - - -def write_string(_f, text, newline=True): - for t in range(tab): - _f.write("\t") - _f.write(text) - if newline: - _f.write("\n") - - -def escape(ret): - ret = ret.replace("&", "&") - ret = ret.replace("<", ">") - ret = ret.replace(">", "<") - ret = ret.replace("'", "'") - ret = ret.replace('"', """) - return ret - - -def inc_tab(): - global tab - tab += 1 - - -def dec_tab(): - global tab - tab -= 1 - - -write_string(f, '<?xml version="1.0" encoding="UTF-8" ?>') -write_string(f, '<doc version="' + new_doc.attrib["version"] + '">') - - -def get_tag(node, name): - tag = "" - if name in node.attrib: - tag = " " + name + '="' + escape(node.attrib[name]) + '" ' - return tag - - -def find_method_descr(old_class, name): - - methods = old_class.find("methods") - if methods != None and len(list(methods)) > 0: - for m in list(methods): - if m.attrib["name"] == name: - description = m.find("description") - if description != None and description.text.strip() != "": - return description.text - - return None - - -def find_signal_descr(old_class, name): - - signals = old_class.find("signals") - if signals != None and len(list(signals)) > 0: - for m in list(signals): - if m.attrib["name"] == name: - description = m.find("description") - if description != None and description.text.strip() != "": - return description.text - - return None - - -def find_constant_descr(old_class, name): - - if old_class is None: - return None - constants = old_class.find("constants") - if constants != None and len(list(constants)) > 0: - for m in list(constants): - if m.attrib["name"] == name: - if m.text.strip() != "": - return m.text - return None - - -def write_class(c): - class_name = c.attrib["name"] - print("Parsing Class: " + class_name) - if class_name in old_classes: - old_class = old_classes[class_name] - else: - old_class = None - - category = get_tag(c, "category") - inherits = get_tag(c, "inherits") - write_string(f, '<class name="' + class_name + '" ' + category + inherits + ">") - inc_tab() - - write_string(f, "<brief_description>") - - if old_class != None: - old_brief_descr = old_class.find("brief_description") - if old_brief_descr != None: - write_string(f, escape(old_brief_descr.text.strip())) - - write_string(f, "</brief_description>") - - write_string(f, "<description>") - if old_class != None: - old_descr = old_class.find("description") - if old_descr != None: - write_string(f, escape(old_descr.text.strip())) - - write_string(f, "</description>") - - methods = c.find("methods") - if methods != None and len(list(methods)) > 0: - - write_string(f, "<methods>") - inc_tab() - - for m in list(methods): - qualifiers = get_tag(m, "qualifiers") - - write_string(f, '<method name="' + escape(m.attrib["name"]) + '" ' + qualifiers + ">") - inc_tab() - - for a in list(m): - if a.tag == "return": - typ = get_tag(a, "type") - write_string(f, "<return" + typ + ">") - write_string(f, "</return>") - elif a.tag == "argument": - - default = get_tag(a, "default") - - write_string( - f, - '<argument index="' - + a.attrib["index"] - + '" name="' - + escape(a.attrib["name"]) - + '" type="' - + a.attrib["type"] - + '"' - + default - + ">", - ) - write_string(f, "</argument>") - - write_string(f, "<description>") - if old_class != None: - old_method_descr = find_method_descr(old_class, m.attrib["name"]) - if old_method_descr: - write_string(f, escape(escape(old_method_descr.strip()))) - - write_string(f, "</description>") - dec_tab() - write_string(f, "</method>") - dec_tab() - write_string(f, "</methods>") - - signals = c.find("signals") - if signals != None and len(list(signals)) > 0: - - write_string(f, "<signals>") - inc_tab() - - for m in list(signals): - - write_string(f, '<signal name="' + escape(m.attrib["name"]) + '">') - inc_tab() - - for a in list(m): - if a.tag == "argument": - - write_string( - f, - '<argument index="' - + a.attrib["index"] - + '" name="' - + escape(a.attrib["name"]) - + '" type="' - + a.attrib["type"] - + '">', - ) - write_string(f, "</argument>") - - write_string(f, "<description>") - if old_class != None: - old_signal_descr = find_signal_descr(old_class, m.attrib["name"]) - if old_signal_descr: - write_string(f, escape(old_signal_descr.strip())) - write_string(f, "</description>") - dec_tab() - write_string(f, "</signal>") - dec_tab() - write_string(f, "</signals>") - - constants = c.find("constants") - if constants != None and len(list(constants)) > 0: - - write_string(f, "<constants>") - inc_tab() - - for m in list(constants): - - write_string(f, '<constant name="' + escape(m.attrib["name"]) + '" value="' + m.attrib["value"] + '">') - old_constant_descr = find_constant_descr(old_class, m.attrib["name"]) - if old_constant_descr: - write_string(f, escape(old_constant_descr.strip())) - write_string(f, "</constant>") - - dec_tab() - write_string(f, "</constants>") - - dec_tab() - write_string(f, "</class>") - - -for c in list(old_doc): - old_classes[c.attrib["name"]] = c - -for c in list(new_doc): - write_class(c) -write_string(f, "</doc>\n") diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index ed147f31cd..5335116c8a 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -1042,6 +1042,8 @@ def make_footer(): # type: () -> str ".. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`\n" ".. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`\n" ".. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`\n" + ".. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`\n" + ".. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`\n" ) # fmt: on diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 90c3d3af83..488fd4b468 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -32,8 +32,8 @@ #ifdef ALSA_ENABLED +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include <errno.h> diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp index 69a6956c2b..07a4360cd2 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.cpp +++ b/drivers/alsamidi/midi_driver_alsamidi.cpp @@ -33,7 +33,7 @@ #include "midi_driver_alsamidi.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <errno.h> diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h index 6aabe8e3fd..fef87459c7 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.h +++ b/drivers/alsamidi/midi_driver_alsamidi.h @@ -36,7 +36,7 @@ #include "core/os/midi_driver.h" #include "core/os/mutex.h" #include "core/os/thread.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include <alsa/asoundlib.h> #include <stdio.h> diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 48d0a29516..60c491f5f8 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -32,8 +32,8 @@ #include "audio_driver_coreaudio.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #define kOutputBus 0 #define kInputBus 1 diff --git a/drivers/coremidi/midi_driver_coremidi.cpp b/drivers/coremidi/midi_driver_coremidi.cpp index 004c594e17..b9e7853735 100644 --- a/drivers/coremidi/midi_driver_coremidi.cpp +++ b/drivers/coremidi/midi_driver_coremidi.cpp @@ -32,7 +32,7 @@ #include "midi_driver_coremidi.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <CoreAudio/HostTime.h> #include <CoreServices/CoreServices.h> diff --git a/drivers/coremidi/midi_driver_coremidi.h b/drivers/coremidi/midi_driver_coremidi.h index 0459544f75..02167aa891 100644 --- a/drivers/coremidi/midi_driver_coremidi.h +++ b/drivers/coremidi/midi_driver_coremidi.h @@ -34,7 +34,7 @@ #define MIDI_DRIVER_COREMIDI_H #include "core/os/midi_driver.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include <CoreMIDI/CoreMIDI.h> #include <stdio.h> diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index bef4d999af..2d1c4f8d85 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -32,8 +32,8 @@ #define RASTERIZER_DUMMY_H #include "core/math/camera_matrix.h" -#include "core/rid_owner.h" -#include "core/self_list.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" #include "scene/resources/mesh.h" #include "servers/rendering/rasterizer.h" #include "servers/rendering_server.h" @@ -98,7 +98,7 @@ public: void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) override {} - void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density) override {} + void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {} void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) override {} void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {} void environment_set_volumetric_fog_filter_active(bool p_enable) override {} @@ -161,7 +161,7 @@ public: void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {} RID render_buffers_create() override { return RID(); } - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) override {} + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) override {} void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {} bool screen_space_roughness_limiter_is_active() const override { return false; } @@ -251,6 +251,15 @@ public: void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} + /* CANVAS TEXTURE API */ + + RID canvas_texture_create() override { return RID(); } + void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override {} + void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override {} + + void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override {} + void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override {} + #if 0 RID texture_create() override { @@ -935,23 +944,22 @@ public: class RasterizerCanvasDummy : public RasterizerCanvas { public: - TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) override { return 0; } - void free_texture_binding(TextureBindingID p_binding) override {} - PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override { return 0; } void free_polygon(PolygonID p_polygon) override {} - void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) override {} + void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) override {} void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override {} RID light_create() override { return RID(); } void light_set_texture(RID p_rid, RID p_texture) override {} - void light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) override {} - void light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override {} + void light_set_use_shadow(RID p_rid, bool p_enable) override {} + void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override {} + void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override {} RID occluder_polygon_create() override { return RID(); } void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) override {} void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override {} + void set_shadow_texture_size(int p_size) override {} void draw_window_margins(int *p_margins, RID *p_margin_textures) override {} diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp index ddd2943720..6158a2ac54 100644 --- a/drivers/dummy/texture_loader_dummy.cpp +++ b/drivers/dummy/texture_loader_dummy.cpp @@ -31,7 +31,7 @@ #include "texture_loader_dummy.h" #include "core/os/file_access.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <string.h> diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp index 79924b849c..cd0c68e947 100644 --- a/drivers/png/image_loader_png.cpp +++ b/drivers/png/image_loader_png.cpp @@ -31,7 +31,7 @@ #include "image_loader_png.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "drivers/png/png_driver_common.h" #include <string.h> diff --git a/drivers/png/png_driver_common.h b/drivers/png/png_driver_common.h index 2099ddc536..e7ec9b96bd 100644 --- a/drivers/png/png_driver_common.h +++ b/drivers/png/png_driver_common.h @@ -31,7 +31,7 @@ #ifndef PNG_DRIVER_COMMON_H #define PNG_DRIVER_COMMON_H -#include "core/image.h" +#include "core/io/image.h" namespace PNGDriverCommon { diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp index 3a0b319a45..a2d0d5881a 100644 --- a/drivers/png/resource_saver_png.cpp +++ b/drivers/png/resource_saver_png.cpp @@ -30,7 +30,7 @@ #include "resource_saver_png.h" -#include "core/image.h" +#include "core/io/image.h" #include "core/os/file_access.h" #include "drivers/png/png_driver_common.h" #include "scene/resources/texture.h" diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h index c32b383521..1d4dcfb57f 100644 --- a/drivers/png/resource_saver_png.h +++ b/drivers/png/resource_saver_png.h @@ -31,7 +31,7 @@ #ifndef RESOURCE_SAVER_PNG_H #define RESOURCE_SAVER_PNG_H -#include "core/image.h" +#include "core/io/image.h" #include "core/io/resource_saver.h" class ResourceSaverPNG : public ResourceFormatSaver { diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index a6bc4f3b2c..5acaa3ac99 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -32,8 +32,8 @@ #ifdef PULSEAUDIO_ENABLED +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) { AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 5b99a2f53f..63fa143a03 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -32,9 +32,9 @@ #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED) -#include "core/list.h" #include "core/os/memory.h" -#include "core/print_string.h" +#include "core/string/print_string.h" +#include "core/templates/list.h" #include <errno.h> #include <stdio.h> diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 51c657007c..ce1e135fe0 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -33,7 +33,7 @@ #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED) #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <sys/stat.h> #include <sys/types.h> diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index eec6eb8303..318638e5d0 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -32,10 +32,10 @@ #ifdef UNIX_ENABLED +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" #include "core/os/thread_dummy.h" -#include "core/project_settings.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "drivers/unix/net_socket_posix.h" diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp index 50b74e84f7..cf24d54c50 100644 --- a/drivers/unix/rw_lock_posix.cpp +++ b/drivers/unix/rw_lock_posix.cpp @@ -32,7 +32,7 @@ #include "rw_lock_posix.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/memory.h" #include <stdio.h> diff --git a/drivers/unix/syslog_logger.cpp b/drivers/unix/syslog_logger.cpp index a4c7070f0e..b29d1ec541 100644 --- a/drivers/unix/syslog_logger.cpp +++ b/drivers/unix/syslog_logger.cpp @@ -31,7 +31,7 @@ #ifdef UNIX_ENABLED #include "syslog_logger.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <syslog.h> void SyslogLogger::logv(const char *p_format, va_list p_list, bool p_err) { diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp index 285088342b..f4e3de7646 100644 --- a/drivers/unix/thread_posix.cpp +++ b/drivers/unix/thread_posix.cpp @@ -32,9 +32,9 @@ #if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS) +#include "core/object/script_language.h" #include "core/os/memory.h" -#include "core/safe_refcount.h" -#include "core/script_language.h" +#include "core/templates/safe_refcount.h" #ifdef PTHREAD_BSD_SET_NAME #include <pthread_np.h> diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index a356586698..902876616b 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -30,10 +30,10 @@ #include "rendering_device_vulkan.h" -#include "core/hashfuncs.h" +#include "core/config/project_settings.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" +#include "core/templates/hashfuncs.h" #include "drivers/vulkan/vulkan_context.h" #include "thirdparty/spirv-reflect/spirv_reflect.h" diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index e6cbf2e01d..6463078d0a 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -31,9 +31,9 @@ #ifndef RENDERING_DEVICE_VULKAN_H #define RENDERING_DEVICE_VULKAN_H -#include "core/oa_hash_map.h" #include "core/os/thread_safe.h" -#include "core/rid_owner.h" +#include "core/templates/oa_hash_map.h" +#include "core/templates/rid_owner.h" #include "servers/rendering/rendering_device.h" #ifdef DEBUG_ENABLED diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 8840391966..ebfd3e0454 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -30,9 +30,9 @@ #include "vulkan_context.h" -#include "core/engine.h" -#include "core/project_settings.h" -#include "core/ustring.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/string/ustring.h" #include "core/version.h" #include "vk_enum_string_helper.h" diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 59e404512a..26d4b76e86 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -31,11 +31,11 @@ #ifndef VULKAN_CONTEXT_H #define VULKAN_CONTEXT_H -#include "core/error_list.h" -#include "core/map.h" +#include "core/error/error_list.h" #include "core/os/mutex.h" -#include "core/rid_owner.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/map.h" +#include "core/templates/rid_owner.h" #include "servers/display_server.h" #include <vulkan/vulkan.h> diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index cd1c08b717..67e175d8d1 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -32,8 +32,8 @@ #include "audio_driver_wasapi.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include <functiondiscoverykeys.h> diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 03e4e30797..3c61aa7289 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -33,7 +33,7 @@ #include "dir_access_windows.h" #include "core/os/memory.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <stdio.h> #include <wchar.h> diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index dd86061ea7..ec393c98ba 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -33,7 +33,7 @@ #include "file_access_windows.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <shlwapi.h> #include <windows.h> diff --git a/drivers/windows/rw_lock_windows.cpp b/drivers/windows/rw_lock_windows.cpp index 757c7661f5..1007689728 100644 --- a/drivers/windows/rw_lock_windows.cpp +++ b/drivers/windows/rw_lock_windows.cpp @@ -32,7 +32,7 @@ #include "rw_lock_windows.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/os/memory.h" #include <stdio.h> diff --git a/drivers/windows/thread_windows.h b/drivers/windows/thread_windows.h index 502c418ce0..939f487fc1 100644 --- a/drivers/windows/thread_windows.h +++ b/drivers/windows/thread_windows.h @@ -33,8 +33,8 @@ #ifdef WINDOWS_ENABLED +#include "core/object/script_language.h" #include "core/os/thread.h" -#include "core/script_language.h" #include <windows.h> diff --git a/drivers/winmidi/midi_driver_winmidi.cpp b/drivers/winmidi/midi_driver_winmidi.cpp index 9cbc7f43e2..75f57b3bb9 100644 --- a/drivers/winmidi/midi_driver_winmidi.cpp +++ b/drivers/winmidi/midi_driver_winmidi.cpp @@ -32,7 +32,7 @@ #include "midi_driver_winmidi.h" -#include "core/print_string.h" +#include "core/string/print_string.h" void MIDIDriverWinMidi::read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { if (wMsg == MIM_DATA) { diff --git a/drivers/winmidi/midi_driver_winmidi.h b/drivers/winmidi/midi_driver_winmidi.h index 934eb5a493..9ed3fc2faa 100644 --- a/drivers/winmidi/midi_driver_winmidi.h +++ b/drivers/winmidi/midi_driver_winmidi.h @@ -34,7 +34,7 @@ #define MIDI_DRIVER_WINMIDI_H #include "core/os/midi_driver.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include <stdio.h> #include <windows.h> diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 421cf6a8cf..c9ad054089 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -30,8 +30,8 @@ #include "audio_driver_xaudio2.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" const char *AudioDriverXAudio2::get_name() const { return "XAudio2"; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 52c984cbc0..6f30d5a492 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -228,9 +228,9 @@ public: if (Variant::can_convert(args[idx].get_type(), t)) { Variant old = args[idx]; Variant *ptrs[1] = { &old }; - args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err); + Variant::construct(t, args.write[idx], (const Variant **)ptrs, 1, err); } else { - args.write[idx] = Variant::construct(t, nullptr, 0, err); + Variant::construct(t, args.write[idx], nullptr, 0, err); } change_notify_deserved = true; d_new["args"] = args; @@ -846,9 +846,9 @@ public: if (Variant::can_convert(args[idx].get_type(), t)) { Variant old = args[idx]; Variant *ptrs[1] = { &old }; - args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err); + Variant::construct(t, args.write[idx], (const Variant **)ptrs, 1, err); } else { - args.write[idx] = Variant::construct(t, nullptr, 0, err); + Variant::construct(t, args.write[idx], nullptr, 0, err); } change_notify_deserved = true; d_new["args"] = args; @@ -3751,7 +3751,8 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b } for (int i = 0; i < leftover_path.size() - 1; i++) { - property_info_base = property_info_base.get_named(leftover_path[i]); + bool valid; + property_info_base = property_info_base.get_named(leftover_path[i], valid); } List<PropertyInfo> pinfo; @@ -4586,7 +4587,8 @@ void AnimationTrackEditor::_add_method_key(const String &p_method) { params.push_back(arg); } else { Callable::CallError ce; - Variant arg = Variant::construct(E->get().arguments[i].type, nullptr, 0, ce); + Variant arg; + Variant::construct(E->get().arguments[i].type, arg, nullptr, 0, ce); params.push_back(arg); } } diff --git a/editor/array_property_edit.cpp b/editor/array_property_edit.cpp index 20f947e707..0b6b1ef6a7 100644 --- a/editor/array_property_edit.cpp +++ b/editor/array_property_edit.cpp @@ -43,7 +43,7 @@ Variant ArrayPropertyEdit::get_array() const { Variant arr = o->get(property); if (!arr.is_array()) { Callable::CallError ce; - arr = Variant::construct(default_type, nullptr, 0, ce); + Variant::construct(default_type, arr, nullptr, 0, ce); } return arr; } @@ -107,7 +107,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { new_type = arr.get(size - 1).get_type(); } if (new_type != Variant::NIL) { - init = Variant::construct(new_type, nullptr, 0, ce); + Variant::construct(new_type, init, nullptr, 0, ce); for (int i = size; i < newsize; i++) { ur->add_do_method(this, "_set_value", i, init); } @@ -136,7 +136,8 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { Variant value = arr.get(idx); if (value.get_type() != type && type >= 0 && type < Variant::VARIANT_MAX) { Callable::CallError ce; - Variant new_value = Variant::construct(Variant::Type(type), nullptr, 0, ce); + Variant new_value; + Variant::construct(Variant::Type(type), new_value, nullptr, 0, ce); UndoRedo *ur = EditorNode::get_undo_redo(); ur->create_action(TTR("Change Array Value Type")); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index ede6dde239..3182bca0eb 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -32,7 +32,7 @@ #include "core/input/input.h" #include "core/os/keyboard.h" -#include "core/string_builder.h" +#include "core/string/string_builder.h" #include "editor/editor_scale.h" #include "editor_node.h" #include "editor_settings.h" @@ -1138,6 +1138,7 @@ void CodeTextEditor::move_lines_up() { int from_col = text_editor->get_selection_from_column(); int to_line = text_editor->get_selection_to_line(); int to_column = text_editor->get_selection_to_column(); + int cursor_line = text_editor->cursor_get_line(); for (int i = from_line; i <= to_line; i++) { int line_id = i; @@ -1155,7 +1156,9 @@ void CodeTextEditor::move_lines_up() { } int from_line_up = from_line > 0 ? from_line - 1 : from_line; int to_line_up = to_line > 0 ? to_line - 1 : to_line; + int cursor_line_up = cursor_line > 0 ? cursor_line - 1 : cursor_line; text_editor->select(from_line_up, from_col, to_line_up, to_column); + text_editor->cursor_set_line(cursor_line_up); } else { int line_id = text_editor->cursor_get_line(); int next_id = line_id - 1; @@ -1181,6 +1184,7 @@ void CodeTextEditor::move_lines_down() { int from_col = text_editor->get_selection_from_column(); int to_line = text_editor->get_selection_to_line(); int to_column = text_editor->get_selection_to_column(); + int cursor_line = text_editor->cursor_get_line(); for (int i = to_line; i >= from_line; i--) { int line_id = i; @@ -1198,7 +1202,9 @@ void CodeTextEditor::move_lines_down() { } int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line; int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line; + int cursor_line_down = cursor_line < text_editor->get_line_count() ? cursor_line + 1 : cursor_line; text_editor->select(from_line_down, from_col, to_line_down, to_column); + text_editor->cursor_set_line(cursor_line_down); } else { int line_id = text_editor->cursor_get_line(); int next_id = line_id + 1; diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index d1661fd7b3..320e5d8510 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -30,7 +30,7 @@ #include "connections_dialog.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index 48fdb91f5a..826c25895c 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -35,7 +35,7 @@ #ifndef CONNECTIONS_DIALOG_H #define CONNECTIONS_DIALOG_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/editor_inspector.h" #include "editor/scene_tree_editor.h" #include "scene/gui/button.h" diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 1e3dc01112..0f9c9bde7b 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -30,7 +30,7 @@ #include "create_dialog.h" -#include "core/class_db.h" +#include "core/object/class_db.h" #include "core/os/keyboard.h" #include "editor_feature_profile.h" #include "editor_node.h" diff --git a/editor/debugger/editor_debugger_server.h b/editor/debugger/editor_debugger_server.h index 10a9a232ab..3ad9d3a9a9 100644 --- a/editor/debugger/editor_debugger_server.h +++ b/editor/debugger/editor_debugger_server.h @@ -32,7 +32,7 @@ #define EDITOR_DEBUGGER_CONNECTION_H #include "core/debugger/remote_debugger_peer.h" -#include "core/reference.h" +#include "core/object/reference.h" class EditorDebuggerServer : public Reference { public: diff --git a/editor/debugger/editor_performance_profiler.h b/editor/debugger/editor_performance_profiler.h index 144dd34103..554a0650b8 100644 --- a/editor/debugger/editor_performance_profiler.h +++ b/editor/debugger/editor_performance_profiler.h @@ -31,8 +31,8 @@ #ifndef EDITOR_PERFORMANCE_PROFILER_H #define EDITOR_PERFORMANCE_PROFILER_H -#include "core/map.h" -#include "core/ordered_hash_map.h" +#include "core/templates/map.h" +#include "core/templates/ordered_hash_map.h" #include "main/performance.h" #include "scene/gui/control.h" #include "scene/gui/label.h" diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 1fca95b6da..248073c5a2 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -30,11 +30,11 @@ #include "script_editor_debugger.h" +#include "core/config/project_settings.h" #include "core/debugger/debugger_marshalls.h" #include "core/debugger/remote_debugger.h" #include "core/io/marshalls.h" -#include "core/project_settings.h" -#include "core/ustring.h" +#include "core/string/ustring.h" #include "editor/debugger/editor_network_profiler.h" #include "editor/debugger/editor_performance_profiler.h" #include "editor/debugger/editor_profiler.h" @@ -1023,7 +1023,7 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n for (int i = 0; i < VARIANT_ARG_MAX; i++) { //no pointers, sorry - if (argptr[i] && (argptr[i]->get_type() == Variant::OBJECT || argptr[i]->get_type() == Variant::_RID)) { + if (argptr[i] && (argptr[i]->get_type() == Variant::OBJECT || argptr[i]->get_type() == Variant::RID)) { return; } } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index cbf39c209a..5e87f866d8 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -471,28 +471,28 @@ void DependencyRemoveDialog::ok_pressed() { // If the file we are deleting for e.g. the main scene, default environment, // or audio bus layout, we must clear its definition in Project Settings. - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("application/config/icon")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/config/icon"))) { ProjectSettings::get_singleton()->set("application/config/icon", ""); } - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("application/run/main_scene")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/run/main_scene"))) { ProjectSettings::get_singleton()->set("application/run/main_scene", ""); } - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("application/boot_splash/image")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/boot_splash/image"))) { ProjectSettings::get_singleton()->set("application/boot_splash/image", ""); } - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("rendering/environment/default_environment")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("rendering/environment/default_environment"))) { ProjectSettings::get_singleton()->set("rendering/environment/default_environment", ""); } - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"))) { ProjectSettings::get_singleton()->set("display/mouse_cursor/custom_image", ""); } - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("gui/theme/custom")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("gui/theme/custom"))) { ProjectSettings::get_singleton()->set("gui/theme/custom", ""); } - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("gui/theme/custom_font")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("gui/theme/custom_font"))) { ProjectSettings::get_singleton()->set("gui/theme/custom_font", ""); } - if (files_to_delete[i] == ProjectSettings::get_singleton()->get("audio/default_bus_layout")) { + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("audio/default_bus_layout"))) { ProjectSettings::get_singleton()->set("audio/default_bus_layout", ""); } diff --git a/editor/doc_data.cpp b/editor/doc_data.cpp index 791b49319a..8504d61d2f 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_data.cpp @@ -30,13 +30,13 @@ #include "doc_data.h" -#include "core/engine.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "core/io/compression.h" #include "core/io/marshalls.h" +#include "core/object/script_language.h" #include "core/os/dir_access.h" -#include "core/project_settings.h" -#include "core/script_language.h" #include "core/version.h" #include "scene/resources/theme.h" @@ -561,18 +561,87 @@ void DocData::generate(bool p_basic_types) { c.name = cname; Callable::CallError cerror; - Variant v = Variant::construct(Variant::Type(i), nullptr, 0, cerror); + Variant v; + Variant::construct(Variant::Type(i), v, nullptr, 0, cerror); List<MethodInfo> method_list; v.get_method_list(&method_list); method_list.sort(); Variant::get_constructor_list(Variant::Type(i), &method_list); + for (int j = 0; j < Variant::OP_AND; j++) { // Showing above 'and' is pretty confusing and there are a lot of variations. + for (int k = 0; k < Variant::VARIANT_MAX; k++) { + Variant::Type rt = Variant::get_operator_return_type(Variant::Operator(j), Variant::Type(i), Variant::Type(k)); + if (rt != Variant::NIL) { // Has operator. + // Skip String % operator as it's registered separately for each Variant arg type, + // we'll add it manually below. + if (i == Variant::STRING && Variant::Operator(j) == Variant::OP_MODULE) { + continue; + } + MethodInfo mi; + mi.name = "operator " + Variant::get_operator_name(Variant::Operator(j)); + mi.return_val.type = rt; + if (k != Variant::NIL) { + PropertyInfo arg; + arg.name = "right"; + arg.type = Variant::Type(k); + mi.arguments.push_back(arg); + } + method_list.push_back(mi); + } + } + } + + if (i == Variant::STRING) { + // We skipped % operator above, and we register it manually once for Variant arg type here. + MethodInfo mi; + mi.name = "operator %"; + mi.return_val.type = Variant::STRING; + + PropertyInfo arg; + arg.name = "right"; + arg.type = Variant::NIL; + arg.usage = PROPERTY_USAGE_NIL_IS_VARIANT; + mi.arguments.push_back(arg); + + method_list.push_back(mi); + } + + if (Variant::is_keyed(Variant::Type(i))) { + MethodInfo mi; + mi.name = "operator []"; + mi.return_val.type = Variant::NIL; + mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT; + + PropertyInfo arg; + arg.name = "key"; + arg.type = Variant::NIL; + arg.usage = PROPERTY_USAGE_NIL_IS_VARIANT; + mi.arguments.push_back(arg); + + method_list.push_back(mi); + } else if (Variant::has_indexing(Variant::Type(i))) { + MethodInfo mi; + mi.name = "operator []"; + mi.return_val.type = Variant::get_indexed_element_type(Variant::Type(i)); + PropertyInfo arg; + arg.name = "index"; + arg.type = Variant::INT; + mi.arguments.push_back(arg); + + method_list.push_back(mi); + } + for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { MethodInfo &mi = E->get(); MethodDoc method; method.name = mi.name; + if (method.name == cname) { + method.qualifiers = "constructor"; + } else if (method.name.begins_with("operator")) { + method.qualifiers = "operator"; + } for (int j = 0; j < mi.arguments.size(); j++) { PropertyInfo arginfo = mi.arguments[j]; @@ -634,16 +703,16 @@ void DocData::generate(bool p_basic_types) { ClassDoc &c = class_list[cname]; c.name = cname; - for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { + for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { ConstantDoc cd; - cd.name = GlobalConstants::get_global_constant_name(i); - if (!GlobalConstants::get_ignore_value_in_docs(i)) { - cd.value = itos(GlobalConstants::get_global_constant_value(i)); + cd.name = CoreConstants::get_global_constant_name(i); + if (!CoreConstants::get_ignore_value_in_docs(i)) { + cd.value = itos(CoreConstants::get_global_constant_value(i)); cd.is_value_valid = true; } else { cd.is_value_valid = false; } - cd.enumeration = GlobalConstants::get_global_constant_enum(i); + cd.enumeration = CoreConstants::get_global_constant_enum(i); c.constants.push_back(cd); } @@ -667,6 +736,43 @@ void DocData::generate(bool p_basic_types) { } c.properties.push_back(pd); } + + List<StringName> utility_functions; + Variant::get_utility_function_list(&utility_functions); + utility_functions.sort_custom<StringName::AlphCompare>(); + for (List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { + MethodDoc md; + md.name = E->get(); + //return + if (Variant::has_utility_function_return_value(E->get())) { + PropertyInfo pi; + pi.type = Variant::get_utility_function_return_type(E->get()); + if (pi.type == Variant::NIL) { + pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; + } + DocData::ArgumentDoc ad; + argument_doc_from_arginfo(ad, pi); + md.return_type = ad.type; + } + + if (Variant::is_utility_function_vararg(E->get())) { + md.qualifiers = "vararg"; + } else { + for (int i = 0; i < Variant::get_utility_function_argument_count(E->get()); i++) { + PropertyInfo pi; + pi.type = Variant::get_utility_function_argument_type(E->get(), i); + pi.name = Variant::get_utility_function_argument_name(E->get(), i); + if (pi.type == Variant::NIL) { + pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; + } + DocData::ArgumentDoc ad; + argument_doc_from_arginfo(ad, pi); + md.arguments.push_back(ad); + } + } + + c.methods.push_back(md); + } } // Built-in script reference. @@ -1096,7 +1202,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri qualifiers += " qualifiers=\"" + m.qualifiers.xml_escape() + "\""; } - _write_string(f, 2, "<method name=\"" + m.name + "\"" + qualifiers + ">"); + _write_string(f, 2, "<method name=\"" + m.name.xml_escape() + "\"" + qualifiers + ">"); if (m.return_type != "") { String enum_text; diff --git a/editor/doc_data.h b/editor/doc_data.h index a35cfb59c7..2cb475d137 100644 --- a/editor/doc_data.h +++ b/editor/doc_data.h @@ -32,8 +32,8 @@ #define DOC_DATA_H #include "core/io/xml_parser.h" -#include "core/map.h" -#include "core/variant.h" +#include "core/templates/map.h" +#include "core/variant/variant.h" class DocData { public: @@ -43,6 +43,9 @@ public: String enumeration; String default_value; bool operator<(const ArgumentDoc &p_arg) const { + if (name == p_arg.name) { + return type < p_arg.type; + } return name < p_arg.name; } }; @@ -55,6 +58,20 @@ public: String description; Vector<ArgumentDoc> arguments; bool operator<(const MethodDoc &p_method) const { + if (name == p_method.name) { + // Must be a constructor since there is no overloading. + // We want this arbitrary order for a class "Foo": + // - 1. Default constructor: Foo() + // - 2. Copy constructor: Foo(Foo) + // - 3+. Other constructors Foo(Bar, ...) based on first argument's name + if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1. + return arguments.size() < p_method.arguments.size(); + } + if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2. + return (arguments[0].type == return_type) || (p_method.arguments[0].type != p_method.return_type); + } + return arguments[0] < p_method.arguments[0]; + } return name < p_method.name; } }; diff --git a/editor/editor_atlas_packer.h b/editor/editor_atlas_packer.h index 33dbe47efb..52ac9524ae 100644 --- a/editor/editor_atlas_packer.h +++ b/editor/editor_atlas_packer.h @@ -33,7 +33,7 @@ #include "core/math/vector2.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include "scene/resources/bit_map.h" class EditorAtlasPacker { diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 5d101ff2c2..2251440544 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -30,8 +30,8 @@ #include "editor_autoload_settings.h" -#include "core/global_constants.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "editor_node.h" #include "editor_scale.h" #include "project_settings_editor.h" @@ -89,8 +89,8 @@ bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, Strin } } - for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { - if (GlobalConstants::get_global_constant_name(i) == p_name) { + for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { + if (CoreConstants::get_global_constant_name(i) == p_name) { if (r_error) { *r_error = TTR("Invalid name.") + "\n" + TTR("Must not collide with an existing global constant name."); } diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 1002c4917b..975405aec4 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -30,10 +30,10 @@ #include "editor_data.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "editor_node.h" #include "editor_settings.h" #include "scene/resources/packed_scene.h" diff --git a/editor/editor_data.h b/editor/editor_data.h index 8083dde09c..5037a6acb4 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -31,9 +31,9 @@ #ifndef EDITOR_DATA_H #define EDITOR_DATA_H -#include "core/list.h" -#include "core/pair.h" -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" +#include "core/templates/list.h" +#include "core/templates/pair.h" #include "editor/editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "scene/resources/texture.h" diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 0f86385031..97800fe961 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -30,6 +30,7 @@ #include "editor_export.h" +#include "core/config/project_settings.h" #include "core/crypto/crypto_core.h" #include "core/io/config_file.h" #include "core/io/file_access_encrypted.h" @@ -37,10 +38,9 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/io/zip_io.h" +#include "core/object/script_language.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" -#include "core/project_settings.h" -#include "core/script_language.h" #include "core/version.h" #include "editor/editor_file_system.h" #include "editor/plugins/script_editor_plugin.h" diff --git a/editor/editor_export.h b/editor/editor_export.h index 55728f0c94..09feaad255 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -31,8 +31,8 @@ #ifndef EDITOR_EXPORT_H #define EDITOR_EXPORT_H +#include "core/io/resource.h" #include "core/os/dir_access.h" -#include "core/resource.h" #include "scene/main/node.h" #include "scene/main/timer.h" #include "scene/resources/texture.h" diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h index d0d08c61f4..0f066b8f4a 100644 --- a/editor/editor_feature_profile.h +++ b/editor/editor_feature_profile.h @@ -31,8 +31,8 @@ #ifndef EDITOR_FEATURE_PROFILE_H #define EDITOR_FEATURE_PROFILE_H +#include "core/object/reference.h" #include "core/os/file_access.h" -#include "core/reference.h" #include "editor/editor_file_dialog.h" #include "scene/gui/dialogs.h" #include "scene/gui/option_button.h" diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 2140b6bd13..e3923a48c5 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -33,7 +33,7 @@ #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "dependency_editor.h" #include "editor_file_system.h" #include "editor_resource_preview.h" diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 3fcc06526b..c66bc9b3fa 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -30,13 +30,13 @@ #include "editor_file_system.h" +#include "core/config/project_settings.h" #include "core/io/resource_importer.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" #include "editor_node.h" #include "editor_resource_preview.h" #include "editor_settings.h" diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 02315d76f3..d5ae046c36 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -34,7 +34,7 @@ #include "core/os/dir_access.h" #include "core/os/thread.h" #include "core/os/thread_safe.h" -#include "core/set.h" +#include "core/templates/set.h" #include "scene/main/node.h" class FileAccess; diff --git a/editor/editor_help_search.h b/editor/editor_help_search.h index b37f74fd7e..f1aab6cc81 100644 --- a/editor/editor_help_search.h +++ b/editor/editor_help_search.h @@ -31,7 +31,7 @@ #ifndef EDITOR_HELP_SEARCH_H #define EDITOR_HELP_SEARCH_H -#include "core/ordered_hash_map.h" +#include "core/templates/ordered_hash_map.h" #include "editor/code_editor.h" #include "editor/editor_help.h" #include "editor/editor_plugin.h" diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 1837b23a0b..371100652f 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2278,7 +2278,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { if (E->get().name == p_path) { Callable::CallError ce; - to_create = Variant::construct(E->get().type, nullptr, 0, ce); + Variant::construct(E->get().type, to_create, nullptr, 0, ce); break; } } diff --git a/editor/editor_layouts_dialog.cpp b/editor/editor_layouts_dialog.cpp index 14478b1386..c50fe81217 100644 --- a/editor/editor_layouts_dialog.cpp +++ b/editor/editor_layouts_dialog.cpp @@ -30,8 +30,8 @@ #include "editor_layouts_dialog.h" -#include "core/class_db.h" #include "core/io/config_file.h" +#include "core/object/class_db.h" #include "core/os/keyboard.h" #include "editor/editor_settings.h" #include "scene/gui/item_list.h" diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3a9715d1ab..c6613cdf63 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -30,21 +30,21 @@ #include "editor_node.h" -#include "core/bind/core_bind.h" -#include "core/class_db.h" +#include "core/config/project_settings.h" +#include "core/core_bind.h" #include "core/input/input.h" #include "core/io/config_file.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/io/stream_peer_ssl.h" -#include "core/message_queue.h" +#include "core/object/class_db.h" +#include "core/object/message_queue.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/project_settings.h" -#include "core/translation.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" #include "core/version.h" #include "main/main.h" #include "scene/gui/center_container.h" @@ -2705,10 +2705,14 @@ void EditorNode::_screenshot(bool p_use_utc) { } void EditorNode::_save_screenshot(NodePath p_path) { - SubViewport *viewport = Object::cast_to<SubViewport>(EditorInterface::get_singleton()->get_editor_viewport()->get_viewport()); - viewport->set_clear_mode(SubViewport::CLEAR_MODE_ONLY_NEXT_FRAME); - Ref<Image> img = viewport->get_texture()->get_data(); - viewport->set_clear_mode(SubViewport::CLEAR_MODE_ALWAYS); + Control *editor_viewport = EditorInterface::get_singleton()->get_editor_viewport(); + ERR_FAIL_COND_MSG(!editor_viewport, "Cannot get editor viewport."); + Viewport *viewport = editor_viewport->get_viewport(); + ERR_FAIL_COND_MSG(!viewport, "Cannot get editor viewport."); + Ref<ViewportTexture> texture = viewport->get_texture(); + ERR_FAIL_COND_MSG(texture.is_null(), "Cannot get editor viewport texture."); + Ref<Image> img = texture->get_data(); + ERR_FAIL_COND_MSG(img.is_null(), "Cannot get editor viewport texture image."); Error error = img->save_png(p_path); ERR_FAIL_COND_MSG(error != OK, "Cannot save screenshot to file '" + p_path + "'."); } diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index e330713cfb..49d8e58955 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -866,6 +866,8 @@ void EditorPlugin::_bind_methods() { ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_canvas_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_canvas_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_spatial_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_spatial_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_plugin_name")); ClassDB::add_virtual_method(get_class_static(), MethodInfo(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "get_plugin_icon")); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "has_main_screen")); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index dd3bf08678..11063066d6 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -32,7 +32,7 @@ #define EDITOR_PLUGIN_H #include "core/io/config_file.h" -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_inspector.h" #include "editor/editor_translation_parser.h" diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index fe49198e8f..f984f48c1c 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -30,10 +30,10 @@ #include "editor_plugin_settings.h" +#include "core/config/project_settings.h" #include "core/io/config_file.h" #include "core/os/file_access.h" #include "core/os/main_loop.h" -#include "core/project_settings.h" #include "editor_node.h" #include "editor_scale.h" #include "scene/gui/margin_container.h" diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h index ceb00eb12f..0b61e28449 100644 --- a/editor/editor_plugin_settings.h +++ b/editor/editor_plugin_settings.h @@ -31,7 +31,7 @@ #ifndef EDITORPLUGINSETTINGS_H #define EDITORPLUGINSETTINGS_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/plugin_config_dialog.h" #include "editor_data.h" #include "property_editor.h" diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 9e7ddd9fac..1443302f3f 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -3645,7 +3645,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ add_property_editor(p_path, editor); } break; - case Variant::_RID: { + case Variant::RID: { EditorPropertyRID *editor = memnew(EditorPropertyRID); add_property_editor(p_path, editor); } break; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 51fac6acec..56fbfbd0c2 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -186,7 +186,7 @@ void EditorPropertyArray::_change_type_menu(int p_index) { Variant value; Callable::CallError ce; - value = Variant::construct(Variant::Type(p_index), nullptr, 0, ce); + Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce); Variant array = object->get_array(); array.set(changing_type_idx, value); @@ -445,7 +445,7 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d // Handle the case where array is not initialised yet if (!array.is_array()) { Callable::CallError ce; - array = Variant::construct(array_type, nullptr, 0, ce); + Variant::construct(array_type, array, nullptr, 0, ce); } // Loop the file array and add to existing array @@ -491,7 +491,7 @@ void EditorPropertyArray::_edit_pressed() { Variant array = get_edited_object()->get(get_edited_property()); if (!array.is_array()) { Callable::CallError ce; - array = Variant::construct(array_type, nullptr, 0, ce); + Variant::construct(array_type, array, nullptr, 0, ce); get_edited_object()->set(get_edited_property(), array); } @@ -524,7 +524,9 @@ void EditorPropertyArray::_length_changed(double p_page) { for (int i = previous_size; i < size; i++) { if (array.get(i).get_type() == Variant::NIL) { Callable::CallError ce; - array.set(i, Variant::construct(subtype, nullptr, 0, ce)); + Variant r; + Variant::construct(subtype, r, nullptr, 0, ce); + array.set(i, r); } } } @@ -534,7 +536,9 @@ void EditorPropertyArray::_length_changed(double p_page) { // Pool*Array don't initialize their elements, have to do it manually for (int i = previous_size; i < size; i++) { Callable::CallError ce; - array.set(i, Variant::construct(array.get(i).get_type(), nullptr, 0, ce)); + Variant r; + Variant::construct(array.get(i).get_type(), r, nullptr, 0, ce); + array.set(i, r); } } @@ -657,7 +661,7 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) { if (changing_type_idx < 0) { Variant value; Callable::CallError ce; - value = Variant::construct(Variant::Type(p_index), nullptr, 0, ce); + Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce); if (changing_type_idx == -1) { object->set_new_item_key(value); } else { @@ -672,7 +676,7 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) { if (p_index < Variant::VARIANT_MAX) { Variant value; Callable::CallError ce; - value = Variant::construct(Variant::Type(p_index), nullptr, 0, ce); + Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce); Variant key = dict.get_key_at_index(changing_type_idx); dict[key] = value; } else { @@ -888,7 +892,7 @@ void EditorPropertyDictionary::update_property() { prop = memnew(EditorPropertyNodePath); } break; - case Variant::_RID: { + case Variant::RID: { prop = memnew(EditorPropertyRID); } break; @@ -1044,7 +1048,7 @@ void EditorPropertyDictionary::_edit_pressed() { Variant prop_val = get_edited_object()->get(get_edited_property()); if (prop_val.get_type() == Variant::NIL) { Callable::CallError ce; - prop_val = Variant::construct(Variant::DICTIONARY, nullptr, 0, ce); + Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce); get_edited_object()->set(get_edited_property(), prop_val); } diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 9723ae188b..d1ec50d786 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -30,11 +30,11 @@ #include "editor_resource_preview.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 7fada633c9..2bba15c017 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -30,7 +30,7 @@ #include "editor_run.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "editor_settings.h" #include "servers/display_server.h" diff --git a/editor/editor_run_script.h b/editor/editor_run_script.h index 261e2a7e41..3cb751ecc8 100644 --- a/editor/editor_run_script.h +++ b/editor/editor_run_script.h @@ -31,7 +31,7 @@ #ifndef EDITOR_RUN_SCRIPT_H #define EDITOR_RUN_SCRIPT_H -#include "core/reference.h" +#include "core/object/reference.h" #include "editor_plugin.h" class EditorNode; class EditorScript : public Reference { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index ac27c4a837..f5c1de9def 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -30,6 +30,7 @@ #include "editor_settings.h" +#include "core/config/project_settings.h" #include "core/io/certs_compressed.gen.h" #include "core/io/compression.h" #include "core/io/config_file.h" @@ -42,7 +43,6 @@ #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "core/version.h" #include "editor/doc_translations.gen.h" #include "editor/editor_node.h" diff --git a/editor/editor_settings.h b/editor/editor_settings.h index c1bb7951fa..41e6bab4ba 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -31,11 +31,11 @@ #ifndef EDITOR_SETTINGS_H #define EDITOR_SETTINGS_H -#include "core/class_db.h" #include "core/io/config_file.h" +#include "core/io/resource.h" +#include "core/object/class_db.h" #include "core/os/thread_safe.h" -#include "core/resource.h" -#include "core/translation.h" +#include "core/string/translation.h" #include "scene/gui/shortcut.h" class EditorPlugin; diff --git a/editor/editor_translation_parser.cpp b/editor/editor_translation_parser.cpp index 7a90d20000..4e6a397840 100644 --- a/editor/editor_translation_parser.cpp +++ b/editor/editor_translation_parser.cpp @@ -30,10 +30,10 @@ #include "editor_translation_parser.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" +#include "core/object/script_language.h" #include "core/os/file_access.h" -#include "core/script_language.h" -#include "core/set.h" +#include "core/templates/set.h" EditorTranslationParser *EditorTranslationParser::singleton = nullptr; diff --git a/editor/editor_translation_parser.h b/editor/editor_translation_parser.h index 18f49b3803..bdebdd10a1 100644 --- a/editor/editor_translation_parser.h +++ b/editor/editor_translation_parser.h @@ -31,8 +31,8 @@ #ifndef EDITOR_TRANSLATION_PARSER_H #define EDITOR_TRANSLATION_PARSER_H -#include "core/error_list.h" -#include "core/reference.h" +#include "core/error/error_list.h" +#include "core/object/reference.h" class EditorTranslationParserPlugin : public Reference { GDCLASS(EditorTranslationParserPlugin, Reference); diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index 6ef55f0a46..7de1883fd7 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -31,8 +31,8 @@ #ifndef EDITOR_VCS_INTERFACE_H #define EDITOR_VCS_INTERFACE_H -#include "core/class_db.h" -#include "core/ustring.h" +#include "core/object/class_db.h" +#include "core/string/ustring.h" #include "scene/gui/panel_container.h" class EditorVCSInterface : public Object { diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index eefaa503c1..ca5a891856 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h @@ -31,10 +31,10 @@ #ifndef EDITOR_FILE_SERVER_H #define EDITOR_FILE_SERVER_H -#include "core/class_db.h" #include "core/io/file_access_network.h" #include "core/io/packet_peer.h" #include "core/io/tcp_server.h" +#include "core/object/class_db.h" #include "core/os/thread.h" class EditorFileServer : public Object { diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 14a46d77a2..ee0ee91893 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -30,13 +30,13 @@ #include "filesystem_dock.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/list.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/project_settings.h" +#include "core/templates/list.h" #include "editor_feature_profile.h" #include "editor_node.h" #include "editor_resource_preview.h" @@ -2665,7 +2665,8 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { editor = p_editor; path = "res://"; - ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KEY_MASK_CMD | KEY_C); + // `KEY_MASK_CMD | KEY_C` conflicts with other editor shortcuts. + ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_C); ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KEY_MASK_CMD | KEY_D); ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), KEY_DELETE); ED_SHORTCUT("filesystem_dock/rename", TTR("Rename")); diff --git a/editor/find_in_files.h b/editor/find_in_files.h index 5f2c6ee174..3b949a35b4 100644 --- a/editor/find_in_files.h +++ b/editor/find_in_files.h @@ -31,7 +31,7 @@ #ifndef FIND_IN_FILES_H #define FIND_IN_FILES_H -#include "core/hash_map.h" +#include "core/templates/hash_map.h" #include "scene/gui/dialogs.h" // Performs the actual search diff --git a/editor/groups_editor.h b/editor/groups_editor.h index d5daaa19eb..6c3489fffb 100644 --- a/editor/groups_editor.h +++ b/editor/groups_editor.h @@ -31,7 +31,7 @@ #ifndef GROUPS_EDITOR_H #define GROUPS_EDITOR_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/scene_tree_editor.h" #include "scene/gui/button.h" #include "scene/gui/dialogs.h" diff --git a/editor/icons/DirectionalLight2D.svg b/editor/icons/DirectionalLight2D.svg new file mode 100644 index 0000000000..f30702b502 --- /dev/null +++ b/editor/icons/DirectionalLight2D.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-2.5352 2.0508-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2zm11 0v2h3v-2zm-7.5352 3.1211-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.5352 1.8789v3h2v-3z" fill="#a5b7f4"/></svg> diff --git a/editor/icons/Light2D.svg b/editor/icons/PointLight2D.svg index d660b82c34..d660b82c34 100644 --- a/editor/icons/Light2D.svg +++ b/editor/icons/PointLight2D.svg diff --git a/editor/import/collada.h b/editor/import/collada.h index 90c6c47e0b..aa0d42035f 100644 --- a/editor/import/collada.h +++ b/editor/import/collada.h @@ -31,9 +31,9 @@ #ifndef COLLADA_H #define COLLADA_H +#include "core/config/project_settings.h" #include "core/io/xml_parser.h" -#include "core/map.h" -#include "core/project_settings.h" +#include "core/templates/map.h" #include "scene/resources/material.h" class Collada { diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index 6d46d4d2e9..2658031bd9 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "editor_import_plugin.h" -#include "core/script_language.h" +#include "core/object/script_language.h" EditorImportPlugin::EditorImportPlugin() { } diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp index da2d1c9bdf..06b56fd73f 100644 --- a/editor/import/resource_importer_bitmask.cpp +++ b/editor/import/resource_importer_bitmask.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "resource_importer_bitmask.h" -#include "core/image.h" #include "core/io/config_file.h" +#include "core/io/image.h" #include "core/io/image_loader.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index 0d3cb23697..83959f87cd 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -31,7 +31,7 @@ #ifndef RESOURCE_IMPORTER_BITMASK_H #define RESOURCE_IMPORTER_BITMASK_H -#include "core/image.h" +#include "core/io/image.h" #include "core/io/resource_importer.h" class StreamBitMap; diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index 04e20dee86..4c6200e033 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -30,10 +30,10 @@ #include "resource_importer_csv_translation.h" -#include "core/compressed_translation.h" #include "core/io/resource_saver.h" #include "core/os/file_access.h" -#include "core/translation.h" +#include "core/string/compressed_translation.h" +#include "core/string/translation.h" String ResourceImporterCSVTranslation::get_importer_name() const { return "csv_translation"; diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h index dc9c2c3014..703b36b091 100644 --- a/editor/import/resource_importer_image.h +++ b/editor/import/resource_importer_image.h @@ -31,7 +31,7 @@ #ifndef RESOURCE_IMPORTER_IMAGE_H #define RESOURCE_IMPORTER_IMAGE_H -#include "core/image.h" +#include "core/io/image.h" #include "core/io/resource_importer.h" class ResourceImporterImage : public ResourceImporter { diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index b54923be00..7ac3d55dec 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -61,7 +61,7 @@ #ifndef RESOURCE_IMPORTER_LAYERED_TEXTURE_H #define RESOURCE_IMPORTER_LAYERED_TEXTURE_H -#include "core/image.h" +#include "core/io/image.h" #include "core/io/resource_importer.h" class StreamTexture2D; diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index bc41aacae5..97c4622731 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -31,7 +31,7 @@ #ifndef RESOURCEIMPORTTEXTURE_H #define RESOURCEIMPORTTEXTURE_H -#include "core/image.h" +#include "core/io/image.h" #include "core/io/resource_importer.h" #include "core/os/file_access.h" #include "scene/resources/texture.h" diff --git a/editor/import/resource_importer_texture_atlas.h b/editor/import/resource_importer_texture_atlas.h index 25a662a333..9d973c3d8d 100644 --- a/editor/import/resource_importer_texture_atlas.h +++ b/editor/import/resource_importer_texture_atlas.h @@ -31,7 +31,7 @@ #ifndef RESOURCE_IMPORTER_TEXTURE_ATLAS_H #define RESOURCE_IMPORTER_TEXTURE_ATLAS_H -#include "core/image.h" +#include "core/io/image.h" #include "core/io/resource_importer.h" class ResourceImporterTextureAtlas : public ResourceImporter { GDCLASS(ResourceImporterTextureAtlas, ResourceImporter); diff --git a/editor/input_map_editor.h b/editor/input_map_editor.h index 87a25e91b0..b9a3ce19d4 100644 --- a/editor/input_map_editor.h +++ b/editor/input_map_editor.h @@ -31,7 +31,7 @@ #ifndef INPUT_MAP_EDITOR_H #define INPUT_MAP_EDITOR_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/editor_data.h" class InputMapEditor : public Control { diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index e4562c57af..e725ce482d 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -30,7 +30,7 @@ #include "localization_editor.h" -#include "core/translation.h" +#include "core/string/translation.h" #include "editor_node.h" #include "editor_translation_parser.h" #include "pot_generator.h" diff --git a/editor/localization_editor.h b/editor/localization_editor.h index b7253fb31d..3c077d9c77 100644 --- a/editor/localization_editor.h +++ b/editor/localization_editor.h @@ -31,7 +31,7 @@ #ifndef LOCALIZATION_EDITOR_H #define LOCALIZATION_EDITOR_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor_file_dialog.h" #include "scene/gui/tree.h" diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 805df0cbb9..60a5188af7 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -30,11 +30,11 @@ #include "animation_blend_space_2d_editor.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/geometry_2d.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "editor/editor_scale.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 6419f62343..38648b5f0a 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -30,10 +30,10 @@ #include "animation_blend_tree_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "editor/editor_inspector.h" #include "editor/editor_scale.h" #include "scene/animation/animation_player.h" diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 6e4a39d3f0..1e56e3d11f 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -30,11 +30,11 @@ #include "animation_player_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "editor/animation_track_editor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 885ec17cb3..4634d15941 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -30,11 +30,11 @@ #include "animation_state_machine_editor.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/geometry_2d.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "editor/editor_scale.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 269c54ba2b..1bbb68d224 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -34,11 +34,11 @@ #include "animation_blend_space_2d_editor.h" #include "animation_blend_tree_editor_plugin.h" #include "animation_state_machine_editor.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/delaunay_2d.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "editor/editor_scale.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index 231f5588a4..e6f6b6f2e0 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "audio_stream_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "editor/audio_stream_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 1af60b59a2..e1f2d2c045 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -30,11 +30,11 @@ #include "canvas_item_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/math/geometry_2d.h" #include "core/os/keyboard.h" -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/string/print_string.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 5038941784..fdbf3415db 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -30,12 +30,12 @@ #include "node_3d_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/math/camera_matrix.h" #include "core/os/keyboard.h" -#include "core/print_string.h" -#include "core/project_settings.h" -#include "core/sort_array.h" +#include "core/string/print_string.h" +#include "core/templates/sort_array.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" @@ -351,8 +351,8 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) { update_transform_gizmo_view(); rotation_control->update(); + spatial_editor->update_grid(); } - spatial_editor->update_grid(); } Transform Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) const { @@ -2426,6 +2426,7 @@ void Node3DEditorViewport::_notification(int p_what) { t.basis = t.basis * aabb_s; RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance, t); + RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t); } if (changed || (spatial_editor->is_gizmo_visible() && !exist)) { @@ -4417,6 +4418,9 @@ Node3DEditorSelectedItem::~Node3DEditorSelectedItem() { if (sbox_instance.is_valid()) { RenderingServer::get_singleton()->free(sbox_instance); } + if (sbox_instance_xray.is_valid()) { + RenderingServer::get_singleton()->free(sbox_instance_xray); + } } void Node3DEditor::select_gizmo_highlight_axis(int p_axis) { @@ -4500,42 +4504,73 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) { Node3DEditorSelectedItem *si = memnew(Node3DEditorSelectedItem); si->sp = sp; - si->sbox_instance = RenderingServer::get_singleton()->instance_create2(selection_box->get_rid(), sp->get_world_3d()->get_scenario()); - RS::get_singleton()->instance_geometry_set_cast_shadows_setting(si->sbox_instance, RS::SHADOW_CASTING_SETTING_OFF); + si->sbox_instance = RenderingServer::get_singleton()->instance_create2( + selection_box->get_rid(), + sp->get_world_3d()->get_scenario()); + RS::get_singleton()->instance_geometry_set_cast_shadows_setting( + si->sbox_instance, + RS::SHADOW_CASTING_SETTING_OFF); + si->sbox_instance_xray = RenderingServer::get_singleton()->instance_create2( + selection_box_xray->get_rid(), + sp->get_world_3d()->get_scenario()); + RS::get_singleton()->instance_geometry_set_cast_shadows_setting( + si->sbox_instance_xray, + RS::SHADOW_CASTING_SETTING_OFF); return si; } -void Node3DEditor::_generate_selection_box() { +void Node3DEditor::_generate_selection_boxes() { + // Use two AABBs to create the illusion of a slightly thicker line. AABB aabb(Vector3(), Vector3(1, 1, 1)); - aabb.grow_by(aabb.get_longest_axis_size() / 20.0); - + AABB aabb_offset(Vector3(), Vector3(1, 1, 1)); + // Grow the bounding boxes slightly to avoid Z-fighting with the mesh's edges. + aabb.grow_by(0.005); + aabb_offset.grow_by(0.01); + + // Create a x-ray (visible through solid surfaces) and standard version of the selection box. + // Both will be drawn at the same position, but with different opacity. + // This lets the user see where the selection is while still having a sense of depth. Ref<SurfaceTool> st = memnew(SurfaceTool); + Ref<SurfaceTool> st_xray = memnew(SurfaceTool); st->begin(Mesh::PRIMITIVE_LINES); + st_xray->begin(Mesh::PRIMITIVE_LINES); for (int i = 0; i < 12; i++) { Vector3 a, b; aabb.get_edge(i, a, b); - st->add_color(Color(1.0, 1.0, 0.8, 0.8)); st->add_vertex(a); - st->add_color(Color(1.0, 1.0, 0.8, 0.4)); - st->add_vertex(a.lerp(b, 0.2)); + st->add_vertex(b); + st_xray->add_vertex(a); + st_xray->add_vertex(b); + } - st->add_color(Color(1.0, 1.0, 0.8, 0.4)); - st->add_vertex(a.lerp(b, 0.8)); - st->add_color(Color(1.0, 1.0, 0.8, 0.8)); + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb_offset.get_edge(i, a, b); + + st->add_vertex(a); st->add_vertex(b); + st_xray->add_vertex(a); + st_xray->add_vertex(b); } Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - mat->set_albedo(Color(1, 1, 1)); + // Use a similar color to the 2D editor selection. + mat->set_albedo(Color(1, 0.5, 0)); mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); st->set_material(mat); selection_box = st->commit(); + + Ref<StandardMaterial3D> mat_xray = memnew(StandardMaterial3D); + mat_xray->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + mat_xray->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + mat_xray->set_albedo(Color(1, 0.5, 0, 0.15)); + mat_xray->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + st_xray->set_material(mat_xray); + selection_box_xray = st_xray->commit(); } Dictionary Node3DEditor::get_state() const { @@ -4687,7 +4722,7 @@ void Node3DEditor::set_state(const Dictionary &p_state) { } int state = EditorNode3DGizmoPlugin::VISIBLE; for (int i = 0; i < keys.size(); i++) { - if (gizmo_plugins_by_name.write[j]->get_name() == keys[i]) { + if (gizmo_plugins_by_name.write[j]->get_name() == String(keys[i])) { state = gizmos_status[keys[i]]; break; } @@ -5514,7 +5549,7 @@ void Node3DEditor::_init_indicators() { } } - _generate_selection_box(); + _generate_selection_boxes(); } void Node3DEditor::_update_gizmos_menu() { diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index e4a384449b..4c4faef07f 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -498,6 +498,7 @@ public: bool last_xform_dirty; Node3D *sp; RID sbox_instance; + RID sbox_instance_xray; Node3DEditorSelectedItem() { sp = nullptr; @@ -613,6 +614,7 @@ private: float snap_rotate_value; float snap_scale_value; + Ref<ArrayMesh> selection_box_xray; Ref<ArrayMesh> selection_box; RID indicators; RID indicators_instance; @@ -701,7 +703,7 @@ private: HBoxContainer *hbc_menu; - void _generate_selection_box(); + void _generate_selection_boxes(); UndoRedo *undo_redo; int camera_override_viewport_id; diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index 9ab5bfd8a3..f317aebe74 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "resource_preloader_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index be8ddf789b..8dd7d6d6e2 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -30,12 +30,12 @@ #include "script_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" #include "editor/editor_run_script.h" @@ -2397,7 +2397,7 @@ void ScriptEditor::_editor_settings_changed() { if (current_theme == "") { current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); - } else if (current_theme != EditorSettings::get_singleton()->get("text_editor/theme/color_theme")) { + } else if (current_theme != String(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))) { current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); EditorSettings::get_singleton()->load_text_editor_theme(); } diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index c2b0b458eb..32f47239ef 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -31,7 +31,7 @@ #ifndef SCRIPT_EDITOR_PLUGIN_H #define SCRIPT_EDITOR_PLUGIN_H -#include "core/script_language.h" +#include "core/object/script_language.h" #include "editor/code_editor.h" #include "editor/editor_help.h" #include "editor/editor_help_search.h" diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 5007983581..69a8a8d92c 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "sprite_frames_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "scene/3d/sprite_3d.h" diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index ba2eef8484..8447a2346f 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "texture_3d_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "editor/editor_settings.h" void Texture3DEditor::_gui_input(Ref<InputEvent> p_event) { diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index b728a6700c..f8facb0fd5 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "texture_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "editor/editor_settings.h" void TextureEditor::_gui_input(Ref<InputEvent> p_event) { diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index 59e87fb273..eafe4d546b 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "texture_layered_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "editor/editor_settings.h" void TextureLayeredEditor::_gui_input(Ref<InputEvent> p_event) { diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 6e722607f7..f599b94428 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -875,7 +875,8 @@ void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_pro if (!is_visible()) { return; } - if (p_prop == StringName("atlas") || p_prop == StringName("texture") || p_prop == StringName("region")) { + String prop = p_prop; + if (prop == "atlas" || prop == "texture" || prop == "region") { _edit_region(); } } diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index e43b8c4b7f..7b516175b2 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -651,9 +651,15 @@ Vector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase, return Vector<Vector2>(); } + // Check if the tile variation is the same + Vector2 prev_position = node->get_cell_autotile_coord(p_start.x, p_start.y); if (ids.size() == 1 && ids[0] == prev_id) { - // Same ID, nothing to change - return Vector<Vector2>(); + int current = manual_palette->get_current(); + Vector2 position = manual_palette->get_item_metadata(current); + if (prev_position == position) { + // Same ID and variation, nothing to change + return Vector<Vector2>(); + } } Rect2i r = node->get_used_rect(); diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index cfbe54ef61..5e98b2d98b 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "version_control_editor_plugin.h" -#include "core/script_language.h" +#include "core/object/script_language.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index ddcba18a78..f3fc22b313 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -30,11 +30,11 @@ #include "visual_shader_editor_plugin.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "core/version.h" #include "editor/editor_log.h" #include "editor/editor_properties.h" diff --git a/editor/pot_generator.cpp b/editor/pot_generator.cpp index f09750efdc..9b3227ad28 100644 --- a/editor/pot_generator.cpp +++ b/editor/pot_generator.cpp @@ -30,8 +30,8 @@ #include "pot_generator.h" -#include "core/error_macros.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/error/error_macros.h" #include "editor_translation_parser.h" #include "plugins/packed_scene_translation_parser_plugin.h" diff --git a/editor/pot_generator.h b/editor/pot_generator.h index 8853b784ed..1fd2956445 100644 --- a/editor/pot_generator.h +++ b/editor/pot_generator.h @@ -31,9 +31,9 @@ #ifndef POT_GENERATOR_H #define POT_GENERATOR_H -#include "core/ordered_hash_map.h" #include "core/os/file_access.h" -#include "core/set.h" +#include "core/templates/ordered_hash_map.h" +#include "core/templates/set.h" //#define DEBUG_POT diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp index 541cba836b..46a656e0af 100644 --- a/editor/progress_dialog.cpp +++ b/editor/progress_dialog.cpp @@ -30,7 +30,7 @@ #include "progress_dialog.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "core/os/os.h" #include "editor_scale.h" #include "main/main.h" diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 71522bb253..e8c2b1f954 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -30,14 +30,14 @@ #include "project_export.h" -#include "core/compressed_translation.h" +#include "core/config/project_settings.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" +#include "core/string/compressed_translation.h" #include "editor_data.h" #include "editor_node.h" #include "editor_scale.h" diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 6393aa30ed..e3c2ba83f2 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -38,7 +38,7 @@ #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/translation.h" +#include "core/string/translation.h" #include "core/version.h" #include "core/version_hash.gen.h" #include "editor_scale.h" diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index b6621d0d1e..55d80021c8 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -30,7 +30,7 @@ #include "project_settings_editor.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" @@ -98,7 +98,8 @@ void ProjectSettingsEditor::_add_setting() { // Initialize the property with the default value for the given type. // The type list starts at 1 (as we exclude Nil), so add 1 to the selected value. Callable::CallError ce; - const Variant value = Variant::construct(Variant::Type(type->get_selected() + 1), nullptr, 0, ce); + Variant value; + Variant::construct(Variant::Type(type->get_selected() + 1), value, nullptr, 0, ce); undo_redo->create_action(TTR("Add Project Setting")); undo_redo->add_do_property(ps, setting, value); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index 4ecd28e514..73e96d7b03 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -31,7 +31,7 @@ #ifndef PROJECT_SETTINGS_EDITOR_H #define PROJECT_SETTINGS_EDITOR_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/editor_data.h" #include "editor/editor_plugin_settings.h" #include "editor/editor_sectioned_inspector.h" diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 7f1b5347cf..1e4ed0c552 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -30,16 +30,16 @@ #include "property_editor.h" -#include "core/class_db.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" #include "core/math/expression.h" +#include "core/object/class_db.h" #include "core/os/keyboard.h" -#include "core/pair.h" -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/string/print_string.h" +#include "core/templates/pair.h" #include "editor/array_property_edit.h" #include "editor/create_dialog.h" #include "editor/dictionary_property_edit.h" @@ -345,7 +345,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: checks20[i]->hide(); } - type = (p_variant.get_type() != Variant::NIL && p_variant.get_type() != Variant::_RID && p_type != Variant::OBJECT) ? p_variant.get_type() : p_type; + type = (p_variant.get_type() != Variant::NIL && p_variant.get_type() != Variant::RID && p_type != Variant::OBJECT) ? p_variant.get_type() : p_type; switch (type) { case Variant::BOOL: { diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 27b11e4fb5..75420a1ef4 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -95,7 +95,7 @@ void PropertySelector::_update_search() { } else if (type != Variant::NIL) { Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); v.get_property_list(&props); } else { @@ -200,7 +200,7 @@ void PropertySelector::_update_search() { if (type != Variant::NIL) { Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); v.get_method_list(&methods); } else { Object *obj = ObjectDB::get_instance(script); diff --git a/editor/pvrtc_compress.h b/editor/pvrtc_compress.h index 77bc11b224..7b6c17d3c4 100644 --- a/editor/pvrtc_compress.h +++ b/editor/pvrtc_compress.h @@ -31,7 +31,7 @@ #ifndef PVRTC_COMPRESS_H #define PVRTC_COMPRESS_H -#include "core/image.h" +#include "core/io/image.h" void _pvrtc_register_compressors(); diff --git a/editor/quick_open.h b/editor/quick_open.h index 6486ee0221..3b199f9561 100644 --- a/editor/quick_open.h +++ b/editor/quick_open.h @@ -31,7 +31,7 @@ #ifndef EDITOR_QUICK_OPEN_H #define EDITOR_QUICK_OPEN_H -#include "core/oa_hash_map.h" +#include "core/templates/oa_hash_map.h" #include "editor_file_system.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 23990bca07..318324e56d 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -30,7 +30,7 @@ #include "rename_dialog.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index 100426af4f..164d7ab1b0 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -36,7 +36,7 @@ #include "scene/gui/option_button.h" #include "scene/gui/spin_box.h" -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/scene_tree_editor.h" /** diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp index 1615336a4b..0ff27af7c1 100644 --- a/editor/reparent_dialog.cpp +++ b/editor/reparent_dialog.cpp @@ -30,7 +30,7 @@ #include "reparent_dialog.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "scene/gui/box_container.h" #include "scene/gui/label.h" diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 46e9cd4676..add5047c99 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -30,10 +30,10 @@ #include "scene_tree_dock.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_saver.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_feature_profile.h" #include "editor/editor_node.h" diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 3dee4a229f..3ec012ce3c 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -30,8 +30,8 @@ #include "scene_tree_editor.h" -#include "core/message_queue.h" -#include "core/print_string.h" +#include "core/object/message_queue.h" +#include "core/string/print_string.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/node_dock.h" diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 21bb0ec062..9373ef41f9 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -31,7 +31,7 @@ #ifndef SCENE_TREE_EDITOR_H #define SCENE_TREE_EDITOR_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor_data.h" #include "editor_settings.h" #include "scene/gui/button.h" diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 90efb11b7d..b5f11fc6f9 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -30,11 +30,11 @@ #include "script_create_dialog.h" +#include "core/config/project_settings.h" #include "core/io/resource_saver.h" +#include "core/object/script_language.h" #include "core/os/file_access.h" -#include "core/project_settings.h" -#include "core/script_language.h" -#include "core/string_builder.h" +#include "core/string/string_builder.h" #include "editor/create_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 5da682a148..864e5976b2 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -30,8 +30,8 @@ #include "settings_config_dialog.h" +#include "core/config/project_settings.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "editor/debugger/editor_debugger_node.h" #include "editor_file_system.h" #include "editor_log.h" diff --git a/editor/shader_globals_editor.h b/editor/shader_globals_editor.h index 33f527f314..00b6cdef9f 100644 --- a/editor/shader_globals_editor.h +++ b/editor/shader_globals_editor.h @@ -31,7 +31,7 @@ #ifndef SHADER_GLOBALS_EDITOR_H #define SHADER_GLOBALS_EDITOR_H -#include "core/undo_redo.h" +#include "core/object/undo_redo.h" #include "editor/editor_autoload_settings.h" #include "editor/editor_data.h" #include "editor/editor_plugin_settings.h" diff --git a/main/main.cpp b/main/main.cpp index f2d057665a..3905366598 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -30,6 +30,7 @@ #include "main.h" +#include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/crypto/crypto.h" #include "core/debugger/engine_debugger.h" @@ -41,12 +42,11 @@ #include "core/io/image_loader.h" #include "core/io/ip.h" #include "core/io/resource_loader.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "core/os/dir_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "core/register_core_types.h" -#include "core/translation.h" +#include "core/string/translation.h" #include "core/version.h" #include "core/version_hash.gen.h" #include "drivers/register_driver_types.h" @@ -1608,7 +1608,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { GLOBAL_DEF("application/config/icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", - PROPERTY_HINT_FILE, "*.png,*.webp")); + PROPERTY_HINT_FILE, "*.png,*.webp,*.svg,*.svgz")); GLOBAL_DEF("application/config/macos_native_icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/macos_native_icon", @@ -2232,7 +2232,7 @@ bool Main::start() { #ifdef TOOLS_ENABLED if (editor) { - if (game_path != GLOBAL_GET("application/run/main_scene") || !editor_node->has_scenes_in_session()) { + if (game_path != String(GLOBAL_GET("application/run/main_scene")) || !editor_node->has_scenes_in_session()) { Error serr = editor_node->load_scene(local_game_path); if (serr != OK) { ERR_PRINT("Failed to load scene"); diff --git a/main/main.h b/main/main.h index 75a1c0d8cd..168b2e5e86 100644 --- a/main/main.h +++ b/main/main.h @@ -31,7 +31,7 @@ #ifndef MAIN_H #define MAIN_H -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/os/thread.h" #include "core/typedefs.h" diff --git a/main/main_timer_sync.h b/main/main_timer_sync.h index 2126381c7c..f8497140cd 100644 --- a/main/main_timer_sync.h +++ b/main/main_timer_sync.h @@ -31,7 +31,7 @@ #ifndef MAIN_TIMER_SYNC_H #define MAIN_TIMER_SYNC_H -#include "core/engine.h" +#include "core/config/engine.h" struct MainFrameTime { float idle_step; // time to advance idles for (argument to process()) diff --git a/main/performance.cpp b/main/performance.cpp index 7234511aeb..3d7971ced3 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -30,7 +30,7 @@ #include "performance.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "core/os/os.h" #include "scene/main/node.h" #include "scene/main/scene_tree.h" diff --git a/main/performance.h b/main/performance.h index f406433cf2..415b49b58c 100644 --- a/main/performance.h +++ b/main/performance.h @@ -31,8 +31,8 @@ #ifndef PERFORMANCE_H #define PERFORMANCE_H -#include "core/class_db.h" -#include "core/ordered_hash_map.h" +#include "core/object/class_db.h" +#include "core/templates/ordered_hash_map.h" #define PERF_WARN_OFFLINE_FUNCTION #define PERF_WARN_PROCESS_SYNC diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index d8da520ed7..bd21883259 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -153,81 +153,6 @@ DevelopmentTeam = $team_id; ProvisioningStyle = Automatic; SystemCapabilities = { - com.apple.AccessWiFi = { - enabled = $access_wifi; - }; - com.apple.ApplePay = { - enabled = 0; - }; - com.apple.ApplicationGroups.iOS = { - enabled = 0; - }; - com.apple.AutoFillCredentialProvider = { - enabled = 0; - }; - com.apple.BackgroundModes = { - enabled = 0; - }; - com.apple.ClassKit = { - enabled = 0; - }; - com.apple.DataProtection = { - enabled = 0; - }; - com.apple.GameCenter.iOS = { - enabled = $game_center; - }; - com.apple.HealthKit = { - enabled = 0; - }; - com.apple.HomeKit = { - enabled = 0; - }; - com.apple.HotspotConfiguration = { - enabled = 0; - }; - com.apple.InAppPurchase = { - enabled = $in_app_purchases; - }; - com.apple.InterAppAudio = { - enabled = 0; - }; - com.apple.Keychain = { - enabled = 0; - }; - com.apple.Maps.iOS = { - enabled = 0; - }; - com.apple.Multipath = { - enabled = 0; - }; - com.apple.NearFieldCommunicationTagReading = { - enabled = 0; - }; - com.apple.NetworkExtensions.iOS = { - enabled = 0; - }; - com.apple.Push = { - enabled = $push_notifications; - }; - com.apple.SafariKeychain = { - enabled = 0; - }; - com.apple.Siri = { - enabled = 0; - }; - com.apple.VPNLite = { - enabled = 0; - }; - com.apple.WAC = { - enabled = 0; - }; - com.apple.Wallet = { - enabled = 0; - }; - com.apple.iCloud = { - enabled = 0; - }; }; }; }; @@ -393,7 +318,7 @@ ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)", + "$(PROJECT_DIR)/**", ); PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -423,7 +348,7 @@ ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)", + "$(PROJECT_DIR)/**", ); PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/modules/SCsub b/modules/SCsub index edfc4ed9c6..24598f4b28 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -47,7 +47,14 @@ for name, path in env.module_list.items(): # Some modules are not linked automatically but can be enabled optionally # on iOS, so we handle those specially. - if env["platform"] == "iphone" and name in ["arkit", "camera"]: + if env["platform"] == "iphone" and name in [ + "arkit", + "camera", + "camera_iphone", + "gamecenter", + "inappstore", + "icloud", + ]: continue lib = env_modules.add_library("module_%s" % name, env.modules_sources) diff --git a/modules/arkit/arkit.gdip b/modules/arkit/arkit.gdip new file mode 100644 index 0000000000..22c0a07e26 --- /dev/null +++ b/modules/arkit/arkit.gdip @@ -0,0 +1,18 @@ +[config] +name="ARKit" +binary="arkit_lib.a" + +initialization="register_arkit_types" +deinitialization="unregister_arkit_types" + +[dependencies] +linked=[] +embedded=[] +system=["AVFoundation.framework", "ARKit.framework"] + +capabilities=["arkit"] + +files=[] + +[plist] +NSCameraUsageDescription="Device camera is used for some functionality" diff --git a/modules/arkit/register_types.cpp b/modules/arkit/arkit_module.cpp index 91069ab364..87ee3b87a5 100644 --- a/modules/arkit/register_types.cpp +++ b/modules/arkit/arkit_module.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* register_types.cpp */ +/* arkit_module.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "register_types.h" +#include "arkit_module.h" #include "arkit_interface.h" diff --git a/modules/arkit/register_types.h b/modules/arkit/arkit_module.h index f8939a1e3f..8aa8175ed5 100644 --- a/modules/arkit/register_types.h +++ b/modules/arkit/arkit_module.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* register_types.h */ +/* arkit_module.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/assimp/editor_scene_importer_assimp.h b/modules/assimp/editor_scene_importer_assimp.h index 7be80c4ad0..80bba6ad66 100644 --- a/modules/assimp/editor_scene_importer_assimp.h +++ b/modules/assimp/editor_scene_importer_assimp.h @@ -32,9 +32,9 @@ #define EDITOR_SCENE_IMPORTER_ASSIMP_H #ifdef TOOLS_ENABLED -#include "core/bind/core_bind.h" +#include "core/core_bind.h" #include "core/io/resource_importer.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include "editor/import/resource_importer_scene.h" #include "editor/project_settings_editor.h" #include "scene/3d/mesh_instance_3d.h" diff --git a/modules/assimp/import_state.h b/modules/assimp/import_state.h index ee22800ac4..a1cce6968b 100644 --- a/modules/assimp/import_state.h +++ b/modules/assimp/import_state.h @@ -31,9 +31,9 @@ #ifndef EDITOR_SCENE_IMPORT_STATE_H #define EDITOR_SCENE_IMPORT_STATE_H -#include "core/bind/core_bind.h" +#include "core/core_bind.h" #include "core/io/resource_importer.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include "editor/import/resource_importer_scene.h" #include "editor/project_settings_editor.h" #include "scene/3d/mesh_instance_3d.h" diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index 757afeb9e3..b08970d110 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -30,6 +30,8 @@ #include "image_loader_bmp.h" +#include "core/io/file_access_memory.h" + Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const uint8_t *p_color_buffer, @@ -293,9 +295,21 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f, return err; } -void ImageLoaderBMP::get_recognized_extensions( - List<String> *p_extensions) const { +void ImageLoaderBMP::get_recognized_extensions(List<String> *p_extensions) const { p_extensions->push_back("bmp"); } -ImageLoaderBMP::ImageLoaderBMP() {} +static Ref<Image> _bmp_mem_loader_func(const uint8_t *p_bmp, int p_size) { + FileAccessMemory memfile; + Error open_memfile_error = memfile.open_custom(p_bmp, p_size); + ERR_FAIL_COND_V_MSG(open_memfile_error, Ref<Image>(), "Could not create memfile for BMP image buffer."); + Ref<Image> img; + img.instance(); + Error load_error = ImageLoaderBMP().load_image(img, &memfile, false, 1.0f); + ERR_FAIL_COND_V_MSG(load_error, Ref<Image>(), "Failed to load BMP image."); + return img; +} + +ImageLoaderBMP::ImageLoaderBMP() { + Image::_bmp_mem_loader_func = _bmp_mem_loader_func; +} diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index c0bcc858fe..152fd785c0 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -32,7 +32,7 @@ #define AREABULLET_H #include "collision_object_bullet.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include "servers/physics_server_3d.h" #include "space_bullet.h" diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 8f64c11867..f7290666ad 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -32,9 +32,9 @@ #include "bullet_utilities.h" #include "cone_twist_joint_bullet.h" -#include "core/class_db.h" -#include "core/error_macros.h" -#include "core/ustring.h" +#include "core/error/error_macros.h" +#include "core/object/class_db.h" +#include "core/string/ustring.h" #include "generic_6dof_joint_bullet.h" #include "hinge_joint_bullet.h" #include "pin_joint_bullet.h" diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 6078babaf8..02ba5458d8 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -32,8 +32,8 @@ #define BULLET_PHYSICS_SERVER_H #include "area_bullet.h" -#include "core/rid.h" -#include "core/rid_owner.h" +#include "core/templates/rid.h" +#include "core/templates/rid_owner.h" #include "joint_bullet.h" #include "rigid_body_bullet.h" #include "servers/physics_server_3d.h" diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index 36b3a9550c..e2d05f2c38 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -31,10 +31,10 @@ #ifndef COLLISION_OBJECT_BULLET_H #define COLLISION_OBJECT_BULLET_H -#include "core/class_db.h" #include "core/math/transform.h" #include "core/math/vector3.h" -#include "core/vset.h" +#include "core/object/class_db.h" +#include "core/templates/vset.h" #include "shape_owner_bullet.h" #include <LinearMath/btTransform.h> diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h index 5a96268ee9..13e7255abf 100644 --- a/modules/bullet/godot_collision_dispatcher.h +++ b/modules/bullet/godot_collision_dispatcher.h @@ -31,7 +31,7 @@ #ifndef GODOT_COLLISION_DISPATCHER_H #define GODOT_COLLISION_DISPATCHER_H -#include "core/int_types.h" +#include <cstdint> #include <btBulletDynamicsCommon.h> diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp index 009d0dff63..d29b699ecd 100644 --- a/modules/bullet/register_types.cpp +++ b/modules/bullet/register_types.cpp @@ -31,8 +31,8 @@ #include "register_types.h" #include "bullet_physics_server.h" -#include "core/class_db.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/object/class_db.h" /** @author AndreaCatania diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h index 3551ca05f9..0db09b2b78 100644 --- a/modules/bullet/rid_bullet.h +++ b/modules/bullet/rid_bullet.h @@ -31,7 +31,7 @@ #ifndef RID_BULLET_H #define RID_BULLET_H -#include "core/rid.h" +#include "core/templates/rid.h" /** @author AndreaCatania diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index fdc2944dad..c7b761e92a 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -34,7 +34,7 @@ #include "bullet_physics_server.h" #include "bullet_types_converter.h" #include "bullet_utilities.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "shape_owner_bullet.h" #include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h> diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index a35a1d8a18..1c29dc1b1f 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -32,7 +32,7 @@ #define SHAPE_BULLET_H #include "core/math/geometry_3d.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "rid_bullet.h" #include "servers/physics_server_3d.h" diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index c581d1804e..abad1beacb 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -34,8 +34,8 @@ #include "bullet_types_converter.h" #include "bullet_utilities.h" #include "constraint_bullet.h" -#include "core/project_settings.h" -#include "core/ustring.h" +#include "core/config/project_settings.h" +#include "core/string/ustring.h" #include "godot_collision_configuration.h" #include "godot_collision_dispatcher.h" #include "rigid_body_bullet.h" diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index de281064af..e362f27d39 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -31,8 +31,8 @@ #ifndef SPACE_BULLET_H #define SPACE_BULLET_H -#include "core/variant.h" -#include "core/vector.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" #include "godot_result_callbacks.h" #include "rid_bullet.h" #include "servers/physics_server_3d.h" diff --git a/modules/camera/SCsub b/modules/camera/SCsub index 631a65bde2..de97724d09 100644 --- a/modules/camera/SCsub +++ b/modules/camera/SCsub @@ -5,17 +5,7 @@ Import("env_modules") env_camera = env_modules.Clone() -if env["platform"] == "iphone": - # (iOS) Enable module support - env_camera.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) - - # (iOS) Build as separate static library - modules_sources = [] - env_camera.add_source_files(modules_sources, "register_types.cpp") - env_camera.add_source_files(modules_sources, "camera_ios.mm") - mod_lib = env_modules.add_library("#bin/libgodot_camera_module" + env["LIBSUFFIX"], modules_sources) - -elif env["platform"] == "windows": +if env["platform"] == "windows": env_camera.add_source_files(env.modules_sources, "register_types.cpp") env_camera.add_source_files(env.modules_sources, "camera_win.cpp") diff --git a/modules/camera/config.py b/modules/camera/config.py index 87d7542741..8a22751aa7 100644 --- a/modules/camera/config.py +++ b/modules/camera/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return platform == "iphone" or platform == "osx" or platform == "windows" + return platform == "osx" or platform == "windows" def configure(env): diff --git a/modules/camera/register_types.cpp b/modules/camera/register_types.cpp index 3b6c916914..9479310a13 100644 --- a/modules/camera/register_types.cpp +++ b/modules/camera/register_types.cpp @@ -33,9 +33,6 @@ #if defined(WINDOWS_ENABLED) #include "camera_win.h" #endif -#if defined(IPHONE_ENABLED) -#include "camera_ios.h" -#endif #if defined(OSX_ENABLED) #include "camera_osx.h" #endif @@ -44,9 +41,6 @@ void register_camera_types() { #if defined(WINDOWS_ENABLED) CameraServer::make_default<CameraWindows>(); #endif -#if defined(IPHONE_ENABLED) - CameraServer::make_default<CameraIOS>(); -#endif #if defined(OSX_ENABLED) CameraServer::make_default<CameraOSX>(); #endif diff --git a/modules/camera_iphone/SCsub b/modules/camera_iphone/SCsub new file mode 100644 index 0000000000..0a37d9a6f5 --- /dev/null +++ b/modules/camera_iphone/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_camera = env_modules.Clone() + +# (iOS) Enable module support +env_camera.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_camera.add_source_files(modules_sources, "*.cpp") +env_camera.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_camera_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/camera_iphone/camera.gdip b/modules/camera_iphone/camera.gdip new file mode 100644 index 0000000000..09017b8d27 --- /dev/null +++ b/modules/camera_iphone/camera.gdip @@ -0,0 +1,18 @@ +[config] +name="Camera" +binary="camera_lib.a" + +initialization="register_camera_types" +deinitialization="unregister_camera_types" + +[dependencies] +linked=[] +embedded=[] +system=["AVFoundation.framework"] + +capabilities=[] + +files=[] + +[plist] +NSCameraUsageDescription="Device camera is used for some functionality" diff --git a/modules/camera/camera_ios.h b/modules/camera_iphone/camera_ios.h index 7da43e4851..7da43e4851 100644 --- a/modules/camera/camera_ios.h +++ b/modules/camera_iphone/camera_ios.h diff --git a/modules/camera/camera_ios.mm b/modules/camera_iphone/camera_ios.mm index e4cb928805..e4cb928805 100644 --- a/modules/camera/camera_ios.mm +++ b/modules/camera_iphone/camera_ios.mm diff --git a/modules/camera_iphone/camera_module.cpp b/modules/camera_iphone/camera_module.cpp new file mode 100644 index 0000000000..f3d00be204 --- /dev/null +++ b/modules/camera_iphone/camera_module.cpp @@ -0,0 +1,40 @@ +/*************************************************************************/ +/* camera_module.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "camera_module.h" + +#include "camera_ios.h" + +void register_camera_types() { + CameraServer::make_default<CameraIOS>(); +} + +void unregister_camera_types() { +} diff --git a/modules/camera_iphone/camera_module.h b/modules/camera_iphone/camera_module.h new file mode 100644 index 0000000000..d123071a70 --- /dev/null +++ b/modules/camera_iphone/camera_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* camera_module.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +void register_camera_types(); +void unregister_camera_types(); diff --git a/modules/camera_iphone/config.py b/modules/camera_iphone/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/camera_iphone/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 47982d519a..04e1c4de35 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -32,7 +32,7 @@ #include "core/math/geometry_2d.h" #include "core/math/math_funcs.h" -#include "core/sort_array.h" +#include "core/templates/sort_array.h" // Static helper functions. diff --git a/modules/csg/csg.h b/modules/csg/csg.h index 34ee239c17..ef1103e1ac 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -31,16 +31,16 @@ #ifndef CSG_H #define CSG_H -#include "core/list.h" -#include "core/map.h" #include "core/math/aabb.h" #include "core/math/plane.h" #include "core/math/transform.h" #include "core/math/vector2.h" #include "core/math/vector3.h" -#include "core/oa_hash_map.h" -#include "core/reference.h" -#include "core/vector.h" +#include "core/object/reference.h" +#include "core/templates/list.h" +#include "core/templates/map.h" +#include "core/templates/oa_hash_map.h" +#include "core/templates/vector.h" #include "scene/resources/material.h" struct CSGBrush { diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index 2a4f836478..5d97164dbf 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -32,7 +32,7 @@ #include "core/os/os.h" #include "core/os/thread.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <ConvectionKernels.h> diff --git a/modules/cvtt/image_compress_cvtt.h b/modules/cvtt/image_compress_cvtt.h index c1772199af..483fb876a6 100644 --- a/modules/cvtt/image_compress_cvtt.h +++ b/modules/cvtt/image_compress_cvtt.h @@ -31,7 +31,7 @@ #ifndef IMAGE_COMPRESS_CVTT_H #define IMAGE_COMPRESS_CVTT_H -#include "core/image.h" +#include "core/io/image.h" void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels); void image_decompress_cvtt(Image *p_image); diff --git a/modules/denoise/lightmap_denoiser.h b/modules/denoise/lightmap_denoiser.h index 74a9d8af86..f4e4335d9b 100644 --- a/modules/denoise/lightmap_denoiser.h +++ b/modules/denoise/lightmap_denoiser.h @@ -31,7 +31,7 @@ #ifndef LIGHTMAP_DENOISER_H #define LIGHTMAP_DENOISER_H -#include "core/class_db.h" +#include "core/object/class_db.h" #include "scene/3d/lightmapper.h" struct OIDNDeviceImpl; diff --git a/modules/denoise/register_types.cpp b/modules/denoise/register_types.cpp index b78734a531..552495ed87 100644 --- a/modules/denoise/register_types.cpp +++ b/modules/denoise/register_types.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "register_types.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "lightmap_denoiser.h" void register_denoise_types() { diff --git a/modules/enet/register_types.cpp b/modules/enet/register_types.cpp index 18051f756a..2683f3155b 100644 --- a/modules/enet/register_types.cpp +++ b/modules/enet/register_types.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "register_types.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "networked_multiplayer_enet.h" static bool enet_ok = false; diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp index d1ba3dc355..6cac2458f9 100644 --- a/modules/etc/image_etc.cpp +++ b/modules/etc/image_etc.cpp @@ -31,10 +31,10 @@ #include "image_etc.h" #include "Etc.h" #include "EtcFilter.h" -#include "core/image.h" +#include "core/io/image.h" #include "core/os/copymem.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" static Image::Format _get_etc2_mode(Image::UsedChannels format) { switch (format) { diff --git a/modules/gamecenter/SCsub b/modules/gamecenter/SCsub new file mode 100644 index 0000000000..72fbf7ab0e --- /dev/null +++ b/modules/gamecenter/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_gamecenter = env_modules.Clone() + +# (iOS) Enable module support +env_gamecenter.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_gamecenter.add_source_files(modules_sources, "*.cpp") +env_gamecenter.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_gamecenter_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/gamecenter/config.py b/modules/gamecenter/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/gamecenter/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/platform/iphone/game_center.h b/modules/gamecenter/game_center.h index 10c8ef52fb..76fd295460 100644 --- a/platform/iphone/game_center.h +++ b/modules/gamecenter/game_center.h @@ -28,12 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef GAME_CENTER_ENABLED - #ifndef GAME_CENTER_H #define GAME_CENTER_H -#include "core/class_db.h" +#include "core/object/class_db.h" class GameCenter : public Object { GDCLASS(GameCenter, Object); @@ -71,5 +69,3 @@ public: }; #endif - -#endif diff --git a/platform/iphone/game_center.mm b/modules/gamecenter/game_center.mm index 0f8c0100c3..114f639a32 100644 --- a/platform/iphone/game_center.mm +++ b/modules/gamecenter/game_center.mm @@ -28,28 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef GAME_CENTER_ENABLED - #include "game_center.h" +#import "platform/iphone/app_delegate.h" -#ifdef __IPHONE_9_0 - -#import <GameKit/GameKit.h> -extern "C" { - -#else - -extern "C" { +#import "game_center_delegate.h" +#import "platform/iphone/view_controller.h" #import <GameKit/GameKit.h> -#endif - -#import "app_delegate.h" -}; - -#import "view_controller.h" - GameCenter *GameCenter::instance = NULL; +GodotGameCenterDelegate *gameCenterDelegate = nil; void GameCenter::_bind_methods() { ClassDB::bind_method(D_METHOD("authenticate"), &GameCenter::authenticate); @@ -76,7 +63,7 @@ Error GameCenter::authenticate() { GKLocalPlayer *player = [GKLocalPlayer localPlayer]; ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE); - ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; + UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController; ERR_FAIL_COND_V(!root_controller, FAILED); // This handler is called several times. First when the view needs to be shown, then again @@ -305,10 +292,10 @@ Error GameCenter::show_game_center(Dictionary p_params) { GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init]; ERR_FAIL_COND_V(!controller, FAILED); - ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; + UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController; ERR_FAIL_COND_V(!root_controller, FAILED); - controller.gameCenterDelegate = root_controller; + controller.gameCenterDelegate = gameCenterDelegate; controller.viewState = view_state; if (view_state == GKGameCenterViewControllerStateLeaderboards) { controller.leaderboardIdentifier = nil; @@ -382,8 +369,12 @@ GameCenter::GameCenter() { ERR_FAIL_COND(instance != NULL); instance = this; authenticated = false; -}; -GameCenter::~GameCenter() {} + gameCenterDelegate = [[GodotGameCenterDelegate alloc] init]; +}; -#endif +GameCenter::~GameCenter() { + if (gameCenterDelegate) { + gameCenterDelegate = nil; + } +} diff --git a/modules/gamecenter/game_center_delegate.h b/modules/gamecenter/game_center_delegate.h new file mode 100644 index 0000000000..1b7025f915 --- /dev/null +++ b/modules/gamecenter/game_center_delegate.h @@ -0,0 +1,35 @@ +/*************************************************************************/ +/* game_center_delegate.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +#import <GameKit/GameKit.h> + +@interface GodotGameCenterDelegate : NSObject <GKGameCenterControllerDelegate> + +@end diff --git a/platform/javascript/native/id_handler.js b/modules/gamecenter/game_center_delegate.mm index 67d29075b8..9a10c439c6 100644 --- a/platform/javascript/native/id_handler.js +++ b/modules/gamecenter/game_center_delegate.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* id_handler.js */ +/* game_center_delegate.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,36 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -var IDHandler = /** @constructor */ function() { +#import "game_center_delegate.h" - var ids = {}; - var size = 0; +#include "game_center.h" - this.has = function(id) { - return ids.hasOwnProperty(id); - } - - this.add = function(obj) { - size += 1; - var id = crypto.getRandomValues(new Int32Array(32))[0]; - ids[id] = obj; - return id; - } - - this.get = function(id) { - return ids[id]; - } - - this.remove = function(id) { - size -= 1; - delete ids[id]; - } +@implementation GodotGameCenterDelegate - this.size = function() { - return size; +- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController { + //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone + if (GameCenter::get_singleton()) { + GameCenter::get_singleton()->game_center_closed(); } + [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; +} - this.ids = ids; -}; - -Module.IDHandler = new IDHandler; +@end diff --git a/modules/gamecenter/game_center_module.cpp b/modules/gamecenter/game_center_module.cpp new file mode 100644 index 0000000000..6c5157345f --- /dev/null +++ b/modules/gamecenter/game_center_module.cpp @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* game_center_module.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "game_center_module.h" + +#include "core/config/engine.h" + +#include "game_center.h" + +GameCenter *game_center; + +void register_gamecenter_types() { + game_center = memnew(GameCenter); + Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center)); +} + +void unregister_gamecenter_types() { + if (game_center) { + memdelete(game_center); + } +} diff --git a/modules/gamecenter/game_center_module.h b/modules/gamecenter/game_center_module.h new file mode 100644 index 0000000000..8da3ae02ee --- /dev/null +++ b/modules/gamecenter/game_center_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* game_center_module.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +void register_gamecenter_types(); +void unregister_gamecenter_types(); diff --git a/modules/gamecenter/gamecenter.gdip b/modules/gamecenter/gamecenter.gdip new file mode 100644 index 0000000000..eb44effbdd --- /dev/null +++ b/modules/gamecenter/gamecenter.gdip @@ -0,0 +1,17 @@ +[config] +name="GameCenter" +binary="gamecenter_lib.a" + +initialization="register_gamecenter_types" +deinitialization="unregister_gamecenter_types" + +[dependencies] +linked=[] +embedded=[] +system=["GameKit.framework"] + +capabilities=["gamekit"] + +files=[] + +[plist] diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index bb2da70c3a..f397ee96c5 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -30,11 +30,11 @@ #include "gdnative.h" -#include "core/global_constants.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "core/io/file_access_encrypted.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/main/scene_tree.h" diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 6d26c2141d..bba2c04a2a 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -31,10 +31,10 @@ #ifndef GDNATIVE_H #define GDNATIVE_H +#include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/thread_safe.h" -#include "core/resource.h" #include "gdnative/gdnative.h" #include "gdnative_api_struct.gen.h" diff --git a/modules/gdnative/gdnative/aabb.cpp b/modules/gdnative/gdnative/aabb.cpp index d5970e8004..dc1b79b9e5 100644 --- a/modules/gdnative/gdnative/aabb.cpp +++ b/modules/gdnative/gdnative/aabb.cpp @@ -31,7 +31,7 @@ #include "gdnative/aabb.h" #include "core/math/aabb.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp index 59953f5182..a5567f1e6b 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -30,12 +30,12 @@ #include "gdnative/array.h" -#include "core/array.h" #include "core/os/memory.h" +#include "core/variant/array.h" -#include "core/color.h" +#include "core/math/color.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 990fd3795d..e5891562a1 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -31,7 +31,7 @@ #include "gdnative/basis.h" #include "core/math/basis.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/callable.cpp b/modules/gdnative/gdnative/callable.cpp index 868b324227..f200e9f171 100644 --- a/modules/gdnative/gdnative/callable.cpp +++ b/modules/gdnative/gdnative/callable.cpp @@ -30,9 +30,9 @@ #include "gdnative/callable.h" -#include "core/callable.h" -#include "core/resource.h" -#include "core/variant.h" +#include "core/io/resource.h" +#include "core/variant/callable.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp index c75e74daba..a93181e142 100644 --- a/modules/gdnative/gdnative/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -30,8 +30,8 @@ #include "gdnative/color.h" -#include "core/color.h" -#include "core/variant.h" +#include "core/math/color.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { @@ -148,13 +148,6 @@ godot_color GDAPI godot_color_inverted(const godot_color *p_self) { return dest; } -godot_color GDAPI godot_color_contrasted(const godot_color *p_self) { - godot_color dest; - const Color *self = (const Color *)p_self; - *((Color *)&dest) = self->contrasted(); - return dest; -} - godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t) { godot_color dest; const Color *self = (const Color *)p_self; diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index a126974815..b6900b28bb 100644 --- a/modules/gdnative/gdnative/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -30,10 +30,10 @@ #include "gdnative/dictionary.h" -#include "core/variant.h" -// core/variant.h before to avoid compile errors with MSVC -#include "core/dictionary.h" +#include "core/variant/variant.h" +// core/variant/variant.h before to avoid compile errors with MSVC #include "core/io/json.h" +#include "core/variant/dictionary.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index e94190b07b..4142ea892b 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -30,12 +30,12 @@ #include "gdnative/gdnative.h" -#include "core/class_db.h" -#include "core/engine.h" -#include "core/error_macros.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/core_constants.h" +#include "core/error/error_macros.h" +#include "core/object/class_db.h" #include "core/os/os.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "modules/gdnative/gdnative.h" @@ -101,10 +101,10 @@ godot_dictionary GDAPI godot_get_global_constants() { godot_dictionary constants; godot_dictionary_new(&constants); Dictionary *p_constants = (Dictionary *)&constants; - const int constants_count = GlobalConstants::get_global_constant_count(); + const int constants_count = CoreConstants::get_global_constant_count(); for (int i = 0; i < constants_count; ++i) { - const char *name = GlobalConstants::get_global_constant_name(i); - int value = GlobalConstants::get_global_constant_value(i); + const char *name = CoreConstants::get_global_constant_name(i); + int value = CoreConstants::get_global_constant_value(i); (*p_constants)[name] = value; } return constants; diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp index 88ed650ebe..c031498612 100644 --- a/modules/gdnative/gdnative/node_path.cpp +++ b/modules/gdnative/gdnative/node_path.cpp @@ -30,8 +30,8 @@ #include "gdnative/node_path.h" -#include "core/node_path.h" -#include "core/variant.h" +#include "core/string/node_path.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp index de93c1d9b3..9139fd89a1 100644 --- a/modules/gdnative/gdnative/packed_arrays.cpp +++ b/modules/gdnative/gdnative/packed_arrays.cpp @@ -30,11 +30,11 @@ #include "gdnative/packed_arrays.h" -#include "core/array.h" +#include "core/variant/array.h" -#include "core/variant.h" +#include "core/variant/variant.h" -#include "core/color.h" +#include "core/math/color.h" #include "core/math/vector2.h" #include "core/math/vector3.h" diff --git a/modules/gdnative/gdnative/plane.cpp b/modules/gdnative/gdnative/plane.cpp index d4ed8d00f4..99fb5ff10a 100644 --- a/modules/gdnative/gdnative/plane.cpp +++ b/modules/gdnative/gdnative/plane.cpp @@ -31,7 +31,7 @@ #include "gdnative/plane.h" #include "core/math/plane.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp index de6308ad2a..a41886e780 100644 --- a/modules/gdnative/gdnative/quat.cpp +++ b/modules/gdnative/gdnative/quat.cpp @@ -31,7 +31,7 @@ #include "gdnative/quat.h" #include "core/math/quat.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp index 516f4d75ce..bacefced5d 100644 --- a/modules/gdnative/gdnative/rect2.cpp +++ b/modules/gdnative/gdnative/rect2.cpp @@ -31,7 +31,7 @@ #include "gdnative/rect2.h" #include "core/math/transform_2d.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/rid.cpp b/modules/gdnative/gdnative/rid.cpp index d7a63f33a7..24af04558b 100644 --- a/modules/gdnative/gdnative/rid.cpp +++ b/modules/gdnative/gdnative/rid.cpp @@ -30,9 +30,9 @@ #include "gdnative/rid.h" -#include "core/resource.h" -#include "core/rid.h" -#include "core/variant.h" +#include "core/io/resource.h" +#include "core/templates/rid.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 1fa19f4ff5..47c7f7b6e7 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -30,9 +30,9 @@ #include "gdnative/string.h" -#include "core/string_name.h" -#include "core/ustring.h" -#include "core/variant.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/variant/variant.h" #include <string.h> diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp index 7bbaaeeaa0..a840d74e18 100644 --- a/modules/gdnative/gdnative/string_name.cpp +++ b/modules/gdnative/gdnative/string_name.cpp @@ -30,8 +30,8 @@ #include "gdnative/string_name.h" -#include "core/string_name.h" -#include "core/ustring.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" #include <string.h> diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp index d19de93e9b..b17d6f8d4c 100644 --- a/modules/gdnative/gdnative/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -31,7 +31,7 @@ #include "gdnative/transform.h" #include "core/math/transform.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index c0f7878eb0..3c1105e323 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -31,7 +31,7 @@ #include "gdnative/transform2d.h" #include "core/math/transform_2d.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index dac4feb0e5..417abeaad3 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -30,8 +30,8 @@ #include "gdnative/variant.h" -#include "core/reference.h" -#include "core/variant.h" +#include "core/object/reference.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { @@ -576,7 +576,9 @@ godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string godot_variant raw_dest; Variant *dest = (Variant *)&raw_dest; Callable::CallError error; - memnew_placement_custom(dest, Variant, Variant(self->call(*method, args, p_argcount, error))); + Variant ret; + self->call(*method, args, p_argcount, ret, error); + memnew_placement_custom(dest, Variant, Variant(ret)); if (r_error) { r_error->error = (godot_variant_call_error_error)error.error; r_error->argument = error.argument; diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 1ee716df86..1ba846d315 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -31,7 +31,7 @@ #include "gdnative/vector2.h" #include "core/math/vector2.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index 32cad30c17..3284afdc31 100644 --- a/modules/gdnative/gdnative/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -30,8 +30,8 @@ #include "gdnative/vector3.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" #ifdef __cplusplus extern "C" { diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 82bfbd23de..40d0f75871 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -1255,13 +1255,6 @@ ] }, { - "name": "godot_color_contrasted", - "return_type": "godot_color", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { "name": "godot_color_lerp", "return_type": "godot_color", "arguments": [ diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h index e7737bf8e1..e64097ef57 100644 --- a/modules/gdnative/include/gdnative/color.h +++ b/modules/gdnative/include/gdnative/color.h @@ -93,8 +93,6 @@ godot_int GDAPI godot_color_to_argb32(const godot_color *p_self); godot_color GDAPI godot_color_inverted(const godot_color *p_self); -godot_color GDAPI godot_color_contrasted(const godot_color *p_self); - godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t); godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over); diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h index 0582d95f63..6043351e84 100644 --- a/modules/gdnative/include/gdnative/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -35,8 +35,13 @@ extern "C" { #endif +#include <stddef.h> #include <stdint.h> -#include <wchar.h> + +#ifndef __cplusplus +typedef uint32_t char32_t; +typedef uint16_t char16_t; +#endif typedef char32_t godot_char_type; diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 8dbaec4e75..6f2f9bfea9 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -32,11 +32,11 @@ #ifdef TOOLS_ENABLED -#include "core/class_db.h" -#include "core/engine.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/core_constants.h" +#include "core/object/class_db.h" #include "core/os/file_access.h" -#include "core/pair.h" +#include "core/templates/pair.h" // helper stuff @@ -173,19 +173,19 @@ List<ClassAPI> generate_c_api_classes() { ClassDB::get_class_list(&classes); classes.sort_custom<StringName::AlphCompare>(); - // Register global constants as a fake GlobalConstants singleton class + // Register global constants as a fake CoreConstants singleton class { ClassAPI global_constants_api; - global_constants_api.class_name = "GlobalConstants"; + global_constants_api.class_name = "CoreConstants"; global_constants_api.api_type = ClassDB::API_CORE; global_constants_api.is_singleton = true; - global_constants_api.singleton_name = "GlobalConstants"; + global_constants_api.singleton_name = "CoreConstants"; global_constants_api.is_instanciable = false; - const int constants_count = GlobalConstants::get_global_constant_count(); + const int constants_count = CoreConstants::get_global_constant_count(); for (int i = 0; i < constants_count; ++i) { ConstantAPI constant_api; - constant_api.constant_name = GlobalConstants::get_global_constant_name(i); - constant_api.constant_value = GlobalConstants::get_global_constant_value(i); + constant_api.constant_name = CoreConstants::get_global_constant_name(i); + constant_api.constant_value = CoreConstants::get_global_constant_value(i); global_constants_api.constants.push_back(constant_api); } global_constants_api.constants.sort_custom<ConstantAPIComparator>(); diff --git a/modules/gdnative/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h index edbb1d1f23..8555af5215 100644 --- a/modules/gdnative/nativescript/api_generator.h +++ b/modules/gdnative/nativescript/api_generator.h @@ -31,8 +31,8 @@ #ifndef API_GENERATOR_H #define API_GENERATOR_H +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" Error generate_c_api(const String &p_path); diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index e47548f3e9..411acbe1ad 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -30,11 +30,11 @@ #include "nativescript/godot_nativescript.h" -#include "core/class_db.h" -#include "core/error_macros.h" -#include "core/global_constants.h" -#include "core/project_settings.h" -#include "core/variant.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" +#include "core/error/error_macros.h" +#include "core/object/class_db.h" +#include "core/variant/variant.h" #include "gdnative/gdnative.h" #include <stdint.h> diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 632f4e5fee..0939cfd06a 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -34,12 +34,12 @@ #include "gdnative/gdnative.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "core/core_string_names.h" -#include "core/global_constants.h" #include "core/io/file_access_encrypted.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/main/scene_tree.h" #include "scene/resources/resource_format_text.h" diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 145bf7dcb6..2aaa4be325 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -31,15 +31,15 @@ #ifndef NATIVE_SCRIPT_H #define NATIVE_SCRIPT_H +#include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/oa_hash_map.h" -#include "core/ordered_hash_map.h" +#include "core/object/script_language.h" #include "core/os/mutex.h" #include "core/os/thread_safe.h" -#include "core/resource.h" -#include "core/script_language.h" -#include "core/self_list.h" +#include "core/templates/oa_hash_map.h" +#include "core/templates/ordered_hash_map.h" +#include "core/templates/self_list.h" #include "scene/main/node.h" #include "modules/gdnative/gdnative.h" diff --git a/modules/gdnative/net/webrtc_gdnative.cpp b/modules/gdnative/net/webrtc_gdnative.cpp index a7355e4d12..d8c3ddc5f8 100644 --- a/modules/gdnative/net/webrtc_gdnative.cpp +++ b/modules/gdnative/net/webrtc_gdnative.cpp @@ -54,7 +54,7 @@ godot_error GDAPI godot_net_set_webrtc_library(const godot_net_webrtc_library *p #ifdef WEBRTC_GDNATIVE_ENABLED return (godot_error)WebRTCPeerConnectionGDNative::set_default_library(p_lib); #else - return ERR_UNAVAILABLE; + return (godot_error)ERR_UNAVAILABLE; #endif } } diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index 7d17a7d5ab..0942fb40a8 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.cpp +++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp @@ -32,7 +32,7 @@ // Godot imports #include "core/os/os.h" -#include "core/variant.h" +#include "core/variant/variant.h" // PluginScript imports #include "pluginscript_language.h" diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index 690d1a0432..76ff9f7097 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -32,7 +32,7 @@ #define PLUGINSCRIPT_INSTANCE_H // Godot imports -#include "core/script_language.h" +#include "core/object/script_language.h" // PluginScript imports #include <pluginscript/godot_pluginscript.h> diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index bccbe95033..fc9c4ebd77 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -29,9 +29,9 @@ /*************************************************************************/ // Godot imports +#include "core/config/project_settings.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" // PluginScript imports #include "pluginscript_language.h" #include "pluginscript_script.h" diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index dd6758713f..53e1e3ae9b 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -34,9 +34,9 @@ // Godot imports #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/map.h" -#include "core/script_language.h" -#include "core/self_list.h" +#include "core/object/script_language.h" +#include "core/templates/map.h" +#include "core/templates/self_list.h" // PluginScript imports #include "pluginscript_loader.h" #include <pluginscript/godot_pluginscript.h> diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h index 35fc79c2ca..7d80f4c733 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.h +++ b/modules/gdnative/pluginscript/pluginscript_loader.h @@ -34,7 +34,7 @@ // Godot imports #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/script_language.h" +#include "core/object/script_language.h" class PluginScriptLanguage; diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 9cd38cd4b4..150de05e74 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -32,7 +32,7 @@ #define PLUGINSCRIPT_SCRIPT_H // Godot imports -#include "core/script_language.h" +#include "core/object/script_language.h" // PluginScript imports #include "pluginscript_language.h" #include <pluginscript/godot_pluginscript.h> diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp index 97a48b0e89..b354c23a9e 100644 --- a/modules/gdnative/pluginscript/register_types.cpp +++ b/modules/gdnative/pluginscript/register_types.cpp @@ -30,11 +30,11 @@ #include "register_types.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/dir_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/main/scene_tree.h" #include "pluginscript_language.h" diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 3a2d0b09a3..b88bf58256 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -40,11 +40,11 @@ #include "videodecoder/register_types.h" #include "xr/register_types.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/os.h" -#include "core/project_settings.h" #ifdef TOOLS_ENABLED #include "editor/editor_export.h" diff --git a/modules/gdnative/videodecoder/register_types.cpp b/modules/gdnative/videodecoder/register_types.cpp index 4181d8813f..8ee1c8d183 100644 --- a/modules/gdnative/videodecoder/register_types.cpp +++ b/modules/gdnative/videodecoder/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "core/class_db.h" +#include "core/object/class_db.h" #include "video_stream_gdnative.h" static Ref<ResourceFormatLoaderVideoStreamGDNative> resource_loader_vsgdnative; diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index fe7c10cad9..61e882f2fe 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -30,7 +30,7 @@ #include "video_stream_gdnative.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "servers/audio_server.h" VideoDecoderServer *VideoDecoderServer::instance = nullptr; diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h index e3e02f3d7c..c00d60ced7 100644 --- a/modules/gdnavigation/gd_navigation_server.h +++ b/modules/gdnavigation/gd_navigation_server.h @@ -31,8 +31,8 @@ #ifndef GD_NAVIGATION_SERVER_H #define GD_NAVIGATION_SERVER_H -#include "core/rid.h" -#include "core/rid_owner.h" +#include "core/templates/rid.h" +#include "core/templates/rid_owner.h" #include "servers/navigation_server_3d.h" #include "nav_map.h" diff --git a/modules/gdnavigation/nav_rid.h b/modules/gdnavigation/nav_rid.h index c119ecc5e0..b727fceb04 100644 --- a/modules/gdnavigation/nav_rid.h +++ b/modules/gdnavigation/nav_rid.h @@ -31,7 +31,7 @@ #ifndef NAV_RID_H #define NAV_RID_H -#include "core/rid.h" +#include "core/templates/rid.h" /** @author AndreaCatania diff --git a/modules/gdnavigation/register_types.cpp b/modules/gdnavigation/register_types.cpp index 088b26bf17..1ae19ebe47 100644 --- a/modules/gdnavigation/register_types.cpp +++ b/modules/gdnavigation/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "gd_navigation_server.h" #include "servers/navigation_server_3d.h" diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h index 1ad9d3ed76..de36508edb 100644 --- a/modules/gdnavigation/rvo_agent.h +++ b/modules/gdnavigation/rvo_agent.h @@ -31,7 +31,7 @@ #ifndef RVO_AGENT_H #define RVO_AGENT_H -#include "core/class_db.h" +#include "core/object/class_db.h" #include "nav_rid.h" #include <Agent.h> diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index e170667a30..d90b3e52d0 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -94,14 +94,15 @@ <argument index="1" name="message" type="String" default=""""> </argument> <description> - Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated and the program is halted until you resume it. Only executes in debug builds, or when running the game from the editor. Use it for debugging purposes, to make sure a statement is [code]true[/code] during development. + Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated. When running from the editor, the running project will also be paused until you resume it. This can be used as a stronger form of [method push_error] for reporting errors to project developers or add-on users. + [b]Note:[/b] For performance reasons, the code inside [method assert] is only executed in debug builds or when running the project from the editor. Don't include code that has side effects in an [method assert] call. Otherwise, the project will behave differently when exported in release mode. The optional [code]message[/code] argument, if given, is shown in addition to the generic "Assertion failed" message. You can use this to provide additional details about why the assertion failed. [codeblock] - # Imagine we always want speed to be between 0 and 20 - speed = -10 + # Imagine we always want speed to be between 0 and 20. + var speed = -10 assert(speed < 20) # True, the program will continue assert(speed >= 0) # False, the program will stop - assert(speed >= 0 && speed < 20) # You can also combine the two conditional statements in one check + assert(speed >= 0 and speed < 20) # You can also combine the two conditional statements in one check assert(speed < 20, "speed = %f, but the speed limit is 20" % speed) # Show a message with clarifying details [/codeblock] </description> @@ -386,24 +387,6 @@ [/codeblock] </description> </method> - <method name="funcref"> - <return type="FuncRef"> - </return> - <argument index="0" name="instance" type="Object"> - </argument> - <argument index="1" name="funcname" type="String"> - </argument> - <description> - Returns a reference to the specified function [code]funcname[/code] in the [code]instance[/code] node. As functions aren't first-class objects in GDscript, use [code]funcref[/code] to store a [FuncRef] in a variable and call it later. - [codeblock] - func foo(): - return("bar") - - a = funcref(self, "foo") - print(a.call_func()) # Prints bar - [/codeblock] - </description> - </method> <method name="get_stack"> <return type="Array"> </return> @@ -921,20 +904,6 @@ [/codeblock] </description> </method> - <method name="rand_range"> - <return type="float"> - </return> - <argument index="0" name="from" type="float"> - </argument> - <argument index="1" name="to" type="float"> - </argument> - <description> - Random range, any floating point value between [code]from[/code] and [code]to[/code]. - [codeblock] - prints(rand_range(0, 1), rand_range(0, 1)) # Prints e.g. 0.135591 0.405263 - [/codeblock] - </description> - </method> <method name="rand_seed"> <return type="Array"> </return> @@ -954,6 +923,20 @@ [/codeblock] </description> </method> + <method name="randf_range"> + <return type="float"> + </return> + <argument index="0" name="from" type="float"> + </argument> + <argument index="1" name="to" type="float"> + </argument> + <description> + Random range, any floating point value between [code]from[/code] and [code]to[/code]. + [codeblock] + prints(randf_range(-10, 10), randf_range(-10, 10)) # Prints e.g. -3.844535 7.45315 + [/codeblock] + </description> + </method> <method name="randi"> <return type="int"> </return> @@ -967,6 +950,21 @@ [/codeblock] </description> </method> + <method name="randi_range"> + <return type="int"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + Random range, any 32-bit integer value between [code]from[/code] and [code]to[/code] (inclusive). If [code]to[/code] is lesser than [code]from[/code] they are swapped. + [codeblock] + print(randi_range(0, 1)) # Prints 0 or 1 + print(randi_range(-10, 1000)) # Prints any number from -10 to 1000 + [/codeblock] + </description> + </method> <method name="randomize"> <return type="void"> </return> diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h index 5ea416d4cc..d763df01f5 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h @@ -31,7 +31,7 @@ #ifndef GDSCRIPT_TRANSLATION_PARSER_PLUGIN_H #define GDSCRIPT_TRANSLATION_PARSER_PLUGIN_H -#include "core/set.h" +#include "core/templates/set.h" #include "editor/editor_translation_parser.h" #include "modules/gdscript/gdscript_parser.h" #include "modules/regex/regex.h" diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index e70e3f7272..53602f7a9b 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -32,13 +32,13 @@ #include <stdint.h> +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "core/core_string_names.h" -#include "core/engine.h" -#include "core/global_constants.h" #include "core/io/file_access_encrypted.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "gdscript_analyzer.h" #include "gdscript_cache.h" #include "gdscript_compiler.h" @@ -1092,7 +1092,8 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { // Try conversion Callable::CallError ce; const Variant *value = &p_value; - Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce); + Variant converted; + Variant::construct(member->data_type.builtin_type, converted, &value, 1, ce); if (ce.error == Callable::CallError::CALL_OK) { members.write[member->index] = converted; return true; @@ -1500,9 +1501,9 @@ void GDScriptLanguage::remove_named_global_constant(const StringName &p_name) { void GDScriptLanguage::init() { //populate global constants - int gcc = GlobalConstants::get_global_constant_count(); + int gcc = CoreConstants::get_global_constant_count(); for (int i = 0; i < gcc; i++) { - _add_global(StaticCString::create(GlobalConstants::get_global_constant_name(i)), GlobalConstants::get_global_constant_value(i)); + _add_global(StaticCString::create(CoreConstants::get_global_constant_name(i)), CoreConstants::get_global_constant_value(i)); } _add_global(StaticCString::create("PI"), Math_PI); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 79317ff846..b69a6e39c0 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -35,7 +35,7 @@ #include "core/debugger/script_debugger.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/script_language.h" +#include "core/object/script_language.h" #include "gdscript_function.h" class GDScriptNativeClass : public Reference { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 5250115608..6b23ab1616 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -30,12 +30,12 @@ #include "gdscript_analyzer.h" -#include "core/class_db.h" -#include "core/hash_map.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" +#include "core/object/class_db.h" +#include "core/object/script_language.h" #include "core/os/file_access.h" -#include "core/project_settings.h" -#include "core/script_language.h" +#include "core/templates/hash_map.h" #include "gdscript.h" // TODO: Move this to a central location (maybe core?). @@ -1711,7 +1711,8 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa } Callable::CallError err; - Variant value = Variant::construct(builtin_type, (const Variant **)args.ptr(), args.size(), err); + Variant value; + Variant::construct(builtin_type, value, (const Variant **)args.ptr(), args.size(), err); switch (err.error) { case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: @@ -2075,7 +2076,8 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod } default: { Callable::CallError temp; - Variant dummy = Variant::construct(base.builtin_type, nullptr, 0, temp); + Variant dummy; + Variant::construct(base.builtin_type, dummy, nullptr, 0, temp); List<PropertyInfo> properties; dummy.get_property_list(&properties); for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) { @@ -2279,10 +2281,12 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident StringName name = p_identifier->name; p_identifier->source = GDScriptParser::IdentifierNode::UNDEFINED_SOURCE; - // Check globals. - if (GDScriptParser::get_builtin_type(name) < Variant::VARIANT_MAX) { + // Check globals. We make an exception for Variant::OBJECT because it's the base class for + // non-builtin types so we allow doing e.g. Object.new() + Variant::Type builtin_type = GDScriptParser::get_builtin_type(name); + if (builtin_type != Variant::OBJECT && builtin_type < Variant::VARIANT_MAX) { if (can_be_builtin) { - p_identifier->set_datatype(make_builtin_meta_type(GDScriptParser::get_builtin_type(name))); + p_identifier->set_datatype(make_builtin_meta_type(builtin_type)); return; } else { push_error(R"(Builtin type cannot be used as a name on its own.)", p_identifier); @@ -2436,7 +2440,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri if (p_subscript->base->is_constant) { // Just try to get it. bool valid = false; - Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, &valid); + Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid); if (!valid) { push_error(vformat(R"(Cannot get member "%s" from "%s".)", p_subscript->attribute->name, p_subscript->base->reduced_value), p_subscript->index); } else { @@ -2537,7 +2541,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::STRING; break; // Don't support indexing, but we will check it later. - case Variant::_RID: + case Variant::RID: case Variant::BOOL: case Variant::CALLABLE: case Variant::FLOAT: @@ -2570,7 +2574,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri switch (base_type.builtin_type) { // Can't index at all. - case Variant::_RID: + case Variant::RID: case Variant::BOOL: case Variant::CALLABLE: case Variant::FLOAT: @@ -2867,7 +2871,8 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, GD if (p_base_type.kind == GDScriptParser::DataType::BUILTIN) { // Construct a base type to get methods. Callable::CallError err; - Variant dummy = Variant::construct(p_base_type.builtin_type, nullptr, 0, err); + Variant dummy; + Variant::construct(p_base_type.builtin_type, dummy, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(false, "Could not construct base Variant type."); } @@ -3093,7 +3098,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator a = a_ref; } else { Callable::CallError err; - a = Variant::construct(a_type, nullptr, 0, err); + Variant::construct(a_type, a, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { r_valid = false; ERR_FAIL_V_MSG(result, vformat("Could not construct value of type %s", Variant::get_type_name(a_type))); @@ -3106,7 +3111,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator b = b_ref; } else { Callable::CallError err; - b = Variant::construct(b_type, nullptr, 0, err); + Variant::construct(b_type, b, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { r_valid = false; ERR_FAIL_V_MSG(result, vformat("Could not construct value of type %s", Variant::get_type_name(b_type))); diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h index f3cbb320b7..0a952cc621 100644 --- a/modules/gdscript/gdscript_analyzer.h +++ b/modules/gdscript/gdscript_analyzer.h @@ -31,9 +31,9 @@ #ifndef GDSCRIPT_ANALYZER_H #define GDSCRIPT_ANALYZER_H -#include "core/object.h" -#include "core/reference.h" -#include "core/set.h" +#include "core/object/object.h" +#include "core/object/reference.h" +#include "core/templates/set.h" #include "gdscript_cache.h" #include "gdscript_parser.h" diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 57b95f5b21..95d24a8b08 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -31,7 +31,7 @@ #include "gdscript_cache.h" #include "core/os/file_access.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include "gdscript.h" #include "gdscript_analyzer.h" #include "gdscript_parser.h" diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h index 865df34051..90c5884985 100644 --- a/modules/gdscript/gdscript_cache.h +++ b/modules/gdscript/gdscript_cache.h @@ -31,10 +31,10 @@ #ifndef GDSCRIPT_CACHE_H #define GDSCRIPT_CACHE_H -#include "core/hash_map.h" +#include "core/object/reference.h" #include "core/os/mutex.h" -#include "core/reference.h" -#include "core/set.h" +#include "core/templates/hash_map.h" +#include "core/templates/set.h" #include "gdscript.h" class GDScriptAnalyzer; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index 31e1e6ba23..9872a61423 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -32,8 +32,8 @@ #define GDSCRIPT_CODEGEN #include "core/io/multiplayer_api.h" -#include "core/string_name.h" -#include "core/variant.h" +#include "core/string/string_name.h" +#include "core/variant/variant.h" #include "gdscript_function.h" #include "gdscript_functions.h" diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index fe34d6cba3..157c801f56 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -31,7 +31,7 @@ #ifndef GDSCRIPT_COMPILER_H #define GDSCRIPT_COMPILER_H -#include "core/set.h" +#include "core/templates/set.h" #include "gdscript.h" #include "gdscript_codegen.h" #include "gdscript_function.h" diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index aec05b6771..a426046797 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -30,8 +30,8 @@ #include "gdscript.h" -#include "core/engine.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/core_constants.h" #include "core/os/file_access.h" #include "gdscript_analyzer.h" #include "gdscript_compiler.h" @@ -39,7 +39,7 @@ #include "gdscript_tokenizer.h" #ifdef TOOLS_ENABLED -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "editor/editor_file_system.h" #include "editor/editor_settings.h" #endif @@ -383,8 +383,8 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> } bool skip = false; - for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { - if (E->key() == GlobalConstants::get_global_constant_name(i)) { + for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { + if (E->key() == CoreConstants::get_global_constant_name(i)) { skip = true; break; } @@ -973,7 +973,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base } break; case GDScriptParser::DataType::BUILTIN: { Callable::CallError err; - Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant tmp; + Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return; } @@ -1523,7 +1524,8 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, found = _guess_identifier_type_from_base(c, base, id, r_type); } else if (!found && index.type.kind == GDScriptParser::DataType::BUILTIN) { Callable::CallError err; - Variant base_val = Variant::construct(base.type.builtin_type, nullptr, 0, err); + Variant base_val; + Variant::construct(base.type.builtin_type, base_val, nullptr, 0, err); bool valid = false; Variant res = base_val.get(index.value, &valid); if (valid) { @@ -1560,9 +1562,14 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, Callable::CallError ce; bool v1_use_value = p1.value.get_type() != Variant::NIL && p1.value.get_type() != Variant::OBJECT; - Variant v1 = (v1_use_value) ? p1.value : Variant::construct(p1.type.builtin_type, nullptr, 0, ce); + Variant d1; + Variant::construct(p1.type.builtin_type, d1, nullptr, 0, ce); + Variant d2; + Variant::construct(p2.type.builtin_type, d2, nullptr, 0, ce); + + Variant v1 = (v1_use_value) ? p1.value : d1; bool v2_use_value = p2.value.get_type() != Variant::NIL && p2.value.get_type() != Variant::OBJECT; - Variant v2 = (v2_use_value) ? p2.value : Variant::construct(p2.type.builtin_type, nullptr, 0, ce); + Variant v2 = (v2_use_value) ? p2.value : d2; // avoid potential invalid ops if ((op->variant_op == Variant::OP_DIVIDE || op->variant_op == Variant::OP_MODULE) && v2.get_type() == Variant::INT) { v2 = 1; @@ -1952,7 +1959,8 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext & } break; case GDScriptParser::DataType::BUILTIN: { Callable::CallError err; - Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant tmp; + Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return false; @@ -2102,7 +2110,8 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex } break; case GDScriptParser::DataType::BUILTIN: { Callable::CallError err; - Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant tmp; + Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return false; } @@ -2139,9 +2148,9 @@ static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_co r_result.insert(option.display, option); } } else { - for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { - if (GlobalConstants::get_global_constant_enum(i) == current_enum) { - ScriptCodeCompletionOption option(GlobalConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM); + for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { + if (CoreConstants::get_global_constant_enum(i) == current_enum) { + ScriptCodeCompletionOption option(CoreConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM); r_result.insert(option.display, option); } } @@ -2257,7 +2266,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c case GDScriptParser::DataType::BUILTIN: { if (base.get_type() == Variant::NIL) { Callable::CallError err; - base = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant::construct(base_type.builtin_type, base, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return; } @@ -2306,11 +2315,6 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c if (GDScriptParser::get_builtin_function(call->function_name) < GDScriptFunctions::FUNC_MAX) { MethodInfo info = GDScriptFunctions::get_info(GDScriptParser::get_builtin_function(call->function_name)); - - if ((info.name == "load" || info.name == "preload") && bool(EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))) { - _get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), r_result); - } - r_arghint = _make_arguments_hint(info, p_argidx); return; } else if (GDScriptParser::get_builtin_type(call->function_name) < Variant::VARIANT_MAX) { @@ -2883,7 +2887,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co v = v_ref; } else { Callable::CallError err; - v = Variant::construct(base_type.builtin_type, NULL, 0, err); + Variant::construct(base_type.builtin_type, v, NULL, 0, err); if (err.error != Callable::CallError::CALL_OK) { break; } diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index e59f99fc56..8372672cf7 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -35,7 +35,7 @@ #include "gdscript_functions.h" #ifdef DEBUG_ENABLED -#include "core/string_builder.h" +#include "core/string/string_builder.h" #endif Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const { @@ -331,7 +331,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a return Variant(); } if (argument_types[i].kind == GDScriptDataType::BUILTIN) { - Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err); + Variant arg; + Variant::construct(argument_types[i].builtin_type, arg, &p_args[i], 1, r_err); memnew_placement(&stack[i], Variant(arg)); } else { memnew_placement(&stack[i], Variant(*p_args[i])); @@ -620,7 +621,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const StringName *index = &_global_names_ptr[indexname]; bool valid; - dst->set_named(*index, *value, &valid); + dst->set_named(*index, *value, valid); #ifdef DEBUG_ENABLED if (!valid) { @@ -647,10 +648,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool valid; #ifdef DEBUG_ENABLED //allow better error message in cases where src and dst are the same stack position - Variant ret = src->get_named(*index, &valid); + Variant ret = src->get_named(*index, valid); #else - *dst = src->get_named(*index, &valid); + *dst = src->get_named(*index, valid); #endif #ifdef DEBUG_ENABLED if (!valid) { @@ -755,7 +756,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (Variant::can_convert_strict(src->get_type(), var_type)) { #endif // DEBUG_ENABLED Callable::CallError ce; - *dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce); + Variant::construct(var_type, *dst, const_cast<const Variant **>(&src), 1, ce); } else { #ifdef DEBUG_ENABLED err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + @@ -857,7 +858,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(to_type < 0 || to_type >= Variant::VARIANT_MAX); Callable::CallError err; - *dst = Variant::construct(to_type, (const Variant **)&src, 1, err); + Variant::construct(to_type, *dst, (const Variant **)&src, 1, err); #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { @@ -955,7 +956,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_VARIANT_PTR(dst, 3 + argc); Callable::CallError err; - *dst = Variant::construct(t, (const Variant **)argptrs, argc, err); + Variant::construct(t, *dst, (const Variant **)argptrs, argc, err); #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { @@ -1047,7 +1048,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Callable::CallError err; if (call_ret) { GET_VARIANT_PTR(ret, argc); - base->call_ptr(*methodname, (const Variant **)argptrs, argc, ret, err); + base->call(*methodname, (const Variant **)argptrs, argc, *ret, err); #ifdef DEBUG_ENABLED if (!call_async && ret->get_type() == Variant::OBJECT) { // Check if getting a function state without await. @@ -1065,7 +1066,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } #endif } else { - base->call_ptr(*methodname, (const Variant **)argptrs, argc, nullptr, err); + Variant ret; + base->call(*methodname, (const Variant **)argptrs, argc, ret, err); } #ifdef DEBUG_ENABLED if (GDScriptLanguage::get_singleton()->profiling) { @@ -1093,6 +1095,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } } + } else if (methodstr == "call_recursive" && basestr == "TreeItem") { + if (argc >= 1) { + methodstr = String(*argptrs[0]) + " (via TreeItem.call_recursive)"; + if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { + err.argument += 1; + } + } } err_text = _get_call_error(err, "function '" + methodstr + "' in base '" + basestr + "'", (const Variant **)argptrs); OPCODE_BREAK; diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index c98ac09310..50eadcaf86 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -31,13 +31,13 @@ #ifndef GDSCRIPT_FUNCTION_H #define GDSCRIPT_FUNCTION_H +#include "core/object/reference.h" +#include "core/object/script_language.h" #include "core/os/thread.h" -#include "core/pair.h" -#include "core/reference.h" -#include "core/script_language.h" -#include "core/self_list.h" -#include "core/string_name.h" -#include "core/variant.h" +#include "core/string/string_name.h" +#include "core/templates/pair.h" +#include "core/templates/self_list.h" +#include "core/variant/variant.h" class GDScriptInstance; class GDScript; diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 31ce63bc6e..3a7c1a8676 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -30,14 +30,13 @@ #include "gdscript_functions.h" -#include "core/class_db.h" -#include "core/func_ref.h" #include "core/io/json.h" #include "core/io/marshalls.h" #include "core/math/math_funcs.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" #include "core/os/os.h" -#include "core/reference.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" #include "gdscript.h" const char *GDScriptFunctions::get_func_name(Function p_func) { @@ -83,7 +82,8 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { "randomize", "randi", "randf", - "rand_range", + "randf_range", + "randi_range", "seed", "rand_seed", "deg2rad", @@ -99,7 +99,6 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { "clamp", "nearest_po2", "weakref", - "funcref", "convert", "typeof", "type_exists", @@ -286,7 +285,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ int64_t i = *p_args[0]; r_ret = i < 0 ? -1 : (i > 0 ? +1 : 0); } else if (p_args[0]->get_type() == Variant::FLOAT) { - real_t r = *p_args[0]; + double r = *p_args[0]; r_ret = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0); } else { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; @@ -419,7 +418,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Math::randomize(); r_ret = Variant(); } break; - case MATH_RAND: { + case MATH_RANDI: { VALIDATE_ARG_COUNT(0); r_ret = Math::rand(); } break; @@ -427,12 +426,18 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_COUNT(0); r_ret = Math::randf(); } break; - case MATH_RANDOM: { + case MATH_RANDF_RANGE: { VALIDATE_ARG_COUNT(2); VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); r_ret = Math::random((double)*p_args[0], (double)*p_args[1]); } break; + case MATH_RANDI_RANGE: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret = Math::random((int)*p_args[0], (int)*p_args[1]); + } break; case MATH_SEED: { VALIDATE_ARG_COUNT(1); VALIDATE_ARG_NUM(0); @@ -505,8 +510,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); - real_t a = *p_args[0]; - real_t b = *p_args[1]; + double a = *p_args[0]; + double b = *p_args[1]; r_ret = MAX(a, b); } @@ -522,8 +527,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); - real_t a = *p_args[0]; - real_t b = *p_args[1]; + double a = *p_args[0]; + double b = *p_args[1]; r_ret = MIN(a, b); } @@ -540,9 +545,9 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_NUM(1); VALIDATE_ARG_NUM(2); - real_t a = *p_args[0]; - real_t b = *p_args[1]; - real_t c = *p_args[2]; + double a = *p_args[0]; + double b = *p_args[1]; + double c = *p_args[2]; r_ret = CLAMP(a, b, c); } @@ -582,31 +587,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ return; } } break; - case FUNC_FUNCREF: { - VALIDATE_ARG_COUNT(2); - if (p_args[0]->get_type() != Variant::OBJECT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - r_ret = Variant(); - return; - } - if (p_args[1]->get_type() != Variant::STRING && p_args[1]->get_type() != Variant::NODE_PATH) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING; - r_ret = Variant(); - return; - } - - Ref<FuncRef> fr = memnew(FuncRef); - - fr->set_instance(*p_args[0]); - fr->set_function(*p_args[1]); - - r_ret = fr; - - } break; case TYPE_CONVERT: { VALIDATE_ARG_COUNT(2); VALIDATE_ARG_NUM(1); @@ -619,7 +599,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ return; } else { - r_ret = Variant::construct(Variant::Type(type), p_args, 1, r_error); + Variant::construct(Variant::Type(type), r_ret, p_args, 1, r_error); } } break; case TYPE_OF: { @@ -1655,7 +1635,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { mi.return_val.type = Variant::NIL; return mi; } break; - case MATH_RAND: { + case MATH_RANDI: { MethodInfo mi("randi"); mi.return_val.type = Variant::INT; return mi; @@ -1665,11 +1645,16 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { mi.return_val.type = Variant::FLOAT; return mi; } break; - case MATH_RANDOM: { - MethodInfo mi("rand_range", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to")); + case MATH_RANDF_RANGE: { + MethodInfo mi("randf_range", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to")); mi.return_val.type = Variant::FLOAT; return mi; } break; + case MATH_RANDI_RANGE: { + MethodInfo mi("randi_range", PropertyInfo(Variant::INT, "from"), PropertyInfo(Variant::INT, "to")); + mi.return_val.type = Variant::INT; + return mi; + } break; case MATH_SEED: { MethodInfo mi("seed", PropertyInfo(Variant::INT, "seed")); mi.return_val.type = Variant::NIL; @@ -1749,13 +1734,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; - case FUNC_FUNCREF: { - MethodInfo mi("funcref", PropertyInfo(Variant::OBJECT, "instance"), PropertyInfo(Variant::STRING, "funcname")); - mi.return_val.type = Variant::OBJECT; - mi.return_val.class_name = "FuncRef"; - return mi; - - } break; case TYPE_CONVERT: { MethodInfo mi("convert", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::INT, "type")); mi.return_val.type = Variant::NIL; diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h index 2c6dc02913..005b49c5da 100644 --- a/modules/gdscript/gdscript_functions.h +++ b/modules/gdscript/gdscript_functions.h @@ -31,7 +31,7 @@ #ifndef GDSCRIPT_FUNCTIONS_H #define GDSCRIPT_FUNCTIONS_H -#include "core/variant.h" +#include "core/variant/variant.h" class GDScriptFunctions { public: @@ -73,9 +73,10 @@ public: MATH_MOVE_TOWARD, MATH_DECTIME, MATH_RANDOMIZE, - MATH_RAND, + MATH_RANDI, MATH_RANDF, - MATH_RANDOM, + MATH_RANDF_RANGE, + MATH_RANDI_RANGE, MATH_SEED, MATH_RANDSEED, MATH_DEG2RAD, @@ -91,7 +92,6 @@ public: LOGIC_CLAMP, LOGIC_NEAREST_PO2, OBJ_WEAKREF, - FUNC_FUNCREF, TYPE_CONVERT, TYPE_OF, TYPE_EXISTS, diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 2a69db130b..fde3662d66 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -30,15 +30,15 @@ #include "gdscript_parser.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "gdscript.h" #ifdef DEBUG_ENABLED #include "core/os/os.h" -#include "core/string_builder.h" +#include "core/string/string_builder.h" #endif // DEBUG_ENABLED #ifdef TOOLS_ENABLED @@ -65,7 +65,7 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) { builtin_types["Basis"] = Variant::BASIS; builtin_types["Transform"] = Variant::TRANSFORM; builtin_types["Color"] = Variant::COLOR; - builtin_types["RID"] = Variant::_RID; + builtin_types["RID"] = Variant::RID; builtin_types["Object"] = Variant::OBJECT; builtin_types["StringName"] = Variant::STRING_NAME; builtin_types["NodePath"] = Variant::NODE_PATH; @@ -2486,26 +2486,28 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_pre } } - if (!check(GDScriptTokenizer::Token::PARENTHESIS_CLOSE)) { - // Arguments. - push_completion_call(call); - make_completion_context(COMPLETION_CALL_ARGUMENTS, call, 0, true); - int argument_index = 0; - do { - make_completion_context(COMPLETION_CALL_ARGUMENTS, call, argument_index++, true); - if (check(GDScriptTokenizer::Token::PARENTHESIS_CLOSE)) { - // Allow for trailing comma. - break; - } - ExpressionNode *argument = parse_expression(false); - if (argument == nullptr) { - push_error(R"(Expected expression as the function argument.)"); - } else { - call->arguments.push_back(argument); - } - } while (match(GDScriptTokenizer::Token::COMMA)); - pop_completion_call(); + // Arguments. + CompletionType ct = COMPLETION_CALL_ARGUMENTS; + if (get_builtin_function(call->function_name) == GDScriptFunctions::RESOURCE_LOAD) { + ct = COMPLETION_RESOURCE_PATH; } + push_completion_call(call); + int argument_index = 0; + do { + make_completion_context(ct, call, argument_index++, true); + if (check(GDScriptTokenizer::Token::PARENTHESIS_CLOSE)) { + // Allow for trailing comma. + break; + } + ExpressionNode *argument = parse_expression(false); + if (argument == nullptr) { + push_error(R"(Expected expression as the function argument.)"); + } else { + call->arguments.push_back(argument); + } + ct = COMPLETION_CALL_ARGUMENTS; + } while (match(GDScriptTokenizer::Token::COMMA)); + pop_completion_call(); pop_multiline(); consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected closing ")" after call arguments.)*"); @@ -2802,7 +2804,9 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) Callable::CallError error; Vector<Variant> args = varray(string->name); const Variant *name = args.ptr(); - p_annotation->resolved_arguments.push_back(Variant::construct(parameter.type, &(name), 1, error)); + Variant r; + Variant::construct(parameter.type, r, &(name), 1, error); + p_annotation->resolved_arguments.push_back(r); if (error.error != Callable::CallError::CALL_OK) { push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); p_annotation->resolved_arguments.remove(p_annotation->resolved_arguments.size() - 1); @@ -2824,7 +2828,9 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) } Callable::CallError error; const Variant *args = &value; - p_annotation->resolved_arguments.push_back(Variant::construct(parameter.type, &(args), 1, error)); + Variant r; + Variant::construct(parameter.type, r, &(args), 1, error); + p_annotation->resolved_arguments.push_back(r); if (error.error != Callable::CallError::CALL_OK) { push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); p_annotation->resolved_arguments.remove(p_annotation->resolved_arguments.size() - 1); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 4c9473c7bd..b24acc4778 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -31,23 +31,23 @@ #ifndef GDSCRIPT_PARSER_H #define GDSCRIPT_PARSER_H -#include "core/hash_map.h" #include "core/io/multiplayer_api.h" -#include "core/list.h" -#include "core/map.h" -#include "core/reference.h" -#include "core/resource.h" -#include "core/script_language.h" -#include "core/string_name.h" -#include "core/ustring.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/io/resource.h" +#include "core/object/reference.h" +#include "core/object/script_language.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/templates/hash_map.h" +#include "core/templates/list.h" +#include "core/templates/map.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" #include "gdscript_cache.h" #include "gdscript_functions.h" #include "gdscript_tokenizer.h" #ifdef DEBUG_ENABLED -#include "core/string_builder.h" +#include "core/string/string_builder.h" #include "gdscript_warning.h" #endif // DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 9a40aa50ac..b91777ede1 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -30,7 +30,7 @@ #include "gdscript_tokenizer.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 4453982d08..d51f1f250f 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -31,10 +31,10 @@ #ifndef GDSCRIPT_TOKENIZER_H #define GDSCRIPT_TOKENIZER_H -#include "core/list.h" -#include "core/set.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/templates/list.h" +#include "core/templates/set.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" class GDScriptTokenizer { public: diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp index 105facd9d0..56704d3e0a 100644 --- a/modules/gdscript/gdscript_warning.cpp +++ b/modules/gdscript/gdscript_warning.cpp @@ -30,7 +30,7 @@ #include "gdscript_warning.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h index e183d6f302..e0857703d8 100644 --- a/modules/gdscript/gdscript_warning.h +++ b/modules/gdscript/gdscript_warning.h @@ -33,8 +33,8 @@ #ifdef DEBUG_ENABLED -#include "core/ustring.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/vector.h" class GDScriptWarning { public: diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h index 0c031d7883..bb02d3dc99 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.h +++ b/modules/gdscript/language_server/gdscript_extend_parser.h @@ -32,7 +32,7 @@ #define GDSCRIPT_EXTEND_PARSER_H #include "../gdscript_parser.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "lsp.hpp" #ifndef LINE_NUMBER_TO_INDEX diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 2a67d2ff4f..6ddb0d149e 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -30,9 +30,9 @@ #include "gdscript_language_protocol.h" +#include "core/config/project_settings.h" #include "core/io/json.h" #include "core/os/copymem.h" -#include "core/project_settings.h" #include "editor/editor_log.h" #include "editor/editor_node.h" diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h index b2fd0c31f9..2a5755bec6 100644 --- a/modules/gdscript/language_server/gdscript_text_document.h +++ b/modules/gdscript/language_server/gdscript_text_document.h @@ -31,8 +31,8 @@ #ifndef GDSCRIPT_TEXT_DOCUMENT_H #define GDSCRIPT_TEXT_DOCUMENT_H +#include "core/object/reference.h" #include "core/os/file_access.h" -#include "core/reference.h" #include "lsp.hpp" class GDScriptTextDocument : public Reference { diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 776193e37c..f6643d07f9 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -32,8 +32,8 @@ #include "../gdscript.h" #include "../gdscript_parser.h" -#include "core/project_settings.h" -#include "core/script_language.h" +#include "core/config/project_settings.h" +#include "core/object/script_language.h" #include "editor/editor_file_system.h" #include "editor/editor_help.h" #include "editor/editor_node.h" diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index e45b06747d..fc244c6357 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -32,7 +32,7 @@ #define GDSCRIPT_WORKSPACE_H #include "../gdscript_parser.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "editor/editor_file_system.h" #include "gdscript_extend_parser.h" #include "lsp.hpp" diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index cf27a1578c..bf32c1c978 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -31,8 +31,8 @@ #ifndef GODOT_LSP_H #define GODOT_LSP_H -#include "core/class_db.h" -#include "core/list.h" +#include "core/object/class_db.h" +#include "core/templates/list.h" #include "editor/doc_data.h" namespace lsp { diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index da4cbe34c7..065f01e654 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -59,7 +59,7 @@ GDScriptCache *gdscript_cache = nullptr; #include "editor/gdscript_translation_parser_plugin.h" #ifndef GDSCRIPT_NO_LSP -#include "core/engine.h" +#include "core/config/engine.h" #include "language_server/gdscript_language_server.h" #endif // !GDSCRIPT_NO_LSP diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index 931b683a44..50b3783388 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -30,12 +30,12 @@ #include "test_gdscript.h" +#include "core/config/project_settings.h" #include "core/io/file_access_pack.h" #include "core/os/file_access.h" #include "core/os/main_loop.h" #include "core/os/os.h" -#include "core/project_settings.h" -#include "core/string_builder.h" +#include "core/string/string_builder.h" #include "scene/resources/packed_scene.h" #include "modules/gdscript/gdscript_analyzer.h" diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 21fa83278b..633b209f0f 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -31,7 +31,7 @@ #include "grid_map.h" #include "core/io/marshalls.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/3d/light_3d.h" #include "scene/resources/mesh_library.h" #include "scene/resources/surface_tool.h" diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp index 906e506b62..ab384fa942 100644 --- a/modules/gridmap/register_types.cpp +++ b/modules/gridmap/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" #ifndef _3D_DISABLED -#include "core/class_db.h" +#include "core/object/class_db.h" #include "grid_map.h" #include "grid_map_editor_plugin.h" #endif diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index 333b1cf377..af3741bae9 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -31,7 +31,7 @@ #include "image_loader_hdr.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { String header = f->get_token(); diff --git a/modules/icloud/SCsub b/modules/icloud/SCsub new file mode 100644 index 0000000000..805a484600 --- /dev/null +++ b/modules/icloud/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_icloud = env_modules.Clone() + +# (iOS) Enable module support +env_icloud.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_icloud.add_source_files(modules_sources, "*.cpp") +env_icloud.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_icloud_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/icloud/config.py b/modules/icloud/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/icloud/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/modules/icloud/icloud.gdip b/modules/icloud/icloud.gdip new file mode 100644 index 0000000000..9f81be8a34 --- /dev/null +++ b/modules/icloud/icloud.gdip @@ -0,0 +1,17 @@ +[config] +name="iCloud" +binary="icloud_lib.a" + +initialization="register_icloud_types" +deinitialization="unregister_icloud_types" + +[dependencies] +linked=[] +embedded=[] +system=[] + +capabilities=[] + +files=[] + +[plist] diff --git a/platform/iphone/icloud.h b/modules/icloud/icloud.h index 6ca1e6594a..35eede0bf9 100644 --- a/platform/iphone/icloud.h +++ b/modules/icloud/icloud.h @@ -28,12 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef ICLOUD_ENABLED - #ifndef ICLOUD_H #define ICLOUD_H -#include "core/class_db.h" +#include "core/object/class_db.h" class ICloud : public Object { GDCLASS(ICloud, Object); @@ -60,5 +58,3 @@ public: }; #endif - -#endif diff --git a/platform/iphone/icloud.mm b/modules/icloud/icloud.mm index 3d81349883..8a8ddbefe9 100644 --- a/platform/iphone/icloud.mm +++ b/modules/icloud/icloud.mm @@ -28,22 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef ICLOUD_ENABLED - #include "icloud.h" -#ifndef __IPHONE_9_0 -extern "C" { -#endif - -#import "app_delegate.h" +#import "platform/iphone/app_delegate.h" #import <Foundation/Foundation.h> -#ifndef __IPHONE_9_0 -}; -#endif - ICloud *ICloud::instance = NULL; void ICloud::_bind_methods() { @@ -353,5 +343,3 @@ ICloud::ICloud() { } ICloud::~ICloud() {} - -#endif diff --git a/modules/icloud/icloud_module.cpp b/modules/icloud/icloud_module.cpp new file mode 100644 index 0000000000..43fdc7d45e --- /dev/null +++ b/modules/icloud/icloud_module.cpp @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* icloud_module.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "icloud_module.h" + +#include "core/config/engine.h" + +#include "icloud.h" + +ICloud *icloud; + +void register_icloud_types() { + icloud = memnew(ICloud); + Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud)); +} + +void unregister_icloud_types() { + if (icloud) { + memdelete(icloud); + } +} diff --git a/modules/icloud/icloud_module.h b/modules/icloud/icloud_module.h new file mode 100644 index 0000000000..7fd057525e --- /dev/null +++ b/modules/icloud/icloud_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* icloud_module.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +void register_icloud_types(); +void unregister_icloud_types(); diff --git a/modules/inappstore/SCsub b/modules/inappstore/SCsub new file mode 100644 index 0000000000..cee6a256d5 --- /dev/null +++ b/modules/inappstore/SCsub @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_inappstore = env_modules.Clone() + +# (iOS) Enable module support +env_inappstore.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) + +# (iOS) Build as separate static library +modules_sources = [] +env_inappstore.add_source_files(modules_sources, "*.cpp") +env_inappstore.add_source_files(modules_sources, "*.mm") +mod_lib = env_modules.add_library("#bin/libgodot_inappstore_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/inappstore/config.py b/modules/inappstore/config.py new file mode 100644 index 0000000000..e68603fc93 --- /dev/null +++ b/modules/inappstore/config.py @@ -0,0 +1,6 @@ +def can_build(env, platform): + return platform == "iphone" + + +def configure(env): + pass diff --git a/platform/iphone/in_app_store.h b/modules/inappstore/in_app_store.h index 1b8f84ec7b..c8e5d17cec 100644 --- a/platform/iphone/in_app_store.h +++ b/modules/inappstore/in_app_store.h @@ -28,12 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef STOREKIT_ENABLED - #ifndef IN_APP_STORE_H #define IN_APP_STORE_H -#include "core/class_db.h" +#include "core/object/class_db.h" #ifdef __OBJC__ @class GodotProductsDelegate; @@ -77,5 +75,3 @@ public: }; #endif - -#endif diff --git a/platform/iphone/in_app_store.mm b/modules/inappstore/in_app_store.mm index 3eec9dae69..62977318c1 100644 --- a/platform/iphone/in_app_store.mm +++ b/modules/inappstore/in_app_store.mm @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef STOREKIT_ENABLED - #include "in_app_store.h" #import <Foundation/Foundation.h> @@ -411,5 +409,3 @@ InAppStore::~InAppStore() { [[SKPaymentQueue defaultQueue] removeTransactionObserver:transactions_observer]; transactions_observer = nil; } - -#endif diff --git a/modules/inappstore/in_app_store_module.cpp b/modules/inappstore/in_app_store_module.cpp new file mode 100644 index 0000000000..039bdd4f83 --- /dev/null +++ b/modules/inappstore/in_app_store_module.cpp @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* in_app_store_module.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "in_app_store_module.h" + +#include "core/config/engine.h" + +#include "in_app_store.h" + +InAppStore *store_kit; + +void register_inappstore_types() { + store_kit = memnew(InAppStore); + Engine::get_singleton()->add_singleton(Engine::Singleton("InAppStore", store_kit)); +} + +void unregister_inappstore_types() { + if (store_kit) { + memdelete(store_kit); + } +} diff --git a/modules/inappstore/in_app_store_module.h b/modules/inappstore/in_app_store_module.h new file mode 100644 index 0000000000..44673e58bc --- /dev/null +++ b/modules/inappstore/in_app_store_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* in_app_store_module.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +void register_inappstore_types(); +void unregister_inappstore_types(); diff --git a/modules/inappstore/inappstore.gdip b/modules/inappstore/inappstore.gdip new file mode 100644 index 0000000000..7a5efb8ad3 --- /dev/null +++ b/modules/inappstore/inappstore.gdip @@ -0,0 +1,17 @@ +[config] +name="InAppStore" +binary="inappstore_lib.a" + +initialization="register_inappstore_types" +deinitialization="unregister_inappstore_types" + +[dependencies] +linked=[] +embedded=[] +system=["StoreKit.framework"] + +capabilities=[] + +files=[] + +[plist] diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp index 9c7ace5cf2..e5f041c618 100644 --- a/modules/jpg/image_loader_jpegd.cpp +++ b/modules/jpg/image_loader_jpegd.cpp @@ -31,7 +31,7 @@ #include "image_loader_jpegd.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <jpgd.h> #include <string.h> diff --git a/modules/jsonrpc/jsonrpc.h b/modules/jsonrpc/jsonrpc.h index 6f3f8003e0..c2acf84515 100644 --- a/modules/jsonrpc/jsonrpc.h +++ b/modules/jsonrpc/jsonrpc.h @@ -31,8 +31,8 @@ #ifndef GODOT_JSON_RPC_H #define GODOT_JSON_RPC_H -#include "core/class_db.h" -#include "core/variant.h" +#include "core/object/class_db.h" +#include "core/variant/variant.h" class JSONRPC : public Object { GDCLASS(JSONRPC, Object) diff --git a/modules/jsonrpc/register_types.cpp b/modules/jsonrpc/register_types.cpp index 0d3e446e3e..e6affaee41 100644 --- a/modules/jsonrpc/register_types.cpp +++ b/modules/jsonrpc/register_types.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "register_types.h" -#include "core/class_db.h" +#include "core/object/class_db.h" #include "jsonrpc.h" void register_jsonrpc_types() { diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 4de523baa0..1ef991841b 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "lightmapper_rd.h" +#include "core/config/project_settings.h" #include "core/math/geometry_2d.h" -#include "core/project_settings.h" #include "lm_blendseams.glsl.gen.h" #include "lm_compute.glsl.gen.h" #include "lm_raster.glsl.gen.h" diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index cd000414cf..e17b5473a8 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -31,7 +31,7 @@ #ifndef LIGHTMAPPER_RD_H #define LIGHTMAPPER_RD_H -#include "core/local_vector.h" +#include "core/templates/local_vector.h" #include "scene/3d/lightmapper.h" #include "scene/resources/mesh.h" #include "servers/rendering/rendering_device.h" diff --git a/modules/lightmapper_rd/register_types.cpp b/modules/lightmapper_rd/register_types.cpp index 0e6d7590cc..b16adaf5d6 100644 --- a/modules/lightmapper_rd/register_types.cpp +++ b/modules/lightmapper_rd/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "lightmapper_rd.h" #include "scene/3d/lightmapper.h" diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index 12a982df6e..bec792450a 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -32,10 +32,10 @@ #include "core/os/file_access.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "core/io/certs_compressed.gen.h" #include "core/io/compression.h" -#include "core/project_settings.h" #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h index 2a446f9d48..e40ca08643 100644 --- a/modules/mbedtls/crypto_mbedtls.h +++ b/modules/mbedtls/crypto_mbedtls.h @@ -32,7 +32,7 @@ #define CRYPTO_MBEDTLS_H #include "core/crypto/crypto.h" -#include "core/resource.h" +#include "core/io/resource.h" #include <mbedtls/ctr_drbg.h> #include <mbedtls/entropy.h> diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h index baaeb6eb85..96703a7eb7 100644 --- a/modules/mbedtls/ssl_context_mbedtls.h +++ b/modules/mbedtls/ssl_context_mbedtls.h @@ -35,7 +35,7 @@ #include "core/os/file_access.h" -#include "core/reference.h" +#include "core/object/reference.h" #include <mbedtls/config.h> #include <mbedtls/ctr_drbg.h> diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp index d7b2028204..e3119a8da7 100644 --- a/modules/mono/class_db_api_json.cpp +++ b/modules/mono/class_db_api_json.cpp @@ -32,9 +32,9 @@ #ifdef DEBUG_METHODS_ENABLED +#include "core/config/project_settings.h" #include "core/io/json.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "core/version.h" void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { diff --git a/modules/mono/class_db_api_json.h b/modules/mono/class_db_api_json.h index 7f016ac3d6..6b7f5a4d88 100644 --- a/modules/mono/class_db_api_json.h +++ b/modules/mono/class_db_api_json.h @@ -31,13 +31,13 @@ #ifndef CLASS_DB_API_JSON_H #define CLASS_DB_API_JSON_H -// 'core/method_bind.h' defines DEBUG_METHODS_ENABLED, but it looks like we -// cannot include it here. That's why we include it through 'core/class_db.h'. -#include "core/class_db.h" +// 'core/object/method_bind.h' defines DEBUG_METHODS_ENABLED, but it looks like we +// cannot include it here. That's why we include it through 'core/object/class_db.h'. +#include "core/object/class_db.h" #ifdef DEBUG_METHODS_ENABLED -#include "core/ustring.h" +#include "core/string/ustring.h" void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 8928b6e5e3..b4537f531d 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -33,6 +33,7 @@ #include <mono/metadata/threads.h> #include <stdint.h> +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" #include "core/io/json.h" @@ -40,7 +41,6 @@ #include "core/os/mutex.h" #include "core/os/os.h" #include "core/os/thread.h" -#include "core/project_settings.h" #ifdef TOOLS_ENABLED #include "editor/bindings_generator.h" @@ -477,7 +477,7 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::COLOR, Variant::STRING_NAME, Variant::NODE_PATH, - Variant::_RID, + Variant::RID, Variant::CALLABLE }; diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 316fd78f2a..3e4e6c3f86 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -33,8 +33,8 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/script_language.h" -#include "core/self_list.h" +#include "core/object/script_language.h" +#include "core/templates/self_list.h" #include "mono_gc_handle.h" #include "mono_gd/gd_mono.h" diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 4c137a2ba4..ff3122a77f 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -32,13 +32,13 @@ #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) -#include "core/engine.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/core_constants.h" #include "core/io/compression.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/ucaps.h" +#include "core/string/ucaps.h" #include "../glue/cs_glue_version.gen.h" #include "../godotsharp_defs.h" @@ -2426,7 +2426,7 @@ bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant & case Variant::VECTOR2: case Variant::RECT2: case Variant::VECTOR3: - case Variant::_RID: + case Variant::RID: case Variant::ARRAY: case Variant::DICTIONARY: case Variant::PACKED_BYTE_ARRAY: @@ -2979,7 +2979,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = "new %s()"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF; break; - case Variant::_RID: + case Variant::RID: ERR_FAIL_COND_V_MSG(r_iarg.type.cname != name_cache.type_RID, false, "Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value of type '" + String(name_cache.type_RID) + "'."); @@ -3399,7 +3399,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { } void BindingsGenerator::_populate_global_constants() { - int global_constants_count = GlobalConstants::get_global_constant_count(); + int global_constants_count = CoreConstants::get_global_constant_count(); if (global_constants_count > 0) { Map<String, DocData::ClassDoc>::Element *match = EditorHelp::get_doc_data()->class_list.find("@GlobalScope"); @@ -3409,7 +3409,7 @@ void BindingsGenerator::_populate_global_constants() { const DocData::ClassDoc &global_scope_doc = match->value(); for (int i = 0; i < global_constants_count; i++) { - String constant_name = GlobalConstants::get_global_constant_name(i); + String constant_name = CoreConstants::get_global_constant_name(i); const DocData::ConstantDoc *const_doc = nullptr; for (int j = 0; j < global_scope_doc.constants.size(); j++) { @@ -3421,8 +3421,8 @@ void BindingsGenerator::_populate_global_constants() { } } - int constant_value = GlobalConstants::get_global_constant_value(i); - StringName enum_name = GlobalConstants::get_global_constant_enum(i); + int constant_value = CoreConstants::get_global_constant_value(i); + StringName enum_name = CoreConstants::get_global_constant_enum(i); ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), constant_value); iconstant.const_doc = const_doc; diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 90c1c9f3ee..eeab518954 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -31,14 +31,14 @@ #ifndef BINDINGS_GENERATOR_H #define BINDINGS_GENERATOR_H -#include "core/class_db.h" -#include "core/string_builder.h" +#include "core/object/class_db.h" +#include "core/string/string_builder.h" #include "editor/doc_data.h" #include "editor/editor_help.h" #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) -#include "core/ustring.h" +#include "core/string/ustring.h" class BindingsGenerator { struct ConstantInterface { diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index 942c6d26a6..9defd65190 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -30,7 +30,7 @@ #include "code_completion.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "editor/editor_file_system.h" #include "editor/editor_settings.h" #include "scene/gui/control.h" diff --git a/modules/mono/editor/code_completion.h b/modules/mono/editor/code_completion.h index 77673b766f..b9d22de0b3 100644 --- a/modules/mono/editor/code_completion.h +++ b/modules/mono/editor/code_completion.h @@ -31,8 +31,8 @@ #ifndef CODE_COMPLETION_H #define CODE_COMPLETION_H -#include "core/ustring.h" -#include "core/variant.h" +#include "core/string/ustring.h" +#include "core/variant/variant.h" namespace gdmono { diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 2edd8c87dc..4fa753ab8b 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -32,9 +32,9 @@ #include <mono/metadata/image.h> +#include "core/config/project_settings.h" #include "core/io/file_access_pack.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "../mono_gd/gd_mono.h" #include "../mono_gd/gd_mono_assembly.h" diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h index 9ab57755de..bd0f86a74b 100644 --- a/modules/mono/editor/godotsharp_export.h +++ b/modules/mono/editor/godotsharp_export.h @@ -31,9 +31,9 @@ #ifndef GODOTSHARP_EXPORT_H #define GODOTSHARP_EXPORT_H -#include "core/dictionary.h" -#include "core/error_list.h" -#include "core/ustring.h" +#include "core/error/error_list.h" +#include "core/string/ustring.h" +#include "core/variant/dictionary.h" #include "../mono_gd/gd_mono_header.h" diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp index f7d6e7e302..70940c279e 100644 --- a/modules/mono/editor/script_class_parser.cpp +++ b/modules/mono/editor/script_class_parser.cpp @@ -30,8 +30,8 @@ #include "script_class_parser.h" -#include "core/map.h" #include "core/os/os.h" +#include "core/templates/map.h" #include "../utils/string_utils.h" diff --git a/modules/mono/editor/script_class_parser.h b/modules/mono/editor/script_class_parser.h index d611e8fb74..3c55fa07a7 100644 --- a/modules/mono/editor/script_class_parser.h +++ b/modules/mono/editor/script_class_parser.h @@ -31,9 +31,9 @@ #ifndef SCRIPT_CLASS_PARSER_H #define SCRIPT_CLASS_PARSER_H -#include "core/ustring.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" class ScriptClassParser { public: diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs index f77d3052f4..ce613f7ef9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs @@ -81,6 +81,11 @@ namespace Godot.Collections return godot_icall_Array_Resize(GetPtr(), newSize); } + public void Shuffle() + { + godot_icall_Array_Shuffle(GetPtr()); + } + public static Array operator +(Array left, Array right) { return new Array(godot_icall_Array_Concatenate(left.GetPtr(), right.GetPtr())); @@ -220,6 +225,9 @@ namespace Godot.Collections internal extern static Error godot_icall_Array_Resize(IntPtr ptr, int newSize); [MethodImpl(MethodImplOptions.InternalCall)] + internal extern static Error godot_icall_Array_Shuffle(IntPtr ptr); + + [MethodImpl(MethodImplOptions.InternalCall)] internal extern static void godot_icall_Array_Generic_GetElementTypeInfo(Type elemType, out int elemTypeEncoding, out IntPtr elemTypeClass); [MethodImpl(MethodImplOptions.InternalCall)] @@ -295,6 +303,11 @@ namespace Godot.Collections return objectArray.Resize(newSize); } + public void Shuffle() + { + objectArray.Shuffle(); + } + public static Array<T> operator +(Array<T> left, Array<T> right) { return new Array<T>(left.objectArray + right.objectArray); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 3700a6194f..d0add835c0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -257,20 +257,6 @@ namespace Godot } /// <summary> - /// Returns the most contrasting color. - /// </summary> - /// <returns>The most contrasting color</returns> - public Color Contrasted() - { - return new Color( - (r + 0.5f) % 1.0f, - (g + 0.5f) % 1.0f, - (b + 0.5f) % 1.0f, - a - ); - } - - /// <summary> /// Returns a new color resulting from making this color darker /// by the specified ratio (on the range of 0 to 1). /// </summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index e050d1fdd1..6699c5992c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -39,14 +39,6 @@ namespace Godot return val * sgn; } - public static FuncRef FuncRef(Object instance, StringName funcName) - { - var ret = new FuncRef(); - ret.SetInstance(instance); - ret.SetFunction(funcName); - return ret; - } - public static int Hash(object var) { return godot_icall_GD_hash(var); @@ -129,7 +121,12 @@ namespace Godot public static double RandRange(double from, double to) { - return godot_icall_GD_rand_range(from, to); + return godot_icall_GD_randf_range(from, to); + } + + public static int RandRange(int from, int to) + { + return godot_icall_GD_randi_range(from, to); } public static uint RandSeed(ulong seed, out ulong newSeed) @@ -238,9 +235,11 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static void godot_icall_GD_randomize(); + [MethodImpl(MethodImplOptions.InternalCall)] + internal extern static double godot_icall_GD_randf_range(double from, double to); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static double godot_icall_GD_rand_range(double from, double to); + internal extern static int godot_icall_GD_randi_range(int from, int to); [MethodImpl(MethodImplOptions.InternalCall)] internal extern static uint godot_icall_GD_rand_seed(ulong seed, out ulong newSeed); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index 06bbe98497..bc0f81b2a7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -221,8 +221,7 @@ namespace Godot real_t dot = v1.Dot(v2); - // Clamp dot to [-1, 1] - dot = dot < -1.0f ? -1.0f : (dot > 1.0f ? 1.0f : dot); + dot = Mathf.Clamp(dot, -1.0f, 1.0f); Vector2 v; diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 439fb1ab0a..544f414cba 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -30,9 +30,9 @@ #ifdef MONO_GLUE_ENABLED -#include "core/class_db.h" -#include "core/reference.h" -#include "core/string_name.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" +#include "core/string/string_name.h" #include "../csharp_script.h" #include "../mono_gd/gd_mono_cache.h" diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp index 3313e8cb77..bb3ea0f730 100644 --- a/modules/mono/glue/collections_glue.cpp +++ b/modules/mono/glue/collections_glue.cpp @@ -32,7 +32,7 @@ #include <mono/metadata/exception.h> -#include "core/array.h" +#include "core/variant/array.h" #include "../mono_gd/gd_mono_cache.h" #include "../mono_gd/gd_mono_class.h" @@ -162,6 +162,10 @@ Error godot_icall_Array_Resize(Array *ptr, int new_size) { return ptr->resize(new_size); } +void godot_icall_Array_Shuffle(Array *ptr) { + ptr->shuffle(); +} + void godot_icall_Array_Generic_GetElementTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class) { MonoType *elem_type = mono_reflection_type_get_type(refltype); @@ -322,6 +326,7 @@ void godot_register_collections_icalls() { mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove); mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", (void *)godot_icall_Array_RemoveAt); mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Resize", (void *)godot_icall_Array_Resize); + mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Shuffle", (void *)godot_icall_Array_Shuffle); mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Generic_GetElementTypeInfo", (void *)godot_icall_Array_Generic_GetElementTypeInfo); mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_ToString", (void *)godot_icall_Array_ToString); diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp index 5e892b616b..58d8dceb25 100644 --- a/modules/mono/glue/gd_glue.cpp +++ b/modules/mono/glue/gd_glue.cpp @@ -30,12 +30,12 @@ #ifdef MONO_GLUE_ENABLED -#include "core/array.h" #include "core/io/marshalls.h" #include "core/os/os.h" -#include "core/ustring.h" -#include "core/variant.h" -#include "core/variant_parser.h" +#include "core/string/ustring.h" +#include "core/variant/array.h" +#include "core/variant/variant.h" +#include "core/variant/variant_parser.h" #include "../mono_gd/gd_mono_cache.h" #include "../mono_gd/gd_mono_marshal.h" @@ -55,7 +55,8 @@ MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type) { Variant what = GDMonoMarshal::mono_object_to_variant(p_what); const Variant *args[1] = { &what }; Callable::CallError ce; - Variant ret = Variant::construct(Variant::Type(p_type), args, 1, ce); + Variant ret; + Variant::construct(Variant::Type(p_type), ret, args, 1, ce); ERR_FAIL_COND_V(ce.error != Callable::CallError::CALL_OK, nullptr); return GDMonoMarshal::variant_to_mono_object(ret); } @@ -193,7 +194,11 @@ void godot_icall_GD_randomize() { Math::randomize(); } -double godot_icall_GD_rand_range(double from, double to) { +double godot_icall_GD_randf_range(double from, double to) { + return Math::random(from, to); +} + +int32_t godot_icall_GD_randi_range(int32_t from, int32_t to) { return Math::random(from, to); } @@ -298,7 +303,8 @@ void godot_register_gd_icalls() { mono_add_internal_call("Godot.GD::godot_icall_GD_randf", (void *)godot_icall_GD_randf); mono_add_internal_call("Godot.GD::godot_icall_GD_randi", (void *)godot_icall_GD_randi); mono_add_internal_call("Godot.GD::godot_icall_GD_randomize", (void *)godot_icall_GD_randomize); - mono_add_internal_call("Godot.GD::godot_icall_GD_rand_range", (void *)godot_icall_GD_rand_range); + mono_add_internal_call("Godot.GD::godot_icall_GD_randf_range", (void *)godot_icall_GD_randf_range); + mono_add_internal_call("Godot.GD::godot_icall_GD_randi_range", (void *)godot_icall_GD_randi_range); mono_add_internal_call("Godot.GD::godot_icall_GD_rand_seed", (void *)godot_icall_GD_rand_seed); mono_add_internal_call("Godot.GD::godot_icall_GD_seed", (void *)godot_icall_GD_seed); mono_add_internal_call("Godot.GD::godot_icall_GD_str", (void *)godot_icall_GD_str); diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h index dc3bf47838..f4263e286e 100644 --- a/modules/mono/glue/glue_header.h +++ b/modules/mono/glue/glue_header.h @@ -58,15 +58,15 @@ void godot_register_glue_header_icalls() { // Used by the generated glue -#include "core/array.h" -#include "core/class_db.h" -#include "core/dictionary.h" -#include "core/engine.h" -#include "core/method_bind.h" -#include "core/node_path.h" -#include "core/reference.h" +#include "core/config/engine.h" +#include "core/object/class_db.h" +#include "core/object/method_bind.h" +#include "core/object/reference.h" +#include "core/string/node_path.h" +#include "core/string/ustring.h" #include "core/typedefs.h" -#include "core/ustring.h" +#include "core/variant/array.h" +#include "core/variant/dictionary.h" #include "../mono_gd/gd_mono_class.h" #include "../mono_gd/gd_mono_internals.h" diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp index 2aa75dd309..09c6d8f482 100644 --- a/modules/mono/glue/nodepath_glue.cpp +++ b/modules/mono/glue/nodepath_glue.cpp @@ -30,8 +30,8 @@ #ifdef MONO_GLUE_ENABLED -#include "core/node_path.h" -#include "core/ustring.h" +#include "core/string/node_path.h" +#include "core/string/ustring.h" #include "../mono_gd/gd_mono_marshal.h" diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp index a7b18c36dd..cb4f26511f 100644 --- a/modules/mono/glue/rid_glue.cpp +++ b/modules/mono/glue/rid_glue.cpp @@ -30,9 +30,9 @@ #ifdef MONO_GLUE_ENABLED -#include "core/class_db.h" -#include "core/resource.h" -#include "core/rid.h" +#include "core/io/resource.h" +#include "core/object/class_db.h" +#include "core/templates/rid.h" #include "../mono_gd/gd_mono_marshal.h" diff --git a/modules/mono/glue/scene_tree_glue.cpp b/modules/mono/glue/scene_tree_glue.cpp index b43daccc1b..53d6c1436d 100644 --- a/modules/mono/glue/scene_tree_glue.cpp +++ b/modules/mono/glue/scene_tree_glue.cpp @@ -30,9 +30,9 @@ #ifdef MONO_GLUE_ENABLED -#include "core/array.h" -#include "core/class_db.h" -#include "core/string_name.h" +#include "core/object/class_db.h" +#include "core/string/string_name.h" +#include "core/variant/array.h" #include "scene/main/node.h" #include "scene/main/scene_tree.h" diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp index 595b8d71f1..9271731573 100644 --- a/modules/mono/glue/string_glue.cpp +++ b/modules/mono/glue/string_glue.cpp @@ -30,9 +30,9 @@ #ifdef MONO_GLUE_ENABLED -#include "core/ustring.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" #include "../mono_gd/gd_mono_marshal.h" diff --git a/modules/mono/glue/string_name_glue.cpp b/modules/mono/glue/string_name_glue.cpp index 4b2e88569b..9323e3bbb3 100644 --- a/modules/mono/glue/string_name_glue.cpp +++ b/modules/mono/glue/string_name_glue.cpp @@ -30,8 +30,8 @@ #ifdef MONO_GLUE_ENABLED -#include "core/string_name.h" -#include "core/ustring.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" #include "../mono_gd/gd_mono_marshal.h" diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index df31823deb..4233732bff 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -30,9 +30,9 @@ #include "godotsharp_dirs.h" +#include "core/config/project_settings.h" #include "core/os/dir_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #ifdef TOOLS_ENABLED #include "core/version.h" diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h index 2ab4b0e309..6391616419 100644 --- a/modules/mono/godotsharp_dirs.h +++ b/modules/mono/godotsharp_dirs.h @@ -31,7 +31,7 @@ #ifndef GODOTSHARP_DIRS_H #define GODOTSHARP_DIRS_H -#include "core/ustring.h" +#include "core/string/ustring.h" namespace GodotSharpDirs { diff --git a/modules/mono/managed_callable.h b/modules/mono/managed_callable.h index 4f71e14a2f..bde1b41781 100644 --- a/modules/mono/managed_callable.h +++ b/modules/mono/managed_callable.h @@ -33,9 +33,9 @@ #include <mono/metadata/object.h> -#include "core/callable.h" #include "core/os/mutex.h" -#include "core/self_list.h" +#include "core/templates/self_list.h" +#include "core/variant/callable.h" #include "mono_gc_handle.h" #include "mono_gd/gd_mono_method.h" diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h index 13cfad4654..5c3a210e97 100644 --- a/modules/mono/mono_gc_handle.h +++ b/modules/mono/mono_gc_handle.h @@ -33,7 +33,7 @@ #include <mono/jit/jit.h> -#include "core/reference.h" +#include "core/object/reference.h" namespace gdmono { diff --git a/modules/mono/mono_gd/android_mono_config.h b/modules/mono/mono_gd/android_mono_config.h index 93f708bba0..9e304939b2 100644 --- a/modules/mono/mono_gd/android_mono_config.h +++ b/modules/mono/mono_gd/android_mono_config.h @@ -33,7 +33,7 @@ #ifdef ANDROID_ENABLED -#include "core/ustring.h" +#include "core/string/ustring.h" // This function is defined in an auto-generated source file String get_godot_android_mono_config(); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index cf5ac33d20..0e335b3349 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -37,12 +37,12 @@ #include <mono/metadata/mono-gc.h> #include <mono/metadata/profiler.h> +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" #include "core/os/thread.h" -#include "core/project_settings.h" #include "../csharp_script.h" #include "../godotsharp_dirs.h" diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 6e351001d4..33628b3ce3 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -33,11 +33,11 @@ #include <mono/metadata/mono-debug.h> #include <mono/metadata/tokentype.h> +#include "core/config/project_settings.h" #include "core/io/file_access_pack.h" -#include "core/list.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" +#include "core/templates/list.h" #include "../godotsharp_dirs.h" #include "gd_mono_cache.h" diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 63899dc9be..fc10480e07 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -34,9 +34,9 @@ #include <mono/jit/jit.h> #include <mono/metadata/assembly.h> -#include "core/hash_map.h" -#include "core/map.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/hash_map.h" +#include "core/templates/map.h" #include "gd_mono_utils.h" class GDMonoAssembly { diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index 44b146b87c..87db2fa033 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -31,8 +31,8 @@ #ifndef GD_MONO_CLASS_H #define GD_MONO_CLASS_H -#include "core/map.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/map.h" #include "gd_mono_field.h" #include "gd_mono_header.h" diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 563c45e71f..00a1e1e507 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -355,7 +355,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ } if (CACHED_CLASS(RID) == type_class) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID()); + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator ::RID()); mono_field_set_value(p_object, mono_field, managed); break; } @@ -450,8 +450,8 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath()); mono_field_set_value(p_object, mono_field, managed); } break; - case Variant::_RID: { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID()); + case Variant::RID: { + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator ::RID()); mono_field_set_value(p_object, mono_field, managed); } break; case Variant::OBJECT: { diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h index 0f4f888546..ffb56e7cec 100644 --- a/modules/mono/mono_gd/gd_mono_header.h +++ b/modules/mono/mono_gd/gd_mono_header.h @@ -31,7 +31,7 @@ #ifndef GD_MONO_HEADER_H #define GD_MONO_HEADER_H -#include "core/int_types.h" +#include <cstdint> #ifdef WIN32 #define GD_MONO_STDCALL __stdcall diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h index cf7efdecd6..d1d5eca263 100644 --- a/modules/mono/mono_gd/gd_mono_internals.h +++ b/modules/mono/mono_gd/gd_mono_internals.h @@ -35,7 +35,7 @@ #include "../utils/macros.h" -#include "core/class_db.h" +#include "core/object/class_db.h" namespace GDMonoInternals { diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index c460e283ea..9d193ab8ab 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -204,7 +204,7 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ } if (CACHED_CLASS(RID) == type_class) { - return Variant::_RID; + return Variant::RID; } if (CACHED_CLASS(Dictionary) == type_class) { @@ -580,7 +580,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty } if (CACHED_CLASS(RID) == type_class) { - return GDMonoUtils::create_managed_from(p_var->operator RID()); + return GDMonoUtils::create_managed_from(p_var->operator ::RID()); } // Godot.Collections.Dictionary or IDictionary @@ -673,8 +673,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return GDMonoUtils::create_managed_from(p_var->operator StringName()); case Variant::NODE_PATH: return GDMonoUtils::create_managed_from(p_var->operator NodePath()); - case Variant::_RID: - return GDMonoUtils::create_managed_from(p_var->operator RID()); + case Variant::RID: + return GDMonoUtils::create_managed_from(p_var->operator ::RID()); case Variant::OBJECT: return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); case Variant::CALLABLE: { diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index a1fd975916..d2c564d67d 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -31,7 +31,7 @@ #ifndef GDMONOMARSHAL_H #define GDMONOMARSHAL_H -#include "core/variant.h" +#include "core/variant/variant.h" #include "../managed_callable.h" #include "gd_mono.h" diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 3f1155f430..2676165cbc 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -35,10 +35,10 @@ #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" +#include "core/object/reference.h" #include "core/os/dir_access.h" #include "core/os/mutex.h" #include "core/os/os.h" -#include "core/reference.h" #ifdef TOOLS_ENABLED #include "editor/debugger/editor_debugger_node.h" diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 80569cb1c7..7088385c4f 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -37,8 +37,8 @@ #include "../utils/macros.h" #include "gd_mono_header.h" -#include "core/class_db.h" -#include "core/reference.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" #define UNHANDLED_EXCEPTION(m_exc) \ if (unlikely(m_exc != nullptr)) { \ diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp index 8bcdeec9dd..386e0576b3 100644 --- a/modules/mono/mono_gd/support/android_support.cpp +++ b/modules/mono/mono_gd/support/android_support.cpp @@ -44,7 +44,7 @@ #endif #include "core/os/os.h" -#include "core/ustring.h" +#include "core/string/ustring.h" #include "platform/android/java_godot_wrapper.h" #include "platform/android/os_android.h" #include "platform/android/thread_jandroid.h" diff --git a/modules/mono/mono_gd/support/android_support.h b/modules/mono/mono_gd/support/android_support.h index dc2e6c95ed..5947395a99 100755 --- a/modules/mono/mono_gd/support/android_support.h +++ b/modules/mono/mono_gd/support/android_support.h @@ -33,7 +33,7 @@ #if defined(ANDROID_ENABLED) -#include "core/ustring.h" +#include "core/string/ustring.h" namespace gdmono { namespace android { diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h index e28af120e3..ed251cb23a 100755 --- a/modules/mono/mono_gd/support/ios_support.h +++ b/modules/mono/mono_gd/support/ios_support.h @@ -33,7 +33,7 @@ #if defined(IPHONE_ENABLED) -#include "core/ustring.h" +#include "core/string/ustring.h" namespace gdmono { namespace ios { diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp index 98c3ba1324..f5c1bda18b 100644 --- a/modules/mono/register_types.cpp +++ b/modules/mono/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "csharp_script.h" diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h index c550315a23..18d1e43e14 100644 --- a/modules/mono/signal_awaiter_utils.h +++ b/modules/mono/signal_awaiter_utils.h @@ -31,7 +31,7 @@ #ifndef SIGNAL_AWAITER_UTILS_H #define SIGNAL_AWAITER_UTILS_H -#include "core/reference.h" +#include "core/object/reference.h" #include "csharp_script.h" #include "mono_gc_handle.h" diff --git a/modules/mono/utils/mono_reg_utils.h b/modules/mono/utils/mono_reg_utils.h index 4ef876f2b6..cc3f1cb035 100644 --- a/modules/mono/utils/mono_reg_utils.h +++ b/modules/mono/utils/mono_reg_utils.h @@ -33,7 +33,7 @@ #ifdef WINDOWS_ENABLED -#include "core/ustring.h" +#include "core/string/ustring.h" struct MonoRegInfo { String version; diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp index e68466b1cf..41be198bcf 100644 --- a/modules/mono/utils/osx_utils.cpp +++ b/modules/mono/utils/osx_utils.cpp @@ -32,7 +32,7 @@ #ifdef OSX_ENABLED -#include "core/print_string.h" +#include "core/string/print_string.h" #include <CoreFoundation/CoreFoundation.h> #include <CoreServices/CoreServices.h> diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/osx_utils.h index 55002702f8..92faead0fb 100644 --- a/modules/mono/utils/osx_utils.h +++ b/modules/mono/utils/osx_utils.h @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/ustring.h" +#include "core/string/ustring.h" #ifndef OSX_UTILS_H #define OSX_UTILS_H diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp index 5d1abd0c09..eb0ba8c700 100644 --- a/modules/mono/utils/path_utils.cpp +++ b/modules/mono/utils/path_utils.cpp @@ -30,10 +30,10 @@ #include "path_utils.h" +#include "core/config/project_settings.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #ifdef WINDOWS_ENABLED #include <windows.h> diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h index bcd8af8bb9..458d1bb849 100644 --- a/modules/mono/utils/path_utils.h +++ b/modules/mono/utils/path_utils.h @@ -31,8 +31,8 @@ #ifndef PATH_UTILS_H #define PATH_UTILS_H -#include "core/string_builder.h" -#include "core/ustring.h" +#include "core/string/string_builder.h" +#include "core/string/ustring.h" namespace path { diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h index 0318fec592..99f3548f31 100644 --- a/modules/mono/utils/string_utils.h +++ b/modules/mono/utils/string_utils.h @@ -31,8 +31,8 @@ #ifndef STRING_FORMAT_H #define STRING_FORMAT_H -#include "core/ustring.h" -#include "core/variant.h" +#include "core/string/ustring.h" +#include "core/variant/variant.h" #include <stdarg.h> diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h index 7357e54e35..73960ba85f 100644 --- a/modules/opensimplex/noise_texture.h +++ b/modules/opensimplex/noise_texture.h @@ -33,8 +33,8 @@ #include "open_simplex_noise.h" -#include "core/image.h" -#include "core/reference.h" +#include "core/io/image.h" +#include "core/object/reference.h" #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "editor/property_editor.h" diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h index dce62bc1f9..835f8ed35e 100644 --- a/modules/opensimplex/open_simplex_noise.h +++ b/modules/opensimplex/open_simplex_noise.h @@ -31,8 +31,8 @@ #ifndef OPEN_SIMPLEX_NOISE_H #define OPEN_SIMPLEX_NOISE_H -#include "core/image.h" -#include "core/reference.h" +#include "core/io/image.h" +#include "core/object/reference.h" #include "scene/resources/texture.h" #include "thirdparty/misc/open-simplex-noise.h" diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 52b49c783e..8cf19e1ca6 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -31,12 +31,12 @@ #ifndef REGEX_H #define REGEX_H -#include "core/array.h" -#include "core/dictionary.h" -#include "core/map.h" -#include "core/reference.h" -#include "core/ustring.h" -#include "core/vector.h" +#include "core/object/reference.h" +#include "core/string/ustring.h" +#include "core/templates/map.h" +#include "core/templates/vector.h" +#include "core/variant/array.h" +#include "core/variant/dictionary.h" class RegExMatch : public Reference { GDCLASS(RegExMatch, Reference); diff --git a/modules/regex/register_types.cpp b/modules/regex/register_types.cpp index 5d4aeba2d7..d470fcdaeb 100644 --- a/modules/regex/register_types.cpp +++ b/modules/regex/register_types.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "register_types.h" -#include "core/class_db.h" +#include "core/object/class_db.h" #include "regex.h" void register_regex_types() { diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h index 19e6d57474..11b9e1c833 100644 --- a/modules/squish/image_compress_squish.h +++ b/modules/squish/image_compress_squish.h @@ -31,7 +31,7 @@ #ifndef IMAGE_COMPRESS_SQUISH_H #define IMAGE_COMPRESS_SQUISH_H -#include "core/image.h" +#include "core/io/image.h" void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels); void image_decompress_squish(Image *p_image); diff --git a/modules/stb_vorbis/register_types.cpp b/modules/stb_vorbis/register_types.cpp index 6669d30278..13c26fc8cc 100644 --- a/modules/stb_vorbis/register_types.cpp +++ b/modules/stb_vorbis/register_types.cpp @@ -33,7 +33,7 @@ #include "audio_stream_ogg_vorbis.h" #ifdef TOOLS_ENABLED -#include "core/engine.h" +#include "core/config/engine.h" #include "resource_importer_ogg_vorbis.h" #endif diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h index ecaba5052b..8e478a40ce 100644 --- a/modules/svg/image_loader_svg.h +++ b/modules/svg/image_loader_svg.h @@ -32,7 +32,7 @@ #define IMAGE_LOADER_SVG_H #include "core/io/image_loader.h" -#include "core/ustring.h" +#include "core/string/ustring.h" /** @author Daniel Ramirez <djrmuv@gmail.com> diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 1475d24792..aa8b3122f4 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -30,10 +30,10 @@ #include "image_loader_tga.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/io/file_access_memory.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size) { Error error; @@ -313,9 +313,9 @@ void ImageLoaderTGA::get_recognized_extensions(List<String> *p_extensions) const p_extensions->push_back("tga"); } -static Ref<Image> _tga_mem_loader_func(const uint8_t *p_png, int p_size) { +static Ref<Image> _tga_mem_loader_func(const uint8_t *p_tga, int p_size) { FileAccessMemory memfile; - Error open_memfile_error = memfile.open_custom(p_png, p_size); + Error open_memfile_error = memfile.open_custom(p_tga, p_size); ERR_FAIL_COND_V_MSG(open_memfile_error, Ref<Image>(), "Could not create memfile for TGA image buffer."); Ref<Image> img; img.instance(); diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 498391e44a..4f33f58ed1 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -30,8 +30,8 @@ #include "video_stream_theora.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "thirdparty/misc/yuv2rgb.h" diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index 84f816acf8..867f464038 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -35,7 +35,7 @@ #include "core/os/file_access.h" #include "core/os/semaphore.h" #include "core/os/thread.h" -#include "core/ring_buffer.h" +#include "core/templates/ring_buffer.h" #include "scene/resources/video_stream.h" #include "servers/audio_server.h" diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index 5bdcb84244..75dc16c39a 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -31,7 +31,7 @@ #include "image_loader_tinyexr.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "thirdparty/tinyexr/tinyexr.h" diff --git a/modules/upnp/register_types.cpp b/modules/upnp/register_types.cpp index 34900206de..e66bc9d11a 100644 --- a/modules/upnp/register_types.cpp +++ b/modules/upnp/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "upnp.h" #include "upnp_device.h" diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h index 1c4b5549f4..e87f93e697 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -31,7 +31,7 @@ #ifndef GODOT_UPNP_H #define GODOT_UPNP_H -#include "core/reference.h" +#include "core/object/reference.h" #include "upnp_device.h" diff --git a/modules/upnp/upnp_device.h b/modules/upnp/upnp_device.h index 4b519fce32..a287c99b0d 100644 --- a/modules/upnp/upnp_device.h +++ b/modules/upnp/upnp_device.h @@ -31,7 +31,7 @@ #ifndef GODOT_UPNP_DEVICE_H #define GODOT_UPNP_DEVICE_H -#include "core/reference.h" +#include "core/object/reference.h" class UPNPDevice : public Reference { GDCLASS(UPNPDevice, Reference); diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml index ef4183e6f6..000fbd0140 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -111,61 +111,61 @@ <constant name="MATH_RANDOMIZE" value="31" enum="BuiltinFunc"> Randomize the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time. </constant> - <constant name="MATH_RAND" value="32" enum="BuiltinFunc"> + <constant name="MATH_RANDI" value="32" enum="BuiltinFunc"> Return a random 32 bits integer value. To obtain a random value between 0 to N (where N is smaller than 2^32 - 1), you can use it with the remainder function. </constant> <constant name="MATH_RANDF" value="33" enum="BuiltinFunc"> Return a random floating-point value between 0 and 1. To obtain a random value between 0 to N, you can use it with multiplication. </constant> - <constant name="MATH_RANDOM" value="34" enum="BuiltinFunc"> + <constant name="MATH_RANDF_RANGE" value="34" enum="BuiltinFunc"> Return a random floating-point value between the two inputs. </constant> - <constant name="MATH_SEED" value="35" enum="BuiltinFunc"> + <constant name="MATH_RANDI_RANGE" value="35" enum="BuiltinFunc"> + Return a random 32-bit integer value between the two inputs. + </constant> + <constant name="MATH_SEED" value="36" enum="BuiltinFunc"> Set the seed for the random number generator. </constant> - <constant name="MATH_RANDSEED" value="36" enum="BuiltinFunc"> + <constant name="MATH_RANDSEED" value="37" enum="BuiltinFunc"> Return a random value from the given seed, along with the new seed. </constant> - <constant name="MATH_DEG2RAD" value="37" enum="BuiltinFunc"> + <constant name="MATH_DEG2RAD" value="38" enum="BuiltinFunc"> Convert the input from degrees to radians. </constant> - <constant name="MATH_RAD2DEG" value="38" enum="BuiltinFunc"> + <constant name="MATH_RAD2DEG" value="39" enum="BuiltinFunc"> Convert the input from radians to degrees. </constant> - <constant name="MATH_LINEAR2DB" value="39" enum="BuiltinFunc"> + <constant name="MATH_LINEAR2DB" value="40" enum="BuiltinFunc"> Convert the input from linear volume to decibel volume. </constant> - <constant name="MATH_DB2LINEAR" value="40" enum="BuiltinFunc"> + <constant name="MATH_DB2LINEAR" value="41" enum="BuiltinFunc"> Convert the input from decibel volume to linear volume. </constant> - <constant name="MATH_POLAR2CARTESIAN" value="41" enum="BuiltinFunc"> + <constant name="MATH_POLAR2CARTESIAN" value="42" enum="BuiltinFunc"> Converts a 2D point expressed in the polar coordinate system (a distance from the origin [code]r[/code] and an angle [code]th[/code]) to the cartesian coordinate system (X and Y axis). </constant> - <constant name="MATH_CARTESIAN2POLAR" value="42" enum="BuiltinFunc"> + <constant name="MATH_CARTESIAN2POLAR" value="43" enum="BuiltinFunc"> Converts a 2D point expressed in the cartesian coordinate system (X and Y axis) to the polar coordinate system (a distance from the origin and an angle). </constant> - <constant name="MATH_WRAP" value="43" enum="BuiltinFunc"> + <constant name="MATH_WRAP" value="44" enum="BuiltinFunc"> </constant> - <constant name="MATH_WRAPF" value="44" enum="BuiltinFunc"> + <constant name="MATH_WRAPF" value="45" enum="BuiltinFunc"> </constant> - <constant name="LOGIC_MAX" value="45" enum="BuiltinFunc"> + <constant name="LOGIC_MAX" value="46" enum="BuiltinFunc"> Return the greater of the two numbers, also known as their maximum. </constant> - <constant name="LOGIC_MIN" value="46" enum="BuiltinFunc"> + <constant name="LOGIC_MIN" value="47" enum="BuiltinFunc"> Return the lesser of the two numbers, also known as their minimum. </constant> - <constant name="LOGIC_CLAMP" value="47" enum="BuiltinFunc"> + <constant name="LOGIC_CLAMP" value="48" enum="BuiltinFunc"> Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code]. </constant> - <constant name="LOGIC_NEAREST_PO2" value="48" enum="BuiltinFunc"> + <constant name="LOGIC_NEAREST_PO2" value="49" enum="BuiltinFunc"> Return the nearest power of 2 to the input. </constant> - <constant name="OBJ_WEAKREF" value="49" enum="BuiltinFunc"> + <constant name="OBJ_WEAKREF" value="50" enum="BuiltinFunc"> Create a [WeakRef] from the input. </constant> - <constant name="FUNC_FUNCREF" value="50" enum="BuiltinFunc"> - Create a [FuncRef] from the input. - </constant> <constant name="TYPE_CONVERT" value="51" enum="BuiltinFunc"> Convert between types. </constant> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml index f13d449064..1c22070ab1 100644 --- a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml +++ b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml @@ -31,5 +31,7 @@ </constant> <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> </constant> + <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> + </constant> </constants> </class> diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index 8afed1229f..0172f29923 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/io/resource_loader.h" #include "visual_script.h" #include "visual_script_builtin_funcs.h" diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 1af4b46e22..1c7d5472cb 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -30,9 +30,9 @@ #include "visual_script.h" +#include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/main/node.h" #include "visual_script_nodes.h" @@ -84,10 +84,10 @@ void VisualScriptNode::validate_input_default_values() { Callable::CallError ce; Variant existing = default_input_values[i]; const Variant *existingp = &existing; - default_input_values[i] = Variant::construct(expected, &existingp, 1, ce, false); + Variant::construct(expected, default_input_values[i], &existingp, 1, ce); if (ce.error != Callable::CallError::CALL_OK) { //could not convert? force.. - default_input_values[i] = Variant::construct(expected, nullptr, 0, ce, false); + Variant::construct(expected, default_input_values[i], nullptr, 0, ce); } } } diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index cb5ed37ba1..85dab4e6cf 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -33,8 +33,8 @@ #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" +#include "core/object/script_language.h" #include "core/os/thread.h" -#include "core/script_language.h" class VisualScriptInstance; class VisualScriptNodeInstance; diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 177f9192b8..a27307aec2 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -30,13 +30,12 @@ #include "visual_script_builtin_funcs.h" -#include "core/class_db.h" -#include "core/func_ref.h" #include "core/io/marshalls.h" #include "core/math/math_funcs.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" #include "core/os/os.h" -#include "core/reference.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX] = { "sin", @@ -73,7 +72,8 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX "randomize", "randi", "randf", - "rand_range", + "randf_range", + "randi_range", "seed", "rand_seed", "deg2rad", @@ -89,7 +89,6 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX "clamp", "nearest_po2", "weakref", - "funcref", "convert", "typeof", "type_exists", @@ -143,7 +142,7 @@ bool VisualScriptBuiltinFunc::has_input_sequence_port() const { int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { switch (p_func) { case MATH_RANDOMIZE: - case MATH_RAND: + case MATH_RANDI: case MATH_RANDF: return 0; case MATH_SIN: @@ -194,12 +193,12 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { case MATH_POW: case MATH_EASE: case MATH_STEPIFY: - case MATH_RANDOM: + case MATH_RANDF_RANGE: + case MATH_RANDI_RANGE: case MATH_POLAR2CARTESIAN: case MATH_CARTESIAN2POLAR: case LOGIC_MAX: case LOGIC_MIN: - case FUNC_FUNCREF: case TYPE_CONVERT: case COLORN: return 2; @@ -361,16 +360,23 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const } } break; case MATH_RANDOMIZE: - case MATH_RAND: + case MATH_RANDI: case MATH_RANDF: { } break; - case MATH_RANDOM: { + case MATH_RANDF_RANGE: { if (p_idx == 0) { return PropertyInfo(Variant::FLOAT, "from"); } else { return PropertyInfo(Variant::FLOAT, "to"); } } break; + case MATH_RANDI_RANGE: { + if (p_idx == 0) { + return PropertyInfo(Variant::INT, "from"); + } else { + return PropertyInfo(Variant::INT, "to"); + } + } break; case MATH_SEED: case MATH_RANDSEED: { return PropertyInfo(Variant::INT, "seed"); @@ -426,13 +432,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const case OBJ_WEAKREF: { return PropertyInfo(Variant::OBJECT, "source"); } break; - case FUNC_FUNCREF: { - if (p_idx == 0) { - return PropertyInfo(Variant::OBJECT, "instance"); - } else { - return PropertyInfo(Variant::STRING, "funcname"); - } - } break; case TYPE_CONVERT: { if (p_idx == 0) { return PropertyInfo(Variant::NIL, "what"); @@ -551,13 +550,16 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons } break; case MATH_RANDOMIZE: { } break; - case MATH_RAND: { + case MATH_RANDI: { t = Variant::INT; } break; case MATH_RANDF: - case MATH_RANDOM: { + case MATH_RANDF_RANGE: { t = Variant::FLOAT; } break; + case MATH_RANDI_RANGE: { + t = Variant::INT; + } break; case MATH_SEED: { } break; case MATH_RANDSEED: { @@ -593,10 +595,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons t = Variant::OBJECT; } break; - case FUNC_FUNCREF: { - t = Variant::OBJECT; - - } break; case TYPE_CONVERT: { } break; case TEXT_ORD: @@ -861,17 +859,22 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in Math::randomize(); } break; - case VisualScriptBuiltinFunc::MATH_RAND: { + case VisualScriptBuiltinFunc::MATH_RANDI: { *r_return = Math::rand(); } break; case VisualScriptBuiltinFunc::MATH_RANDF: { *r_return = Math::randf(); } break; - case VisualScriptBuiltinFunc::MATH_RANDOM: { + case VisualScriptBuiltinFunc::MATH_RANDF_RANGE: { VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); *r_return = Math::random((double)*p_inputs[0], (double)*p_inputs[1]); } break; + case VisualScriptBuiltinFunc::MATH_RANDI_RANGE: { + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + *r_return = Math::random((int)*p_inputs[0], (int)*p_inputs[1]); + } break; case VisualScriptBuiltinFunc::MATH_SEED: { VALIDATE_ARG_NUM(0); uint64_t seed = *p_inputs[0]; @@ -1013,30 +1016,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in } } break; - case VisualScriptBuiltinFunc::FUNC_FUNCREF: { - if (p_inputs[0]->get_type() != Variant::OBJECT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - - return; - } - if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING; - - return; - } - - Ref<FuncRef> fr = memnew(FuncRef); - - fr->set_instance(*p_inputs[0]); - fr->set_function(*p_inputs[1]); - - *r_return = fr; - - } break; case VisualScriptBuiltinFunc::TYPE_CONVERT: { VALIDATE_ARG_NUM(1); int type = *p_inputs[1]; @@ -1048,7 +1027,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in return; } else { - *r_return = Variant::construct(Variant::Type(type), p_inputs, 1, r_error); + Variant::construct(Variant::Type(type), *r_return, p_inputs, 1, r_error); } } break; case VisualScriptBuiltinFunc::TYPE_OF: { @@ -1283,9 +1262,10 @@ void VisualScriptBuiltinFunc::_bind_methods() { BIND_ENUM_CONSTANT(MATH_MOVE_TOWARD); BIND_ENUM_CONSTANT(MATH_DECTIME); BIND_ENUM_CONSTANT(MATH_RANDOMIZE); - BIND_ENUM_CONSTANT(MATH_RAND); + BIND_ENUM_CONSTANT(MATH_RANDI); BIND_ENUM_CONSTANT(MATH_RANDF); - BIND_ENUM_CONSTANT(MATH_RANDOM); + BIND_ENUM_CONSTANT(MATH_RANDF_RANGE); + BIND_ENUM_CONSTANT(MATH_RANDI_RANGE); BIND_ENUM_CONSTANT(MATH_SEED); BIND_ENUM_CONSTANT(MATH_RANDSEED); BIND_ENUM_CONSTANT(MATH_DEG2RAD); @@ -1301,7 +1281,6 @@ void VisualScriptBuiltinFunc::_bind_methods() { BIND_ENUM_CONSTANT(LOGIC_CLAMP); BIND_ENUM_CONSTANT(LOGIC_NEAREST_PO2); BIND_ENUM_CONSTANT(OBJ_WEAKREF); - BIND_ENUM_CONSTANT(FUNC_FUNCREF); BIND_ENUM_CONSTANT(TYPE_CONVERT); BIND_ENUM_CONSTANT(TYPE_OF); BIND_ENUM_CONSTANT(TYPE_EXISTS); @@ -1375,9 +1354,10 @@ void register_visual_script_builtin_func_node() { VisualScriptLanguage::singleton->add_register_func("functions/built_in/move_toward", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_MOVE_TOWARD>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/dectime", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECTIME>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/randomize", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOMIZE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/rand", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAND>); + VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/random", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOM>); + VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF_RANGE>); + VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI_RANGE>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/seed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SEED>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/randseed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDSEED>); @@ -1396,7 +1376,6 @@ void register_visual_script_builtin_func_node() { VisualScriptLanguage::singleton->add_register_func("functions/built_in/nearest_po2", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_NEAREST_PO2>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/weakref", create_builtin_func_node<VisualScriptBuiltinFunc::OBJ_WEAKREF>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/funcref", create_builtin_func_node<VisualScriptBuiltinFunc::FUNC_FUNCREF>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/convert", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_CONVERT>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/typeof", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_OF>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/type_exists", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_EXISTS>); diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h index aee2ed79ce..361b445e30 100644 --- a/modules/visual_script/visual_script_builtin_funcs.h +++ b/modules/visual_script/visual_script_builtin_funcs.h @@ -70,9 +70,10 @@ public: MATH_MOVE_TOWARD, MATH_DECTIME, MATH_RANDOMIZE, - MATH_RAND, + MATH_RANDI, MATH_RANDF, - MATH_RANDOM, + MATH_RANDF_RANGE, + MATH_RANDI_RANGE, MATH_SEED, MATH_RANDSEED, MATH_DEG2RAD, @@ -88,7 +89,6 @@ public: LOGIC_CLAMP, LOGIC_NEAREST_PO2, OBJ_WEAKREF, - FUNC_FUNCREF, TYPE_CONVERT, TYPE_OF, TYPE_EXISTS, diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 01c674d086..1bb96a47f3 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -30,11 +30,11 @@ #include "visual_script_editor.h" -#include "core/class_db.h" #include "core/input/input.h" +#include "core/object/class_db.h" +#include "core/object/script_language.h" #include "core/os/keyboard.h" -#include "core/script_language.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" @@ -388,7 +388,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::NODE_PATH: color = Color(0.41, 0.58, 0.93); break; - case Variant::_RID: + case Variant::RID: color = Color(0.41, 0.93, 0.6); break; case Variant::OBJECT: @@ -494,7 +494,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::NODE_PATH: color = Color(0.41, 0.58, 0.93); break; - case Variant::_RID: + case Variant::RID: color = Color(0.17, 0.9, 0.45); break; case Variant::OBJECT: @@ -885,7 +885,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { //not the same, reconvert Callable::CallError ce; const Variant *existingp = &value; - value = Variant::construct(left_type, &existingp, 1, ce, false); + Variant::construct(left_type, value, &existingp, 1, ce); } if (left_type == Variant::COLOR) { @@ -1173,7 +1173,9 @@ String VisualScriptEditor::_sanitized_variant_text(const StringName &property_na if (script->get_variable_info(property_name).type != Variant::NIL) { Callable::CallError ce; const Variant *converted = &var; - var = Variant::construct(script->get_variable_info(property_name).type, &converted, 1, ce, false); + Variant n; + Variant::construct(script->get_variable_info(property_name).type, n, &converted, 1, ce); + var = n; } return String(var); @@ -3959,8 +3961,9 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i Variant existing = vsn->get_default_input_value(p_input_port); if (pinfo.type != Variant::NIL && existing.get_type() != pinfo.type) { Callable::CallError ce; - const Variant *existingp = &existing; - existing = Variant::construct(pinfo.type, &existingp, 1, ce, false); + Variant e = existing; + const Variant *existingp = &e; + Variant::construct(pinfo.type, existing, &existingp, 1, ce); } default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_global_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y)); diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 60a439b291..10a18dfd5e 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -1341,7 +1341,7 @@ public: } bool valid; - r_ret = base.get_named(index->name, &valid); + r_ret = base.get_named(index->name, valid); if (!valid) { r_error_str = "Invalid index '" + String(index->name) + "' for base of type " + Variant::get_type_name(base.get_type()) + "."; return true; @@ -1405,7 +1405,7 @@ public: argp.write[i] = &arr[i]; } - r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce); + Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = "Invalid arguments to construct '" + Variant::get_type_name(constructor->data_type) + "'."; @@ -1463,7 +1463,7 @@ public: argp.write[i] = &arr[i]; } - r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce); + base.call(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = "On call to '" + String(call->method) + "':"; diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index 3ed20fab35..36c756fc58 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -30,9 +30,9 @@ #include "visual_script_flow_control.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" ////////////////////////////////////////// ////////////////RETURN//////////////////// diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 68de686272..34a1cfc4fc 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -30,7 +30,7 @@ #include "visual_script_func_nodes.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/io/resource_loader.h" #include "core/os/os.h" #include "scene/main/node.h" @@ -42,7 +42,7 @@ ////////////////////////////////////////// int VisualScriptFunctionCall::get_output_sequence_port_count() const { - if ((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_method_const(basic_type, function))) { + if ((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_builtin_method_const(basic_type, function))) { return 0; } else { return 1; @@ -50,7 +50,7 @@ int VisualScriptFunctionCall::get_output_sequence_port_count() const { } bool VisualScriptFunctionCall::has_input_sequence_port() const { - return !((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_method_const(basic_type, function))); + return !((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_builtin_method_const(basic_type, function))); } #ifdef TOOLS_ENABLED @@ -130,7 +130,11 @@ StringName VisualScriptFunctionCall::_get_base_type() const { int VisualScriptFunctionCall::get_input_value_port_count() const { if (call_mode == CALL_MODE_BASIC_TYPE) { - Vector<Variant::Type> types = Variant::get_method_argument_types(basic_type, function); + Vector<Variant::Type> types; + int argc = Variant::get_builtin_method_argument_count(basic_type, function); + for (int i = 0; i < argc; i++) { + types.push_back(Variant::get_builtin_method_argument_type(basic_type, function, i)); + } return types.size() + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) + 1; } else { @@ -147,8 +151,7 @@ int VisualScriptFunctionCall::get_input_value_port_count() const { int VisualScriptFunctionCall::get_output_value_port_count() const { if (call_mode == CALL_MODE_BASIC_TYPE) { - bool returns = false; - Variant::get_method_return_type(basic_type, function, &returns); + bool returns = Variant::has_builtin_method_return_value(basic_type, function); return returns ? 1 : 0; } else { @@ -195,10 +198,7 @@ PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) cons #ifdef DEBUG_METHODS_ENABLED if (call_mode == CALL_MODE_BASIC_TYPE) { - Vector<StringName> names = Variant::get_method_argument_names(basic_type, function); - Vector<Variant::Type> types = Variant::get_method_argument_types(basic_type, function); - return PropertyInfo(types[p_idx], names[p_idx]); - + return PropertyInfo(Variant::get_builtin_method_argument_type(basic_type, function, p_idx), Variant::get_builtin_method_argument_name(basic_type, function, p_idx)); } else { MethodBind *mb = ClassDB::get_method(_get_base_type(), function); if (mb) { @@ -220,7 +220,7 @@ PropertyInfo VisualScriptFunctionCall::get_output_value_port_info(int p_idx) con #ifdef DEBUG_METHODS_ENABLED if (call_mode == CALL_MODE_BASIC_TYPE) { - return PropertyInfo(Variant::get_method_return_type(basic_type, function), ""); + return PropertyInfo(Variant::get_builtin_method_return_type(basic_type, function), ""); } else { if (call_mode == CALL_MODE_INSTANCE) { if (p_idx == 0) { @@ -419,7 +419,7 @@ void VisualScriptFunctionCall::set_function(const StringName &p_type) { function = p_type; if (call_mode == CALL_MODE_BASIC_TYPE) { - use_default_args = Variant::get_method_default_arguments(basic_type, function).size(); + use_default_args = Variant::get_builtin_method_default_arguments(basic_type, function).size(); } else { //update all caches @@ -606,7 +606,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const int mc = 0; if (call_mode == CALL_MODE_BASIC_TYPE) { - mc = Variant::get_method_default_arguments(basic_type, function).size(); + mc = Variant::get_builtin_method_default_arguments(basic_type, function).size(); } else { MethodBind *mb = ClassDB::get_method(_get_base_type(), function); if (mb) { @@ -805,19 +805,21 @@ public: } else if (returns) { if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) { if (returns >= 2) { - *p_outputs[1] = v.call(function, p_inputs + 1, input_args, r_error); + v.call(function, p_inputs + 1, input_args, *p_outputs[1], r_error); } else if (returns == 1) { - v.call(function, p_inputs + 1, input_args, r_error); + Variant ret; + v.call(function, p_inputs + 1, input_args, ret, r_error); } else { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; r_error_str = "Invalid returns count for call_mode == CALL_MODE_INSTANCE"; return 0; } } else { - *p_outputs[0] = v.call(function, p_inputs + 1, input_args, r_error); + v.call(function, p_inputs + 1, input_args, *p_outputs[0], r_error); } } else { - v.call(function, p_inputs + 1, input_args, r_error); + Variant ret; + v.call(function, p_inputs + 1, input_args, ret, r_error); } if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) { @@ -976,7 +978,7 @@ void VisualScriptPropertySet::_adjust_input_index(PropertyInfo &pinfo) const { if (index != StringName()) { Variant v; Callable::CallError ce; - v = Variant::construct(pinfo.type, nullptr, 0, ce); + Variant::construct(pinfo.type, v, nullptr, 0, ce); Variant i = v.get(index); pinfo.type = i.get_type(); } @@ -1117,7 +1119,7 @@ void VisualScriptPropertySet::_update_cache() { Variant v; Callable::CallError ce; - v = Variant::construct(basic_type, nullptr, 0, ce); + Variant::construct(basic_type, v, nullptr, 0, ce); List<PropertyInfo> pinfo; v.get_property_list(&pinfo); @@ -1336,7 +1338,8 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { if (property.name == "index") { Callable::CallError ce; - Variant v = Variant::construct(type_cache.type, nullptr, 0, ce); + Variant v; + Variant::construct(type_cache.type, v, nullptr, 0, ce); List<PropertyInfo> plist; v.get_property_list(&plist); String options = ""; @@ -1449,11 +1452,11 @@ public: _FORCE_INLINE_ void _process_get(Variant &source, const Variant &p_argument, bool &valid) { if (index != StringName() && assign_op == VisualScriptPropertySet::ASSIGN_OP_NONE) { - source.set_named(index, p_argument, &valid); + source.set_named(index, p_argument, valid); } else { Variant value; if (index != StringName()) { - value = source.get_named(index, &valid); + value = source.get_named(index, valid); } else { value = source; } @@ -1497,7 +1500,7 @@ public: } if (index != StringName()) { - source.set_named(index, value, &valid); + source.set_named(index, value, valid); } else { source = value; } @@ -1562,12 +1565,12 @@ public: bool valid; if (needs_get) { - Variant value = v.get_named(property, &valid); + Variant value = v.get_named(property, valid); _process_get(value, *p_inputs[1], valid); - v.set_named(property, value, &valid); + v.set_named(property, value, valid); } else { - v.set_named(property, *p_inputs[1], &valid); + v.set_named(property, *p_inputs[1], valid); } if (!valid) { @@ -1786,7 +1789,7 @@ void VisualScriptPropertyGet::_update_cache() { Variant v; Callable::CallError ce; - v = Variant::construct(basic_type, nullptr, 0, ce); + Variant::construct(basic_type, v, nullptr, 0, ce); List<PropertyInfo> pinfo; v.get_property_list(&pinfo); @@ -2012,7 +2015,8 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { if (property.name == "index") { Callable::CallError ce; - Variant v = Variant::construct(type_cache, nullptr, 0, ce); + Variant v; + Variant::construct(type_cache, v, nullptr, 0, ce); List<PropertyInfo> plist; v.get_property_list(&plist); String options = ""; @@ -2111,7 +2115,7 @@ public: *p_outputs[0] = object->get(property, &valid); if (index != StringName()) { - *p_outputs[0] = p_outputs[0]->get_named(index); + *p_outputs[0] = p_outputs[0]->get_named(index, valid); } if (!valid) { @@ -2140,7 +2144,7 @@ public: *p_outputs[0] = another->get(property, &valid); if (index != StringName()) { - *p_outputs[0] = p_outputs[0]->get_named(index); + *p_outputs[0] = p_outputs[0]->get_named(index, valid); } if (!valid) { @@ -2156,7 +2160,7 @@ public: *p_outputs[0] = v.get(property, &valid); if (index != StringName()) { - *p_outputs[0] = p_outputs[0]->get_named(index); + *p_outputs[0] = p_outputs[0]->get_named(index, valid); } if (!valid) { @@ -2368,7 +2372,8 @@ void register_visual_script_func_nodes() { Variant::Type t = Variant::Type(i); String type_name = Variant::get_type_name(t); Callable::CallError ce; - Variant vt = Variant::construct(t, nullptr, 0, ce); + Variant vt; + Variant::construct(t, vt, nullptr, 0, ce); List<MethodInfo> ml; vt.get_method_list(&ml); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 28122ade99..edec270adc 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -30,11 +30,11 @@ #include "visual_script_nodes.h" -#include "core/engine.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "core/input/input.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/main/node.h" #include "scene/main/scene_tree.h" @@ -828,7 +828,6 @@ PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const { { Variant::NIL, Variant::NIL }, //OP_NEGATE, { Variant::NIL, Variant::NIL }, //OP_POSITIVE, { Variant::INT, Variant::INT }, //OP_MODULE, - { Variant::STRING, Variant::STRING }, //OP_STRING_CONCAT, //bitwise { Variant::INT, Variant::INT }, //OP_SHIFT_LEFT, { Variant::INT, Variant::INT }, //OP_SHIFT_RIGHT, @@ -873,7 +872,6 @@ PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const { Variant::NIL, //OP_NEGATE, Variant::NIL, //OP_POSITIVE, Variant::INT, //OP_MODULE, - Variant::STRING, //OP_STRING_CONCAT, //bitwise Variant::INT, //OP_SHIFT_LEFT, Variant::INT, //OP_SHIFT_RIGHT, @@ -1433,7 +1431,7 @@ void VisualScriptConstant::set_constant_type(Variant::Type p_type) { type = p_type; Callable::CallError ce; - value = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, value, nullptr, 0, ce); ports_changed_notify(); _change_notify(); } @@ -1756,7 +1754,7 @@ PropertyInfo VisualScriptGlobalConstant::get_input_value_port_info(int p_idx) co } PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) const { - String name = GlobalConstants::get_global_constant_name(index); + String name = CoreConstants::get_global_constant_name(index); return PropertyInfo(Variant::INT, name); } @@ -1780,7 +1778,7 @@ public: //virtual int get_working_memory_size() const { return 0; } virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) { - *p_outputs[0] = GlobalConstants::get_global_constant_value(index); + *p_outputs[0] = CoreConstants::get_global_constant_value(index); return 0; } }; @@ -1797,11 +1795,11 @@ void VisualScriptGlobalConstant::_bind_methods() { String cc; - for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { + for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { if (i > 0) { cc += ","; } - cc += GlobalConstants::get_global_constant_name(i); + cc += CoreConstants::get_global_constant_name(i); } ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant"); } @@ -3257,7 +3255,7 @@ public: virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) { Callable::CallError ce; - *p_outputs[0] = Variant::construct(type, p_inputs, argcount, ce); + Variant::construct(type, *p_outputs[0], p_inputs, argcount, ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = "Invalid arguments for constructor"; } @@ -3729,7 +3727,7 @@ void VisualScriptDeconstruct::_update_elements() { elements.clear(); Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); List<PropertyInfo> pinfo; v.get_property_list(&pinfo); @@ -3881,7 +3879,6 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("operators/math/negate", create_op_node<Variant::OP_NEGATE>); VisualScriptLanguage::singleton->add_register_func("operators/math/positive", create_op_node<Variant::OP_POSITIVE>); VisualScriptLanguage::singleton->add_register_func("operators/math/remainder", create_op_node<Variant::OP_MODULE>); - VisualScriptLanguage::singleton->add_register_func("operators/math/string_concat", create_op_node<Variant::OP_STRING_CONCAT>); //bitwise VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_left", create_op_node<Variant::OP_SHIFT_LEFT>); VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_right", create_op_node<Variant::OP_SHIFT_RIGHT>); diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 3c44faab90..875270e74f 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -196,7 +196,7 @@ void VisualScriptPropertySelector::_update_search() { if (type != Variant::NIL) { Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); v.get_method_list(&methods); } else { Object *obj = ObjectDB::get_instance(script); diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 832e14d91a..2128b82e3f 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -30,9 +30,9 @@ #include "video_stream_webm.h" +#include "core/config/project_settings.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "servers/audio_server.h" #include "thirdparty/misc/yuv2rgb.h" diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp index d5c80e7909..b169687f25 100644 --- a/modules/webp/image_loader_webp.cpp +++ b/modules/webp/image_loader_webp.cpp @@ -32,7 +32,7 @@ #include "core/io/marshalls.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include <stdlib.h> #include <webp/decode.h> diff --git a/modules/webrtc/SCsub b/modules/webrtc/SCsub index 20b4c8f8d2..4f870ddb2f 100644 --- a/modules/webrtc/SCsub +++ b/modules/webrtc/SCsub @@ -12,4 +12,8 @@ if use_gdnative: # GDNative is retained in Javascript for export compatibility env_webrtc.Append(CPPDEFINES=["WEBRTC_GDNATIVE_ENABLED"]) env_webrtc.Prepend(CPPPATH=["#modules/gdnative/include/"]) +if env["platform"] == "javascript": + # Our JavaScript/C++ interface. + env.AddJSLibraries(["library_godot_webrtc.js"]) + env_webrtc.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/webrtc/library_godot_webrtc.js b/modules/webrtc/library_godot_webrtc.js new file mode 100644 index 0000000000..b75996b1f3 --- /dev/null +++ b/modules/webrtc/library_godot_webrtc.js @@ -0,0 +1,407 @@ +/*************************************************************************/ +/* library_godot_webrtc.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +var GodotRTCDataChannel = { + // Our socket implementation that forwards events to C++. + $GodotRTCDataChannel__deps: ['$IDHandler', '$GodotOS'], + $GodotRTCDataChannel: { + + connect: function(p_id, p_on_open, p_on_message, p_on_error, p_on_close) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + + ref.binaryType = 'arraybuffer'; + ref.onopen = function (event) { + p_on_open(); + }; + ref.onclose = function (event) { + p_on_close(); + }; + ref.onerror = function (event) { + p_on_error(); + }; + ref.onmessage = function(event) { + var buffer; + var is_string = 0; + if (event.data instanceof ArrayBuffer) { + buffer = new Uint8Array(event.data); + } else if (event.data instanceof Blob) { + console.error("Blob type not supported"); + return; + } else if (typeof event.data === "string") { + is_string = 1; + var enc = new TextEncoder("utf-8"); + buffer = new Uint8Array(enc.encode(event.data)); + } else { + console.error("Unknown message type"); + return; + } + var len = buffer.length*buffer.BYTES_PER_ELEMENT; + var out = _malloc(len); + HEAPU8.set(buffer, out); + p_on_message(out, len, is_string); + _free(out); + } + }, + + close: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + ref.onopen = null; + ref.onmessage = null; + ref.onerror = null; + ref.onclose = null; + ref.close(); + }, + + get_prop: function(p_id, p_prop, p_def) { + const ref = IDHandler.get(p_id); + return (ref && ref[p_prop] !== undefined) ? ref[p_prop] : p_def; + }, + }, + + godot_js_rtc_datachannel_ready_state_get: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return 3; // CLOSED + } + + switch(ref.readyState) { + case "connecting": + return 0; + case "open": + return 1; + case "closing": + return 2; + case "closed": + return 3; + } + return 3; // CLOSED + }, + + godot_js_rtc_datachannel_send: function(p_id, p_buffer, p_length, p_raw) { + const ref = IDHandler.get(p_id); + if (!ref) { + return 1; + } + + const bytes_array = new Uint8Array(p_length); + for (var i = 0; i < p_length; i++) { + bytes_array[i] = getValue(p_buffer + i, 'i8'); + } + + if (p_raw) { + ref.send(bytes_array.buffer); + } else { + const string = new TextDecoder('utf-8').decode(bytes_array); + ref.send(string); + } + }, + + godot_js_rtc_datachannel_is_ordered: function(p_id) { + return IDHandler.get_prop(p_id, 'ordered', true); + }, + + godot_js_rtc_datachannel_id_get: function(p_id) { + return IDHandler.get_prop(p_id, 'id', 65535); + }, + + godot_js_rtc_datachannel_max_packet_lifetime_get: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return 65535; + } + if (ref['maxPacketLifeTime'] !== undefined) { + return ref['maxPacketLifeTime']; + } else if (ref['maxRetransmitTime'] !== undefined) { + // Guess someone didn't appreciate the standardization process. + return ref['maxRetransmitTime']; + } + return 65535; + }, + + godot_js_rtc_datachannel_max_retransmits_get: function(p_id) { + return IDHandler.get_prop(p_id, 'maxRetransmits', 65535); + }, + + godot_js_rtc_datachannel_is_negotiated: function(p_id, p_def) { + return IDHandler.get_prop(p_id, 'negotiated', 65535); + }, + + godot_js_rtc_datachannel_label_get: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref || !ref.label) { + return 0; + } + return GodotOS.allocString(ref.label); + }, + + godot_js_rtc_datachannel_protocol_get: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref || !ref.protocol) { + return 0; + } + return GodotOS.allocString(ref.protocol); + }, + + godot_js_rtc_datachannel_destroy: function(p_id) { + GodotRTCDataChannel.close(p_id); + IDHandler.remove(p_id); + }, + + godot_js_rtc_datachannel_connect: function(p_id, p_ref, p_on_open, p_on_message, p_on_error, p_on_close) { + const onopen = GodotOS.get_func(p_on_open).bind(null, p_ref); + const onmessage = GodotOS.get_func(p_on_message).bind(null, p_ref); + const onerror = GodotOS.get_func(p_on_error).bind(null, p_ref); + const onclose = GodotOS.get_func(p_on_close).bind(null, p_ref); + GodotRTCDataChannel.connect(p_id, onopen, onmessage, onerror, onclose); + }, + + godot_js_rtc_datachannel_close: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + GodotRTCDataChannel.close(p_id); + }, +}; + +autoAddDeps(GodotRTCDataChannel, '$GodotRTCDataChannel'); +mergeInto(LibraryManager.library, GodotRTCDataChannel); + +var GodotRTCPeerConnection = { + + $GodotRTCPeerConnection__deps: ['$IDHandler', '$GodotOS', '$GodotRTCDataChannel'], + $GodotRTCPeerConnection: { + onstatechange: function(p_id, p_conn, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + var state = 5; // CLOSED + switch(p_conn.iceConnectionState) { + case "new": + state = 0; + case "checking": + state = 1; + case "connected": + case "completed": + state = 2; + case "disconnected": + state = 3; + case "failed": + state = 4; + case "closed": + state = 5; + } + callback(state); + }, + + onicecandidate: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref || !event.candidate) { + return; + } + + let c = event.candidate; + let candidate_str = GodotOS.allocString(c.candidate); + let mid_str = GodotOS.allocString(c.sdpMid); + callback(mid_str, c.sdpMLineIndex, candidate_str); + _free(candidate_str); + _free(mid_str); + }, + + ondatachannel: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + + const cid = IDHandler.add(event.channel); + callback(cid); + }, + + onsession: function(p_id, callback, session) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + let type_str = GodotOS.allocString(session.type); + let sdp_str = GodotOS.allocString(session.sdp); + callback(type_str, sdp_str); + _free(type_str); + _free(sdp_str); + }, + + onerror: function(p_id, callback, error) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + console.error(error); + callback(); + }, + }, + + godot_js_rtc_pc_create: function(p_config, p_ref, p_on_state_change, p_on_candidate, p_on_datachannel) { + const onstatechange = GodotOS.get_func(p_on_state_change).bind(null, p_ref); + const oncandidate = GodotOS.get_func(p_on_candidate).bind(null, p_ref); + const ondatachannel = GodotOS.get_func(p_on_datachannel).bind(null, p_ref); + + var config = JSON.parse(UTF8ToString(p_config)); + var conn = null; + try { + conn = new RTCPeerConnection(config); + } catch (e) { + console.error(e); + return 0; + } + + const base = GodotRTCPeerConnection; + const id = IDHandler.add(conn); + conn.oniceconnectionstatechange = base.onstatechange.bind(null, id, conn, onstatechange); + conn.onicecandidate = base.onicecandidate.bind(null, id, oncandidate); + conn.ondatachannel = base.ondatachannel.bind(null, id, ondatachannel); + return id; + }, + + godot_js_rtc_pc_close: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + ref.close(); + }, + + godot_js_rtc_pc_destroy: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + ref.oniceconnectionstatechange = null; + ref.onicecandidate = null; + ref.ondatachannel = null; + IDHandler.remove(p_id); + }, + + godot_js_rtc_pc_offer_create: function(p_id, p_obj, p_on_session, p_on_error) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const onsession = GodotOS.get_func(p_on_session).bind(null, p_obj); + const onerror = GodotOS.get_func(p_on_error).bind(null, p_obj); + ref.createOffer().then(function(session) { + GodotRTCPeerConnection.onsession(p_id, onsession, session); + }).catch(function(error) { + GodotRTCPeerConnection.onerror(p_id, onerror, error); + }); + }, + + godot_js_rtc_pc_local_description_set: function(p_id, p_type, p_sdp, p_obj, p_on_error) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const type = UTF8ToString(p_type); + const sdp = UTF8ToString(p_sdp); + const onerror = GodotOS.get_func(p_on_error).bind(null, p_obj); + ref.setLocalDescription({ + 'sdp': sdp, + 'type': type + }).catch(function(error) { + GodotRTCPeerConnection.onerror(p_id, onerror, error); + }); + }, + + godot_js_rtc_pc_remote_description_set: function(p_id, p_type, p_sdp, p_obj, p_session_created, p_on_error) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + const type = UTF8ToString(p_type); + const sdp = UTF8ToString(p_sdp); + const onerror = GodotOS.get_func(p_on_error).bind(null, p_obj); + const onsession = GodotOS.get_func(p_session_created).bind(null, p_obj); + ref.setRemoteDescription({ + 'sdp': sdp, + 'type': type + }).then(function() { + if (type != 'offer') { + return; + } + return ref.createAnswer().then(function(session) { + GodotRTCPeerConnection.onsession(p_id, onsession, session); + }); + }).catch(function(error) { + GodotRTCPeerConnection.onerror(p_id, onerror, error); + }); + }, + + godot_js_rtc_pc_ice_candidate_add: function(p_id, p_mid_name, p_mline_idx, p_sdp) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + var sdpMidName = UTF8ToString(p_mid_name); + var sdpName = UTF8ToString(p_sdp); + ref.addIceCandidate(new RTCIceCandidate({ + "candidate": sdpName, + "sdpMid": sdpMidName, + "sdpMlineIndex": p_mline_idx, + })); + }, + + godot_js_rtc_pc_datachannel_create__deps: ['$GodotRTCDataChannel'], + godot_js_rtc_pc_datachannel_create: function(p_id, p_label, p_config) { + try { + const ref = IDHandler.get(p_id); + if (!ref) { + return 0; + } + + const label = UTF8ToString(p_label); + const config = JSON.parse(UTF8ToString(p_config)); + + const channel = ref.createDataChannel(label, config); + return IDHandler.add(channel); + } catch (e) { + console.error(e); + return 0; + } + }, +}; + +autoAddDeps(GodotRTCPeerConnection, '$GodotRTCPeerConnection') +mergeInto(LibraryManager.library, GodotRTCPeerConnection); diff --git a/modules/webrtc/register_types.cpp b/modules/webrtc/register_types.cpp index 5b296b1ac6..0e830f0540 100644 --- a/modules/webrtc/register_types.cpp +++ b/modules/webrtc/register_types.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "register_types.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "webrtc_data_channel.h" #include "webrtc_peer_connection.h" diff --git a/modules/webrtc/webrtc_data_channel.cpp b/modules/webrtc/webrtc_data_channel.cpp index 7566532982..cd9e77aff8 100644 --- a/modules/webrtc/webrtc_data_channel.cpp +++ b/modules/webrtc/webrtc_data_channel.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "webrtc_data_channel.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" void WebRTCDataChannel::_bind_methods() { ClassDB::bind_method(D_METHOD("poll"), &WebRTCDataChannel::poll); diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp index 2c648ba9f9..3a63001a56 100644 --- a/modules/webrtc/webrtc_data_channel_js.cpp +++ b/modules/webrtc/webrtc_data_channel_js.cpp @@ -34,65 +34,58 @@ #include "emscripten.h" extern "C" { -EMSCRIPTEN_KEEPALIVE void _emrtc_on_ch_error(void *obj) { - WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(obj); - peer->_on_error(); -} +typedef void (*RTCChOnOpen)(void *p_obj); +typedef void (*RTCChOnMessage)(void *p_obj, const uint8_t *p_buffer, int p_size, int p_is_string); +typedef void (*RTCChOnClose)(void *p_obj); +typedef void (*RTCChOnError)(void *p_obj); -EMSCRIPTEN_KEEPALIVE void _emrtc_on_ch_open(void *obj) { - WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(obj); - peer->_on_open(); +extern int godot_js_rtc_datachannel_ready_state_get(int p_id); +extern int godot_js_rtc_datachannel_send(int p_id, const uint8_t *p_buffer, int p_length, int p_raw); +extern int godot_js_rtc_datachannel_is_ordered(int p_id); +extern int godot_js_rtc_datachannel_id_get(int p_id); +extern int godot_js_rtc_datachannel_max_packet_lifetime_get(int p_id); +extern int godot_js_rtc_datachannel_max_retransmits_get(int p_id); +extern int godot_js_rtc_datachannel_is_negotiated(int p_id); +extern char *godot_js_rtc_datachannel_label_get(int p_id); // Must free the returned string. +extern char *godot_js_rtc_datachannel_protocol_get(int p_id); // Must free the returned string. +extern void godot_js_rtc_datachannel_destroy(int p_id); +extern void godot_js_rtc_datachannel_connect(int p_id, void *p_obj, RTCChOnOpen p_on_open, RTCChOnMessage p_on_message, RTCChOnError p_on_error, RTCChOnClose p_on_close); +extern void godot_js_rtc_datachannel_close(int p_id); } -EMSCRIPTEN_KEEPALIVE void _emrtc_on_ch_close(void *obj) { - WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(obj); - peer->_on_close(); +void WebRTCDataChannelJS::_on_open(void *p_obj) { + WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(p_obj); + peer->in_buffer.resize(peer->_in_buffer_shift); } -EMSCRIPTEN_KEEPALIVE void _emrtc_on_ch_message(void *obj, uint8_t *p_data, uint32_t p_size, bool p_is_string) { - WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(obj); - peer->_on_message(p_data, p_size, p_is_string); -} +void WebRTCDataChannelJS::_on_close(void *p_obj) { + WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(p_obj); + peer->close(); } -void WebRTCDataChannelJS::_on_open() { - in_buffer.resize(_in_buffer_shift); +void WebRTCDataChannelJS::_on_error(void *p_obj) { + WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(p_obj); + peer->close(); } -void WebRTCDataChannelJS::_on_close() { - close(); -} +void WebRTCDataChannelJS::_on_message(void *p_obj, const uint8_t *p_data, int p_size, int p_is_string) { + WebRTCDataChannelJS *peer = static_cast<WebRTCDataChannelJS *>(p_obj); + RingBuffer<uint8_t> &in_buffer = peer->in_buffer; -void WebRTCDataChannelJS::_on_error() { - close(); -} - -void WebRTCDataChannelJS::_on_message(uint8_t *p_data, uint32_t p_size, bool p_is_string) { ERR_FAIL_COND_MSG(in_buffer.space_left() < (int)(p_size + 5), "Buffer full! Dropping data."); uint8_t is_string = p_is_string ? 1 : 0; in_buffer.write((uint8_t *)&p_size, 4); in_buffer.write((uint8_t *)&is_string, 1); in_buffer.write(p_data, p_size); - queue_count++; + peer->queue_count++; } void WebRTCDataChannelJS::close() { in_buffer.resize(0); queue_count = 0; _was_string = false; - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - if (!dict) return; - var channel = dict["channel"]; - channel.onopen = null; - channel.onclose = null; - channel.onerror = null; - channel.onmessage = null; - channel.close(); - }, _js_id); - /* clang-format on */ + godot_js_rtc_datachannel_close(_js_id); } Error WebRTCDataChannelJS::poll() { @@ -100,24 +93,7 @@ Error WebRTCDataChannelJS::poll() { } WebRTCDataChannelJS::ChannelState WebRTCDataChannelJS::get_ready_state() const { - /* clang-format off */ - return (ChannelState) EM_ASM_INT({ - var dict = Module.IDHandler.get($0); - if (!dict) return 3; // CLOSED - var channel = dict["channel"]; - switch(channel.readyState) { - case "connecting": - return 0; - case "open": - return 1; - case "closing": - return 2; - case "closed": - return 3; - } - return 3; // CLOSED - }, _js_id); - /* clang-format on */ + return (ChannelState)godot_js_rtc_datachannel_ready_state_get(_js_id); } int WebRTCDataChannelJS::get_available_packet_count() const { @@ -157,27 +133,7 @@ Error WebRTCDataChannelJS::put_packet(const uint8_t *p_buffer, int p_buffer_size ERR_FAIL_COND_V(get_ready_state() != STATE_OPEN, ERR_UNCONFIGURED); int is_bin = _write_mode == WebRTCDataChannel::WRITE_MODE_BINARY ? 1 : 0; - - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - var channel = dict["channel"]; - var bytes_array = new Uint8Array($2); - var i = 0; - - for(i=0; i<$2; i++) { - bytes_array[i] = getValue($1+i, 'i8'); - } - - if ($3) { - channel.send(bytes_array.buffer); - } else { - var string = new TextDecoder("utf-8").decode(bytes_array); - channel.send(string); - } - }, _js_id, p_buffer, p_buffer_size, is_bin); - /* clang-format on */ - + godot_js_rtc_datachannel_send(_js_id, p_buffer, p_buffer_size, is_bin); return OK; } @@ -201,46 +157,20 @@ String WebRTCDataChannelJS::get_label() const { return _label; } -/* clang-format off */ -#define _JS_GET(PROP, DEF) \ -EM_ASM_INT({ \ - var dict = Module.IDHandler.get($0); \ - if (!dict || !dict["channel"]) { \ - return DEF; \ - } \ - var out = dict["channel"].PROP; \ - return out === null ? DEF : out; \ -}, _js_id) -/* clang-format on */ - bool WebRTCDataChannelJS::is_ordered() const { - return _JS_GET(ordered, true); + return godot_js_rtc_datachannel_is_ordered(_js_id); } int WebRTCDataChannelJS::get_id() const { - return _JS_GET(id, 65535); + return godot_js_rtc_datachannel_id_get(_js_id); } int WebRTCDataChannelJS::get_max_packet_life_time() const { - // Can't use macro, webkit workaround. - /* clang-format off */ - return EM_ASM_INT({ - var dict = Module.IDHandler.get($0); - if (!dict || !dict["channel"]) { - return 65535; - } - if (dict["channel"].maxRetransmitTime !== undefined) { - // Guess someone didn't appreciate the standardization process. - return dict["channel"].maxRetransmitTime; - } - var out = dict["channel"].maxPacketLifeTime; - return out === null ? 65535 : out; - }, _js_id); - /* clang-format on */ + return godot_js_rtc_datachannel_max_packet_lifetime_get(_js_id); } int WebRTCDataChannelJS::get_max_retransmits() const { - return _JS_GET(maxRetransmits, 65535); + return godot_js_rtc_datachannel_max_retransmits_get(_js_id); } String WebRTCDataChannelJS::get_protocol() const { @@ -248,7 +178,7 @@ String WebRTCDataChannelJS::get_protocol() const { } bool WebRTCDataChannelJS::is_negotiated() const { - return _JS_GET(negotiated, false); + return godot_js_rtc_datachannel_is_negotiated(_js_id); } WebRTCDataChannelJS::WebRTCDataChannelJS() { @@ -264,101 +194,22 @@ WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) { _write_mode = WRITE_MODE_BINARY; _js_id = js_id; - /* clang-format off */ - EM_ASM({ - var c_ptr = $0; - var dict = Module.IDHandler.get($1); - if (!dict) return; - var channel = dict["channel"]; - dict["ptr"] = c_ptr; - - channel.binaryType = "arraybuffer"; - channel.onopen = function (evt) { - ccall("_emrtc_on_ch_open", - "void", - ["number"], - [c_ptr] - ); - }; - channel.onclose = function (evt) { - ccall("_emrtc_on_ch_close", - "void", - ["number"], - [c_ptr] - ); - }; - channel.onerror = function (evt) { - ccall("_emrtc_on_ch_error", - "void", - ["number"], - [c_ptr] - ); - }; - channel.onmessage = function(event) { - var buffer; - var is_string = 0; - if (event.data instanceof ArrayBuffer) { - buffer = new Uint8Array(event.data); - } else if (event.data instanceof Blob) { - console.error("Blob type not supported"); - return; - } else if (typeof event.data === "string") { - is_string = 1; - var enc = new TextEncoder("utf-8"); - buffer = new Uint8Array(enc.encode(event.data)); - } else { - console.error("Unknown message type"); - return; - } - var len = buffer.length*buffer.BYTES_PER_ELEMENT; - var out = _malloc(len); - HEAPU8.set(buffer, out); - ccall("_emrtc_on_ch_message", - "void", - ["number", "number", "number", "number"], - [c_ptr, out, len, is_string] - ); - _free(out); - } - - }, this, js_id); + godot_js_rtc_datachannel_connect(js_id, this, &_on_open, &_on_message, &_on_error, &_on_close); // Parse label - char *str; - str = (char *)EM_ASM_INT({ - var dict = Module.IDHandler.get($0); - if (!dict || !dict["channel"]) return 0; - var str = dict["channel"].label; - var len = lengthBytesUTF8(str)+1; - var ptr = _malloc(str); - stringToUTF8(str, ptr, len+1); - return ptr; - }, js_id); - if(str != nullptr) { - _label.parse_utf8(str); - EM_ASM({ _free($0) }, str); + char *label = godot_js_rtc_datachannel_label_get(js_id); + if (label) { + _label.parse_utf8(label); + free(label); } - str = (char *)EM_ASM_INT({ - var dict = Module.IDHandler.get($0); - if (!dict || !dict["channel"]) return 0; - var str = dict["channel"].protocol; - var len = lengthBytesUTF8(str)+1; - var ptr = _malloc(str); - stringToUTF8(str, ptr, len+1); - return ptr; - }, js_id); - if(str != nullptr) { - _protocol.parse_utf8(str); - EM_ASM({ _free($0) }, str); + char *protocol = godot_js_rtc_datachannel_protocol_get(js_id); + if (protocol) { + _protocol.parse_utf8(protocol); + free(protocol); } - /* clang-format on */ } WebRTCDataChannelJS::~WebRTCDataChannelJS() { close(); - /* clang-format off */ - EM_ASM({ - Module.IDHandler.remove($0); - }, _js_id); - /* clang-format on */ -}; + godot_js_rtc_datachannel_destroy(_js_id); +} #endif diff --git a/modules/webrtc/webrtc_data_channel_js.h b/modules/webrtc/webrtc_data_channel_js.h index 7545910e66..e251760019 100644 --- a/modules/webrtc/webrtc_data_channel_js.h +++ b/modules/webrtc/webrtc_data_channel_js.h @@ -54,12 +54,12 @@ private: int queue_count; uint8_t packet_buffer[PACKET_BUFFER_SIZE]; -public: - void _on_open(); - void _on_close(); - void _on_error(); - void _on_message(uint8_t *p_data, uint32_t p_size, bool p_is_string); + static void _on_open(void *p_obj); + static void _on_close(void *p_obj); + static void _on_error(void *p_obj); + static void _on_message(void *p_obj, const uint8_t *p_data, int p_size, int p_is_string); +public: virtual void set_write_mode(WriteMode mode) override; virtual WriteMode get_write_mode() const override; virtual bool was_string_packet() const override; diff --git a/modules/webrtc/webrtc_peer_connection_js.cpp b/modules/webrtc/webrtc_peer_connection_js.cpp index 593c3a5162..ad9b46a8af 100644 --- a/modules/webrtc/webrtc_peer_connection_js.cpp +++ b/modules/webrtc/webrtc_peer_connection_js.cpp @@ -37,116 +37,32 @@ #include "core/io/json.h" #include "emscripten.h" -extern "C" { -EMSCRIPTEN_KEEPALIVE void _emrtc_on_ice_candidate(void *obj, char *p_MidName, int p_MlineIndexName, char *p_sdpName) { - WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(obj); - peer->emit_signal("ice_candidate_created", String(p_MidName), p_MlineIndexName, String(p_sdpName)); +void WebRTCPeerConnectionJS::_on_ice_candidate(void *p_obj, const char *p_mid_name, int p_mline_idx, const char *p_candidate) { + WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(p_obj); + peer->emit_signal("ice_candidate_created", String(p_mid_name), p_mline_idx, String(p_candidate)); } -EMSCRIPTEN_KEEPALIVE void _emrtc_session_description_created(void *obj, char *p_type, char *p_offer) { - WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(obj); - peer->emit_signal("session_description_created", String(p_type), String(p_offer)); +void WebRTCPeerConnectionJS::_on_session_created(void *p_obj, const char *p_type, const char *p_session) { + WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(p_obj); + peer->emit_signal("session_description_created", String(p_type), String(p_session)); } -EMSCRIPTEN_KEEPALIVE void _emrtc_on_connection_state_changed(void *obj) { - WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(obj); - peer->_on_connection_state_changed(); +void WebRTCPeerConnectionJS::_on_connection_state_changed(void *p_obj, int p_state) { + WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(p_obj); + peer->_conn_state = (ConnectionState)p_state; } -EMSCRIPTEN_KEEPALIVE void _emrtc_on_error() { +void WebRTCPeerConnectionJS::_on_error(void *p_obj) { ERR_PRINT("RTCPeerConnection error!"); } -EMSCRIPTEN_KEEPALIVE void _emrtc_emit_channel(void *obj, int p_id) { - WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(obj); +void WebRTCPeerConnectionJS::_on_data_channel(void *p_obj, int p_id) { + WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(p_obj); peer->emit_signal("data_channel_received", Ref<WebRTCDataChannelJS>(new WebRTCDataChannelJS(p_id))); } -} - -void _emrtc_create_pc(int p_id, const Dictionary &p_config) { - String config = JSON::print(p_config); - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - var c_ptr = dict["ptr"]; - var config = JSON.parse(UTF8ToString($1)); - // Setup local connaction - var conn = null; - try { - conn = new RTCPeerConnection(config); - } catch (e) { - console.log(e); - return; - } - conn.oniceconnectionstatechange = function(event) { - if (!Module.IDHandler.get($0)) return; - ccall("_emrtc_on_connection_state_changed", "void", ["number"], [c_ptr]); - }; - conn.onicecandidate = function(event) { - if (!Module.IDHandler.get($0)) return; - if (!event.candidate) return; - - var c = event.candidate; - // should emit on ice candidate - ccall("_emrtc_on_ice_candidate", - "void", - ["number", "string", "number", "string"], - [c_ptr, c.sdpMid, c.sdpMLineIndex, c.candidate] - ); - }; - conn.ondatachannel = function (evt) { - var dict = Module.IDHandler.get($0); - if (!dict) { - return; - } - var id = Module.IDHandler.add({"channel": evt.channel, "ptr": null}); - ccall("_emrtc_emit_channel", - "void", - ["number", "number"], - [c_ptr, id] - ); - }; - dict["conn"] = conn; - }, p_id, config.utf8().get_data()); - /* clang-format on */ -} - -void WebRTCPeerConnectionJS::_on_connection_state_changed() { - /* clang-format off */ - _conn_state = (ConnectionState)EM_ASM_INT({ - var dict = Module.IDHandler.get($0); - if (!dict) return 5; // CLOSED - var conn = dict["conn"]; - switch(conn.iceConnectionState) { - case "new": - return 0; - case "checking": - return 1; - case "connected": - case "completed": - return 2; - case "disconnected": - return 3; - case "failed": - return 4; - case "closed": - return 5; - } - return 5; // CLOSED - }, _js_id); - /* clang-format on */ -} void WebRTCPeerConnectionJS::close() { - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - if (!dict) return; - if (dict["conn"]) { - dict["conn"].close(); - } - }, _js_id); - /* clang-format on */ + godot_js_rtc_pc_close(_js_id); _conn_state = STATE_CLOSED; } @@ -154,46 +70,12 @@ Error WebRTCPeerConnectionJS::create_offer() { ERR_FAIL_COND_V(_conn_state != STATE_NEW, FAILED); _conn_state = STATE_CONNECTING; - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - var conn = dict["conn"]; - var c_ptr = dict["ptr"]; - var onError = function(error) { - console.error(error); - ccall("_emrtc_on_error", "void", [], []); - }; - var onCreated = function(offer) { - ccall("_emrtc_session_description_created", - "void", - ["number", "string", "string"], - [c_ptr, offer.type, offer.sdp] - ); - }; - conn.createOffer().then(onCreated).catch(onError); - }, _js_id); - /* clang-format on */ + godot_js_rtc_pc_offer_create(_js_id, this, &_on_session_created, &_on_error); return OK; } Error WebRTCPeerConnectionJS::set_local_description(String type, String sdp) { - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - var conn = dict["conn"]; - var c_ptr = dict["ptr"]; - var type = UTF8ToString($1); - var sdp = UTF8ToString($2); - var onError = function(error) { - console.error(error); - ccall("_emrtc_on_error", "void", [], []); - }; - conn.setLocalDescription({ - "sdp": sdp, - "type": type - }).catch(onError); - }, _js_id, type.utf8().get_data(), sdp.utf8().get_data()); - /* clang-format on */ + godot_js_rtc_pc_local_description_set(_js_id, type.utf8().get_data(), sdp.utf8().get_data(), this, &_on_error); return OK; } @@ -202,83 +84,32 @@ Error WebRTCPeerConnectionJS::set_remote_description(String type, String sdp) { ERR_FAIL_COND_V(_conn_state != STATE_NEW, FAILED); _conn_state = STATE_CONNECTING; } - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - var conn = dict["conn"]; - var c_ptr = dict["ptr"]; - var type = UTF8ToString($1); - var sdp = UTF8ToString($2); - - var onError = function(error) { - console.error(error); - ccall("_emrtc_on_error", "void", [], []); - }; - var onCreated = function(offer) { - ccall("_emrtc_session_description_created", - "void", - ["number", "string", "string"], - [c_ptr, offer.type, offer.sdp] - ); - }; - var onSet = function() { - if (type != "offer") { - return; - } - conn.createAnswer().then(onCreated); - }; - conn.setRemoteDescription({ - "sdp": sdp, - "type": type - }).then(onSet).catch(onError); - }, _js_id, type.utf8().get_data(), sdp.utf8().get_data()); - /* clang-format on */ + godot_js_rtc_pc_remote_description_set(_js_id, type.utf8().get_data(), sdp.utf8().get_data(), this, &_on_session_created, &_on_error); return OK; } Error WebRTCPeerConnectionJS::add_ice_candidate(String sdpMidName, int sdpMlineIndexName, String sdpName) { - /* clang-format off */ - EM_ASM({ - var dict = Module.IDHandler.get($0); - var conn = dict["conn"]; - var c_ptr = dict["ptr"]; - var sdpMidName = UTF8ToString($1); - var sdpMlineIndexName = UTF8ToString($2); - var sdpName = UTF8ToString($3); - conn.addIceCandidate(new RTCIceCandidate({ - "candidate": sdpName, - "sdpMid": sdpMidName, - "sdpMlineIndex": sdpMlineIndexName - })); - }, _js_id, sdpMidName.utf8().get_data(), sdpMlineIndexName, sdpName.utf8().get_data()); - /* clang-format on */ + godot_js_rtc_pc_ice_candidate_add(_js_id, sdpMidName.utf8().get_data(), sdpMlineIndexName, sdpName.utf8().get_data()); return OK; } Error WebRTCPeerConnectionJS::initialize(Dictionary p_config) { - _emrtc_create_pc(_js_id, p_config); - return OK; + if (_js_id) { + godot_js_rtc_pc_destroy(_js_id); + _js_id = 0; + } + _conn_state = STATE_NEW; + + String config = JSON::print(p_config); + _js_id = godot_js_rtc_pc_create(config.utf8().get_data(), this, &_on_connection_state_changed, &_on_ice_candidate, &_on_data_channel); + return _js_id ? OK : FAILED; } Ref<WebRTCDataChannel> WebRTCPeerConnectionJS::create_data_channel(String p_channel, Dictionary p_channel_config) { + ERR_FAIL_COND_V(_conn_state != STATE_NEW, nullptr); + String config = JSON::print(p_channel_config); - /* clang-format off */ - int id = EM_ASM_INT({ - try { - var dict = Module.IDHandler.get($0); - if (!dict) return 0; - var label = UTF8ToString($1); - var config = JSON.parse(UTF8ToString($2)); - var conn = dict["conn"]; - return Module.IDHandler.add({ - "channel": conn.createDataChannel(label, config), - "ptr": null - }) - } catch (e) { - return 0; - } - }, _js_id, p_channel.utf8().get_data(), config.utf8().get_data()); - /* clang-format on */ + int id = godot_js_rtc_pc_datachannel_create(_js_id, p_channel.utf8().get_data(), config.utf8().get_data()); ERR_FAIL_COND_V(id == 0, nullptr); return memnew(WebRTCDataChannelJS(id)); } @@ -293,22 +124,17 @@ WebRTCPeerConnection::ConnectionState WebRTCPeerConnectionJS::get_connection_sta WebRTCPeerConnectionJS::WebRTCPeerConnectionJS() { _conn_state = STATE_NEW; + _js_id = 0; - /* clang-format off */ - _js_id = EM_ASM_INT({ - return Module.IDHandler.add({"conn": null, "ptr": $0}); - }, this); - /* clang-format on */ Dictionary config; - _emrtc_create_pc(_js_id, config); + initialize(config); } WebRTCPeerConnectionJS::~WebRTCPeerConnectionJS() { close(); - /* clang-format off */ - EM_ASM({ - Module.IDHandler.remove($0); - }, _js_id); - /* clang-format on */ + if (_js_id) { + godot_js_rtc_pc_destroy(_js_id); + _js_id = 0; + } }; #endif diff --git a/modules/webrtc/webrtc_peer_connection_js.h b/modules/webrtc/webrtc_peer_connection_js.h index cdaf3068e3..e33dd5f259 100644 --- a/modules/webrtc/webrtc_peer_connection_js.h +++ b/modules/webrtc/webrtc_peer_connection_js.h @@ -35,16 +35,37 @@ #include "webrtc_peer_connection.h" +extern "C" { +typedef void (*RTCOnIceConnectionStateChange)(void *p_obj, int p_state); +typedef void (*RTCOnIceCandidate)(void *p_obj, const char *p_mid, int p_mline_idx, const char *p_candidate); +typedef void (*RTCOnDataChannel)(void *p_obj, int p_id); +typedef void (*RTCOnSession)(void *p_obj, const char *p_type, const char *p_sdp); +typedef void (*RTCOnError)(void *p_obj); +extern int godot_js_rtc_pc_create(const char *p_config, void *p_obj, RTCOnIceConnectionStateChange p_on_state_change, RTCOnIceCandidate p_on_candidate, RTCOnDataChannel p_on_datachannel); +extern void godot_js_rtc_pc_close(int p_id); +extern void godot_js_rtc_pc_destroy(int p_id); +extern void godot_js_rtc_pc_offer_create(int p_id, void *p_obj, RTCOnSession p_on_session, RTCOnError p_on_error); +extern void godot_js_rtc_pc_local_description_set(int p_id, const char *p_type, const char *p_sdp, void *p_obj, RTCOnError p_on_error); +extern void godot_js_rtc_pc_remote_description_set(int p_id, const char *p_type, const char *p_sdp, void *p_obj, RTCOnSession p_on_session, RTCOnError p_on_error); +extern void godot_js_rtc_pc_ice_candidate_add(int p_id, const char *p_mid_name, int p_mline_idx, const char *p_sdo); +extern int godot_js_rtc_pc_datachannel_create(int p_id, const char *p_label, const char *p_config); +} + class WebRTCPeerConnectionJS : public WebRTCPeerConnection { private: int _js_id; ConnectionState _conn_state; + static void _on_connection_state_changed(void *p_obj, int p_state); + static void _on_ice_candidate(void *p_obj, const char *p_mid_name, int p_mline_idx, const char *p_candidate); + static void _on_data_channel(void *p_obj, int p_channel); + static void _on_session_created(void *p_obj, const char *p_type, const char *p_session); + static void _on_error(void *p_obj); + public: static WebRTCPeerConnection *_create() { return memnew(WebRTCPeerConnectionJS); } static void make_default() { WebRTCPeerConnection::_create = WebRTCPeerConnectionJS::_create; } - void _on_connection_state_changed(); virtual ConnectionState get_connection_state() const; virtual Error initialize(Dictionary configuration = Dictionary()); diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub index af60055855..13e51a39c0 100644 --- a/modules/websocket/SCsub +++ b/modules/websocket/SCsub @@ -3,11 +3,13 @@ Import("env") Import("env_modules") -# Thirdparty source files - env_ws = env_modules.Clone() -if env["builtin_wslay"] and not env["platform"] == "javascript": # already builtin for javascript +if env["platform"] == "javascript": + # Our JavaScript/C++ interface. + env.AddJSLibraries(["library_godot_websocket.js"]) +elif env["builtin_wslay"]: + # Thirdparty source files wslay_dir = "#thirdparty/wslay/" wslay_sources = [ "wslay_net.c", diff --git a/modules/websocket/editor_debugger_server_websocket.cpp b/modules/websocket/editor_debugger_server_websocket.cpp index 95ea7ceafa..8eb975b323 100644 --- a/modules/websocket/editor_debugger_server_websocket.cpp +++ b/modules/websocket/editor_debugger_server_websocket.cpp @@ -30,7 +30,7 @@ #include "editor_debugger_server_websocket.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "editor/editor_settings.h" #include "modules/websocket/remote_debugger_peer_websocket.h" diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 7c31449709..d6e00a26af 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -31,18 +31,17 @@ #ifdef JAVASCRIPT_ENABLED #include "emws_client.h" +#include "core/config/project_settings.h" #include "core/io/ip.h" -#include "core/project_settings.h" #include "emscripten.h" -extern "C" { -EMSCRIPTEN_KEEPALIVE void _esws_on_connect(void *obj, char *proto) { +void EMWSClient::_esws_on_connect(void *obj, char *proto) { EMWSClient *client = static_cast<EMWSClient *>(obj); client->_is_connecting = false; client->_on_connect(String(proto)); } -EMSCRIPTEN_KEEPALIVE void _esws_on_message(void *obj, uint8_t *p_data, int p_data_size, int p_is_string) { +void EMWSClient::_esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string) { EMWSClient *client = static_cast<EMWSClient *>(obj); Error err = static_cast<EMWSPeer *>(*client->get_peer(1))->read_msg(p_data, p_data_size, p_is_string == 1); @@ -50,21 +49,26 @@ EMSCRIPTEN_KEEPALIVE void _esws_on_message(void *obj, uint8_t *p_data, int p_dat client->_on_peer_packet(); } -EMSCRIPTEN_KEEPALIVE void _esws_on_error(void *obj) { +void EMWSClient::_esws_on_error(void *obj) { EMWSClient *client = static_cast<EMWSClient *>(obj); client->_is_connecting = false; client->_on_error(); } -EMSCRIPTEN_KEEPALIVE void _esws_on_close(void *obj, int code, char *reason, int was_clean) { +void EMWSClient::_esws_on_close(void *obj, int code, const char *reason, int was_clean) { EMWSClient *client = static_cast<EMWSClient *>(obj); client->_on_close_request(code, String(reason)); client->_is_connecting = false; + client->disconnect_from_host(); client->_on_disconnect(was_clean != 0); } -} Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocols, const Vector<String> p_custom_headers) { + if (_js_id) { + godot_js_websocket_destroy(_js_id); + _js_id = 0; + } + String proto_string; for (int i = 0; i < p_protocols.size(); i++) { if (i != 0) @@ -84,106 +88,17 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, } } str += p_host + ":" + itos(p_port) + p_path; - _is_connecting = true; - /* clang-format off */ - int peer_sock = EM_ASM_INT({ - var proto_str = UTF8ToString($2); - var socket = null; - try { - if (proto_str) { - socket = new WebSocket(UTF8ToString($1), proto_str.split(",")); - } else { - socket = new WebSocket(UTF8ToString($1)); - } - } catch (e) { - return -1; - } - var c_ptr = Module.IDHandler.get($0); - socket.binaryType = "arraybuffer"; - - // Connection opened - socket.addEventListener("open", function (event) { - if (!Module.IDHandler.has($0)) - return; // Godot Object is gone! - ccall("_esws_on_connect", - "void", - ["number", "string"], - [c_ptr, socket.protocol] - ); - }); - - // Listen for messages - socket.addEventListener("message", function (event) { - if (!Module.IDHandler.has($0)) - return; // Godot Object is gone! - var buffer; - var is_string = 0; - if (event.data instanceof ArrayBuffer) { - - buffer = new Uint8Array(event.data); - - } else if (event.data instanceof Blob) { - - alert("Blob type not supported"); - return; - - } else if (typeof event.data === "string") { - - is_string = 1; - var enc = new TextEncoder("utf-8"); - buffer = new Uint8Array(enc.encode(event.data)); - - } else { - - alert("Unknown message type"); - return; - - } - var len = buffer.length*buffer.BYTES_PER_ELEMENT; - var out = _malloc(len); - HEAPU8.set(buffer, out); - ccall("_esws_on_message", - "void", - ["number", "number", "number", "number"], - [c_ptr, out, len, is_string] - ); - _free(out); - }); - - socket.addEventListener("error", function (event) { - if (!Module.IDHandler.has($0)) - return; // Godot Object is gone! - ccall("_esws_on_error", - "void", - ["number"], - [c_ptr] - ); - }); - - socket.addEventListener("close", function (event) { - if (!Module.IDHandler.has($0)) - return; // Godot Object is gone! - var was_clean = 0; - if (event.wasClean) - was_clean = 1; - ccall("_esws_on_close", - "void", - ["number", "number", "string", "number"], - [c_ptr, event.code, event.reason, was_clean] - ); - }); - - return Module.IDHandler.add(socket); - }, _js_id, str.utf8().get_data(), proto_string.utf8().get_data()); - /* clang-format on */ - if (peer_sock == -1) + + _js_id = godot_js_websocket_create(this, str.utf8().get_data(), proto_string.utf8().get_data(), &_esws_on_connect, &_esws_on_message, &_esws_on_error, &_esws_on_close); + if (!_js_id) { return FAILED; + } - static_cast<Ref<EMWSPeer>>(_peer)->set_sock(peer_sock, _in_buf_size, _in_pkt_size); + static_cast<Ref<EMWSPeer>>(_peer)->set_sock(_js_id, _in_buf_size, _in_pkt_size); return OK; -}; +} void EMWSClient::poll() { } @@ -200,19 +115,19 @@ NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() c } return CONNECTION_DISCONNECTED; -}; +} void EMWSClient::disconnect_from_host(int p_code, String p_reason) { _peer->close(p_code, p_reason); -}; +} IP_Address EMWSClient::get_connected_host() const { ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export."); -}; +} uint16_t EMWSClient::get_connected_port() const { ERR_FAIL_V_MSG(0, "Not supported in HTML5 export."); -}; +} int EMWSClient::get_max_packet_size() const { return (1 << _in_buf_size) - PROTO_SIZE; @@ -227,24 +142,17 @@ Error EMWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffe EMWSClient::EMWSClient() { _in_buf_size = DEF_BUF_SHIFT; _in_pkt_size = DEF_PKT_SHIFT; - _is_connecting = false; _peer = Ref<EMWSPeer>(memnew(EMWSPeer)); - /* clang-format off */ - _js_id = EM_ASM_INT({ - return Module.IDHandler.add($0); - }, this); - /* clang-format on */ -}; + _js_id = 0; +} EMWSClient::~EMWSClient() { disconnect_from_host(); _peer = Ref<EMWSPeer>(); - /* clang-format off */ - EM_ASM({ - Module.IDHandler.remove($0); - }, _js_id); - /* clang-format on */ -}; + if (_js_id) { + godot_js_websocket_destroy(_js_id); + } +} #endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index ab8a0612bb..0123c37457 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -33,7 +33,7 @@ #ifdef JAVASCRIPT_ENABLED -#include "core/error_list.h" +#include "core/error/error_list.h" #include "emws_peer.h" #include "websocket_client.h" @@ -41,13 +41,17 @@ class EMWSClient : public WebSocketClient { GDCIIMPL(EMWSClient, WebSocketClient); private: + int _js_id; + bool _is_connecting; int _in_buf_size; int _in_pkt_size; - int _js_id; -public: - bool _is_connecting; + static void _esws_on_connect(void *obj, char *proto); + static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string); + static void _esws_on_error(void *obj); + static void _esws_on_close(void *obj, int code, const char *reason, int was_clean); +public: Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets); Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocol = Vector<String>(), const Vector<String> p_custom_headers = Vector<String>()); Ref<WebSocketPeer> get_peer(int p_peer_id) const; diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 749f45451a..5dcfba5567 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -47,38 +47,14 @@ EMWSPeer::WriteMode EMWSPeer::get_write_mode() const { return write_mode; } -Error EMWSPeer::read_msg(uint8_t *p_data, uint32_t p_size, bool p_is_string) { +Error EMWSPeer::read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string) { uint8_t is_string = p_is_string ? 1 : 0; return _in_buffer.write_packet(p_data, p_size, &is_string); } Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { int is_bin = write_mode == WebSocketPeer::WRITE_MODE_BINARY ? 1 : 0; - - /* clang-format off */ - EM_ASM({ - var sock = Module.IDHandler.get($0); - var bytes_array = new Uint8Array($2); - var i = 0; - - for(i=0; i<$2; i++) { - bytes_array[i] = getValue($1+i, 'i8'); - } - - try { - if ($3) { - sock.send(bytes_array.buffer); - } else { - var string = new TextDecoder("utf-8").decode(bytes_array); - sock.send(string); - } - } catch (e) { - return 1; - } - return 0; - }, peer_sock, p_buffer, p_buffer_size, is_bin); - /* clang-format on */ - + godot_js_websocket_send(peer_sock, p_buffer, p_buffer_size, is_bin); return OK; }; @@ -110,15 +86,7 @@ bool EMWSPeer::is_connected_to_host() const { void EMWSPeer::close(int p_code, String p_reason) { if (peer_sock != -1) { - /* clang-format off */ - EM_ASM({ - var sock = Module.IDHandler.get($0); - var code = $1; - var reason = UTF8ToString($2); - sock.close(code, reason); - Module.IDHandler.remove($0); - }, peer_sock, p_code, p_reason.utf8().get_data()); - /* clang-format on */ + godot_js_websocket_close(peer_sock, p_code, p_reason.utf8().get_data()); } _is_string = 0; _in_buffer.clear(); diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index 9c00f2d58b..2291a32bbc 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -33,13 +33,25 @@ #ifdef JAVASCRIPT_ENABLED -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/io/packet_peer.h" -#include "core/ring_buffer.h" +#include "core/templates/ring_buffer.h" #include "emscripten.h" #include "packet_buffer.h" #include "websocket_peer.h" +extern "C" { +typedef void (*WSOnOpen)(void *p_ref, char *p_protocol); +typedef void (*WSOnMessage)(void *p_ref, const uint8_t *p_buf, int p_buf_len, int p_is_string); +typedef void (*WSOnClose)(void *p_ref, int p_code, const char *p_reason, int p_is_clean); +typedef void (*WSOnError)(void *p_ref); + +extern int godot_js_websocket_create(void *p_ref, const char *p_url, const char *p_proto, WSOnOpen p_on_open, WSOnMessage p_on_message, WSOnError p_on_error, WSOnClose p_on_close); +extern int godot_js_websocket_send(int p_id, const uint8_t *p_buf, int p_buf_len, int p_raw); +extern void godot_js_websocket_close(int p_id, int p_code, const char *p_reason); +extern void godot_js_websocket_destroy(int p_id); +} + class EMWSPeer : public WebSocketPeer { GDCIIMPL(EMWSPeer, WebSocketPeer); @@ -52,7 +64,7 @@ private: uint8_t _is_string; public: - Error read_msg(uint8_t *p_data, uint32_t p_size, bool p_is_string); + Error read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string); void set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size); virtual int get_available_packet_count() const; virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h index bb6f35a711..1ce17855fe 100644 --- a/modules/websocket/emws_server.h +++ b/modules/websocket/emws_server.h @@ -33,7 +33,7 @@ #ifdef JAVASCRIPT_ENABLED -#include "core/reference.h" +#include "core/object/reference.h" #include "emws_peer.h" #include "websocket_server.h" diff --git a/modules/websocket/library_godot_websocket.js b/modules/websocket/library_godot_websocket.js new file mode 100644 index 0000000000..f7d3195807 --- /dev/null +++ b/modules/websocket/library_godot_websocket.js @@ -0,0 +1,187 @@ +/*************************************************************************/ +/* library_godot_websocket.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +var GodotWebSocket = { + + // Our socket implementation that forwards events to C++. + $GodotWebSocket__deps: ['$IDHandler'], + $GodotWebSocket: { + // Connection opened, report selected protocol + _onopen: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; // Godot object is gone. + } + let c_str = GodotOS.allocString(ref.protocol); + callback(c_str); + _free(c_str); + }, + + // Message received, report content and type (UTF8 vs binary) + _onmessage: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; // Godot object is gone. + } + var buffer; + var is_string = 0; + if (event.data instanceof ArrayBuffer) { + buffer = new Uint8Array(event.data); + } else if (event.data instanceof Blob) { + alert("Blob type not supported"); + return; + } else if (typeof event.data === "string") { + is_string = 1; + var enc = new TextEncoder("utf-8"); + buffer = new Uint8Array(enc.encode(event.data)); + } else { + alert("Unknown message type"); + return; + } + var len = buffer.length*buffer.BYTES_PER_ELEMENT; + var out = _malloc(len); + HEAPU8.set(buffer, out); + callback(out, len, is_string); + _free(out); + }, + + // An error happened, 'onclose' will be called after this. + _onerror: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; // Godot object is gone. + } + callback(); + }, + + // Connection is closed, this is always fired. Report close code, reason, and clean status. + _onclose: function(p_id, callback, event) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; // Godot object is gone. + } + let c_str = GodotOS.allocString(event.reason); + callback(event.code, c_str, event.wasClean ? 1 : 0); + _free(c_str); + }, + + // Send a message + send: function(p_id, p_data) { + const ref = IDHandler.get(p_id); + if (!ref || ref.readyState != ref.OPEN) { + return 1; // Godot object is gone or socket is not in a ready state. + } + ref.send(p_data); + return 0; + }, + + create: function(socket, p_on_open, p_on_message, p_on_error, p_on_close) { + const id = IDHandler.add(socket); + socket.onopen = GodotWebSocket._onopen.bind(null, id, p_on_open); + socket.onmessage = GodotWebSocket._onmessage.bind(null, id, p_on_message); + socket.onerror = GodotWebSocket._onerror.bind(null, id, p_on_error); + socket.onclose = GodotWebSocket._onclose.bind(null, id, p_on_close); + return id; + }, + + // Closes the JavaScript WebSocket (if not already closing) associated to a given C++ object. + close: function(p_id, p_code, p_reason) { + const ref = IDHandler.get(p_id); + if (ref && ref.readyState < ref.CLOSING) { + const code = p_code; + const reason = UTF8ToString(p_reason); + ref.close(code, reason); + } + }, + + // Deletes the reference to a C++ object (closing any connected socket if necessary). + destroy: function(p_id) { + const ref = IDHandler.get(p_id); + if (!ref) { + return; + } + GodotWebSocket.close(p_id, 1001, ''); + IDHandler.remove(p_id); + ref.onopen = null; + ref.onmessage = null; + ref.onerror = null; + ref.onclose = null; + }, + }, + + godot_js_websocket_create: function(p_ref, p_url, p_proto, p_on_open, p_on_message, p_on_error, p_on_close) { + const on_open = GodotOS.get_func(p_on_open).bind(null, p_ref); + const on_message = GodotOS.get_func(p_on_message).bind(null, p_ref); + const on_error = GodotOS.get_func(p_on_error).bind(null, p_ref); + const on_close = GodotOS.get_func(p_on_close).bind(null, p_ref); + const url = UTF8ToString(p_url); + const protos = UTF8ToString(p_proto); + var socket = null; + try { + if (protos) { + socket = new WebSocket(url, protos.split(",")); + } else { + socket = new WebSocket(url); + } + } catch (e) { + return 0; + } + socket.binaryType = "arraybuffer"; + return GodotWebSocket.create(socket, on_open, on_message, on_error, on_close); + }, + + godot_js_websocket_send: function(p_id, p_buf, p_buf_len, p_raw) { + var bytes_array = new Uint8Array(p_buf_len); + var i = 0; + for(i = 0; i < p_buf_len; i++) { + bytes_array[i] = getValue(p_buf + i, 'i8'); + } + var out = bytes_array; + if (p_raw) { + out = bytes_array.buffer; + } else { + out = new TextDecoder("utf-8").decode(bytes_array); + } + return GodotWebSocket.send(p_id, out); + }, + + godot_js_websocket_close: function(p_id, p_code, p_reason) { + const code = p_code; + const reason = UTF8ToString(p_reason); + GodotWebSocket.close(p_id, code, reason); + }, + + godot_js_websocket_destroy: function(p_id) { + GodotWebSocket.destroy(p_id); + }, +}; + +autoAddDeps(GodotWebSocket, '$GodotWebSocket') +mergeInto(LibraryManager.library, GodotWebSocket); diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h index 9973efe297..18b47b8d50 100644 --- a/modules/websocket/packet_buffer.h +++ b/modules/websocket/packet_buffer.h @@ -32,7 +32,7 @@ #define PACKET_BUFFER_H #include "core/os/copymem.h" -#include "core/ring_buffer.h" +#include "core/templates/ring_buffer.h" template <class T> class PacketBuffer { diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp index bc50de414e..8979a09619 100644 --- a/modules/websocket/register_types.cpp +++ b/modules/websocket/register_types.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "register_types.h" -#include "core/error_macros.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/error/error_macros.h" #ifdef JAVASCRIPT_ENABLED #include "emscripten.h" #include "emws_client.h" diff --git a/modules/websocket/remote_debugger_peer_websocket.cpp b/modules/websocket/remote_debugger_peer_websocket.cpp index a67a959e31..9a72e460e2 100644 --- a/modules/websocket/remote_debugger_peer_websocket.cpp +++ b/modules/websocket/remote_debugger_peer_websocket.cpp @@ -30,7 +30,7 @@ #include "remote_debugger_peer_websocket.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" Error RemoteDebuggerPeerWebSocket::connect_to_host(const String &p_uri) { Vector<String> protocols; diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index 1053be22e3..2966dc480b 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -32,7 +32,7 @@ #define WEBSOCKET_CLIENT_H #include "core/crypto/crypto.h" -#include "core/error_list.h" +#include "core/error/error_list.h" #include "websocket_multiplayer_peer.h" #include "websocket_peer.h" diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index af26aef21e..54daae23a6 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -31,9 +31,9 @@ #ifndef WEBSOCKET_MULTIPLAYER_PEER_H #define WEBSOCKET_MULTIPLAYER_PEER_H -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/io/networked_multiplayer_peer.h" -#include "core/list.h" +#include "core/templates/list.h" #include "websocket_peer.h" class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer { diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index a61943b615..729fdfd340 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -31,7 +31,7 @@ #ifndef WEBSOCKETPEER_H #define WEBSOCKETPEER_H -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/io/packet_peer.h" #include "websocket_macros.h" diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index 064ad4f179..34ae52a1ee 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -32,7 +32,7 @@ #define WEBSOCKET_H #include "core/crypto/crypto.h" -#include "core/reference.h" +#include "core/object/reference.h" #include "websocket_multiplayer_peer.h" #include "websocket_peer.h" diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 7d16c2e99f..a2b81438df 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -31,8 +31,8 @@ #ifndef JAVASCRIPT_ENABLED #include "wsl_client.h" +#include "core/config/project_settings.h" #include "core/io/ip.h" -#include "core/project_settings.h" void WSLClient::_do_handshake() { if (_requested < _request.size() - 1) { diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 8355a5a737..0141ea93ea 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -33,7 +33,7 @@ #ifndef JAVASCRIPT_ENABLED -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/io/stream_peer_ssl.h" #include "core/io/stream_peer_tcp.h" #include "websocket_client.h" diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index fe4abfb64c..35ac18615a 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -33,10 +33,10 @@ #ifndef JAVASCRIPT_ENABLED -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/io/packet_peer.h" #include "core/io/stream_peer_tcp.h" -#include "core/ring_buffer.h" +#include "core/templates/ring_buffer.h" #include "packet_buffer.h" #include "websocket_peer.h" #include "wslay/wslay.h" diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index da7bfc70c0..9a05967e4e 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -31,8 +31,8 @@ #ifndef JAVASCRIPT_ENABLED #include "wsl_server.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" WSLServer::PendingPeer::PendingPeer() { use_ssl = false; diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 6242009f67..65350518c3 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/crypto/crypto_core.h" diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp index 1f140f7119..8b82733d2d 100644 --- a/platform/android/api/api.cpp +++ b/platform/android/api/api.cpp @@ -30,7 +30,7 @@ #include "api.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "java_class_wrapper.h" #include "jni_singleton.h" diff --git a/platform/android/api/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h index 1fa2726784..4718de29ad 100644 --- a/platform/android/api/java_class_wrapper.h +++ b/platform/android/api/java_class_wrapper.h @@ -31,7 +31,7 @@ #ifndef JAVA_CLASS_WRAPPER_H #define JAVA_CLASS_WRAPPER_H -#include "core/reference.h" +#include "core/object/reference.h" #ifdef ANDROID_ENABLED #include <android/log.h> diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h index 5e63f20d6c..7f20c354a0 100644 --- a/platform/android/api/jni_singleton.h +++ b/platform/android/api/jni_singleton.h @@ -31,8 +31,8 @@ #ifndef JNI_SINGLETON_H #define JNI_SINGLETON_H -#include <core/engine.h> -#include <core/variant.h> +#include <core/config/engine.h> +#include <core/variant/variant.h> #ifdef ANDROID_ENABLED #include <platform/android/jni_utils.h> #endif diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index 09c981b3fa..1363c5ac1e 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -30,8 +30,8 @@ #include "audio_driver_jandroid.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "thread_jandroid.h" AudioDriverAndroid *AudioDriverAndroid::s_ad = nullptr; diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index ca312b427f..ba75a4b10c 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "dir_access_jandroid.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "file_access_jandroid.h" #include "string_android.h" #include "thread_jandroid.h" diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index d6d64b0265..e82a12ece5 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -31,7 +31,7 @@ #include "display_server_android.h" #include "android_keys_utils.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "java_godot_io_wrapper.h" #include "java_godot_wrapper.h" #include "os_android.h" diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 943a473717..5007b3f570 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -31,13 +31,13 @@ #include "export.h" #include "gradle_export_util.h" +#include "core/config/project_settings.h" #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "core/version.h" #include "drivers/png/png_driver_common.h" #include "editor/editor_export.h" diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp index 05d5fb576d..11faeff3e8 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "file_access_android.h" -#include "core/print_string.h" +#include "core/string/print_string.h" AAssetManager *FileAccessAndroid::asset_manager = nullptr; diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index eec385f44e..8d1db395ab 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "java_godot_io_wrapper.h" -#include "core/error_list.h" +#include "core/error/error_list.h" // JNIEnv is only valid within the thread it belongs to, in a multi threading environment // we can't cache it. diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 35bd53a958..5dc773fae2 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -37,9 +37,9 @@ #include "api/java_class_wrapper.h" #include "api/jni_singleton.h" #include "audio_driver_jandroid.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "core/input/input.h" -#include "core/project_settings.h" #include "dir_access_jandroid.h" #include "display_server_android.h" #include "file_access_android.h" diff --git a/platform/android/jni_utils.h b/platform/android/jni_utils.h index 5320715853..bda056604f 100644 --- a/platform/android/jni_utils.h +++ b/platform/android/jni_utils.h @@ -32,8 +32,8 @@ #define JNI_UTILS_H #include "string_android.h" -#include <core/engine.h> -#include <core/variant.h> +#include <core/config/engine.h> +#include <core/variant/variant.h> #include <jni.h> struct jvalret { diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index cde3abe20c..00733f6dbb 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -30,8 +30,8 @@ #include "os_android.h" +#include "core/config/project_settings.h" #include "core/io/file_access_buffered_fa.h" -#include "core/project_settings.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "file_access_android.h" diff --git a/platform/android/plugin/godot_plugin_config.h b/platform/android/plugin/godot_plugin_config.h index ea3c7b4f55..ecb9c0c7f5 100644 --- a/platform/android/plugin/godot_plugin_config.h +++ b/platform/android/plugin/godot_plugin_config.h @@ -31,9 +31,9 @@ #ifndef GODOT_PLUGIN_CONFIG_H #define GODOT_PLUGIN_CONFIG_H -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/io/config_file.h" -#include "core/ustring.h" +#include "core/string/ustring.h" static const char *PLUGIN_CONFIG_EXT = ".gdap"; diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp index d2528bebeb..b8e5345b85 100644 --- a/platform/android/plugin/godot_plugin_jni.cpp +++ b/platform/android/plugin/godot_plugin_jni.cpp @@ -30,9 +30,9 @@ #include "godot_plugin_jni.h" -#include <core/engine.h> -#include <core/error_macros.h> -#include <core/project_settings.h> +#include <core/config/engine.h> +#include <core/config/project_settings.h> +#include <core/error/error_macros.h> #include <platform/android/api/jni_singleton.h> #include <platform/android/jni_utils.h> #include <platform/android/string_android.h> diff --git a/platform/android/string_android.h b/platform/android/string_android.h index 88ccd3b652..0a7dbf475d 100644 --- a/platform/android/string_android.h +++ b/platform/android/string_android.h @@ -30,7 +30,7 @@ #ifndef STRING_ANDROID_H #define STRING_ANDROID_H -#include "core/ustring.h" +#include "core/string/ustring.h" #include "thread_jandroid.h" #include <jni.h> diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp index 13aa313ebf..442e4d781b 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -30,9 +30,9 @@ #include "thread_jandroid.h" +#include "core/object/script_language.h" #include "core/os/memory.h" -#include "core/safe_refcount.h" -#include "core/script_language.h" +#include "core/templates/safe_refcount.h" static void _thread_id_key_destr_callback(void *p_value) { memdelete(static_cast<Thread::ID *>(p_value)); diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 1dd37dabe5..0a558f8e3d 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -8,9 +8,6 @@ iphone_lib = [ "main.m", "app_delegate.mm", "view_controller.mm", - "game_center.mm", - "in_app_store.mm", - "icloud.mm", "ios.mm", "vulkan_context_iphone.mm", "display_server_iphone.mm", diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 40a63d7ad2..c1942e77dd 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -29,13 +29,14 @@ /*************************************************************************/ #import "app_delegate.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" #import "godot_view.h" #include "main/main.h" #include "os_iphone.h" #import "view_controller.h" +#import <AVFoundation/AVFoundation.h> #import <AudioToolbox/AudioServices.h> #define kRenderingFrequency 60 diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index 5ebabdd3dc..0456458326 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -35,9 +35,6 @@ def get_opts(): " validation layers)", False, ), - BoolVariable("game_center", "Support for game center", True), - BoolVariable("store_kit", "Support for in-app store", True), - BoolVariable("icloud", "Support for iCloud", True), BoolVariable("ios_exceptions", "Enable exceptions", False), ("ios_triple", "Triple for ios toolchain", ""), ] @@ -119,7 +116,7 @@ def configure(env): arch_flag = "i386" if env["arch"] == "x86" else env["arch"] env.Append( CCFLAGS=( - "-arch " + "-fobjc-arc -arch " + arch_flag + " -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks" " -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=13.0" @@ -222,18 +219,6 @@ def configure(env): ] ) - # Feature options - if env["game_center"]: - env.Append(CPPDEFINES=["GAME_CENTER_ENABLED"]) - env.Append(LINKFLAGS=["-framework", "GameKit"]) - - if env["store_kit"]: - env.Append(CPPDEFINES=["STOREKIT_ENABLED"]) - env.Append(LINKFLAGS=["-framework", "StoreKit"]) - - if env["icloud"]: - env.Append(CPPDEFINES=["ICLOUD_ENABLED"]) - env.Prepend( CPPPATH=[ "$IPHONESDK/usr/include", diff --git a/platform/iphone/display_layer.mm b/platform/iphone/display_layer.mm index 2716538b89..7420a5ebe6 100644 --- a/platform/iphone/display_layer.mm +++ b/platform/iphone/display_layer.mm @@ -29,8 +29,8 @@ /*************************************************************************/ #import "display_layer.h" +#include "core/config/project_settings.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #include "display_server_iphone.h" #include "main/main.h" #include "os_iphone.h" diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm index d456f9cbf6..6fa5e6ee4a 100644 --- a/platform/iphone/display_server_iphone.mm +++ b/platform/iphone/display_server_iphone.mm @@ -30,8 +30,8 @@ #include "display_server_iphone.h" #import "app_delegate.h" +#include "core/config/project_settings.h" #include "core/io/file_access_pack.h" -#include "core/project_settings.h" #import "device_metrics.h" #import "godot_view.h" #include "ios.h" diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 19f7c8e482..cbef136247 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -30,19 +30,20 @@ #include "export.h" +#include "core/config/project_settings.h" #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_saver.h" #include "core/io/zip_io.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "core/version.h" #include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "main/splash.gen.h" #include "platform/iphone/logo.gen.h" +#include "platform/iphone/plugin/godot_plugin_config.h" #include "string.h" #include <sys/stat.h> @@ -54,6 +55,13 @@ class EditorExportPlatformIOS : public EditorExportPlatform { Ref<ImageTexture> logo; + // Plugins + volatile bool plugins_changed; + Thread *check_for_changes_thread; + volatile bool quit_request; + Mutex plugins_lock; + Vector<PluginConfig> plugins; + typedef Error (*FileHandler)(String p_file, void *p_userdata); static Error _walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata); static Error _codesign(String p_file, void *p_userdata); @@ -70,6 +78,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { String modules_fileref; String modules_buildphase; String modules_buildgrp; + Vector<String> capabilities; }; struct ExportArchitecture { String name; @@ -102,7 +111,9 @@ class EditorExportPlatformIOS : public EditorExportPlatform { void _add_assets_to_project(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets); Error _export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets); + Error _copy_asset(const String &p_out_dir, const String &p_asset, const String *p_custom_file_name, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets); Error _export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets); + Error _export_ios_plugins(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &dest_dir, Vector<IOSExportAsset> &r_exported_assets, bool p_debug); bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const { String pname = p_package; @@ -127,6 +138,40 @@ class EditorExportPlatformIOS : public EditorExportPlatform { return true; } + static void _check_for_changes_poll_thread(void *ud) { + EditorExportPlatformIOS *ea = (EditorExportPlatformIOS *)ud; + + while (!ea->quit_request) { + // Nothing to do if we already know the plugins have changed. + if (!ea->plugins_changed) { + MutexLock lock(ea->plugins_lock); + + Vector<PluginConfig> loaded_plugins = get_plugins(); + + if (ea->plugins.size() != loaded_plugins.size()) { + ea->plugins_changed = true; + } else { + for (int i = 0; i < ea->plugins.size(); i++) { + if (ea->plugins[i].name != loaded_plugins[i].name || ea->plugins[i].last_updated != loaded_plugins[i].last_updated) { + ea->plugins_changed = true; + break; + } + } + } + } + + uint64_t wait = 3000000; + uint64_t time = OS::get_singleton()->get_ticks_usec(); + while (OS::get_singleton()->get_ticks_usec() - time < wait) { + OS::get_singleton()->delay_usec(300000); + + if (ea->quit_request) { + break; + } + } + } + } + protected: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; virtual void get_export_options(List<ExportOption> *r_options) override; @@ -136,13 +181,21 @@ public: virtual String get_os_name() const override { return "iOS"; } virtual Ref<Texture2D> get_logo() const override { return logo; } + virtual bool should_update_export_options() override { + bool export_options_changed = plugins_changed; + if (export_options_changed) { + // don't clear unless we're reporting true, to avoid race + plugins_changed = false; + } + return export_options_changed; + } + virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override { List<String> list; list.push_back("ipa"); return list; } virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; - virtual void add_module_code(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid); virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; @@ -156,6 +209,85 @@ public: EditorExportPlatformIOS(); ~EditorExportPlatformIOS(); + + /// List the gdip files in the directory specified by the p_path parameter. + static Vector<String> list_plugin_config_files(const String &p_path, bool p_check_directories) { + Vector<String> dir_files; + DirAccessRef da = DirAccess::open(p_path); + if (da) { + da->list_dir_begin(); + while (true) { + String file = da->get_next(); + if (file.empty()) { + break; + } + + if (file == "." || file == "..") { + continue; + } + + if (da->current_is_hidden()) { + continue; + } + + if (da->current_is_dir()) { + if (p_check_directories) { + Vector<String> directory_files = list_plugin_config_files(p_path.plus_file(file), false); + for (int i = 0; i < directory_files.size(); ++i) { + dir_files.push_back(file.plus_file(directory_files[i])); + } + } + + continue; + } + + if (file.ends_with(PLUGIN_CONFIG_EXT)) { + dir_files.push_back(file); + } + } + da->list_dir_end(); + } + + return dir_files; + } + + static Vector<PluginConfig> get_plugins() { + Vector<PluginConfig> loaded_plugins; + + String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("ios/plugins"); + + if (DirAccess::exists(plugins_dir)) { + Vector<String> plugins_filenames = list_plugin_config_files(plugins_dir, true); + + if (!plugins_filenames.empty()) { + Ref<ConfigFile> config_file = memnew(ConfigFile); + for (int i = 0; i < plugins_filenames.size(); i++) { + PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i])); + if (config.valid_config) { + loaded_plugins.push_back(config); + } else { + print_error("Invalid plugin config file " + plugins_filenames[i]); + } + } + } + } + + return loaded_plugins; + } + + static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) { + Vector<PluginConfig> enabled_plugins; + Vector<PluginConfig> all_plugins = get_plugins(); + for (int i = 0; i < all_plugins.size(); i++) { + PluginConfig plugin = all_plugins[i]; + bool enabled = p_presets->get("plugins/" + plugin.name); + if (enabled) { + enabled_plugins.push_back(plugin); + } + } + + return enabled_plugins; + } }; void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { @@ -224,12 +356,16 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/arkit"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/camera"), false)); + Vector<PluginConfig> found_plugins = get_plugins(); + + for (int i = 0; i < found_plugins.size(); i++) { + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + found_plugins[i].name), false)); + } + + plugins_changed = false; + plugins = found_plugins; r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/access_wifi"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/game_center"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/in_app_purchases"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/push_notifications"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data/accessible_from_files_app"), false)); @@ -345,18 +481,6 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$docs_in_place", ((bool)p_preset->get("user_data/accessible_from_files_app")) ? "<true/>" : "<false/>") + "\n"; } else if (lines[i].find("$docs_sharing") != -1) { strnew += lines[i].replace("$docs_sharing", ((bool)p_preset->get("user_data/accessible_from_itunes_sharing")) ? "<true/>" : "<false/>") + "\n"; - } else if (lines[i].find("$access_wifi") != -1) { - bool is_on = p_preset->get("capabilities/access_wifi"); - strnew += lines[i].replace("$access_wifi", is_on ? "1" : "0") + "\n"; - } else if (lines[i].find("$game_center") != -1) { - bool is_on = p_preset->get("capabilities/game_center"); - strnew += lines[i].replace("$game_center", is_on ? "1" : "0") + "\n"; - } else if (lines[i].find("$in_app_purchases") != -1) { - bool is_on = p_preset->get("capabilities/in_app_purchases"); - strnew += lines[i].replace("$in_app_purchases", is_on ? "1" : "0") + "\n"; - } else if (lines[i].find("$push_notifications") != -1) { - bool is_on = p_preset->get("capabilities/push_notifications"); - strnew += lines[i].replace("$push_notifications", is_on ? "1" : "0") + "\n"; } else if (lines[i].find("$entitlements_push_notifications") != -1) { bool is_on = p_preset->get("capabilities/push_notifications"); strnew += lines[i].replace("$entitlements_push_notifications", is_on ? "<key>aps-environment</key><string>development</string>" : "") + "\n"; @@ -366,15 +490,14 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ // I've removed armv7 as we can run on 64bit only devices // Note that capabilities listed here are requirements for the app to be installed. // They don't enable anything. + Vector<String> capabilities_list = p_config.capabilities; - if ((bool)p_preset->get("capabilities/arkit")) { - capabilities += "<string>arkit</string>\n"; - } - if ((bool)p_preset->get("capabilities/game_center")) { - capabilities += "<string>gamekit</string>\n"; + if ((bool)p_preset->get("capabilities/access_wifi") && !capabilities_list.has("wifi")) { + capabilities_list.push_back("wifi"); } - if ((bool)p_preset->get("capabilities/access_wifi")) { - capabilities += "<string>wifi</string>\n"; + + for (int idx = 0; idx < capabilities_list.size(); idx++) { + capabilities += "<string>" + capabilities_list[idx] + "</string>\n"; } strnew += lines[i].replace("$required_device_capabilities", capabilities); @@ -984,28 +1107,6 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese // Note, frameworks like gamekit are always included in our project.pbxprof file // even if turned off in capabilities. - // We do need our ARKit framework - if ((bool)p_preset->get("capabilities/arkit")) { - String build_id = (++current_id).str(); - String ref_id = (++current_id).str(); - - if (pbx_frameworks_build.length() > 0) { - pbx_frameworks_build += ",\n"; - pbx_frameworks_refs += ",\n"; - } - - pbx_frameworks_build += build_id; - pbx_frameworks_refs += ref_id; - - Dictionary format_dict; - format_dict["build_id"] = build_id; - format_dict["ref_id"] = ref_id; - format_dict["name"] = "ARKit.framework"; - format_dict["file_path"] = "System/Library/Frameworks/ARKit.framework"; - format_dict["file_type"] = "wrapper.framework"; - pbx_files += file_info_format.format(format_dict, "$_"); - } - String str = String::utf8((const char *)p_project_data.ptr(), p_project_data.size()); str = str.replace("$additional_pbx_files", pbx_files); str = str.replace("$additional_pbx_frameworks_build", pbx_frameworks_build); @@ -1021,142 +1122,179 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese } } -Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets) { +Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String &p_asset, const String *p_custom_file_name, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets) { DirAccess *filesystem_da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + ERR_FAIL_COND_V_MSG(!filesystem_da, ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_out_dir + "'."); + String binary_name = p_out_dir.get_file().get_basename(); - ERR_FAIL_COND_V_MSG(!filesystem_da, ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_out_dir + "'."); - for (int f_idx = 0; f_idx < p_assets.size(); ++f_idx) { - String asset = p_assets[f_idx]; - if (!asset.begins_with("res://")) { - // either SDK-builtin or already a part of the export template - IOSExportAsset exported_asset = { asset, p_is_framework, p_should_embed }; - r_exported_assets.push_back(exported_asset); + DirAccess *da = DirAccess::create_for_path(p_asset); + if (!da) { + memdelete(filesystem_da); + ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't create directory: " + p_asset + "."); + } + bool file_exists = da->file_exists(p_asset); + bool dir_exists = da->dir_exists(p_asset); + if (!file_exists && !dir_exists) { + memdelete(da); + memdelete(filesystem_da); + return ERR_FILE_NOT_FOUND; + } + + String base_dir = p_asset.get_base_dir().replace("res://", ""); + String destination_dir; + String destination; + String asset_path; + + bool create_framework = false; + + if (p_is_framework && p_asset.ends_with(".dylib")) { + // For iOS we need to turn .dylib into .framework + // to be able to send application to AppStore + asset_path = String("dylibs").plus_file(base_dir); + + String file_name; + + if (!p_custom_file_name) { + file_name = p_asset.get_basename().get_file(); } else { - DirAccess *da = DirAccess::create_for_path(asset); - if (!da) { - memdelete(filesystem_da); - ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't create directory: " + asset + "."); - } - bool file_exists = da->file_exists(asset); - bool dir_exists = da->dir_exists(asset); - if (!file_exists && !dir_exists) { - memdelete(da); - memdelete(filesystem_da); - return ERR_FILE_NOT_FOUND; - } + file_name = *p_custom_file_name; + } - String base_dir = asset.get_base_dir().replace("res://", ""); - String destination_dir; - String destination; - String asset_path; + String framework_name = file_name + ".framework"; - bool create_framework = false; + asset_path = asset_path.plus_file(framework_name); + destination_dir = p_out_dir.plus_file(asset_path); + destination = destination_dir.plus_file(file_name); + create_framework = true; + } else if (p_is_framework && (p_asset.ends_with(".framework") || p_asset.ends_with(".xcframework"))) { + asset_path = String("dylibs").plus_file(base_dir); - if (p_is_framework && asset.ends_with(".dylib")) { - // For iOS we need to turn .dylib into .framework - // to be able to send application to AppStore - asset_path = String("dylibs").plus_file(base_dir); + String file_name; - String file_name = asset.get_basename().get_file(); - String framework_name = file_name + ".framework"; + if (!p_custom_file_name) { + file_name = p_asset.get_file(); + } else { + file_name = *p_custom_file_name; + } - asset_path = asset_path.plus_file(framework_name); - destination_dir = p_out_dir.plus_file(asset_path); - destination = destination_dir.plus_file(file_name); - create_framework = true; - } else if (p_is_framework && (asset.ends_with(".framework") || asset.ends_with(".xcframework"))) { - asset_path = String("dylibs").plus_file(base_dir); + asset_path = asset_path.plus_file(file_name); + destination_dir = p_out_dir.plus_file(asset_path); + destination = destination_dir; + } else { + asset_path = base_dir; - String file_name = asset.get_file(); - asset_path = asset_path.plus_file(file_name); - destination_dir = p_out_dir.plus_file(asset_path); - destination = destination_dir; - } else { - asset_path = base_dir; + String file_name; - String file_name = asset.get_file(); - destination_dir = p_out_dir.plus_file(asset_path); - asset_path = asset_path.plus_file(file_name); - destination = p_out_dir.plus_file(asset_path); - } + if (!p_custom_file_name) { + file_name = p_asset.get_file(); + } else { + file_name = *p_custom_file_name; + } - if (!filesystem_da->dir_exists(destination_dir)) { - Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir); - if (make_dir_err) { - memdelete(da); - memdelete(filesystem_da); - return make_dir_err; - } - } + destination_dir = p_out_dir.plus_file(asset_path); + asset_path = asset_path.plus_file(file_name); + destination = p_out_dir.plus_file(asset_path); + } - Error err = dir_exists ? da->copy_dir(asset, destination) : da->copy(asset, destination); + if (!filesystem_da->dir_exists(destination_dir)) { + Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir); + if (make_dir_err) { memdelete(da); - if (err) { - memdelete(filesystem_da); - return err; - } - IOSExportAsset exported_asset = { binary_name.plus_file(asset_path), p_is_framework, p_should_embed }; - r_exported_assets.push_back(exported_asset); + memdelete(filesystem_da); + return make_dir_err; + } + } - if (create_framework) { - String file_name = asset.get_basename().get_file(); - String framework_name = file_name + ".framework"; + Error err = dir_exists ? da->copy_dir(p_asset, destination) : da->copy(p_asset, destination); + memdelete(da); + if (err) { + memdelete(filesystem_da); + return err; + } + IOSExportAsset exported_asset = { binary_name.plus_file(asset_path), p_is_framework, p_should_embed }; + r_exported_assets.push_back(exported_asset); - // Performing `install_name_tool -id @rpath/{name}.framework/{name} ./{name}` on dylib - { - List<String> install_name_args; - install_name_args.push_back("-id"); - install_name_args.push_back(String("@rpath").plus_file(framework_name).plus_file(file_name)); - install_name_args.push_back(destination); + if (create_framework) { + String file_name; - OS::get_singleton()->execute("install_name_tool", install_name_args, true); - } + if (!p_custom_file_name) { + file_name = p_asset.get_basename().get_file(); + } else { + file_name = *p_custom_file_name; + } - // Creating Info.plist - { - String info_plist_format = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" - "<plist version=\"1.0\">\n" - "<dict>\n" - "<key>CFBundleShortVersionString</key>\n" - "<string>1.0</string>\n" - "<key>CFBundleIdentifier</key>\n" - "<string>com.gdnative.framework.$name</string>\n" - "<key>CFBundleName</key>\n" - "<string>$name</string>\n" - "<key>CFBundleExecutable</key>\n" - "<string>$name</string>\n" - "<key>DTPlatformName</key>\n" - "<string>iphoneos</string>\n" - "<key>CFBundleInfoDictionaryVersion</key>\n" - "<string>6.0</string>\n" - "<key>CFBundleVersion</key>\n" - "<string>1</string>\n" - "<key>CFBundlePackageType</key>\n" - "<string>FMWK</string>\n" - "<key>MinimumOSVersion</key>\n" - "<string>10.0</string>\n" - "</dict>\n" - "</plist>"; - - String info_plist = info_plist_format.replace("$name", file_name); - - FileAccess *f = FileAccess::open(destination_dir.plus_file("Info.plist"), FileAccess::WRITE); - if (f) { - f->store_string(info_plist); - f->close(); - memdelete(f); - } - } + String framework_name = file_name + ".framework"; + + // Performing `install_name_tool -id @rpath/{name}.framework/{name} ./{name}` on dylib + { + List<String> install_name_args; + install_name_args.push_back("-id"); + install_name_args.push_back(String("@rpath").plus_file(framework_name).plus_file(file_name)); + install_name_args.push_back(destination); + + OS::get_singleton()->execute("install_name_tool", install_name_args, true); + } + + // Creating Info.plist + { + String info_plist_format = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" + "<plist version=\"1.0\">\n" + "<dict>\n" + "<key>CFBundleShortVersionString</key>\n" + "<string>1.0</string>\n" + "<key>CFBundleIdentifier</key>\n" + "<string>com.gdnative.framework.$name</string>\n" + "<key>CFBundleName</key>\n" + "<string>$name</string>\n" + "<key>CFBundleExecutable</key>\n" + "<string>$name</string>\n" + "<key>DTPlatformName</key>\n" + "<string>iphoneos</string>\n" + "<key>CFBundleInfoDictionaryVersion</key>\n" + "<string>6.0</string>\n" + "<key>CFBundleVersion</key>\n" + "<string>1</string>\n" + "<key>CFBundlePackageType</key>\n" + "<string>FMWK</string>\n" + "<key>MinimumOSVersion</key>\n" + "<string>10.0</string>\n" + "</dict>\n" + "</plist>"; + + String info_plist = info_plist_format.replace("$name", file_name); + + FileAccess *f = FileAccess::open(destination_dir.plus_file("Info.plist"), FileAccess::WRITE); + if (f) { + f->store_string(info_plist); + f->close(); + memdelete(f); } } } + memdelete(filesystem_da); return OK; } +Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets) { + for (int f_idx = 0; f_idx < p_assets.size(); ++f_idx) { + String asset = p_assets[f_idx]; + if (!asset.begins_with("res://")) { + // either SDK-builtin or already a part of the export template + IOSExportAsset exported_asset = { asset, p_is_framework, p_should_embed }; + r_exported_assets.push_back(exported_asset); + } else { + Error err = _copy_asset(p_out_dir, asset, nullptr, p_is_framework, p_should_embed, r_exported_assets); + ERR_FAIL_COND_V(err, err); + } + } + + return OK; +} + Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets) { Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); for (int i = 0; i < export_plugins.size(); i++) { @@ -1202,20 +1340,173 @@ Vector<String> EditorExportPlatformIOS::_get_preset_architectures(const Ref<Edit return enabled_archs; } -void EditorExportPlatformIOS::add_module_code(const Ref<EditorExportPreset> &p_preset, EditorExportPlatformIOS::IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid) { - if ((bool)p_preset->get("capabilities/" + p_name)) { - //add module static library - print_line("ADDING MODULE: " + p_name); +Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &dest_dir, Vector<IOSExportAsset> &r_exported_assets, bool p_debug) { + String plugin_definition_cpp_code; + String plugin_initialization_cpp_code; + String plugin_deinitialization_cpp_code; - p_config_data.modules_buildfile += p_gid + " /* libgodot_" + p_name + "_module.a in Frameworks */ = {isa = PBXBuildFile; fileRef = " + p_fid + " /* libgodot_" + p_name + "_module.a */; };\n\t\t"; - p_config_data.modules_fileref += p_fid + " /* libgodot_" + p_name + "_module.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot_" + p_name + "_module ; path = \"libgodot_" + p_name + "_module.a\"; sourceTree = \"<group>\"; };\n\t\t"; - p_config_data.modules_buildphase += p_gid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t"; - p_config_data.modules_buildgrp += p_fid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t"; - } else { - //add stub function for disabled module - p_config_data.cpp_code += "void register_" + p_name + "_types() { /*stub*/ };\n"; - p_config_data.cpp_code += "void unregister_" + p_name + "_types() { /*stub*/ };\n"; + Vector<String> plugin_linked_dependencies; + Vector<String> plugin_embedded_dependencies; + Vector<String> plugin_files; + + Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset); + + Vector<String> added_linked_dependenciy_names; + Vector<String> added_embedded_dependenciy_names; + HashMap<String, String> plist_values; + + Error err; + + for (int i = 0; i < enabled_plugins.size(); i++) { + PluginConfig plugin = enabled_plugins[i]; + + // Export plugin binary. + if (!plugin.supports_targets) { + err = _copy_asset(dest_dir, plugin.binary, nullptr, true, true, r_exported_assets); + } else { + String plugin_binary_dir = plugin.binary.get_base_dir(); + String plugin_name_prefix = plugin.binary.get_basename().get_file(); + String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + ".a"; + String result_file_name = plugin.binary.get_file(); + + err = _copy_asset(dest_dir, plugin_binary_dir.plus_file(plugin_file), &result_file_name, true, true, r_exported_assets); + } + + ERR_FAIL_COND_V(err, err); + + // Adding dependencies. + // Use separate container for names to check for duplicates. + for (int j = 0; j < plugin.linked_dependencies.size(); j++) { + String dependency = plugin.linked_dependencies[j]; + String name = dependency.get_file(); + + if (added_linked_dependenciy_names.has(name)) { + continue; + } + + added_linked_dependenciy_names.push_back(name); + plugin_linked_dependencies.push_back(dependency); + } + + for (int j = 0; j < plugin.system_dependencies.size(); j++) { + String dependency = plugin.system_dependencies[j]; + String name = dependency.get_file(); + + if (added_linked_dependenciy_names.has(name)) { + continue; + } + + added_linked_dependenciy_names.push_back(name); + plugin_linked_dependencies.push_back(dependency); + } + + for (int j = 0; j < plugin.embedded_dependencies.size(); j++) { + String dependency = plugin.embedded_dependencies[j]; + String name = dependency.get_file(); + + if (added_embedded_dependenciy_names.has(name)) { + continue; + } + + added_embedded_dependenciy_names.push_back(name); + plugin_embedded_dependencies.push_back(dependency); + } + + plugin_files.append_array(plugin.files_to_copy); + + // Capabilities + // Also checking for duplicates. + for (int j = 0; j < plugin.capabilities.size(); j++) { + String capability = plugin.capabilities[j]; + + if (p_config_data.capabilities.has(capability)) { + continue; + } + + p_config_data.capabilities.push_back(capability); + } + + // Plist + // Using hash map container to remove duplicates + const String *K = nullptr; + + while ((K = plugin.plist.next(K))) { + String key = *K; + String value = plugin.plist[key]; + + if (key.empty() || value.empty()) { + continue; + } + + plist_values[key] = value; + } + + // CPP Code + String definition_comment = "// Plugin: " + plugin.name + "\n"; + String initialization_method = plugin.initialization_method + "();\n"; + String deinitialization_method = plugin.deinitialization_method + "();\n"; + + plugin_definition_cpp_code += definition_comment + + "extern void " + initialization_method + + "extern void " + deinitialization_method + "\n"; + + plugin_initialization_cpp_code += "\t" + initialization_method; + plugin_deinitialization_cpp_code += "\t" + deinitialization_method; + } + + // Updating `Info.plist` + { + const String *K = nullptr; + while ((K = plist_values.next(K))) { + String key = *K; + String value = plist_values[key]; + + if (key.empty() || value.empty()) { + continue; + } + + p_config_data.plist_content += "<key>" + key + "</key><string>" + value + "</string>\n"; + } } + + // Export files + { + // Export linked plugin dependency + err = _export_additional_assets(dest_dir, plugin_linked_dependencies, true, false, r_exported_assets); + ERR_FAIL_COND_V(err, err); + + // Export embedded plugin dependency + err = _export_additional_assets(dest_dir, plugin_embedded_dependencies, true, true, r_exported_assets); + ERR_FAIL_COND_V(err, err); + + // Export plugin files + err = _export_additional_assets(dest_dir, plugin_files, false, false, r_exported_assets); + ERR_FAIL_COND_V(err, err); + } + + // Update CPP + { + Dictionary plugin_format; + plugin_format["definition"] = plugin_definition_cpp_code; + plugin_format["initialization"] = plugin_initialization_cpp_code; + plugin_format["deinitialization"] = plugin_deinitialization_cpp_code; + + String plugin_cpp_code = "\n// Godot Plugins\n" + "void godot_ios_plugins_initialize();\n" + "void godot_ios_plugins_deinitialize();\n" + "// Exported Plugins\n\n" + "$definition" + "// Use Plugins\n" + "void godot_ios_plugins_initialize() {\n" + "$initialization" + "}\n\n" + "void godot_ios_plugins_deinitialize() {\n" + "$deinitialization" + "}\n"; + + p_config_data.cpp_code += plugin_cpp_code.format(plugin_format, "$_"); + } + return OK; } Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { @@ -1324,9 +1615,12 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p "", "", "", - "" + "", + Vector<String>() }; + Vector<IOSExportAsset> assets; + DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir); ERR_FAIL_COND_V(!tmp_app_path, ERR_CANT_CREATE); @@ -1339,8 +1633,8 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p return ERR_CANT_OPEN; } - add_module_code(p_preset, config_data, "arkit", "F9B95E6E2391205500AF0000", "F9C95E812391205C00BF0000"); - add_module_code(p_preset, config_data, "camera", "F9B95E6E2391205500AF0001", "F9C95E812391205C00BF0001"); + err = _export_ios_plugins(p_preset, config_data, dest_dir + binary_name, assets, p_debug); + ERR_FAIL_COND_V(err, err); //export rest of the files int ret = unzGoToFirstFile(src_pkg_zip); @@ -1382,21 +1676,8 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p is_execute = true; #endif file = "godot_ios.a"; - } else if (file.begins_with("libgodot_arkit")) { - if ((bool)p_preset->get("capabilities/arkit") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) { - file = "libgodot_arkit_module.a"; - } else { - ret = unzGoToNextFile(src_pkg_zip); - continue; //ignore! - } - } else if (file.begins_with("libgodot_camera")) { - if ((bool)p_preset->get("capabilities/camera") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) { - file = "libgodot_camera_module.a"; - } else { - ret = unzGoToNextFile(src_pkg_zip); - continue; //ignore! - } } + if (file == project_file) { project_file_data = data; } @@ -1530,7 +1811,6 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p } print_line("Exporting additional assets"); - Vector<IOSExportAsset> assets; _export_additional_assets(dest_dir + binary_name, libraries, assets); _add_assets_to_project(p_preset, project_file_data, assets); String project_file_name = dest_dir + binary_name + ".xcodeproj/project.pbxproj"; @@ -1665,9 +1945,17 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() { Ref<Image> img = memnew(Image(_iphone_logo)); logo.instance(); logo->create_from_image(img); + + plugins_changed = true; + quit_request = false; + + check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this); } EditorExportPlatformIOS::~EditorExportPlatformIOS() { + quit_request = true; + Thread::wait_to_finish(check_for_changes_thread); + memdelete(check_for_changes_thread); } void register_iphone_exporter() { diff --git a/platform/iphone/godot_iphone.mm b/platform/iphone/godot_iphone.mm index 6d95276f37..a4119bcafd 100644 --- a/platform/iphone/godot_iphone.mm +++ b/platform/iphone/godot_iphone.mm @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/ustring.h" +#include "core/string/ustring.h" #include "main/main.h" #include "os_iphone.h" diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm index 3b4344c46d..eaf7e962ce 100644 --- a/platform/iphone/godot_view.mm +++ b/platform/iphone/godot_view.mm @@ -30,7 +30,7 @@ #import "godot_view.h" #include "core/os/keyboard.h" -#include "core/ustring.h" +#include "core/string/ustring.h" #import "display_layer.h" #include "display_server_iphone.h" #import "godot_view_gesture_recognizer.h" diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/iphone/godot_view_gesture_recognizer.mm index 71367a629c..91cc07fcf6 100644 --- a/platform/iphone/godot_view_gesture_recognizer.mm +++ b/platform/iphone/godot_view_gesture_recognizer.mm @@ -30,7 +30,7 @@ #import "godot_view_gesture_recognizer.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" // Minimum distance for touches to move to fire // a delay timer before scheduled time. diff --git a/platform/iphone/godot_view_renderer.mm b/platform/iphone/godot_view_renderer.mm index 045fb451f0..f2ff417e6f 100644 --- a/platform/iphone/godot_view_renderer.mm +++ b/platform/iphone/godot_view_renderer.mm @@ -29,8 +29,8 @@ /*************************************************************************/ #import "godot_view_renderer.h" +#include "core/config/project_settings.h" #include "core/os/keyboard.h" -#include "core/project_settings.h" #import "display_server_iphone.h" #include "main/main.h" #include "os_iphone.h" diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h index 6a89cd38cb..5415c36cd9 100644 --- a/platform/iphone/ios.h +++ b/platform/iphone/ios.h @@ -31,7 +31,7 @@ #ifndef IOS_H #define IOS_H -#include "core/class_db.h" +#include "core/object/class_db.h" class iOS : public Object { GDCLASS(iOS, Object); diff --git a/platform/iphone/joypad_iphone.mm b/platform/iphone/joypad_iphone.mm index b0a8076b56..22d7dd4bd2 100644 --- a/platform/iphone/joypad_iphone.mm +++ b/platform/iphone/joypad_iphone.mm @@ -29,7 +29,7 @@ /*************************************************************************/ #import "joypad_iphone.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "main/main.h" diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index c6f95869ee..04a0a478d5 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -35,9 +35,6 @@ #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/unix/os_unix.h" -#include "game_center.h" -#include "icloud.h" -#include "in_app_store.h" #include "ios.h" #include "joypad_iphone.h" #include "servers/audio_server.h" @@ -48,6 +45,9 @@ #include "platform/iphone/vulkan_context_iphone.h" #endif +extern void godot_ios_plugins_initialize(); +extern void godot_ios_plugins_deinitialize(); + class OSIPhone : public OS_Unix { private: static HashMap<String, void *> dynamic_symbol_lookup_table; @@ -55,15 +55,6 @@ private: AudioDriverCoreAudio audio_driver; -#ifdef GAME_CENTER_ENABLED - GameCenter *game_center; -#endif -#ifdef STOREKIT_ENABLED - InAppStore *store_kit; -#endif -#ifdef ICLOUD_ENABLED - ICloud *icloud; -#endif iOS *ios; JoypadIPhone *joypad_iphone; diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index e007276b4b..b87e6f37a0 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -32,10 +32,10 @@ #include "os_iphone.h" #import "app_delegate.h" +#include "core/config/project_settings.h" #include "core/io/file_access_pack.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "display_server_iphone.h" #include "drivers/unix/syslog_logger.h" #import "godot_view.h" @@ -125,21 +125,6 @@ void OSIPhone::initialize() { } void OSIPhone::initialize_modules() { -#ifdef GAME_CENTER_ENABLED - game_center = memnew(GameCenter); - Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center)); -#endif - -#ifdef STOREKIT_ENABLED - store_kit = memnew(InAppStore); - Engine::get_singleton()->add_singleton(Engine::Singleton("InAppStore", store_kit)); -#endif - -#ifdef ICLOUD_ENABLED - icloud = memnew(ICloud); - Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud)); -#endif - ios = memnew(iOS); Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", ios)); @@ -155,26 +140,12 @@ void OSIPhone::deinitialize_modules() { memdelete(ios); } -#ifdef GAME_CENTER_ENABLED - if (game_center) { - memdelete(game_center); - } -#endif - -#ifdef STOREKIT_ENABLED - if (store_kit) { - memdelete(store_kit); - } -#endif - -#ifdef ICLOUD_ENABLED - if (icloud) { - memdelete(icloud); - } -#endif + godot_ios_plugins_deinitialize(); } void OSIPhone::set_main_loop(MainLoop *p_main_loop) { + godot_ios_plugins_initialize(); + main_loop = p_main_loop; if (main_loop) { diff --git a/platform/iphone/plugin/godot_plugin_config.h b/platform/iphone/plugin/godot_plugin_config.h new file mode 100644 index 0000000000..5323f94989 --- /dev/null +++ b/platform/iphone/plugin/godot_plugin_config.h @@ -0,0 +1,265 @@ +/*************************************************************************/ +/* godot_plugin_config.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_PLUGIN_CONFIG_H +#define GODOT_PLUGIN_CONFIG_H + +#include "core/error/error_list.h" +#include "core/io/config_file.h" +#include "core/string/ustring.h" + +static const char *PLUGIN_CONFIG_EXT = ".gdip"; + +static const char *CONFIG_SECTION = "config"; +static const char *CONFIG_NAME_KEY = "name"; +static const char *CONFIG_BINARY_KEY = "binary"; +static const char *CONFIG_INITIALIZE_KEY = "initialization"; +static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization"; + +static const char *DEPENDENCIES_SECTION = "dependencies"; +static const char *DEPENDENCIES_LINKED_KEY = "linked"; +static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded"; +static const char *DEPENDENCIES_SYSTEM_KEY = "system"; +static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities"; +static const char *DEPENDENCIES_FILES_KEY = "files"; + +static const char *PLIST_SECTION = "plist"; + +/* + The `config` section and fields are required and defined as follow: +- **name**: name of the plugin +- **binary**: path to static `.a` library + +The `dependencies` and fields are optional. +- **linked**: dependencies that should only be linked. +- **embedded**: dependencies that should be linked and embedded into application. +- **system**: system dependencies that should be linked. +- **capabilities**: capabilities that would be used for `UIRequiredDeviceCapabilities` options in Info.plist file. +- **files**: files that would be copied into application + +The `plist` section are optional. +- **key**: key and value that would be added in Info.plist file. + */ + +struct PluginConfig { + // Set to true when the config file is properly loaded. + bool valid_config = false; + bool supports_targets = false; + // Unix timestamp of last change to this plugin. + uint64_t last_updated = 0; + + // Required config section + String name; + String binary; + String initialization_method; + String deinitialization_method; + + // Optional dependencies section + Vector<String> linked_dependencies; + Vector<String> embedded_dependencies; + Vector<String> system_dependencies; + + Vector<String> files_to_copy; + Vector<String> capabilities; + + // Optional plist section + // Supports only string types for now + HashMap<String, String> plist; +}; + +static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) { + String absolute_path; + + if (dependency_path.empty()) { + return absolute_path; + } + + if (dependency_path.is_abs_path()) { + return dependency_path; + } + + String res_path = ProjectSettings::get_singleton()->globalize_path("res://"); + absolute_path = plugin_config_dir.plus_file(dependency_path); + + return absolute_path.replace(res_path, "res://"); +} + +static inline String resolve_system_dependency_path(String dependency_path) { + String absolute_path; + + if (dependency_path.empty()) { + return absolute_path; + } + + if (dependency_path.is_abs_path()) { + return dependency_path; + } + + String system_path = "/System/Library/Frameworks"; + + return system_path.plus_file(dependency_path); +} + +static inline Vector<String> resolve_local_dependencies(String plugin_config_dir, Vector<String> p_paths) { + Vector<String> paths; + + for (int i = 0; i < p_paths.size(); i++) { + String path = resolve_local_dependency_path(plugin_config_dir, p_paths[i]); + + if (path.empty()) { + continue; + } + + paths.push_back(path); + } + + return paths; +} + +static inline Vector<String> resolve_system_dependencies(Vector<String> p_paths) { + Vector<String> paths; + + for (int i = 0; i < p_paths.size(); i++) { + String path = resolve_system_dependency_path(p_paths[i]); + + if (path.empty()) { + continue; + } + + paths.push_back(path); + } + + return paths; +} + +static inline bool validate_plugin(PluginConfig &plugin_config) { + bool valid_name = !plugin_config.name.empty(); + bool valid_binary_name = !plugin_config.binary.empty(); + bool valid_initialize = !plugin_config.initialization_method.empty(); + bool valid_deinitialize = !plugin_config.deinitialization_method.empty(); + + bool fields_value = valid_name && valid_binary_name && valid_initialize && valid_deinitialize; + + if (fields_value && FileAccess::exists(plugin_config.binary)) { + plugin_config.valid_config = true; + plugin_config.supports_targets = false; + } else if (fields_value) { + String file_path = plugin_config.binary.get_base_dir(); + String file_name = plugin_config.binary.get_basename().get_file(); + String release_file_name = file_path.plus_file(file_name + ".release.a"); + String debug_file_name = file_path.plus_file(file_name + ".debug.a"); + + if (FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) { + plugin_config.valid_config = true; + plugin_config.supports_targets = true; + } + } + + return plugin_config.valid_config; +} + +static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_config, const String &config_path) { + uint64_t last_updated = FileAccess::get_modified_time(config_path); + + if (!plugin_config.supports_targets) { + last_updated = MAX(last_updated, FileAccess::get_modified_time(plugin_config.binary)); + } else { + String file_path = plugin_config.binary.get_base_dir(); + String file_name = plugin_config.binary.get_basename().get_file(); + String release_file_name = file_path.plus_file(file_name + ".release.a"); + String debug_file_name = file_path.plus_file(file_name + ".debug.a"); + + last_updated = MAX(last_updated, FileAccess::get_modified_time(release_file_name)); + last_updated = MAX(last_updated, FileAccess::get_modified_time(debug_file_name)); + } + + return last_updated; +} + +static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) { + PluginConfig plugin_config = {}; + + if (!config_file.is_valid()) { + return plugin_config; + } + + Error err = config_file->load(path); + + if (err != OK) { + return plugin_config; + } + + String config_base_dir = path.get_base_dir(); + + plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String()); + plugin_config.initialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_INITIALIZE_KEY, String()); + plugin_config.deinitialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_DEINITIALIZE_KEY, String()); + + String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String()); + plugin_config.binary = resolve_local_dependency_path(config_base_dir, binary_path); + + if (config_file->has_section(DEPENDENCIES_SECTION)) { + Vector<String> linked_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LINKED_KEY, Vector<String>()); + Vector<String> embedded_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_EMBEDDED_KEY, Vector<String>()); + Vector<String> system_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_SYSTEM_KEY, Vector<String>()); + Vector<String> files = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_FILES_KEY, Vector<String>()); + + plugin_config.linked_dependencies = resolve_local_dependencies(config_base_dir, linked_dependencies); + plugin_config.embedded_dependencies = resolve_local_dependencies(config_base_dir, embedded_dependencies); + plugin_config.system_dependencies = resolve_system_dependencies(system_dependencies); + + plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files); + + plugin_config.capabilities = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CAPABILITIES_KEY, Vector<String>()); + } + + if (config_file->has_section(PLIST_SECTION)) { + List<String> keys; + config_file->get_section_keys(PLIST_SECTION, &keys); + + for (int i = 0; i < keys.size(); i++) { + String value = config_file->get_value(PLIST_SECTION, keys[i], String()); + + if (value.empty()) { + continue; + } + + plugin_config.plist[keys[i]] = value; + } + } + + if (validate_plugin(plugin_config)) { + plugin_config.last_updated = get_plugin_modification_time(plugin_config, path); + } + + return plugin_config; +} + +#endif // GODOT_PLUGIN_CONFIG_H diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h index b0b31ae377..2cc4e4c388 100644 --- a/platform/iphone/view_controller.h +++ b/platform/iphone/view_controller.h @@ -28,13 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#import <GameKit/GameKit.h> #import <UIKit/UIKit.h> @class GodotView; @class GodotNativeVideoView; -@interface ViewController : UIViewController <GKGameCenterControllerDelegate> +@interface ViewController : UIViewController @property(nonatomic, readonly, strong) GodotView *godotView; @property(nonatomic, readonly, strong) GodotNativeVideoView *videoView; diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index fb25041779..5d18a72be1 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -29,13 +29,14 @@ /*************************************************************************/ #import "view_controller.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "display_server_iphone.h" #import "godot_view.h" #import "godot_view_renderer.h" #import "native_video_view.h" #include "os_iphone.h" +#import <AVFoundation/AVFoundation.h> #import <GameController/GameController.h> @interface ViewController () @@ -214,14 +215,4 @@ } } -// MARK: Delegates - -#ifdef GAME_CENTER_ENABLED -- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController { - //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone - GameCenter::get_singleton()->game_center_closed(); - [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; -} -#endif - @end diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index 7381ea13b7..a0e6fa0e18 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -18,21 +18,22 @@ if env["threads_enabled"]: build = env.add_program(build_targets, javascript_files) -js_libraries = [ - "native/http_request.js", - "native/library_godot_audio.js", -] -for lib in js_libraries: - env.Append(LINKFLAGS=["--js-library", env.File(lib).path]) -env.Depends(build, js_libraries) +env.AddJSLibraries( + [ + "native/http_request.js", + "native/library_godot_audio.js", + "native/library_godot_display.js", + "native/library_godot_os.js", + ] +) -js_pre = [ - "native/id_handler.js", - "native/utils.js", -] -for js in js_pre: - env.Append(LINKFLAGS=["--pre-js", env.File(js).path]) -env.Depends(build, js_pre) +if env["tools"]: + env.AddJSLibraries(["native/library_godot_editor_tools.js"]) +if env["javascript_eval"]: + env.AddJSLibraries(["native/library_godot_eval.js"]) +for lib in env["JS_LIBS"]: + env.Append(LINKFLAGS=["--js-library", lib]) +env.Depends(build, env["JS_LIBS"]) engine = [ "engine/preloader.js", @@ -55,9 +56,10 @@ out_files = [ zip_dir.File(binary_name + ".js"), zip_dir.File(binary_name + ".wasm"), zip_dir.File(binary_name + ".html"), + zip_dir.File(binary_name + ".audio.worklet.js"), ] html_file = "#misc/dist/html/editor.html" if env["tools"] else "#misc/dist/html/full-size.html" -in_files = [js_wrapped, build[1], html_file] +in_files = [js_wrapped, build[1], html_file, "#platform/javascript/native/audio.worklet.js"] if env["threads_enabled"]: in_files.append(build[2]) out_files.append(zip_dir.File(binary_name + ".worker.js")) diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp index aa0206d144..6fd6c0ddf1 100644 --- a/platform/javascript/api/api.cpp +++ b/platform/javascript/api/api.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "api.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "javascript_eval.h" #include "javascript_tools_editor_plugin.h" diff --git a/platform/javascript/api/javascript_eval.h b/platform/javascript/api/javascript_eval.h index 26b5b9e484..389983077e 100644 --- a/platform/javascript/api/javascript_eval.h +++ b/platform/javascript/api/javascript_eval.h @@ -31,7 +31,7 @@ #ifndef JAVASCRIPT_EVAL_H #define JAVASCRIPT_EVAL_H -#include "core/class_db.h" +#include "core/object/class_db.h" class JavaScript : public Object { private: diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp index e487bf23b7..8d781703ed 100644 --- a/platform/javascript/api/javascript_tools_editor_plugin.cpp +++ b/platform/javascript/api/javascript_tools_editor_plugin.cpp @@ -31,14 +31,19 @@ #if defined(TOOLS_ENABLED) && defined(JAVASCRIPT_ENABLED) #include "javascript_tools_editor_plugin.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "editor/editor_node.h" #include <emscripten/emscripten.h> +// JavaScript functions defined in library_godot_editor_tools.js +extern "C" { +extern void godot_js_editor_download_file(const char *p_path, const char *p_name, const char *p_mime); +} + static void _javascript_editor_init_callback() { EditorNode::get_singleton()->add_editor_plugin(memnew(JavaScriptToolsEditorPlugin(EditorNode::get_singleton()))); } @@ -65,25 +70,7 @@ void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) { String base_path = resource_path.substr(0, resource_path.rfind("/")) + "/"; _zip_recursive(resource_path, base_path, zip); zipClose(zip, NULL); - EM_ASM({ - const path = "/tmp/project.zip"; - const size = FS.stat(path)["size"]; - const buf = new Uint8Array(size); - const fd = FS.open(path, "r"); - FS.read(fd, buf, 0, size); - FS.close(fd); - FS.unlink(path); - const blob = new Blob([buf], { type: "application/zip" }); - const url = window.URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = "project.zip"; - a.style.display = "none"; - document.body.appendChild(a); - a.click(); - a.remove(); - window.URL.revokeObjectURL(url); - }); + godot_js_editor_download_file("/tmp/project.zip", "project.zip", "application/zip"); } void JavaScriptToolsEditorPlugin::_bind_methods() { diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp index 6ea948004e..dd982bc3a8 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -30,8 +30,7 @@ #include "audio_driver_javascript.h" -#include "core/project_settings.h" -#include "godot_audio.h" +#include "core/config/project_settings.h" #include <emscripten.h> @@ -45,92 +44,109 @@ const char *AudioDriverJavaScript::get_name() const { return "JavaScript"; } -#ifndef NO_THREADS -void AudioDriverJavaScript::_audio_thread_func(void *p_data) { - AudioDriverJavaScript *obj = static_cast<AudioDriverJavaScript *>(p_data); - while (!obj->quit) { - obj->lock(); - if (!obj->needs_process) { - obj->unlock(); - OS::get_singleton()->delay_usec(1000); // Give the browser some slack. - continue; - } - obj->_js_driver_process(); - obj->needs_process = false; - obj->unlock(); - } +void AudioDriverJavaScript::_state_change_callback(int p_state) { + singleton->state = p_state; } -#endif -extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_process_start() { -#ifndef NO_THREADS - AudioDriverJavaScript::singleton->lock(); -#else - AudioDriverJavaScript::singleton->_js_driver_process(); -#endif +void AudioDriverJavaScript::_latency_update_callback(float p_latency) { + singleton->output_latency = p_latency; } -extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_process_end() { -#ifndef NO_THREADS - AudioDriverJavaScript::singleton->needs_process = true; - AudioDriverJavaScript::singleton->unlock(); -#endif -} +void AudioDriverJavaScript::_audio_driver_process(int p_from, int p_samples) { + int32_t *stream_buffer = reinterpret_cast<int32_t *>(output_rb); + const int max_samples = memarr_len(output_rb); -extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_process_capture(float sample) { - AudioDriverJavaScript::singleton->process_capture(sample); + int write_pos = p_from; + int to_write = p_samples; + if (to_write == 0) { + to_write = max_samples; + } + // High part + if (write_pos + to_write > max_samples) { + const int samples_high = max_samples - write_pos; + audio_server_process(samples_high / channel_count, &stream_buffer[write_pos]); + for (int i = write_pos; i < max_samples; i++) { + output_rb[i] = float(stream_buffer[i] >> 16) / 32768.f; + } + to_write -= samples_high; + write_pos = 0; + } + // Leftover + audio_server_process(to_write / channel_count, &stream_buffer[write_pos]); + for (int i = write_pos; i < write_pos + to_write; i++) { + output_rb[i] = float(stream_buffer[i] >> 16) / 32768.f; + } } -void AudioDriverJavaScript::_js_driver_process() { - int sample_count = memarr_len(internal_buffer) / channel_count; - int32_t *stream_buffer = reinterpret_cast<int32_t *>(internal_buffer); - audio_server_process(sample_count, stream_buffer); - for (int i = 0; i < sample_count * channel_count; i++) { - internal_buffer[i] = float(stream_buffer[i] >> 16) / 32768.f; +void AudioDriverJavaScript::_audio_driver_capture(int p_from, int p_samples) { + if (get_input_buffer().size() == 0) { + return; // Input capture stopped. } -} + const int max_samples = memarr_len(input_rb); -void AudioDriverJavaScript::process_capture(float sample) { - int32_t sample32 = int32_t(sample * 32768.f) * (1U << 16); - input_buffer_write(sample32); + int read_pos = p_from; + int to_read = p_samples; + if (to_read == 0) { + to_read = max_samples; + } + // High part + if (read_pos + to_read > max_samples) { + const int samples_high = max_samples - read_pos; + for (int i = read_pos; i < max_samples; i++) { + input_buffer_write(int32_t(input_rb[i] * 32768.f) * (1U << 16)); + } + to_read -= samples_high; + read_pos = 0; + } + // Leftover + for (int i = read_pos; i < read_pos + to_read; i++) { + input_buffer_write(int32_t(input_rb[i] * 32768.f) * (1U << 16)); + } } Error AudioDriverJavaScript::init() { mix_rate = GLOBAL_GET("audio/mix_rate"); int latency = GLOBAL_GET("audio/output_latency"); - channel_count = godot_audio_init(mix_rate, latency); - buffer_length = closest_power_of_2((latency * mix_rate / 1000) * channel_count); - buffer_length = godot_audio_create_processor(buffer_length, channel_count); - if (!buffer_length) { - return FAILED; + channel_count = godot_audio_init(mix_rate, latency, &_state_change_callback, &_latency_update_callback); + buffer_length = closest_power_of_2((latency * mix_rate / 1000)); +#ifndef NO_THREADS + node = memnew(WorkletNode); +#else + node = memnew(ScriptProcessorNode); +#endif + buffer_length = node->create(buffer_length, channel_count); + if (output_rb) { + memdelete_arr(output_rb); } - - if (!internal_buffer || (int)memarr_len(internal_buffer) != buffer_length * channel_count) { - if (internal_buffer) - memdelete_arr(internal_buffer); - internal_buffer = memnew_arr(float, buffer_length *channel_count); + output_rb = memnew_arr(float, buffer_length *channel_count); + if (!output_rb) { + return ERR_OUT_OF_MEMORY; } - - if (!internal_buffer) { + if (input_rb) { + memdelete_arr(input_rb); + } + input_rb = memnew_arr(float, buffer_length *channel_count); + if (!input_rb) { return ERR_OUT_OF_MEMORY; } return OK; } void AudioDriverJavaScript::start() { -#ifndef NO_THREADS - thread = Thread::create(_audio_thread_func, this); -#endif - godot_audio_start(internal_buffer); + if (node) { + node->start(output_rb, memarr_len(output_rb), input_rb, memarr_len(input_rb)); + } } void AudioDriverJavaScript::resume() { - godot_audio_resume(); + if (state == 0) { // 'suspended' + godot_audio_resume(); + } } float AudioDriverJavaScript::get_latency() { - return godot_audio_get_latency(); + return output_latency + (float(buffer_length) / mix_rate); } int AudioDriverJavaScript::get_mix_rate() const { @@ -142,48 +158,128 @@ AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const { } void AudioDriverJavaScript::lock() { -#ifndef NO_THREADS - mutex.lock(); -#endif + if (node) { + node->unlock(); + } } void AudioDriverJavaScript::unlock() { -#ifndef NO_THREADS - mutex.unlock(); -#endif -} - -void AudioDriverJavaScript::finish_async() { -#ifndef NO_THREADS - quit = true; // Ask thread to quit. -#endif - godot_audio_finish_async(); + if (node) { + node->unlock(); + } } void AudioDriverJavaScript::finish() { -#ifndef NO_THREADS - Thread::wait_to_finish(thread); - memdelete(thread); - thread = NULL; -#endif - if (internal_buffer) { - memdelete_arr(internal_buffer); - internal_buffer = nullptr; + if (node) { + node->finish(); + memdelete(node); + node = nullptr; + } + if (output_rb) { + memdelete_arr(output_rb); + output_rb = nullptr; + } + if (input_rb) { + memdelete_arr(input_rb); + input_rb = nullptr; } } Error AudioDriverJavaScript::capture_start() { - godot_audio_capture_stop(); + lock(); input_buffer_init(buffer_length); + unlock(); godot_audio_capture_start(); return OK; } Error AudioDriverJavaScript::capture_stop() { + godot_audio_capture_stop(); + lock(); input_buffer.clear(); + unlock(); return OK; } AudioDriverJavaScript::AudioDriverJavaScript() { singleton = this; } + +#ifdef NO_THREADS +/// ScriptProcessorNode implementation +void AudioDriverJavaScript::ScriptProcessorNode::_process_callback() { + AudioDriverJavaScript::singleton->_audio_driver_capture(); + AudioDriverJavaScript::singleton->_audio_driver_process(); +} + +int AudioDriverJavaScript::ScriptProcessorNode::create(int p_buffer_samples, int p_channels) { + return godot_audio_script_create(p_buffer_samples, p_channels); +} + +void AudioDriverJavaScript::ScriptProcessorNode::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) { + godot_audio_script_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, &_process_callback); +} +#else +/// AudioWorkletNode implementation +void AudioDriverJavaScript::WorkletNode::_audio_thread_func(void *p_data) { + AudioDriverJavaScript::WorkletNode *obj = static_cast<AudioDriverJavaScript::WorkletNode *>(p_data); + AudioDriverJavaScript *driver = AudioDriverJavaScript::singleton; + const int out_samples = memarr_len(driver->output_rb); + const int in_samples = memarr_len(driver->input_rb); + int wpos = 0; + int to_write = out_samples; + int rpos = 0; + int to_read = 0; + int32_t step = 0; + while (!obj->quit) { + if (to_read) { + driver->lock(); + driver->_audio_driver_capture(rpos, to_read); + godot_audio_worklet_state_add(obj->state, STATE_SAMPLES_IN, -to_read); + driver->unlock(); + rpos += to_read; + if (rpos >= in_samples) { + rpos -= in_samples; + } + } + if (to_write) { + driver->lock(); + driver->_audio_driver_process(wpos, to_write); + godot_audio_worklet_state_add(obj->state, STATE_SAMPLES_OUT, to_write); + driver->unlock(); + wpos += to_write; + if (wpos >= out_samples) { + wpos -= out_samples; + } + } + step = godot_audio_worklet_state_wait(obj->state, STATE_PROCESS, step, 1); + to_write = out_samples - godot_audio_worklet_state_get(obj->state, STATE_SAMPLES_OUT); + to_read = godot_audio_worklet_state_get(obj->state, STATE_SAMPLES_IN); + } +} + +int AudioDriverJavaScript::WorkletNode::create(int p_buffer_size, int p_channels) { + godot_audio_worklet_create(p_channels); + return p_buffer_size; +} + +void AudioDriverJavaScript::WorkletNode::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) { + godot_audio_worklet_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, state); + thread = Thread::create(_audio_thread_func, this); +} + +void AudioDriverJavaScript::WorkletNode::lock() { + mutex.lock(); +} + +void AudioDriverJavaScript::WorkletNode::unlock() { + mutex.unlock(); +} + +void AudioDriverJavaScript::WorkletNode::finish() { + quit = true; // Ask thread to quit. + Thread::wait_to_finish(thread); + memdelete(thread); + thread = nullptr; +} +#endif diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index 56a7da0307..f112a1ede4 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -31,53 +31,96 @@ #ifndef AUDIO_DRIVER_JAVASCRIPT_H #define AUDIO_DRIVER_JAVASCRIPT_H -#include "servers/audio_server.h" - #include "core/os/mutex.h" #include "core/os/thread.h" +#include "servers/audio_server.h" + +#include "godot_audio.h" class AudioDriverJavaScript : public AudioDriver { +public: + class AudioNode { + public: + virtual int create(int p_buffer_size, int p_output_channels) = 0; + virtual void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) = 0; + virtual void finish() {} + virtual void lock() {} + virtual void unlock() {} + virtual ~AudioNode() {} + }; + + class WorkletNode : public AudioNode { + private: + enum { + STATE_LOCK, + STATE_PROCESS, + STATE_SAMPLES_IN, + STATE_SAMPLES_OUT, + STATE_MAX, + }; + Mutex mutex; + Thread *thread = nullptr; + bool quit = false; + int32_t state[STATE_MAX] = { 0 }; + + static void _audio_thread_func(void *p_data); + + public: + int create(int p_buffer_size, int p_output_channels) override; + void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override; + void finish() override; + void lock() override; + void unlock() override; + }; + + class ScriptProcessorNode : public AudioNode { + private: + static void _process_callback(); + + public: + int create(int p_buffer_samples, int p_channels) override; + void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override; + }; + private: - float *internal_buffer = nullptr; + AudioNode *node = nullptr; + + float *output_rb = nullptr; + float *input_rb = nullptr; int buffer_length = 0; int mix_rate = 0; int channel_count = 0; + int state = 0; + float output_latency = 0.0; -public: -#ifndef NO_THREADS - Mutex mutex; - Thread *thread = nullptr; - bool quit = false; - bool needs_process = true; - - static void _audio_thread_func(void *p_data); -#endif + static void _state_change_callback(int p_state); + static void _latency_update_callback(float p_latency); - void _js_driver_process(); +protected: + void _audio_driver_process(int p_from = 0, int p_samples = 0); + void _audio_driver_capture(int p_from = 0, int p_samples = 0); +public: static bool is_available(); - void process_capture(float sample); static AudioDriverJavaScript *singleton; - const char *get_name() const override; + virtual const char *get_name() const; - Error init() override; - void start() override; + virtual Error init(); + virtual void start(); void resume(); - float get_latency() override; - int get_mix_rate() const override; - SpeakerMode get_speaker_mode() const override; - void lock() override; - void unlock() override; - void finish() override; - void finish_async(); + virtual float get_latency(); + virtual int get_mix_rate() const; + virtual SpeakerMode get_speaker_mode() const; + virtual void lock(); + virtual void unlock(); + virtual void finish(); - Error capture_start() override; - Error capture_stop() override; + virtual Error capture_start(); + virtual Error capture_stop(); AudioDriverJavaScript(); }; - #endif diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 8f2961b33d..e6e35f6aa9 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -1,6 +1,6 @@ import os -from emscripten_helpers import run_closure_compiler, create_engine_file +from emscripten_helpers import run_closure_compiler, create_engine_file, add_js_libraries from SCons.Util import WhereIs @@ -85,7 +85,8 @@ def configure(env): if env["use_lto"]: env.Append(CCFLAGS=["-s", "WASM_OBJECT_FILES=0"]) env.Append(LINKFLAGS=["-s", "WASM_OBJECT_FILES=0"]) - env.Append(LINKFLAGS=["--llvm-lto", "1"]) + env.Append(CCFLAGS=["-flto"]) + env.Append(LINKFLAGS=["-flto"]) # Closure compiler if env["use_closure_compiler"]: @@ -95,6 +96,9 @@ def configure(env): jscc = env.Builder(generator=run_closure_compiler, suffix=".cc.js", src_suffix=".js") env.Append(BUILDERS={"BuildJS": jscc}) + # Add helper method for adding libraries. + env.AddMethod(add_js_libraries, "AddJSLibraries") + # Add method that joins/compiles our Engine files. env.AddMethod(create_engine_file, "CreateEngineFile") @@ -165,6 +169,6 @@ def configure(env): env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"]) # callMain for manual start, FS for preloading, PATH and ERRNO_CODES for BrowserFS. - env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain', 'FS', 'PATH']"]) + env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"]) # Add code that allow exiting runtime. env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"]) diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index 8dc33bdf64..768e326e80 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -37,6 +37,7 @@ #include <png.h> #include "dom_keys.inc" +#include "godot_js.h" #define DOM_BUTTON_LEFT 0 #define DOM_BUTTON_MIDDLE 1 @@ -44,28 +45,17 @@ #define DOM_BUTTON_XBUTTON1 3 #define DOM_BUTTON_XBUTTON2 4 -char DisplayServerJavaScript::canvas_id[256] = { 0 }; -static bool cursor_inside_canvas = true; - DisplayServerJavaScript *DisplayServerJavaScript::get_singleton() { return static_cast<DisplayServerJavaScript *>(DisplayServer::get_singleton()); } // Window (canvas) void DisplayServerJavaScript::focus_canvas() { - /* clang-format off */ - EM_ASM( - Module['canvas'].focus(); - ); - /* clang-format on */ + godot_js_display_canvas_focus(); } bool DisplayServerJavaScript::is_canvas_focused() { - /* clang-format off */ - return EM_ASM_INT_V( - return document.activeElement == Module['canvas']; - ); - /* clang-format on */ + return godot_js_display_canvas_is_focused() != 0; } bool DisplayServerJavaScript::check_size_force_redraw() { @@ -83,19 +73,17 @@ bool DisplayServerJavaScript::check_size_force_redraw() { } Point2 DisplayServerJavaScript::compute_position_in_canvas(int p_x, int p_y) { - int canvas_x = EM_ASM_INT({ - return Module['canvas'].getBoundingClientRect().x; - }); - int canvas_y = EM_ASM_INT({ - return Module['canvas'].getBoundingClientRect().y; - }); + DisplayServerJavaScript *display = get_singleton(); + int canvas_x; + int canvas_y; + godot_js_display_canvas_bounding_rect_position_get(&canvas_x, &canvas_y); int canvas_width; int canvas_height; - emscripten_get_canvas_element_size(canvas_id, &canvas_width, &canvas_height); + emscripten_get_canvas_element_size(display->canvas_id, &canvas_width, &canvas_height); double element_width; double element_height; - emscripten_get_element_css_size(canvas_id, &element_width, &element_height); + emscripten_get_element_css_size(display->canvas_id, &element_width, &element_height); return Point2((int)(canvas_width / element_width * (p_x - canvas_x)), (int)(canvas_height / element_height * (p_y - canvas_y))); @@ -105,8 +93,7 @@ EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, co DisplayServerJavaScript *display = get_singleton(); // Empty ID is canvas. String target_id = String::utf8(p_event->id); - String canvas_str_id = String::utf8(canvas_id); - if (target_id.empty() || target_id == canvas_str_id) { + if (target_id.empty() || target_id == String::utf8(display->canvas_id)) { // This event property is the only reliable data on // browser fullscreen state. if (p_event->isFullscreen) { @@ -118,14 +105,15 @@ EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, co return false; } -// Drag and drop callback (see native/utils.js). -extern "C" EMSCRIPTEN_KEEPALIVE void _drop_files_callback(char *p_filev[], int p_filec) { - DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton(); +// Drag and drop callback. +void DisplayServerJavaScript::drop_files_js_callback(char **p_filev, int p_filec) { + DisplayServerJavaScript *ds = get_singleton(); if (!ds) { ERR_FAIL_MSG("Unable to drop files because the DisplayServer is not active"); } - if (ds->drop_files_callback.is_null()) + if (ds->drop_files_callback.is_null()) { return; + } Vector<String> files; for (int i = 0; i < p_filec; i++) { files.push_back(String::utf8(p_filev[i])); @@ -137,6 +125,18 @@ extern "C" EMSCRIPTEN_KEEPALIVE void _drop_files_callback(char *p_filev[], int p ds->drop_files_callback.call((const Variant **)&vp, 1, ret, ce); } +// JavaScript quit request callback. +void DisplayServerJavaScript::request_quit_callback() { + DisplayServerJavaScript *ds = get_singleton(); + if (ds && !ds->window_event_callback.is_null()) { + Variant event = int(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST); + Variant *eventp = &event; + Variant ret; + Callable::CallError ce; + ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce); + } +} + // Keys template <typename T> @@ -272,12 +272,13 @@ EM_BOOL DisplayServerJavaScript::mouse_button_callback(int p_event_type, const E } EM_BOOL DisplayServerJavaScript::mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) { + DisplayServerJavaScript *ds = get_singleton(); Input *input = Input::get_singleton(); int input_mask = input->get_mouse_button_mask(); Point2 pos = compute_position_in_canvas(p_event->clientX, p_event->clientY); // For motion outside the canvas, only read mouse movement if dragging // started inside the canvas; imitating desktop app behaviour. - if (!cursor_inside_canvas && !input_mask) + if (!ds->cursor_inside_canvas && !input_mask) return false; Ref<InputEventMouseMotion> ev; @@ -339,35 +340,13 @@ const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape } } -void DisplayServerJavaScript::set_css_cursor(const char *p_cursor) { - /* clang-format off */ - EM_ASM_({ - Module['canvas'].style.cursor = UTF8ToString($0); - }, p_cursor); - /* clang-format on */ -} - -bool DisplayServerJavaScript::is_css_cursor_hidden() const { - /* clang-format off */ - return EM_ASM_INT({ - return Module['canvas'].style.cursor === 'none'; - }); - /* clang-format on */ -} - void DisplayServerJavaScript::cursor_set_shape(CursorShape p_shape) { ERR_FAIL_INDEX(p_shape, CURSOR_MAX); - - if (mouse_get_mode() == MOUSE_MODE_VISIBLE) { - if (cursors[p_shape] != "") { - Vector<String> url = cursors[p_shape].split("?"); - set_css_cursor(("url(\"" + url[0] + "\") " + url[1] + ", auto").utf8()); - } else { - set_css_cursor(godot2dom_cursor(p_shape)); - } + if (cursor_shape == p_shape) { + return; } - cursor_shape = p_shape; + godot_js_display_cursor_set_shape(godot2dom_cursor(cursor_shape)); } DisplayServer::CursorShape DisplayServerJavaScript::cursor_get_shape() const { @@ -376,17 +355,6 @@ DisplayServer::CursorShape DisplayServerJavaScript::cursor_get_shape() const { void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (p_cursor.is_valid()) { - Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape); - - if (cursor_c) { - if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { - cursor_set_shape(p_shape); - return; - } - - cursors_cache.erase(p_shape); - } - Ref<Texture2D> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; @@ -449,53 +417,10 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso png.resize(len); ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr)); - char *object_url; - /* clang-format off */ - EM_ASM({ - var PNG_PTR = $0; - var PNG_LEN = $1; - var PTR = $2; - - var png = new Blob([HEAPU8.slice(PNG_PTR, PNG_PTR + PNG_LEN)], { type: 'image/png' }); - var url = URL.createObjectURL(png); - var length_bytes = lengthBytesUTF8(url) + 1; - var string_on_wasm_heap = _malloc(length_bytes); - setValue(PTR, string_on_wasm_heap, '*'); - stringToUTF8(url, string_on_wasm_heap, length_bytes); - }, png.ptr(), len, &object_url); - /* clang-format on */ - - String url = String::utf8(object_url) + "?" + itos(p_hotspot.x) + " " + itos(p_hotspot.y); - - /* clang-format off */ - EM_ASM({ _free($0); }, object_url); - /* clang-format on */ - - if (cursors[p_shape] != "") { - /* clang-format off */ - EM_ASM({ - URL.revokeObjectURL(UTF8ToString($0).split('?')[0]); - }, cursors[p_shape].utf8().get_data()); - /* clang-format on */ - cursors[p_shape] = ""; - } - - cursors[p_shape] = url; + godot_js_display_cursor_set_custom_shape(godot2dom_cursor(p_shape), png.ptr(), len, p_hotspot.x, p_hotspot.y); - Vector<Variant> params; - params.push_back(p_cursor); - params.push_back(p_hotspot); - cursors_cache.insert(p_shape, params); - - } else if (cursors[p_shape] != "") { - /* clang-format off */ - EM_ASM({ - URL.revokeObjectURL(UTF8ToString($0).split('?')[0]); - }, cursors[p_shape].utf8().get_data()); - /* clang-format on */ - cursors[p_shape] = ""; - - cursors_cache.erase(p_shape); + } else { + godot_js_display_cursor_set_custom_shape(godot2dom_cursor(p_shape), NULL, 0, 0, 0); } cursor_set_shape(cursor_shape); @@ -508,40 +433,37 @@ void DisplayServerJavaScript::mouse_set_mode(MouseMode p_mode) { return; if (p_mode == MOUSE_MODE_VISIBLE) { - // set_css_cursor must be called before set_cursor_shape to make the cursor visible - set_css_cursor(godot2dom_cursor(cursor_shape)); - cursor_set_shape(cursor_shape); + godot_js_display_cursor_set_visible(1); emscripten_exit_pointerlock(); } else if (p_mode == MOUSE_MODE_HIDDEN) { - set_css_cursor("none"); + godot_js_display_cursor_set_visible(0); emscripten_exit_pointerlock(); } else if (p_mode == MOUSE_MODE_CAPTURED) { - EMSCRIPTEN_RESULT result = emscripten_request_pointerlock("canvas", false); + godot_js_display_cursor_set_visible(1); + EMSCRIPTEN_RESULT result = emscripten_request_pointerlock(canvas_id, false); ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback."); ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback."); - // set_css_cursor must be called before cursor_set_shape to make the cursor visible - set_css_cursor(godot2dom_cursor(cursor_shape)); - cursor_set_shape(cursor_shape); } } DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const { - if (is_css_cursor_hidden()) + if (godot_js_display_cursor_is_hidden()) { return MOUSE_MODE_HIDDEN; + } EmscriptenPointerlockChangeEvent ev; emscripten_get_pointerlock_status(&ev); - return (ev.isActive && String::utf8(ev.id) == "canvas") ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE; + return (ev.isActive && String::utf8(ev.id) == String::utf8(canvas_id)) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE; } // Wheel - EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data) { ERR_FAIL_COND_V(p_event_type != EMSCRIPTEN_EVENT_WHEEL, false); + DisplayServerJavaScript *ds = get_singleton(); if (!is_canvas_focused()) { - if (cursor_inside_canvas) { + if (ds->cursor_inside_canvas) { focus_canvas(); } else { return false; @@ -632,7 +554,7 @@ EM_BOOL DisplayServerJavaScript::touchmove_callback(int p_event_type, const Emsc } bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const { - return EM_ASM_INT({ return 'ontouchstart' in window; }); + return godot_js_display_touchscreen_is_available(); } // Gamepad @@ -696,53 +618,30 @@ Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() { } // Clipboard -extern "C" EMSCRIPTEN_KEEPALIVE void update_clipboard(const char *p_text) { - // Only call set_clipboard from OS (sets local clipboard) - DisplayServerJavaScript::get_singleton()->clipboard = p_text; +void DisplayServerJavaScript::update_clipboard_callback(const char *p_text) { + get_singleton()->clipboard = p_text; } void DisplayServerJavaScript::clipboard_set(const String &p_text) { - /* clang-format off */ - int err = EM_ASM_INT({ - var text = UTF8ToString($0); - if (!navigator.clipboard || !navigator.clipboard.writeText) - return 1; - navigator.clipboard.writeText(text).catch(function(e) { - // Setting OS clipboard is only possible from an input callback. - console.error("Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:", e); - }); - return 0; - }, p_text.utf8().get_data()); - /* clang-format on */ + clipboard = p_text; + int err = godot_js_display_clipboard_set(p_text.utf8().get_data()); ERR_FAIL_COND_MSG(err, "Clipboard API is not supported."); } String DisplayServerJavaScript::clipboard_get() const { - /* clang-format off */ - EM_ASM({ - try { - navigator.clipboard.readText().then(function (result) { - ccall('update_clipboard', 'void', ['string'], [result]); - }).catch(function (e) { - // Fail graciously. - }); - } catch (e) { - // Fail graciously. - } - }); - /* clang-format on */ + godot_js_display_clipboard_get(update_clipboard_callback); return clipboard; } -extern "C" EMSCRIPTEN_KEEPALIVE void send_window_event(int p_notification) { +void DisplayServerJavaScript::send_window_event_callback(int p_notification) { + DisplayServerJavaScript *ds = get_singleton(); + if (!ds) { + return; + } if (p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER || p_notification == DisplayServer::WINDOW_EVENT_MOUSE_EXIT) { - cursor_inside_canvas = p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER; + ds->cursor_inside_canvas = p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER; } - OS_JavaScript *os = OS_JavaScript::get_singleton(); - if (os->is_finalizing()) - return; // We don't want events anymore. - DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton(); - if (ds && !ds->window_event_callback.is_null()) { + if (!ds->window_event_callback.is_null()) { Variant event = int(p_notification); Variant *eventp = &event; Variant ret; @@ -752,11 +651,7 @@ extern "C" EMSCRIPTEN_KEEPALIVE void send_window_event(int p_notification) { } void DisplayServerJavaScript::alert(const String &p_alert, const String &p_title) { - /* clang-format off */ - EM_ASM_({ - window.alert(UTF8ToString($0)); - }, p_alert.utf8().get_data()); - /* clang-format on */ + godot_js_display_alert(p_alert.utf8().get_data()); } void DisplayServerJavaScript::set_icon(const Ref<Image> &p_icon) { @@ -787,29 +682,11 @@ void DisplayServerJavaScript::set_icon(const Ref<Image> &p_icon) { png.resize(len); ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr)); - /* clang-format off */ - EM_ASM({ - var PNG_PTR = $0; - var PNG_LEN = $1; - - var png = new Blob([HEAPU8.slice(PNG_PTR, PNG_PTR + PNG_LEN)], { type: "image/png" }); - var url = URL.createObjectURL(png); - var link = document.getElementById('-gd-engine-icon'); - if (link === null) { - link = document.createElement('link'); - link.rel = 'icon'; - link.id = '-gd-engine-icon'; - document.head.appendChild(link); - } - link.href = url; - }, png.ptr(), len); - /* clang-format on */ + godot_js_display_window_icon_set(png.ptr(), len); } void DisplayServerJavaScript::_dispatch_input_event(const Ref<InputEvent> &p_event) { OS_JavaScript *os = OS_JavaScript::get_singleton(); - if (os->is_finalizing()) - return; // We don't want events anymore. // Resume audio context after input in case autoplay was denied. os->resume_audio(); @@ -831,16 +708,14 @@ DisplayServer *DisplayServerJavaScript::create_func(const String &p_rendering_dr DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { r_error = OK; // Always succeeds for now. - /* clang-format off */ - swap_cancel_ok = EM_ASM_INT({ - const win = (['Windows', 'Win64', 'Win32', 'WinCE']); - const plat = navigator.platform || ""; - if (win.indexOf(plat) !== -1) { - return 1; - } - return 0; - }) == 1; - /* clang-format on */ + // Ensure the canvas ID. + godot_js_config_canvas_id_get(canvas_id, 256); + + // Check if it's windows. + swap_cancel_ok = godot_js_display_is_swap_ok_cancel() == 1; + + // Expose method for requesting quit. + godot_js_os_request_quit_cb(request_quit_callback); RasterizerDummy::make_current(); // TODO GLES2 in Godot 4.0... or webgpu? #if 0 @@ -878,10 +753,8 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive video_driver_index = p_video_driver; #endif - /* clang-format off */ window_set_mode(p_mode); - if (EM_ASM_INT_V({ return Module['resizeCanvasOnStart'] })) { - /* clang-format on */ + if (godot_js_config_is_resize_on_start()) { window_set_size(p_resolution); } @@ -899,8 +772,7 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive result = emscripten_set_##ev##_callback(nullptr, true, &cb); \ EM_CHECK(ev) // These callbacks from Emscripten's html5.h suffice to access most - // JavaScript APIs. For APIs that are not (sufficiently) exposed, EM_ASM - // is used below. + // JavaScript APIs. SET_EM_CALLBACK(canvas_id, mousedown, mouse_button_callback) SET_EM_WINDOW_CALLBACK(mousemove, mousemove_callback) SET_EM_WINDOW_CALLBACK(mouseup, mouse_button_callback) @@ -919,42 +791,20 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive #undef SET_EM_CALLBACK #undef EM_CHECK - /* clang-format off */ - EM_ASM_ARGS({ - // Bind native event listeners. - // Module.listeners, and Module.drop_handler are defined in native/utils.js - const canvas = Module['canvas']; - const send_window_event = cwrap('send_window_event', null, ['number']); - const notifications = arguments; - (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, index) { - Module.listeners.add(canvas, event, send_window_event.bind(null, notifications[index]), true); - }); - // Clipboard - const update_clipboard = cwrap('update_clipboard', null, ['string']); - Module.listeners.add(window, 'paste', function(evt) { - update_clipboard(evt.clipboardData.getData('text')); - }, false); - // Drag an drop - Module.listeners.add(canvas, 'dragover', function(ev) { - // Prevent default behavior (which would try to open the file(s)) - ev.preventDefault(); - }, false); - Module.listeners.add(canvas, 'drop', Module.drop_handler, false); - }, - WINDOW_EVENT_MOUSE_ENTER, - WINDOW_EVENT_MOUSE_EXIT, - WINDOW_EVENT_FOCUS_IN, - WINDOW_EVENT_FOCUS_OUT - ); - /* clang-format on */ + // For APIs that are not (sufficiently) exposed, a + // library is used below (implemented in library_godot_display.js). + godot_js_display_notification_cb(&send_window_event_callback, + WINDOW_EVENT_MOUSE_ENTER, + WINDOW_EVENT_MOUSE_EXIT, + WINDOW_EVENT_FOCUS_IN, + WINDOW_EVENT_FOCUS_OUT); + godot_js_display_paste_cb(update_clipboard_callback); + godot_js_display_drop_files_cb(drop_files_js_callback); Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event); } DisplayServerJavaScript::~DisplayServerJavaScript() { - EM_ASM({ - Module.listeners.clear(); - }); //emscripten_webgl_commit_frame(); //emscripten_webgl_destroy_context(webgl_ctx); } @@ -1057,11 +907,7 @@ void DisplayServerJavaScript::window_set_drop_files_callback(const Callable &p_c } void DisplayServerJavaScript::window_set_title(const String &p_title, WindowID p_window) { - /* clang-format off */ - EM_ASM_({ - document.title = UTF8ToString($0); - }, p_title.utf8().get_data()); - /* clang-format on */ + godot_js_display_window_title_set(p_title.utf8().get_data()); } int DisplayServerJavaScript::window_get_current_screen(WindowID p_window) const { @@ -1103,9 +949,7 @@ Size2i DisplayServerJavaScript::window_get_min_size(WindowID p_window) const { void DisplayServerJavaScript::window_set_size(const Size2i p_size, WindowID p_window) { last_width = p_size.x; last_height = p_size.y; - double scale = EM_ASM_DOUBLE({ - return window.devicePixelRatio || 1; - }); + double scale = godot_js_display_pixel_ratio_get(); emscripten_set_canvas_element_size(canvas_id, p_size.x * scale, p_size.y * scale); emscripten_set_element_css_size(canvas_id, p_size.x, p_size.y); } @@ -1130,7 +974,7 @@ void DisplayServerJavaScript::window_set_mode(WindowMode p_mode, WindowID p_wind emscripten_exit_fullscreen(); } window_mode = WINDOW_MODE_WINDOWED; - window_set_size(windowed_size); + window_set_size(Size2i(last_width, last_height)); } break; case WINDOW_MODE_FULLSCREEN: { EmscriptenFullscreenStrategy strategy; diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index d7116be36f..1f00295d48 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -37,18 +37,22 @@ #include <emscripten/html5.h> class DisplayServerJavaScript : public DisplayServer { - //int video_driver_index; - - Vector2 windowed_size; - +private: + WindowMode window_mode = WINDOW_MODE_WINDOWED; ObjectID window_attached_instance_id = {}; + Callable window_event_callback; + Callable input_event_callback; + Callable input_text_callback; + Callable drop_files_callback; + + String clipboard; Ref<InputEventKey> deferred_key_event; - CursorShape cursor_shape = CURSOR_ARROW; - String cursors[CURSOR_MAX]; - Map<CursorShape, Vector<Variant>> cursors_cache; Point2 touches[32]; + char canvas_id[256] = { 0 }; + bool cursor_inside_canvas = true; + CursorShape cursor_shape = CURSOR_ARROW; Point2i last_click_pos = Point2(-100, -100); // TODO check this again. double last_click_ms = 0; int last_click_button_index = -1; @@ -66,8 +70,6 @@ class DisplayServerJavaScript : public DisplayServer { static void dom2godot_mod(T *emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event); static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscripten_event); static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape); - static void set_css_cursor(const char *p_cursor); - bool is_css_cursor_hidden() const; // events static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data); @@ -92,22 +94,17 @@ class DisplayServerJavaScript : public DisplayServer { static void _dispatch_input_event(const Ref<InputEvent> &p_event); + static void request_quit_callback(); + static void update_clipboard_callback(const char *p_text); + static void send_window_event_callback(int p_notification); + static void drop_files_js_callback(char **p_filev, int p_filec); + protected: int get_current_video_driver() const; public: // Override return type to make writing static callbacks less tedious. static DisplayServerJavaScript *get_singleton(); - static char canvas_id[256]; - - WindowMode window_mode = WINDOW_MODE_WINDOWED; - - String clipboard; - - Callable window_event_callback; - Callable input_event_callback; - Callable input_text_callback; - Callable drop_files_callback; // utilities bool check_size_force_redraw(); diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py index f6db10fbbd..cc874c432e 100644 --- a/platform/javascript/emscripten_helpers.py +++ b/platform/javascript/emscripten_helpers.py @@ -19,3 +19,9 @@ def create_engine_file(env, target, source, externs): if env["use_closure_compiler"]: return env.BuildJS(target, source, JSEXTERNS=externs) return env.Textfile(target, [env.File(s) for s in source]) + + +def add_js_libraries(env, libraries): + if "JS_LIBS" not in env: + env["JS_LIBS"] = [] + env.Append(JS_LIBS=env.File(libraries)) diff --git a/platform/javascript/engine/engine.js b/platform/javascript/engine/engine.js index 05a11701c0..3745e04479 100644 --- a/platform/javascript/engine/engine.js +++ b/platform/javascript/engine/engine.js @@ -33,7 +33,7 @@ Function('return this')()['Engine'] = (function() { this.resizeCanvasOnStart = false; this.onExecute = null; this.onExit = null; - this.persistentPaths = []; + this.persistentPaths = ['/userfs']; }; Engine.prototype.init = /** @param {string=} basePath */ function(basePath) { @@ -114,18 +114,30 @@ Function('return this')()['Engine'] = (function() { locale = navigator.languages ? navigator.languages[0] : navigator.language; locale = locale.split('.')[0]; } - me.rtenv['locale'] = locale; - me.rtenv['canvas'] = me.canvas; + // Emscripten configuration. me.rtenv['thisProgram'] = me.executableName; - me.rtenv['resizeCanvasOnStart'] = me.resizeCanvasOnStart; me.rtenv['noExitRuntime'] = true; - me.rtenv['onExecute'] = me.onExecute; - me.rtenv['onExit'] = function(code) { - me.rtenv['deinitFS'](); - if (me.onExit) - me.onExit(code); - me.rtenv = null; - }; + // Godot configuration. + me.rtenv['initConfig']({ + 'resizeCanvasOnStart': me.resizeCanvasOnStart, + 'canvas': me.canvas, + 'locale': locale, + 'onExecute': function(p_args) { + if (me.onExecute) { + me.onExecute(p_args); + return 0; + } + return 1; + }, + 'onExit': function(p_code) { + me.rtenv['deinitFS'](); + if (me.onExit) { + me.onExit(p_code); + } + me.rtenv = null; + }, + }); + return new Promise(function(resolve, reject) { preloader.preloadedFiles.forEach(function(file) { me.rtenv['copyToFS'](file.path, file.buffer); @@ -208,8 +220,6 @@ Function('return this')()['Engine'] = (function() { }; Engine.prototype.setOnExecute = function(onExecute) { - if (this.rtenv) - this.rtenv.onExecute = onExecute; this.onExecute = onExecute; }; diff --git a/platform/javascript/engine/utils.js b/platform/javascript/engine/utils.js index 0c97b38199..10e3abe91e 100644 --- a/platform/javascript/engine/utils.js +++ b/platform/javascript/engine/utils.js @@ -4,6 +4,8 @@ var Utils = { function rw(path) { if (path.endsWith('.worker.js')) { return execName + '.worker.js'; + } else if (path.endsWith('.audio.worklet.js')) { + return execName + '.audio.worklet.js'; } else if (path.endsWith('.js')) { return execName + '.js'; } else if (path.endsWith('.wasm')) { diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index a83ff44d20..d520931067 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -94,6 +94,9 @@ public: } else if (req[1] == basereq + ".js") { filepath += ".js"; ctype = "application/javascript"; + } else if (req[1] == basereq + ".audio.worklet.js") { + filepath += ".audio.worklet.js"; + ctype = "application/javascript"; } else if (req[1] == basereq + ".worker.js") { filepath += ".worker.js"; ctype = "application/javascript"; @@ -440,6 +443,9 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese } else if (file == "godot.worker.js") { file = p_path.get_file().get_basename() + ".worker.js"; + } else if (file == "godot.audio.worklet.js") { + file = p_path.get_file().get_basename() + ".audio.worklet.js"; + } else if (file == "godot.wasm") { file = p_path.get_file().get_basename() + ".wasm"; } @@ -566,6 +572,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese DirAccess::remove_file_or_error(basepath + ".html"); DirAccess::remove_file_or_error(basepath + ".js"); DirAccess::remove_file_or_error(basepath + ".worker.js"); + DirAccess::remove_file_or_error(basepath + ".audio.worklet.js"); DirAccess::remove_file_or_error(basepath + ".pck"); DirAccess::remove_file_or_error(basepath + ".png"); DirAccess::remove_file_or_error(basepath + ".wasm"); diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h index f7f26e5262..7ebda3ad39 100644 --- a/platform/javascript/godot_audio.h +++ b/platform/javascript/godot_audio.h @@ -38,19 +38,24 @@ extern "C" { #include "stddef.h" extern int godot_audio_is_available(); - -extern int godot_audio_init(int p_mix_rate, int p_latency); -extern int godot_audio_create_processor(int p_buffer_length, int p_channel_count); - -extern void godot_audio_start(float *r_buffer_ptr); +extern int godot_audio_init(int p_mix_rate, int p_latency, void (*_state_cb)(int), void (*_latency_cb)(float)); extern void godot_audio_resume(); -extern void godot_audio_finish_async(); - -extern float godot_audio_get_latency(); extern void godot_audio_capture_start(); extern void godot_audio_capture_stop(); +// Worklet +typedef int32_t GodotAudioState[4]; +extern void godot_audio_worklet_create(int p_channels); +extern void godot_audio_worklet_start(float *p_in_buf, int p_in_size, float *p_out_buf, int p_out_size, GodotAudioState p_state); +extern void godot_audio_worklet_state_add(GodotAudioState p_state, int p_idx, int p_value); +extern int godot_audio_worklet_state_get(GodotAudioState p_state, int p_idx); +extern int godot_audio_worklet_state_wait(int32_t *p_state, int p_idx, int32_t p_expected, int p_timeout); + +// Script +extern int godot_audio_script_create(int p_buffer_size, int p_channels); +extern void godot_audio_script_start(float *p_in_buf, int p_in_size, float *p_out_buf, int p_out_size, void (*p_cb)()); + #ifdef __cplusplus } #endif diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h new file mode 100644 index 0000000000..23596a0897 --- /dev/null +++ b/platform/javascript/godot_js.h @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* godot_js.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_JS_H +#define GODOT_JS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stddef.h" + +// Config +extern void godot_js_config_locale_get(char *p_ptr, int p_ptr_max); +extern void godot_js_config_canvas_id_get(char *p_ptr, int p_ptr_max); +extern int godot_js_config_is_resize_on_start(); + +// OS +extern void godot_js_os_finish_async(void (*p_callback)()); +extern void godot_js_os_request_quit_cb(void (*p_callback)()); +extern int godot_js_os_fs_is_persistent(); +extern void godot_js_os_fs_sync(void (*p_callback)()); +extern int godot_js_os_execute(const char *p_json); +extern void godot_js_os_shell_open(const char *p_uri); + +// Display +extern double godot_js_display_pixel_ratio_get(); +extern void godot_js_display_alert(const char *p_text); +extern int godot_js_display_touchscreen_is_available(); +extern int godot_js_display_is_swap_ok_cancel(); + +// Display canvas +extern void godot_js_display_canvas_focus(); +extern int godot_js_display_canvas_is_focused(); +extern void godot_js_display_canvas_bounding_rect_position_get(int32_t *p_x, int32_t *p_y); + +// Display window +extern void godot_js_display_window_request_fullscreen(); +extern void godot_js_display_window_title_set(const char *p_text); +extern void godot_js_display_window_icon_set(const uint8_t *p_ptr, int p_len); + +// Display clipboard +extern int godot_js_display_clipboard_set(const char *p_text); +extern int godot_js_display_clipboard_get(void (*p_callback)(const char *p_text)); + +// Display cursor +extern void godot_js_display_cursor_set_shape(const char *p_cursor); +extern int godot_js_display_cursor_is_hidden(); +extern void godot_js_display_cursor_set_custom_shape(const char *p_shape, const uint8_t *p_ptr, int p_len, int p_hotspot_x, int p_hotspot_y); +extern void godot_js_display_cursor_set_visible(int p_visible); + +// Display listeners +extern void godot_js_display_notification_cb(void (*p_callback)(int p_notification), int p_enter, int p_exit, int p_in, int p_out); +extern void godot_js_display_paste_cb(void (*p_callback)(const char *p_text)); +extern void godot_js_display_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec)); +#ifdef __cplusplus +} +#endif + +#endif /* GODOT_JS_H */ diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp index 3a72b10dd4..b203253a39 100644 --- a/platform/javascript/javascript_eval.cpp +++ b/platform/javascript/javascript_eval.cpp @@ -33,95 +33,30 @@ #include "api/javascript_eval.h" #include "emscripten.h" -extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_PackedByteArray_and_open_write(PackedByteArray *p_arr, VectorWriteProxy<uint8_t> *r_write, int p_len) { - p_arr->resize(p_len); - *r_write = p_arr->write; - return p_arr->ptrw(); +extern "C" { +union js_eval_ret { + uint32_t b; + double d; + char *s; +}; + +extern int godot_js_eval(const char *p_js, int p_use_global_ctx, union js_eval_ret *p_union_ptr, void *p_byte_arr, void *p_byte_arr_write, void *(*p_callback)(void *p_ptr, void *p_ptr2, int p_len)); } -Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { - union { - bool b; - double d; - char *s; - } js_data; +void *resize_PackedByteArray_and_open_write(void *p_arr, void *r_write, int p_len) { + PackedByteArray *arr = (PackedByteArray *)p_arr; + VectorWriteProxy<uint8_t> *write = (VectorWriteProxy<uint8_t> *)r_write; + arr->resize(p_len); + *write = arr->write; + return arr->ptrw(); +} +Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { + union js_eval_ret js_data; PackedByteArray arr; VectorWriteProxy<uint8_t> arr_write; - /* clang-format off */ - Variant::Type return_type = static_cast<Variant::Type>(EM_ASM_INT({ - - const CODE = $0; - const USE_GLOBAL_EXEC_CONTEXT = $1; - const PTR = $2; - const BYTEARRAY_PTR = $3; - const BYTEARRAY_WRITE_PTR = $4; - var eval_ret; - try { - if (USE_GLOBAL_EXEC_CONTEXT) { - // indirect eval call grants global execution context - var global_eval = eval; - eval_ret = global_eval(UTF8ToString(CODE)); - } else { - eval_ret = eval(UTF8ToString(CODE)); - } - } catch (e) { - err(e); - eval_ret = null; - } - - switch (typeof eval_ret) { - - case 'boolean': - setValue(PTR, eval_ret, 'i32'); - return 1; // BOOL - - case 'number': - setValue(PTR, eval_ret, 'double'); - return 3; // FLOAT - - case 'string': - var array_len = lengthBytesUTF8(eval_ret)+1; - var array_ptr = _malloc(array_len); - try { - if (array_ptr===0) { - throw new Error('String allocation failed (probably out of memory)'); - } - setValue(PTR, array_ptr , '*'); - stringToUTF8(eval_ret, array_ptr, array_len); - return 4; // STRING - } catch (e) { - if (array_ptr!==0) { - _free(array_ptr) - } - err(e); - // fall through - } - break; - - case 'object': - if (eval_ret === null) { - break; - } - - if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) { - eval_ret = new Uint8Array(eval_ret.buffer); - } - else if (eval_ret instanceof ArrayBuffer) { - eval_ret = new Uint8Array(eval_ret); - } - if (eval_ret instanceof Uint8Array) { - var bytes_ptr = ccall('resize_PackedByteArray_and_open_write', 'number', ['number', 'number' ,'number'], [BYTEARRAY_PTR, BYTEARRAY_WRITE_PTR, eval_ret.length]); - HEAPU8.set(eval_ret, bytes_ptr); - return 20; // PACKED_BYTE_ARRAY - } - break; - } - return 0; // NIL - - }, p_code.utf8().get_data(), p_use_global_exec_context, &js_data, &arr, &arr_write)); - /* clang-format on */ + Variant::Type return_type = static_cast<Variant::Type>(godot_js_eval(p_code.utf8().get_data(), p_use_global_exec_context, &js_data, &arr, &arr_write, resize_PackedByteArray_and_open_write)); switch (return_type) { case Variant::BOOL: @@ -130,9 +65,7 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { return js_data.d; case Variant::STRING: { String str = String::utf8(js_data.s); - /* clang-format off */ - EM_ASM_({ _free($0); }, js_data.s); - /* clang-format on */ + free(js_data.s); // Must free the string allocated in JS. return str; } case Variant::PACKED_BYTE_ARRAY: diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index 01722c4bc8..2d28a63566 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -36,20 +36,11 @@ #include <emscripten/emscripten.h> #include <stdlib.h> +#include "godot_js.h" + static OS_JavaScript *os = nullptr; static uint64_t target_ticks = 0; -extern "C" EMSCRIPTEN_KEEPALIVE void _request_quit_callback(char *p_filev[], int p_filec) { - DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton(); - if (ds) { - Variant event = int(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST); - Variant *eventp = &event; - Variant ret; - Callable::CallError ce; - ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce); - } -} - void exit_callback() { emscripten_cancel_main_loop(); // After this, we can exit! Main::cleanup(); @@ -59,6 +50,10 @@ void exit_callback() { emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing. } +void cleanup_after_sync() { + emscripten_set_main_loop(exit_callback, -1, false); +} + void main_loop_callback() { uint64_t current_ticks = os->get_ticks_usec(); @@ -74,68 +69,14 @@ void main_loop_callback() { target_ticks += (uint64_t)(1000000 / target_fps); } if (os->main_loop_iterate()) { - emscripten_cancel_main_loop(); // Cancel current loop and wait for finalize_async. - /* clang-format off */ - EM_ASM({ - // This will contain the list of operations that need to complete before cleanup. - Module.async_finish = [ - // Always contains at least one async promise, to avoid firing immediately if nothing is added. - new Promise(function(accept, reject) { - setTimeout(accept, 0); - }) - ]; - }); - /* clang-format on */ - os->get_main_loop()->finish(); - os->finalize_async(); // Will add all the async finish functions. - /* clang-format off */ - EM_ASM({ - Promise.all(Module.async_finish).then(function() { - Module.async_finish = []; - return new Promise(function(accept, reject) { - if (!Module.idbfs) { - accept(); - return; - } - FS.syncfs(function(error) { - if (error) { - err('Failed to save IDB file system: ' + error.message); - } - accept(); - }); - }); - }).then(function() { - ccall("cleanup_after_sync", null, []); - }); - }); - /* clang-format on */ + emscripten_cancel_main_loop(); // Cancel current loop and wait for cleanup_after_sync. + godot_js_os_finish_async(cleanup_after_sync); } } -extern "C" EMSCRIPTEN_KEEPALIVE void cleanup_after_sync() { - emscripten_set_main_loop(exit_callback, -1, false); -} - /// When calling main, it is assumed FS is setup and synced. int main(int argc, char *argv[]) { - // Configure locale. - char locale_ptr[16]; - /* clang-format off */ - EM_ASM({ - stringToUTF8(Module['locale'], $0, 16); - }, locale_ptr); - /* clang-format on */ - setenv("LANG", locale_ptr, true); - - // Ensure the canvas ID. - /* clang-format off */ - EM_ASM({ - stringToUTF8("#" + Module['canvas'].id, $0, 255); - }, DisplayServerJavaScript::canvas_id); - /* clang-format on */ - os = new OS_JavaScript(); - os->set_idb_available((bool)EM_ASM_INT({ return Module.idbfs })); // We must override main when testing is enabled TEST_MAIN_OVERRIDE @@ -147,14 +88,6 @@ int main(int argc, char *argv[]) { Main::start(); os->get_main_loop()->init(); - // Expose method for requesting quit. - /* clang-format off */ - EM_ASM({ - Module['request_quit'] = function() { - ccall("_request_quit_callback", null, []); - }; - }); - /* clang-format on */ emscripten_set_main_loop(main_loop_callback, -1, false); // Immediately run the first iteration. // We are inside an animation frame, we want to immediately draw on the newly setup canvas. diff --git a/platform/javascript/native/audio.worklet.js b/platform/javascript/native/audio.worklet.js new file mode 100644 index 0000000000..ad7957e45c --- /dev/null +++ b/platform/javascript/native/audio.worklet.js @@ -0,0 +1,186 @@ +/*************************************************************************/ +/* audio.worklet.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ +class RingBuffer { + + constructor(p_buffer, p_state) { + this.buffer = p_buffer; + this.avail = p_state; + this.rpos = 0; + this.wpos = 0; + } + + data_left() { + return Atomics.load(this.avail, 0); + } + + space_left() { + return this.buffer.length - this.data_left(); + } + + read(output) { + const size = this.buffer.length; + let from = 0 + let to_write = output.length; + if (this.rpos + to_write > size) { + const high = size - this.rpos; + output.set(this.buffer.subarray(this.rpos, size)); + from = high; + to_write -= high; + this.rpos = 0; + } + output.set(this.buffer.subarray(this.rpos, this.rpos + to_write), from); + this.rpos += to_write; + Atomics.add(this.avail, 0, -output.length); + Atomics.notify(this.avail, 0); + } + + write(p_buffer) { + const to_write = p_buffer.length; + const mw = this.buffer.length - this.wpos; + if (mw >= to_write) { + this.buffer.set(p_buffer, this.wpos); + } else { + const high = p_buffer.subarray(0, to_write - mw); + const low = p_buffer.subarray(to_write - mw); + this.buffer.set(high, this.wpos); + this.buffer.set(low); + } + let diff = to_write; + if (this.wpos + diff >= this.buffer.length) { + diff -= this.buffer.length; + } + this.wpos += diff; + Atomics.add(this.avail, 0, to_write); + Atomics.notify(this.avail, 0); + } +} + +class GodotProcessor extends AudioWorkletProcessor { + constructor() { + super(); + this.running = true; + this.lock = null; + this.notifier = null; + this.output = null; + this.output_buffer = new Float32Array(); + this.input = null; + this.input_buffer = new Float32Array(); + this.port.onmessage = (event) => { + const cmd = event.data['cmd']; + const data = event.data['data']; + this.parse_message(cmd, data); + }; + } + + process_notify() { + Atomics.add(this.notifier, 0, 1); + Atomics.notify(this.notifier, 0); + } + + parse_message(p_cmd, p_data) { + if (p_cmd == "start" && p_data) { + const state = p_data[0]; + let idx = 0; + this.lock = state.subarray(idx, ++idx); + this.notifier = state.subarray(idx, ++idx); + const avail_in = state.subarray(idx, ++idx); + const avail_out = state.subarray(idx, ++idx); + this.input = new RingBuffer(p_data[1], avail_in); + this.output = new RingBuffer(p_data[2], avail_out); + } else if (p_cmd == "stop") { + this.runing = false; + this.output = null; + this.input = null; + } + } + + array_has_data(arr) { + return arr.length && arr[0].length && arr[0][0].length; + } + + process(inputs, outputs, parameters) { + if (!this.running) { + return false; // Stop processing. + } + if (this.output === null) { + return true; // Not ready yet, keep processing. + } + const process_input = this.array_has_data(inputs); + if (process_input) { + const input = inputs[0]; + const chunk = input[0].length * input.length; + if (this.input_buffer.length != chunk) { + this.input_buffer = new Float32Array(chunk); + } + if (this.input.space_left() >= chunk) { + this.write_input(this.input_buffer, input); + this.input.write(this.input_buffer); + } else { + this.port.postMessage("Input buffer is full! Skipping input frame."); + } + } + const process_output = this.array_has_data(outputs); + if (process_output) { + const output = outputs[0]; + const chunk = output[0].length * output.length; + if (this.output_buffer.length != chunk) { + this.output_buffer = new Float32Array(chunk) + } + if (this.output.data_left() >= chunk) { + this.output.read(this.output_buffer); + this.write_output(output, this.output_buffer); + } else { + this.port.postMessage("Output buffer has not enough frames! Skipping output frame."); + } + } + this.process_notify(); + return true; + } + + write_output(dest, source) { + const channels = dest.length; + for (let ch = 0; ch < channels; ch++) { + for (let sample = 0; sample < dest[ch].length; sample++) { + dest[ch][sample] = source[sample * channels + ch]; + } + } + } + + write_input(dest, source) { + const channels = source.length; + for (let ch = 0; ch < channels; ch++) { + for (let sample = 0; sample < source[ch].length; sample++) { + dest[sample * channels + ch] = source[ch][sample]; + } + } + } +} + +registerProcessor('godot-processor', GodotProcessor); diff --git a/platform/javascript/native/library_godot_audio.js b/platform/javascript/native/library_godot_audio.js index d300280ccd..846359b8b2 100644 --- a/platform/javascript/native/library_godot_audio.js +++ b/platform/javascript/native/library_godot_audio.js @@ -27,13 +27,109 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -var GodotAudio = { - $GodotAudio: { +const GodotAudio = { + $GodotAudio__deps: ['$GodotOS'], + $GodotAudio: { ctx: null, input: null, - script: null, + driver: null, + interval: 0, + + init: function(mix_rate, latency, onstatechange, onlatencyupdate) { + const ctx = new (window.AudioContext || window.webkitAudioContext)({ + sampleRate: mix_rate, + // latencyHint: latency / 1000 // Do not specify, leave 'interactive' for good performance. + }); + GodotAudio.ctx = ctx; + onstatechange(ctx.state); // Immeditately notify state. + ctx.onstatechange = function() { + let state = 0; + switch (ctx.state) { + case 'suspended': + state = 0; + break; + case 'running': + state = 1; + break; + case 'closed': + state = 2; + break; + } + onstatechange(state); + } + // Update computed latency + GodotAudio.interval = setInterval(function() { + let latency = 0; + if (ctx.baseLatency) { + latency += GodotAudio.ctx.baseLatency; + } + if (ctx.outputLatency) { + latency += GodotAudio.ctx.outputLatency; + } + onlatencyupdate(latency); + }, 1000); + GodotOS.atexit(GodotAudio.close_async); + return ctx.destination.channelCount; + }, + + create_input: function(callback) { + if (GodotAudio.input) { + return; // Already started. + } + function gotMediaInput(stream) { + GodotAudio.input = GodotAudio.ctx.createMediaStreamSource(stream); + callback(GodotAudio.input) + } + if (navigator.mediaDevices.getUserMedia) { + navigator.mediaDevices.getUserMedia({ + "audio": true + }).then(gotMediaInput, function(e) { out(e) }); + } else { + if (!navigator.getUserMedia) { + navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; + } + navigator.getUserMedia({ + "audio": true + }, gotMediaInput, function(e) { out(e) }); + } + }, + + close_async: function(resolve, reject) { + const ctx = GodotAudio.ctx; + GodotAudio.ctx = null; + // Audio was not initialized. + if (!ctx) { + resolve(); + return; + } + // Remove latency callback + if (GodotAudio.interval) { + clearInterval(GodotAudio.interval); + GodotAudio.interval = 0; + } + // Disconnect input, if it was started. + if (GodotAudio.input) { + GodotAudio.input.disconnect(); + GodotAudio.input = null; + } + // Disconnect output + let closed = Promise.resolve(); + if (GodotAudio.driver) { + closed = GodotAudio.driver.close(); + } + closed.then(function() { + return ctx.close(); + }).then(function() { + ctx.onstatechange = null; + resolve(); + }).catch(function(e) { + ctx.onstatechange = null; + console.error("Error closing AudioContext", e); + resolve(); + }); + }, }, godot_audio_is_available__proxy: 'sync', @@ -44,50 +140,10 @@ var GodotAudio = { return 1; }, - godot_audio_init: function(mix_rate, latency) { - GodotAudio.ctx = new (window.AudioContext || window.webkitAudioContext)({ - sampleRate: mix_rate, - latencyHint: latency - }); - return GodotAudio.ctx.destination.channelCount; - }, - - godot_audio_create_processor: function(buffer_length, channel_count) { - GodotAudio.script = GodotAudio.ctx.createScriptProcessor(buffer_length, 2, channel_count); - GodotAudio.script.connect(GodotAudio.ctx.destination); - return GodotAudio.script.bufferSize; - }, - - godot_audio_start: function(buffer_ptr) { - var audioDriverProcessStart = cwrap('audio_driver_process_start'); - var audioDriverProcessEnd = cwrap('audio_driver_process_end'); - var audioDriverProcessCapture = cwrap('audio_driver_process_capture', null, ['number']); - GodotAudio.script.onaudioprocess = function(audioProcessingEvent) { - audioDriverProcessStart(); - - var input = audioProcessingEvent.inputBuffer; - var output = audioProcessingEvent.outputBuffer; - var internalBuffer = HEAPF32.subarray( - buffer_ptr / HEAPF32.BYTES_PER_ELEMENT, - buffer_ptr / HEAPF32.BYTES_PER_ELEMENT + output.length * output.numberOfChannels); - for (var channel = 0; channel < output.numberOfChannels; channel++) { - var outputData = output.getChannelData(channel); - // Loop through samples. - for (var sample = 0; sample < outputData.length; sample++) { - outputData[sample] = internalBuffer[sample * output.numberOfChannels + channel]; - } - } - - if (GodotAudio.input) { - var inputDataL = input.getChannelData(0); - var inputDataR = input.getChannelData(1); - for (var i = 0; i < inputDataL.length; i++) { - audioDriverProcessCapture(inputDataL[i]); - audioDriverProcessCapture(inputDataR[i]); - } - } - audioDriverProcessEnd(); - }; + godot_audio_init: function(p_mix_rate, p_latency, p_state_change, p_latency_update) { + const statechange = GodotOS.get_func(p_state_change); + const latencyupdate = GodotOS.get_func(p_latency_update); + return GodotAudio.init(p_mix_rate, p_latency, statechange, latencyupdate); }, godot_audio_resume: function() { @@ -96,72 +152,22 @@ var GodotAudio = { } }, - godot_audio_finish_async: function() { - Module.async_finish.push(new Promise(function(accept, reject) { - if (!GodotAudio.ctx) { - setTimeout(accept, 0); - } else { - if (GodotAudio.script) { - GodotAudio.script.disconnect(); - GodotAudio.script = null; - } - if (GodotAudio.input) { - GodotAudio.input.disconnect(); - GodotAudio.input = null; - } - GodotAudio.ctx.close().then(function() { - accept(); - }).catch(function(e) { - accept(); - }); - GodotAudio.ctx = null; - } - })); - }, - - godot_audio_get_latency__proxy: 'sync', - godot_audio_get_latency: function() { - var latency = 0; - if (GodotAudio.ctx) { - if (GodotAudio.ctx.baseLatency) { - latency += GodotAudio.ctx.baseLatency; - } - if (GodotAudio.ctx.outputLatency) { - latency += GodotAudio.ctx.outputLatency; - } - } - return latency; - }, - godot_audio_capture_start__proxy: 'sync', godot_audio_capture_start: function() { if (GodotAudio.input) { return; // Already started. } - function gotMediaInput(stream) { - GodotAudio.input = GodotAudio.ctx.createMediaStreamSource(stream); - GodotAudio.input.connect(GodotAudio.script); - } - - function gotMediaInputError(e) { - out(e); - } - - if (navigator.mediaDevices.getUserMedia) { - navigator.mediaDevices.getUserMedia({"audio": true}).then(gotMediaInput, gotMediaInputError); - } else { - if (!navigator.getUserMedia) - navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; - navigator.getUserMedia({"audio": true}, gotMediaInput, gotMediaInputError); - } + GodotAudio.create_input(function(input) { + input.connect(GodotAudio.driver.get_node()); + }); }, godot_audio_capture_stop__proxy: 'sync', godot_audio_capture_stop: function() { if (GodotAudio.input) { - const tracks = GodotAudio.input.mediaStream.getTracks(); - for (var i = 0; i < tracks.length; i++) { - tracks[i].stop(); + const tracks = GodotAudio.input['mediaStream']['getTracks'](); + for (let i = 0; i < tracks.length; i++) { + tracks[i]['stop'](); } GodotAudio.input.disconnect(); GodotAudio.input = null; @@ -171,3 +177,165 @@ var GodotAudio = { autoAddDeps(GodotAudio, "$GodotAudio"); mergeInto(LibraryManager.library, GodotAudio); + +/** + * The AudioWorklet API driver, used when threads are available. + */ +const GodotAudioWorklet = { + + $GodotAudioWorklet__deps: ['$GodotAudio'], + $GodotAudioWorklet: { + promise: null, + worklet: null, + + create: function(channels) { + const path = Module['locateFile']('godot.audio.worklet.js'); + GodotAudioWorklet.promise = GodotAudio.ctx.audioWorklet.addModule(path).then(function() { + GodotAudioWorklet.worklet = new AudioWorkletNode( + GodotAudio.ctx, + 'godot-processor', + { + 'outputChannelCount': [channels] + } + ); + return Promise.resolve(); + }); + GodotAudio.driver = GodotAudioWorklet; + }, + + start: function(in_buf, out_buf, state) { + GodotAudioWorklet.promise.then(function() { + const node = GodotAudioWorklet.worklet; + node.connect(GodotAudio.ctx.destination); + node.port.postMessage({ + 'cmd': 'start', + 'data': [state, in_buf, out_buf], + }); + node.port.onmessage = function(event) { + console.error(event.data); + }; + }); + }, + + get_node: function() { + return GodotAudioWorklet.worklet; + }, + + close: function() { + return new Promise(function(resolve, reject) { + GodotAudioWorklet.promise.then(function() { + GodotAudioWorklet.worklet.port.postMessage({ + 'cmd': 'stop', + 'data': null, + }); + GodotAudioWorklet.worklet.disconnect(); + GodotAudioWorklet.worklet = null; + GodotAudioWorklet.promise = null; + resolve(); + }); + }); + }, + }, + + godot_audio_worklet_create: function(channels) { + GodotAudioWorklet.create(channels); + }, + + godot_audio_worklet_start: function(p_in_buf, p_in_size, p_out_buf, p_out_size, p_state) { + const out_buffer = GodotOS.heapSub(HEAPF32, p_out_buf, p_out_size); + const in_buffer = GodotOS.heapSub(HEAPF32, p_in_buf, p_in_size); + const state = GodotOS.heapSub(HEAP32, p_state, 4); + GodotAudioWorklet.start(in_buffer, out_buffer, state); + }, + + godot_audio_worklet_state_wait: function(p_state, p_idx, p_expected, p_timeout) { + Atomics.wait(HEAP32, (p_state >> 2) + p_idx, p_expected, p_timeout); + return Atomics.load(HEAP32, (p_state >> 2) + p_idx); + }, + + godot_audio_worklet_state_add: function(p_state, p_idx, p_value) { + return Atomics.add(HEAP32, (p_state >> 2) + p_idx, p_value); + }, + + godot_audio_worklet_state_get: function(p_state, p_idx) { + return Atomics.load(HEAP32, (p_state >> 2) + p_idx); + }, +}; + +autoAddDeps(GodotAudioWorklet, "$GodotAudioWorklet"); +mergeInto(LibraryManager.library, GodotAudioWorklet); + +/* + * The deprecated ScriptProcessorNode API, used when threads are disabled. + */ +const GodotAudioScript = { + + $GodotAudioScript__deps: ['$GodotAudio'], + $GodotAudioScript: { + script: null, + + create: function(buffer_length, channel_count) { + GodotAudioScript.script = GodotAudio.ctx.createScriptProcessor(buffer_length, 2, channel_count); + GodotAudio.driver = GodotAudioScript; + return GodotAudioScript.script.bufferSize; + }, + + start: function(p_in_buf, p_in_size, p_out_buf, p_out_size, onprocess) { + GodotAudioScript.script.onaudioprocess = function(event) { + // Read input + const inb = GodotOS.heapSub(HEAPF32, p_in_buf, p_in_size); + const input = event.inputBuffer; + if (GodotAudio.input) { + const inlen = input.getChannelData(0).length; + for (let ch = 0; ch < 2; ch++) { + const data = input.getChannelData(ch); + for (let s = 0; s < inlen; s++) { + inb[s * 2 + ch] = data[s]; + } + } + } + + // Let Godot process the input/output. + onprocess(); + + // Write the output. + const outb = GodotOS.heapSub(HEAPF32, p_out_buf, p_out_size); + const output = event.outputBuffer; + const channels = output.numberOfChannels; + for (let ch = 0; ch < channels; ch++) { + const data = output.getChannelData(ch); + // Loop through samples and assign computed values. + for (let sample = 0; sample < data.length; sample++) { + data[sample] = outb[sample * channels + ch]; + } + } + }; + GodotAudioScript.script.connect(GodotAudio.ctx.destination); + }, + + get_node: function() { + return GodotAudioScript.script; + }, + + close: function() { + return new Promise(function(resolve, reject) { + GodotAudioScript.script.disconnect(); + GodotAudioScript.script.onaudioprocess = null; + GodotAudioScript.script = null; + resolve(); + }); + }, + }, + + godot_audio_script_create: function(buffer_length, channel_count) { + return GodotAudioScript.create(buffer_length, channel_count); + }, + + godot_audio_script_start: function(p_in_buf, p_in_size, p_out_buf, p_out_size, p_cb) { + const onprocess = GodotOS.get_func(p_cb); + GodotAudioScript.start(p_in_buf, p_in_size, p_out_buf, p_out_size, onprocess); + }, +}; + +autoAddDeps(GodotAudioScript, "$GodotAudioScript"); +mergeInto(LibraryManager.library, GodotAudioScript); diff --git a/platform/javascript/native/library_godot_display.js b/platform/javascript/native/library_godot_display.js new file mode 100644 index 0000000000..490b9181d0 --- /dev/null +++ b/platform/javascript/native/library_godot_display.js @@ -0,0 +1,478 @@ +/*************************************************************************/ +/* library_godot_display.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +/* + * Display Server listeners. + * Keeps track of registered event listeners so it can remove them on shutdown. + */ +const GodotDisplayListeners = { + $GodotDisplayListeners__postset: 'GodotOS.atexit(function(resolve, reject) { GodotDisplayListeners.clear(); resolve(); });', + $GodotDisplayListeners: { + handlers: [], + + has: function(target, event, method, capture) { + return GodotDisplayListeners.handlers.findIndex(function(e) { + return e.target === target && e.event === event && e.method === method && e.capture == capture; + }) !== -1; + }, + + add: function(target, event, method, capture) { + if (GodotDisplayListeners.has(target, event, method, capture)) { + return; + } + function Handler(target, event, method, capture) { + this.target = target; + this.event = event; + this.method = method; + this.capture = capture; + }; + GodotDisplayListeners.handlers.push(new Handler(target, event, method, capture)); + target.addEventListener(event, method, capture); + }, + + clear: function() { + GodotDisplayListeners.handlers.forEach(function(h) { + h.target.removeEventListener(h.event, h.method, h.capture); + }); + GodotDisplayListeners.handlers.length = 0; + }, + }, +}; +mergeInto(LibraryManager.library, GodotDisplayListeners); + +/* + * Drag and drop handler. + * This is pretty big, but basically detect dropped files on GodotConfig.canvas, + * process them one by one (recursively for directories), and copies them to + * the temporary FS path '/tmp/drop-[random]/' so it can be emitted as a godot + * event (that requires a string array of paths). + * + * NOTE: The temporary files are removed after the callback. This means that + * deferred callbacks won't be able to access the files. + */ +const GodotDisplayDragDrop = { + + $GodotDisplayDragDrop__deps: ['$FS', '$GodotFS'], + $GodotDisplayDragDrop: { + promises: [], + pending_files: [], + + add_entry: function(entry) { + if (entry.isDirectory) { + GodotDisplayDragDrop.add_dir(entry); + } else if (entry.isFile) { + GodotDisplayDragDrop.add_file(entry); + } else { + console.error("Unrecognized entry...", entry); + } + }, + + add_dir: function(entry) { + GodotDisplayDragDrop.promises.push(new Promise(function(resolve, reject) { + const reader = entry.createReader(); + reader.readEntries(function(entries) { + for (let i = 0; i < entries.length; i++) { + GodotDisplayDragDrop.add_entry(entries[i]); + } + resolve(); + }); + })); + }, + + add_file: function(entry) { + GodotDisplayDragDrop.promises.push(new Promise(function(resolve, reject) { + entry.file(function(file) { + const reader = new FileReader(); + reader.onload = function() { + const f = { + "path": file.relativePath || file.webkitRelativePath, + "name": file.name, + "type": file.type, + "size": file.size, + "data": reader.result + }; + if (!f['path']) { + f['path'] = f['name']; + } + GodotDisplayDragDrop.pending_files.push(f); + resolve() + }; + reader.onerror = function() { + console.log("Error reading file"); + reject(); + } + reader.readAsArrayBuffer(file); + }, function(err) { + console.log("Error!"); + reject(); + }); + })); + }, + + process: function(resolve, reject) { + if (GodotDisplayDragDrop.promises.length == 0) { + resolve(); + return; + } + GodotDisplayDragDrop.promises.pop().then(function() { + setTimeout(function() { + GodotDisplayDragDrop.process(resolve, reject); + }, 0); + }); + }, + + _process_event: function(ev, callback) { + ev.preventDefault(); + if (ev.dataTransfer.items) { + // Use DataTransferItemList interface to access the file(s) + for (let i = 0; i < ev.dataTransfer.items.length; i++) { + const item = ev.dataTransfer.items[i]; + let entry = null; + if ("getAsEntry" in item) { + entry = item.getAsEntry(); + } else if ("webkitGetAsEntry" in item) { + entry = item.webkitGetAsEntry(); + } + if (entry) { + GodotDisplayDragDrop.add_entry(entry); + } + } + } else { + console.error("File upload not supported"); + } + new Promise(GodotDisplayDragDrop.process).then(function() { + const DROP = "/tmp/drop-" + parseInt(Math.random() * Math.pow(2, 31)) + "/"; + const drops = []; + const files = []; + FS.mkdir(DROP); + GodotDisplayDragDrop.pending_files.forEach((elem) => { + const path = elem['path']; + GodotFS.copy_to_fs(DROP + path, elem['data']); + let idx = path.indexOf("/"); + if (idx == -1) { + // Root file + drops.push(DROP + path); + } else { + // Subdir + const sub = path.substr(0, idx); + idx = sub.indexOf("/"); + if (idx < 0 && drops.indexOf(DROP + sub) == -1) { + drops.push(DROP + sub); + } + } + files.push(DROP + path); + }); + GodotDisplayDragDrop.promises = []; + GodotDisplayDragDrop.pending_files = []; + callback(drops); + const dirs = [DROP.substr(0, DROP.length -1)]; + // Remove temporary files + files.forEach(function (file) { + FS.unlink(file); + let dir = file.replace(DROP, ""); + let idx = dir.lastIndexOf("/"); + while (idx > 0) { + dir = dir.substr(0, idx); + if (dirs.indexOf(DROP + dir) == -1) { + dirs.push(DROP + dir); + } + idx = dir.lastIndexOf("/"); + } + }); + // Remove dirs. + dirs.sort(function(a, b) { + const al = (a.match(/\//g) || []).length; + const bl = (b.match(/\//g) || []).length; + if (al > bl) + return -1; + else if (al < bl) + return 1; + return 0; + }).forEach(function(dir) { + FS.rmdir(dir); + }); + }); + }, + + handler: function(callback) { + return function(ev) { + GodotDisplayDragDrop._process_event(ev, callback); + }; + }, + }, +}; +mergeInto(LibraryManager.library, GodotDisplayDragDrop); + +/* + * Display server cursor helper. + * Keeps track of cursor status and custom shapes. + */ +const GodotDisplayCursor = { + $GodotDisplayCursor__postset: 'GodotOS.atexit(function(resolve, reject) { GodotDisplayCursor.clear(); resolve(); });', + $GodotDisplayCursor__deps: ['$GodotConfig', '$GodotOS'], + $GodotDisplayCursor: { + shape: 'auto', + visible: true, + cursors: {}, + set_style: function(style) { + GodotConfig.canvas.style.cursor = style; + }, + set_shape: function(shape) { + GodotDisplayCursor.shape = shape; + let css = shape; + if (shape in GodotDisplayCursor.cursors) { + const c = GodotDisplayCursor.cursors[shape]; + css = 'url("' + c.url + '") ' + c.x + ' ' + c.y + ', auto'; + } + if (GodotDisplayCursor.visible) { + GodotDisplayCursor.set_style(css); + } + }, + clear: function() { + GodotDisplayCursor.set_style(''); + GodotDisplayCursor.shape = 'auto'; + GodotDisplayCursor.visible = true; + Object.keys(GodotDisplayCursor.cursors).forEach(function(key) { + URL.revokeObjectURL(GodotDisplayCursor.cursors[key]); + delete GodotDisplayCursor.cursors[key]; + }); + }, + }, +}; +mergeInto(LibraryManager.library, GodotDisplayCursor); + +/** + * Display server interface. + * + * Exposes all the functions needed by DisplayServer implementation. + */ +const GodotDisplay = { + $GodotDisplay__deps: ['$GodotConfig', '$GodotOS', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop'], + $GodotDisplay: { + window_icon: '', + }, + + godot_js_display_is_swap_ok_cancel: function() { + const win = (['Windows', 'Win64', 'Win32', 'WinCE']); + const plat = navigator.platform || ""; + if (win.indexOf(plat) !== -1) { + return 1; + } + return 0; + }, + + godot_js_display_alert: function(p_text) { + window.alert(UTF8ToString(p_text)); + }, + + godot_js_display_pixel_ratio_get: function() { + return window.devicePixelRatio || 1; + }, + + /* + * Canvas + */ + godot_js_display_canvas_focus: function() { + GodotConfig.canvas.focus(); + }, + + godot_js_display_canvas_is_focused: function() { + return document.activeElement == GodotConfig.canvas; + }, + + godot_js_display_canvas_bounding_rect_position_get: function(r_x, r_y) { + const brect = GodotConfig.canvas.getBoundingClientRect(); + setValue(r_x, brect.x, 'i32'); + setValue(r_y, brect.y, 'i32'); + }, + + /* + * Touchscreen + */ + godot_js_display_touchscreen_is_available: function() { + return 'ontouchstart' in window; + }, + + /* + * Clipboard + */ + godot_js_display_clipboard_set: function(p_text) { + const text = UTF8ToString(p_text); + if (!navigator.clipboard || !navigator.clipboard.writeText) { + return 1; + } + navigator.clipboard.writeText(text).catch(function(e) { + // Setting OS clipboard is only possible from an input callback. + console.error("Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:", e); + }); + return 0; + }, + + godot_js_display_clipboard_get_deps: ['$GodotOS'], + godot_js_display_clipboard_get: function(callback) { + const func = GodotOS.get_func(callback); + try { + navigator.clipboard.readText().then(function (result) { + const ptr = allocate(intArrayFromString(result), ALLOC_NORMAL); + func(ptr); + _free(ptr); + }).catch(function (e) { + // Fail graciously. + }); + } catch (e) { + // Fail graciously. + } + }, + + /* + * Window + */ + godot_js_display_window_request_fullscreen: function() { + const canvas = GodotConfig.canvas; + (canvas.requestFullscreen || canvas.msRequestFullscreen || + canvas.mozRequestFullScreen || canvas.mozRequestFullscreen || + canvas.webkitRequestFullscreen + ).call(canvas); + }, + + godot_js_display_window_title_set: function(p_data) { + document.title = UTF8ToString(p_data); + }, + + godot_js_display_window_icon_set: function(p_ptr, p_len) { + let link = document.getElementById('-gd-engine-icon'); + if (link === null) { + link = document.createElement('link'); + link.rel = 'icon'; + link.id = '-gd-engine-icon'; + document.head.appendChild(link); + } + const old_icon = GodotDisplay.window_icon; + const png = new Blob([GodotOS.heapCopy(HEAPU8, p_ptr, p_len)], { type: "image/png" }); + GodotDisplay.window_icon = URL.createObjectURL(png); + link.href = GodotDisplay.window_icon; + if (old_icon) { + URL.revokeObjectURL(old_icon); + } + }, + + /* + * Cursor + */ + godot_js_display_cursor_set_visible: function(p_visible) { + const visible = p_visible != 0; + if (visible == GodotDisplayCursor.visible) { + return; + } + GodotDisplayCursor.visible = visible; + if (visible) { + GodotDisplayCursor.set_shape(GodotDisplayCursor.shape); + } else { + GodotDisplayCursor.set_style('none'); + } + }, + + godot_js_display_cursor_is_hidden: function() { + return !GodotDisplayCursor.visible; + }, + + godot_js_display_cursor_set_shape: function(p_string) { + GodotDisplayCursor.set_shape(UTF8ToString(p_string)); + }, + + godot_js_display_cursor_set_custom_shape: function(p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) { + const shape = UTF8ToString(p_shape); + const old_shape = GodotDisplayCursor.cursors[shape]; + if (p_len > 0) { + const png = new Blob([GodotOS.heapCopy(HEAPU8, p_ptr, p_len)], { type: 'image/png' }); + const url = URL.createObjectURL(png); + GodotDisplayCursor.cursors[shape] = { + url: url, + x: p_hotspot_x, + y: p_hotspot_y, + }; + } else { + delete GodotDisplayCursor.cursors[shape]; + } + if (shape == GodotDisplayCursor.shape) { + GodotDisplayCursor.set_shape(GodotDisplayCursor.shape); + } + if (old_shape) { + URL.revokeObjectURL(old_shape.url); + } + }, + + /* + * Listeners + */ + godot_js_display_notification_cb: function(callback, p_enter, p_exit, p_in, p_out) { + const canvas = GodotConfig.canvas; + const func = GodotOS.get_func(callback); + const notif = [p_enter, p_exit, p_in, p_out]; + ['mouseover', 'mouseleave', 'focus', 'blur'].forEach(function(evt_name, idx) { + GodotDisplayListeners.add(canvas, evt_name, function() { + func.bind(null, notif[idx]); + }, true); + }); + }, + + godot_js_display_paste_cb: function(callback) { + const func = GodotOS.get_func(callback); + GodotDisplayListeners.add(window, 'paste', function(evt) { + const text = evt.clipboardData.getData('text'); + const ptr = allocate(intArrayFromString(text), ALLOC_NORMAL); + func(ptr); + _free(ptr); + }, false); + }, + + godot_js_display_drop_files_cb: function(callback) { + const func = GodotOS.get_func(callback) + const dropFiles = function(files) { + const args = files || []; + if (!args.length) { + return; + } + const argc = args.length; + const argv = GodotOS.allocStringArray(args); + func(argv, argc); + GodotOS.freeStringArray(argv, argc); + }; + const canvas = GodotConfig.canvas; + GodotDisplayListeners.add(canvas, 'dragover', function(ev) { + // Prevent default behavior (which would try to open the file(s)) + ev.preventDefault(); + }, false); + GodotDisplayListeners.add(canvas, 'drop', GodotDisplayDragDrop.handler(dropFiles)); + }, +}; + +autoAddDeps(GodotDisplay, '$GodotDisplay'); +mergeInto(LibraryManager.library, GodotDisplay); diff --git a/core/func_ref.h b/platform/javascript/native/library_godot_editor_tools.js index 75b84e705e..bd62bbf4e1 100644 --- a/core/func_ref.h +++ b/platform/javascript/native/library_godot_editor_tools.js @@ -1,5 +1,5 @@ /*************************************************************************/ -/* func_ref.h */ +/* library_godot_editor_tools.js */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,28 +28,30 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef FUNC_REF_H -#define FUNC_REF_H +const GodotEditorTools = { -#include "core/reference.h" - -class FuncRef : public Reference { - GDCLASS(FuncRef, Reference); - ObjectID id; - StringName function; - -protected: - static void _bind_methods(); - -public: - Variant call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - Variant call_funcv(const Array &p_args); - void set_instance(Object *p_obj); - void set_function(const StringName &p_func); - StringName get_function(); - bool is_valid() const; - - FuncRef() {} + godot_js_editor_download_file__deps: ['$FS'], + godot_js_editor_download_file: function(p_path, p_name, p_mime) { + const path = UTF8ToString(p_path); + const name = UTF8ToString(p_name); + const mime = UTF8ToString(p_mime); + const size = FS.stat(path)['size']; + const buf = new Uint8Array(size); + const fd = FS.open(path, 'r'); + FS.read(fd, buf, 0, size); + FS.close(fd); + FS.unlink(path); + const blob = new Blob([buf], { type: mime }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = name; + a.style.display = 'none'; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }, }; -#endif // FUNC_REF_H +mergeInto(LibraryManager.library, GodotEditorTools); diff --git a/platform/javascript/native/library_godot_eval.js b/platform/javascript/native/library_godot_eval.js new file mode 100644 index 0000000000..e83c61dd9d --- /dev/null +++ b/platform/javascript/native/library_godot_eval.js @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* library_godot_eval.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +const GodotEval = { + + godot_js_eval__deps: ['$GodotOS'], + godot_js_eval: function(p_js, p_use_global_ctx, p_union_ptr, p_byte_arr, p_byte_arr_write, p_callback) { + const js_code = UTF8ToString(p_js); + let eval_ret = null; + try { + if (p_use_global_ctx) { + // indirect eval call grants global execution context + const global_eval = eval; + eval_ret = global_eval(js_code); + } else { + eval_ret = eval(js_code); + } + } catch (e) { + err(e); + } + + switch (typeof eval_ret) { + + case 'boolean': + setValue(p_union_ptr, eval_ret, 'i32'); + return 1; // BOOL + + case 'number': + setValue(p_union_ptr, eval_ret, 'double'); + return 3; // REAL + + case 'string': + let array_ptr = GodotOS.allocString(eval_ret); + setValue(p_union_ptr, array_ptr , '*'); + return 4; // STRING + + case 'object': + if (eval_ret === null) { + break; + } + + if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) { + eval_ret = new Uint8Array(eval_ret.buffer); + } + else if (eval_ret instanceof ArrayBuffer) { + eval_ret = new Uint8Array(eval_ret); + } + if (eval_ret instanceof Uint8Array) { + const func = GodotOS.get_func(p_callback); + const bytes_ptr = func(p_byte_arr, p_byte_arr_write, eval_ret.length); + HEAPU8.set(eval_ret, bytes_ptr); + return 20; // POOL_BYTE_ARRAY + } + break; + } + return 0; // NIL + }, +} + +mergeInto(LibraryManager.library, GodotEval); diff --git a/platform/javascript/native/library_godot_os.js b/platform/javascript/native/library_godot_os.js new file mode 100644 index 0000000000..ed48280674 --- /dev/null +++ b/platform/javascript/native/library_godot_os.js @@ -0,0 +1,313 @@ +/*************************************************************************/ +/* library_godot_os.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +const IDHandler = { + $IDHandler: { + _last_id: 0, + _references: {}, + + get: function(p_id) { + return IDHandler._references[p_id]; + }, + + add: function(p_data) { + const id = ++IDHandler._last_id; + IDHandler._references[id] = p_data; + return id; + }, + + remove: function(p_id) { + delete IDHandler._references[p_id]; + }, + }, +}; + +autoAddDeps(IDHandler, "$IDHandler"); +mergeInto(LibraryManager.library, IDHandler); + +const GodotConfig = { + + $GodotConfig__postset: 'Module["initConfig"] = GodotConfig.init_config;', + $GodotConfig: { + canvas: null, + locale: "en", + resize_on_start: false, + on_execute: null, + + init_config: function(p_opts) { + GodotConfig.resize_on_start = p_opts['resizeCanvasOnStart'] ? true : false; + GodotConfig.canvas = p_opts['canvas']; + GodotConfig.locale = p_opts['locale'] || GodotConfig.locale; + GodotConfig.on_execute = p_opts['onExecute']; + // This is called by emscripten, even if undocumented. + Module['onExit'] = p_opts['onExit']; + }, + }, + + godot_js_config_canvas_id_get: function(p_ptr, p_ptr_max) { + stringToUTF8('#' + GodotConfig.canvas.id, p_ptr, p_ptr_max); + }, + + godot_js_config_locale_get: function(p_ptr, p_ptr_max) { + stringToUTF8(GodotConfig.locale, p_ptr, p_ptr_max); + }, + + godot_js_config_is_resize_on_start: function() { + return GodotConfig.resize_on_start ? 1 : 0; + }, +}; + +autoAddDeps(GodotConfig, '$GodotConfig'); +mergeInto(LibraryManager.library, GodotConfig); + +const GodotFS = { + $GodotFS__deps: ['$FS', '$IDBFS'], + $GodotFS__postset: [ + 'Module["initFS"] = GodotFS.init;', + 'Module["deinitFS"] = GodotFS.deinit;', + 'Module["copyToFS"] = GodotFS.copy_to_fs;', + ].join(''), + $GodotFS: { + _idbfs: false, + _syncing: false, + _mount_points: [], + + is_persistent: function() { + return GodotFS._idbfs ? 1 : 0; + }, + + // Initialize godot file system, setting up persistent paths. + // Returns a promise that resolves when the FS is ready. + // We keep track of mount_points, so that we can properly close the IDBFS + // since emscripten is not doing it by itself. (emscripten GH#12516). + init: function(persistentPaths) { + GodotFS._idbfs = false; + if (!Array.isArray(persistentPaths)) { + return Promise.reject(new Error('Persistent paths must be an array')); + } + if (!persistentPaths.length) { + return Promise.resolve(); + } + GodotFS._mount_points = persistentPaths.slice(); + + function createRecursive(dir) { + try { + FS.stat(dir); + } catch (e) { + if (e.errno !== ERRNO_CODES.ENOENT) { + throw e; + } + FS.mkdirTree(dir); + } + } + + GodotFS._mount_points.forEach(function(path) { + createRecursive(path); + FS.mount(IDBFS, {}, path); + }); + return new Promise(function(resolve, reject) { + FS.syncfs(true, function(err) { + if (err) { + GodotFS._mount_points = []; + GodotFS._idbfs = false; + console.log("IndexedDB not available: " + err.message); + } else { + GodotFS._idbfs = true; + } + resolve(err); + }); + }); + }, + + // Deinit godot file system, making sure to unmount file systems, and close IDBFS(s). + deinit: function() { + GodotFS._mount_points.forEach(function(path) { + try { + FS.unmount(path); + } catch (e) { + console.log("Already unmounted", e); + } + if (GodotFS._idbfs && IDBFS.dbs[path]) { + IDBFS.dbs[path].close(); + delete IDBFS.dbs[path]; + } + }); + GodotFS._mount_points = []; + GodotFS._idbfs = false; + GodotFS._syncing = false; + }, + + sync: function() { + if (GodotFS._syncing) { + err('Already syncing!'); + return Promise.resolve(); + } + GodotFS._syncing = true; + return new Promise(function (resolve, reject) { + FS.syncfs(false, function(error) { + if (error) { + err('Failed to save IDB file system: ' + error.message); + } + GodotFS._syncing = false; + resolve(error); + }); + }); + }, + + // Copies a buffer to the internal file system. Creating directories recursively. + copy_to_fs: function(path, buffer) { + const idx = path.lastIndexOf("/"); + let dir = "/"; + if (idx > 0) { + dir = path.slice(0, idx); + } + try { + FS.stat(dir); + } catch (e) { + if (e.errno !== ERRNO_CODES.ENOENT) { + throw e; + } + FS.mkdirTree(dir); + } + FS.writeFile(path, new Uint8Array(buffer), {'flags': 'wx+'}); + }, + }, +}; +mergeInto(LibraryManager.library, GodotFS); + +const GodotOS = { + $GodotOS__deps: ['$GodotFS'], + $GodotOS__postset: [ + 'Module["request_quit"] = function() { GodotOS.request_quit() };', + 'GodotOS._fs_sync_promise = Promise.resolve();', + ].join(''), + $GodotOS: { + + request_quit: function() {}, + _async_cbs: [], + _fs_sync_promise: null, + + get_func: function(ptr) { + return wasmTable.get(ptr); + }, + + atexit: function(p_promise_cb) { + GodotOS._async_cbs.push(p_promise_cb); + }, + + finish_async: function(callback) { + GodotOS._fs_sync_promise.then(function(err) { + const promises = []; + GodotOS._async_cbs.forEach(function(cb) { + promises.push(new Promise(cb)); + }); + return Promise.all(promises); + }).then(function() { + return GodotFS.sync(); // Final FS sync. + }).then(function(err) { + // Always deferred. + setTimeout(function() { + callback(); + }, 0); + }); + }, + + allocString: function(p_str) { + const length = lengthBytesUTF8(p_str)+1; + const c_str = _malloc(length); + stringToUTF8(p_str, c_str, length); + return c_str; + }, + + allocStringArray: function(strings) { + const size = strings.length; + const c_ptr = _malloc(size * 4); + for (let i = 0; i < size; i++) { + HEAP32[(c_ptr >> 2) + i] = GodotOS.allocString(strings[i]); + } + return c_ptr; + }, + + freeStringArray: function(c_ptr, size) { + for (let i = 0; i < size; i++) { + _free(HEAP32[(c_ptr >> 2) + i]); + } + _free(c_ptr); + }, + + heapSub: function(heap, ptr, size) { + const bytes = heap.BYTES_PER_ELEMENT; + return heap.subarray(ptr / bytes, ptr / bytes + size); + }, + + heapCopy: function(heap, ptr, size) { + const bytes = heap.BYTES_PER_ELEMENT; + return heap.slice(ptr / bytes, ptr / bytes + size); + }, + }, + + godot_js_os_finish_async: function(p_callback) { + const func = GodotOS.get_func(p_callback); + GodotOS.finish_async(func); + }, + + godot_js_os_request_quit_cb: function(p_callback) { + GodotOS.request_quit = GodotOS.get_func(p_callback); + }, + + godot_js_os_fs_is_persistent: function() { + return GodotFS.is_persistent(); + }, + + godot_js_os_fs_sync: function(callback) { + const func = GodotOS.get_func(callback); + GodotOS._fs_sync_promise = GodotFS.sync(); + GodotOS._fs_sync_promise.then(function(err) { + func(); + }); + }, + + godot_js_os_execute: function(p_json) { + const json_args = UTF8ToString(p_json); + const args = JSON.parse(json_args); + if (GodotConfig.on_execute) { + GodotConfig.on_execute(args); + return 0; + } + return 1; + }, + + godot_js_os_shell_open: function(p_uri) { + window.open(UTF8ToString(p_uri), '_blank'); + }, +}; + +autoAddDeps(GodotOS, '$GodotOS'); +mergeInto(LibraryManager.library, GodotOS); diff --git a/platform/javascript/native/utils.js b/platform/javascript/native/utils.js deleted file mode 100644 index 8d0beba454..0000000000 --- a/platform/javascript/native/utils.js +++ /dev/null @@ -1,292 +0,0 @@ -/*************************************************************************/ -/* utils.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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. */ -/*************************************************************************/ - -Module['initFS'] = function(persistentPaths) { - Module.mount_points = ['/userfs'].concat(persistentPaths); - - function createRecursive(dir) { - try { - FS.stat(dir); - } catch (e) { - if (e.errno !== ERRNO_CODES.ENOENT) { - throw e; - } - FS.mkdirTree(dir); - } - } - - Module.mount_points.forEach(function(path) { - createRecursive(path); - FS.mount(IDBFS, {}, path); - }); - return new Promise(function(resolve, reject) { - FS.syncfs(true, function(err) { - if (err) { - Module.mount_points = []; - Module.idbfs = false; - console.log("IndexedDB not available: " + err.message); - } else { - Module.idbfs = true; - } - resolve(err); - }); - }); -}; - -Module['deinitFS'] = function() { - Module.mount_points.forEach(function(path) { - try { - FS.unmount(path); - } catch (e) { - console.log("Already unmounted", e); - } - if (Module.idbfs && IDBFS.dbs[path]) { - IDBFS.dbs[path].close(); - delete IDBFS.dbs[path]; - } - }); - Module.mount_points = []; -}; - -Module['copyToFS'] = function(path, buffer) { - var p = path.lastIndexOf("/"); - var dir = "/"; - if (p > 0) { - dir = path.slice(0, path.lastIndexOf("/")); - } - try { - FS.stat(dir); - } catch (e) { - if (e.errno !== ERRNO_CODES.ENOENT) { - throw e; - } - FS.mkdirTree(dir); - } - // With memory growth, canOwn should be false. - FS.writeFile(path, new Uint8Array(buffer), {'flags': 'wx+'}); -} - -Module.drop_handler = (function() { - var upload = []; - var uploadPromises = []; - var uploadCallback = null; - - function readFilePromise(entry, path) { - return new Promise(function(resolve, reject) { - entry.file(function(file) { - var reader = new FileReader(); - reader.onload = function() { - var f = { - "path": file.relativePath || file.webkitRelativePath, - "name": file.name, - "type": file.type, - "size": file.size, - "data": reader.result - }; - if (!f['path']) - f['path'] = f['name']; - upload.push(f); - resolve() - }; - reader.onerror = function() { - console.log("Error reading file"); - reject(); - } - - reader.readAsArrayBuffer(file); - - }, function(err) { - console.log("Error!"); - reject(); - }); - }); - } - - function readDirectoryPromise(entry) { - return new Promise(function(resolve, reject) { - var reader = entry.createReader(); - reader.readEntries(function(entries) { - for (var i = 0; i < entries.length; i++) { - var ent = entries[i]; - if (ent.isDirectory) { - uploadPromises.push(readDirectoryPromise(ent)); - } else if (ent.isFile) { - uploadPromises.push(readFilePromise(ent)); - } - } - resolve(); - }); - }); - } - - function processUploadsPromises(resolve, reject) { - if (uploadPromises.length == 0) { - resolve(); - return; - } - uploadPromises.pop().then(function() { - setTimeout(function() { - processUploadsPromises(resolve, reject); - //processUploadsPromises.bind(null, resolve, reject) - }, 0); - }); - } - - function dropFiles(files) { - var args = files || []; - var argc = args.length; - var argv = stackAlloc((argc + 1) * 4); - for (var i = 0; i < argc; i++) { - HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i]); - } - HEAP32[(argv >> 2) + argc] = 0; - // Defined in display_server_javascript.cpp - ccall('_drop_files_callback', 'void', ['number', 'number'], [argv, argc]); - } - - return function(ev) { - ev.preventDefault(); - if (ev.dataTransfer.items) { - // Use DataTransferItemList interface to access the file(s) - for (var i = 0; i < ev.dataTransfer.items.length; i++) { - const item = ev.dataTransfer.items[i]; - var entry = null; - if ("getAsEntry" in item) { - entry = item.getAsEntry(); - } else if ("webkitGetAsEntry" in item) { - entry = item.webkitGetAsEntry(); - } - if (!entry) { - console.error("File upload not supported"); - } else if (entry.isDirectory) { - uploadPromises.push(readDirectoryPromise(entry)); - } else if (entry.isFile) { - uploadPromises.push(readFilePromise(entry)); - } else { - console.error("Unrecognized entry...", entry); - } - } - } else { - console.error("File upload not supported"); - } - uploadCallback = new Promise(processUploadsPromises).then(function() { - const DROP = "/tmp/drop-" + parseInt(Math.random() * Math.pow(2, 31)) + "/"; - var drops = []; - var files = []; - upload.forEach((elem) => { - var path = elem['path']; - Module['copyToFS'](DROP + path, elem['data']); - var idx = path.indexOf("/"); - if (idx == -1) { - // Root file - drops.push(DROP + path); - } else { - // Subdir - var sub = path.substr(0, idx); - idx = sub.indexOf("/"); - if (idx < 0 && drops.indexOf(DROP + sub) == -1) { - drops.push(DROP + sub); - } - } - files.push(DROP + path); - }); - uploadPromises = []; - upload = []; - dropFiles(drops); - var dirs = [DROP.substr(0, DROP.length -1)]; - files.forEach(function (file) { - FS.unlink(file); - var dir = file.replace(DROP, ""); - var idx = dir.lastIndexOf("/"); - while (idx > 0) { - dir = dir.substr(0, idx); - if (dirs.indexOf(DROP + dir) == -1) { - dirs.push(DROP + dir); - } - idx = dir.lastIndexOf("/"); - } - }); - // Remove dirs. - dirs = dirs.sort(function(a, b) { - var al = (a.match(/\//g) || []).length; - var bl = (b.match(/\//g) || []).length; - if (al > bl) - return -1; - else if (al < bl) - return 1; - return 0; - }); - dirs.forEach(function(dir) { - FS.rmdir(dir); - }); - }); - } -})(); - -function EventHandlers() { - function Handler(target, event, method, capture) { - this.target = target; - this.event = event; - this.method = method; - this.capture = capture; - } - - var listeners = []; - - function has(target, event, method, capture) { - return listeners.findIndex(function(e) { - return e.target === target && e.event === event && e.method === method && e.capture == capture; - }) !== -1; - } - - this.add = function(target, event, method, capture) { - if (has(target, event, method, capture)) { - return; - } - listeners.push(new Handler(target, event, method, capture)); - target.addEventListener(event, method, capture); - }; - - this.remove = function(target, event, method, capture) { - if (!has(target, event, method, capture)) { - return; - } - target.removeEventListener(event, method, capture); - }; - - this.clear = function() { - listeners.forEach(function(h) { - h.target.removeEventListener(h.event, h.method, h.capture); - }); - listeners.length = 0; - }; -} - -Module.listeners = new EventHandlers(); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index cf5751f384..80723d54fc 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -46,6 +46,8 @@ #include <emscripten.h> #include <stdlib.h> +#include "godot_js.h" + // Lifecycle void OS_JavaScript::initialize() { OS_Unix::initialize_core(); @@ -72,24 +74,15 @@ MainLoop *OS_JavaScript::get_main_loop() const { return main_loop; } -extern "C" EMSCRIPTEN_KEEPALIVE void _idb_synced() { - OS_JavaScript::get_singleton()->idb_is_syncing = false; +void OS_JavaScript::fs_sync_callback() { + get_singleton()->idb_is_syncing = false; } bool OS_JavaScript::main_loop_iterate() { if (is_userfs_persistent() && idb_needs_sync && !idb_is_syncing) { idb_is_syncing = true; idb_needs_sync = false; - /* clang-format off */ - EM_ASM({ - FS.syncfs(function(error) { - if (error) { - err('Failed to save IDB file system: ' + error.message); - } - ccall("_idb_synced", 'void', [], []); - }); - }); - /* clang-format on */ + godot_js_os_fs_sync(&fs_sync_callback); } DisplayServer::get_singleton()->process_events(); @@ -104,13 +97,6 @@ void OS_JavaScript::delete_main_loop() { main_loop = nullptr; } -void OS_JavaScript::finalize_async() { - finalizing = true; - if (audio_driver_javascript) { - audio_driver_javascript->finish_async(); - } -} - void OS_JavaScript::finalize() { delete_main_loop(); if (audio_driver_javascript) { @@ -127,17 +113,7 @@ Error OS_JavaScript::execute(const String &p_path, const List<String> &p_argumen args.push_back(E->get()); } String json_args = JSON::print(args); - /* clang-format off */ - int failed = EM_ASM_INT({ - const json_args = UTF8ToString($0); - const args = JSON.parse(json_args); - if (Module["onExecute"]) { - Module["onExecute"](args); - return 0; - } - return 1; - }, json_args.utf8().get_data()); - /* clang-format on */ + int failed = godot_js_os_execute(json_args.utf8().get_data()); ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() must be implemented in JavaScript via 'engine.setOnExecute' if required."); return OK; } @@ -168,11 +144,7 @@ String OS_JavaScript::get_executable_path() const { Error OS_JavaScript::shell_open(String p_uri) { // Open URI in a new tab, browser will deal with it by protocol. - /* clang-format off */ - EM_ASM_({ - window.open(UTF8ToString($0), '_blank'); - }, p_uri.utf8().get_data()); - /* clang-format on */ + godot_js_os_shell_open(p_uri.utf8().get_data()); return OK; } @@ -211,10 +183,6 @@ void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags } } -void OS_JavaScript::set_idb_available(bool p_idb_available) { - idb_available = p_idb_available; -} - bool OS_JavaScript::is_userfs_persistent() const { return idb_available; } @@ -227,11 +195,17 @@ void OS_JavaScript::initialize_joypads() { } OS_JavaScript::OS_JavaScript() { + char locale_ptr[16]; + godot_js_config_locale_get(locale_ptr, 16); + setenv("LANG", locale_ptr, true); + if (AudioDriverJavaScript::is_available()) { audio_driver_javascript = memnew(AudioDriverJavaScript); AudioDriverManager::add_driver(audio_driver_javascript); } + idb_available = godot_js_os_fs_is_persistent(); + Vector<Logger *> loggers; loggers.push_back(memnew(StdLogger)); _set_logger(memnew(CompositeLogger(loggers))); diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 85551d708b..03a3053367 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -42,13 +42,14 @@ class OS_JavaScript : public OS_Unix { MainLoop *main_loop = nullptr; AudioDriverJavaScript *audio_driver_javascript = nullptr; - bool finalizing = false; + bool idb_is_syncing = false; bool idb_available = false; bool idb_needs_sync = false; static void main_loop_callback(); static void file_access_close_callback(const String &p_file, int p_flags); + static void fs_sync_callback(); protected: void initialize() override; @@ -61,15 +62,12 @@ protected: bool _check_internal_feature_support(const String &p_feature) override; public: - bool idb_is_syncing = false; - // Override return type to make writing static callbacks less tedious. static OS_JavaScript *get_singleton(); void initialize_joypads() override; MainLoop *get_main_loop() const override; - void finalize_async(); bool main_loop_iterate(); Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override; @@ -88,11 +86,9 @@ public: String get_data_path() const override; String get_user_data_dir() const override; - void set_idb_available(bool p_idb_available); bool is_userfs_persistent() const override; void resume_audio(); - bool is_finalizing() { return finalizing; } OS_JavaScript(); }; diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index ae75a75830..6e43ffcedb 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -18,5 +18,5 @@ common_x11 = [ prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_x11) -if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: +if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_linuxbsd_builders.make_debug_linuxbsd)) diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp index e2b88b7704..36c304b7f9 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.cpp +++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp @@ -30,8 +30,8 @@ #include "crash_handler_linuxbsd.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "main/main.h" #ifdef DEBUG_ENABLED diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index f5e2c72bbc..ea101e24dd 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -73,7 +73,7 @@ def get_opts(): BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False), BoolVariable("pulseaudio", "Detect and use PulseAudio", True), BoolVariable("udev", "Use udev for gamepad connection callbacks", False), - EnumVariable("debug_symbols", "Add debugging symbols to release builds", "yes", ("yes", "no", "full")), + EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("touch", "Enable touch events", True), BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False), @@ -96,8 +96,6 @@ def configure(env): env.Prepend(CCFLAGS=["-Os"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -108,8 +106,6 @@ def configure(env): env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp index 1e46d3222d..e5a9bb4737 100644 --- a/platform/linuxbsd/detect_prime_x11.cpp +++ b/platform/linuxbsd/detect_prime_x11.cpp @@ -33,8 +33,8 @@ #include "detect_prime.h" -#include "core/print_string.h" -#include "core/ustring.h" +#include "core/string/print_string.h" +#include "core/string/ustring.h" #include <stdlib.h> diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 176878bc12..35418116b4 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -32,8 +32,8 @@ #ifdef X11_ENABLED -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/string/print_string.h" #include "detect_prime_x11.h" #include "key_mapping_x11.h" #include "main/main.h" diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 740bf81fd9..9ff28b9ed2 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -36,7 +36,7 @@ #include "servers/display_server.h" #include "core/input/input.h" -#include "core/local_vector.h" +#include "core/templates/local_vector.h" #include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsamidi/midi_driver_alsamidi.h" #include "drivers/pulseaudio/audio_driver_pulseaudio.h" diff --git a/platform/osx/SCsub b/platform/osx/SCsub index ad62db358b..aa95a89444 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -18,5 +18,5 @@ files = [ prog = env.add_program("#bin/godot", files) -if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: +if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_osx_builders.make_debug_osx)) diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h index cce00fb35f..1d467513e2 100644 --- a/platform/osx/context_gl_osx.h +++ b/platform/osx/context_gl_osx.h @@ -33,7 +33,7 @@ #if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/os/os.h" #include <AppKit/AppKit.h> diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index 9fb2f63935..1429024598 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -30,8 +30,8 @@ #include "crash_handler_osx.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "main/main.h" #include <string.h> diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 50e9bd2653..64e1d94f39 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -31,7 +31,7 @@ def get_opts(): " validation layers)", False, ), - EnumVariable("debug_symbols", "Add debugging symbols to release builds", "yes", ("yes", "no", "full")), + EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), @@ -57,8 +57,6 @@ def configure(env): env.Prepend(CCFLAGS=["-msse2"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -68,8 +66,6 @@ def configure(env): env.Prepend(CCFLAGS=["-Os"]) env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 9f2160dd9e..e988e51e72 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -30,13 +30,13 @@ #include "export.h" +#include "core/config/project_settings.h" #include "core/io/marshalls.h" #include "core/io/resource_saver.h" #include "core/io/zip_io.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "core/version.h" #include "editor/editor_export.h" #include "editor/editor_node.h" diff --git a/platform/server/detect.py b/platform/server/detect.py index 4c5a4527ae..f9e151f956 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -39,7 +39,7 @@ def get_opts(): BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False), BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False), - EnumVariable("debug_symbols", "Add debugging symbols to release builds", "yes", ("yes", "no", "full")), + EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False), ] @@ -61,8 +61,6 @@ def configure(env): env.Prepend(CCFLAGS=["-Os"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -73,8 +71,6 @@ def configure(env): env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index fbe526ef6d..9937ae5b62 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -30,7 +30,7 @@ #include "os_server.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "drivers/dummy/rasterizer_dummy.h" #include "drivers/dummy/texture_loader_dummy.h" #include "servers/rendering/rendering_server_raster.h" diff --git a/platform/uwp/context_egl_uwp.h b/platform/uwp/context_egl_uwp.h index 6f333b8e6a..5e7dc1802d 100644 --- a/platform/uwp/context_egl_uwp.h +++ b/platform/uwp/context_egl_uwp.h @@ -35,7 +35,7 @@ #include <EGL/egl.h> -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/os/os.h" using namespace Windows::UI::Core; diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index e9e536837f..e0c03df48e 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -30,14 +30,14 @@ #include "export.h" -#include "core/bind/core_bind.h" -#include "core/class_db.h" +#include "core/config/project_settings.h" +#include "core/core_bind.h" #include "core/crypto/crypto_core.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" +#include "core/object/class_db.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "core/version.h" #include "editor/editor_export.h" #include "editor/editor_node.h" diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 44ab075816..79508055e5 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -33,8 +33,8 @@ #include "os_uwp.h" +#include "core/config/project_settings.h" #include "core/io/marshalls.h" -#include "core/project_settings.h" #include "drivers/unix/ip_unix.h" #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 892327bac5..88961bf143 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -35,7 +35,7 @@ #include "core/input/input.h" #include "core/math/transform_2d.h" #include "core/os/os.h" -#include "core/ustring.h" +#include "core/string/ustring.h" #include "drivers/xaudio2/audio_driver_xaudio2.h" #include "joypad_uwp.h" #include "servers/audio_server.h" diff --git a/platform/windows/SCsub b/platform/windows/SCsub index e3f86977a4..0c9aa77803 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -32,5 +32,5 @@ if env["vsproj"]: env.vs_srcs += ["platform/windows/" + str(x)] if not os.getenv("VCINSTALLDIR"): - if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: + if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw)) diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h index 046e3437ea..0013177609 100644 --- a/platform/windows/context_gl_windows.h +++ b/platform/windows/context_gl_windows.h @@ -35,7 +35,7 @@ #ifndef CONTEXT_GL_WIN_H #define CONTEXT_GL_WIN_H -#include "core/error_list.h" +#include "core/error/error_list.h" #include "core/os/os.h" #include <windows.h> diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp index 02031ef6bb..7abf451062 100644 --- a/platform/windows/crash_handler_windows.cpp +++ b/platform/windows/crash_handler_windows.cpp @@ -30,8 +30,8 @@ #include "crash_handler_windows.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "main/main.h" #ifdef CRASH_HANDLER_EXCEPTION diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 489e45404f..934314b2f2 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -64,7 +64,7 @@ def get_opts(): # XP support dropped after EOL due to missing API for IPv6 and other issues # Vista support dropped after EOL due to GH-10243 ("target_win_version", "Targeted Windows version, >= 0x0601 (Windows 7)", "0x0601"), - EnumVariable("debug_symbols", "Add debugging symbols to release builds", "yes", ("yes", "no", "full")), + EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), EnumVariable("windows_subsystem", "Windows subsystem", "default", ("default", "console", "gui")), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), ("msvc_version", "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", None), @@ -209,7 +209,7 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"]) env.Append(LINKFLAGS=["/DEBUG"]) - if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": + if env["debug_symbols"] == "yes": env.AppendUnique(CCFLAGS=["/Z7"]) env.AppendUnique(LINKFLAGS=["/DEBUG"]) @@ -337,16 +337,12 @@ def configure_mingw(env): env.Prepend(CCFLAGS=["-Os"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": env.Append(CCFLAGS=["-O2"]) env.Append(CPPDEFINES=["DEBUG_ENABLED"]) if env["debug_symbols"] == "yes": - env.Prepend(CCFLAGS=["-g1"]) - if env["debug_symbols"] == "full": env.Prepend(CCFLAGS=["-g2"]) if env["optimize"] == "speed": # optimize for speed (default) env.Append(CCFLAGS=["-O2"]) diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 0fca2589ae..c64a1b3b09 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -33,9 +33,9 @@ #include "servers/display_server.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "crash_handler_windows.h" #include "drivers/unix/ip_unix.h" #include "drivers/wasapi/audio_driver_wasapi.h" diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index 90f0b55d0a..1f625cfb77 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -49,7 +49,7 @@ <DisplayString Condition="type == Variant::QUAT">{*(Quat *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::NODE_PATH">{*(NodePath *)_data._mem}</DisplayString> - <DisplayString Condition="type == Variant::_RID">{*(RID *)_data._mem}</DisplayString> + <DisplayString Condition="type == Variant::RID">{*(RID *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::OBJECT">{*(Object *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::DICTIONARY">{*(Dictionary *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString> @@ -79,7 +79,7 @@ <Item Name="[value]" Condition="type == Variant::QUAT">*(Quat *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::COLOR">*(Color *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::NODE_PATH">*(NodePath *)_data._mem</Item> - <Item Name="[value]" Condition="type == Variant::_RID">*(RID *)_data._mem</Item> + <Item Name="[value]" Condition="type == Variant::RID">*(RID *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::OBJECT">*(Object *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::DICTIONARY">*(Dictionary *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::ARRAY">*(Array *)_data._mem</Item> diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index d1454c9096..2a5c8a7763 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -194,7 +194,7 @@ void JoypadWindows::setup_joypad_object(const DIDEVICEOBJECTINSTANCE *ob, int p_ HRESULT res; DIPROPRANGE prop_range; DIPROPDWORD dilong; - DWORD ofs; + LONG ofs; if (ob->guidType == GUID_XAxis) ofs = DIJOFS_X; else if (ob->guidType == GUID_YAxis) @@ -395,7 +395,7 @@ void JoypadWindows::process_joypads() { // on mingw, these constants are not constants int count = 8; - unsigned int axes[] = { DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1) }; + LONG axes[] = { DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, (LONG)DIJOFS_SLIDER(0), (LONG)DIJOFS_SLIDER(1) }; int values[] = { js.lX, js.lY, js.lZ, js.lRx, js.lRy, js.lRz, js.rglSlider[0], js.rglSlider[1] }; for (int j = 0; j < joy->joy_axis.size(); j++) { diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h index c961abf0a5..223b44fcd6 100644 --- a/platform/windows/joypad_windows.h +++ b/platform/windows/joypad_windows.h @@ -77,7 +77,7 @@ private: DWORD last_pad; LPDIRECTINPUTDEVICE8 di_joy; - List<DWORD> joy_axis; + List<LONG> joy_axis; GUID guid; dinput_gamepad() { diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index f73516b370..b108d74b2e 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -244,7 +244,7 @@ void OS_Windows::finalize_core() { } Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { - String path = p_path; + String path = p_path.replace("/", "\\"); if (!FileAccess::exists(path)) { //this code exists so gdnative can load .dll files from within the executable path @@ -412,8 +412,10 @@ String OS_Windows::_quote_command_line_argument(const String &p_text) const { } Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { + String path = p_path.replace("/", "\\"); + if (p_blocking && r_pipe) { - String argss = _quote_command_line_argument(p_path); + String argss = _quote_command_line_argument(path); for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { argss += " " + _quote_command_line_argument(E->get()); } @@ -446,7 +448,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, return OK; } - String cmdline = _quote_command_line_argument(p_path); + String cmdline = _quote_command_line_argument(path); const List<String>::Element *I = p_arguments.front(); while (I) { cmdline += " " + _quote_command_line_argument(I->get()); @@ -509,7 +511,7 @@ Error OS_Windows::set_cwd(const String &p_cwd) { String OS_Windows::get_executable_path() const { WCHAR bufname[4096]; GetModuleFileNameW(nullptr, bufname, 4096); - String s = String::utf16((const char16_t *)bufname); + String s = String::utf16((const char16_t *)bufname).replace("\\", "/"); return s; } diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 910a83539a..a3dbb23182 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -31,9 +31,9 @@ #ifndef OS_WINDOWS_H #define OS_WINDOWS_H +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "crash_handler_windows.h" #include "drivers/unix/ip_unix.h" #include "drivers/wasapi/audio_driver_wasapi.h" diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 32226ef5a4..01426db999 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -31,7 +31,7 @@ #ifndef AREA_2D_H #define AREA_2D_H -#include "core/vset.h" +#include "core/templates/vset.h" #include "scene/2d/collision_object_2d.h" class Area2D : public CollisionObject2D { diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 5b89ac15b1..9bd716aeaa 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -30,7 +30,7 @@ #include "audio_stream_player_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/2d/area_2d.h" #include "scene/main/window.h" diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index fd4d5981ff..e22b24c16f 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -30,7 +30,7 @@ #include "camera_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/math/math_funcs.h" #include "scene/scene_string_names.h" #include "servers/rendering_server.h" diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 3cbb0f72f8..64d82d715c 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -31,7 +31,7 @@ #include "collision_polygon_2d.h" #include "collision_object_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/math/geometry_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index d022c857f3..a5cd624235 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -31,7 +31,7 @@ #include "collision_shape_2d.h" #include "collision_object_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/resources/capsule_shape_2d.h" #include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 5b405246e2..2296e0434e 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -31,7 +31,7 @@ #ifndef CPU_PARTICLES_2D_H #define CPU_PARTICLES_2D_H -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/2d/node_2d.h" #include "scene/resources/texture.h" diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index a9fdb103b2..a4a930455b 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -35,7 +35,7 @@ #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED -#include "core/engine.h" +#include "core/config/engine.h" #endif void GPUParticles2D::set_emitting(bool p_emitting) { diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index f1001a39fe..0d1b82d93e 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -31,7 +31,7 @@ #ifndef PARTICLES_2D_H #define PARTICLES_2D_H -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/2d/node_2d.h" #include "scene/resources/texture.h" diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 8df72d7aac..0e4b1836da 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -30,7 +30,7 @@ #include "joints_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "physics_body_2d.h" #include "servers/physics_server_2d.h" diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 4fc0882fdd..2b373a669b 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -30,57 +30,9 @@ #include "light_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "servers/rendering_server.h" -#ifdef TOOLS_ENABLED -Dictionary Light2D::_edit_get_state() const { - Dictionary state = Node2D::_edit_get_state(); - state["offset"] = get_texture_offset(); - return state; -} - -void Light2D::_edit_set_state(const Dictionary &p_state) { - Node2D::_edit_set_state(p_state); - set_texture_offset(p_state["offset"]); -} - -void Light2D::_edit_set_pivot(const Point2 &p_pivot) { - set_position(get_transform().xform(p_pivot)); - set_texture_offset(get_texture_offset() - p_pivot); -} - -Point2 Light2D::_edit_get_pivot() const { - return Vector2(); -} - -bool Light2D::_edit_use_pivot() const { - return true; -} - -Rect2 Light2D::_edit_get_rect() const { - if (texture.is_null()) { - return Rect2(); - } - - Size2 s = texture->get_size() * _scale; - return Rect2(texture_offset - s / 2.0, s); -} - -bool Light2D::_edit_use_rect() const { - return !texture.is_null(); -} -#endif - -Rect2 Light2D::get_anchorable_rect() const { - if (texture.is_null()) { - return Rect2(); - } - - Size2 s = texture->get_size() * _scale; - return Rect2(texture_offset - s / 2.0, s); -} - void Light2D::_update_light_visibility() { if (!is_inside_tree()) { return; @@ -123,32 +75,6 @@ bool Light2D::is_editor_only() const { return editor_only; } -void Light2D::set_texture(const Ref<Texture2D> &p_texture) { - texture = p_texture; - if (texture.is_valid()) { - RS::get_singleton()->canvas_light_set_texture(canvas_light, texture->get_rid()); - } else { - RS::get_singleton()->canvas_light_set_texture(canvas_light, RID()); - } - - update_configuration_warning(); -} - -Ref<Texture2D> Light2D::get_texture() const { - return texture; -} - -void Light2D::set_texture_offset(const Vector2 &p_offset) { - texture_offset = p_offset; - RS::get_singleton()->canvas_light_set_texture_offset(canvas_light, texture_offset); - item_rect_changed(); - _change_notify("offset"); -} - -Vector2 Light2D::get_texture_offset() const { - return texture_offset; -} - void Light2D::set_color(const Color &p_color) { color = p_color; RS::get_singleton()->canvas_light_set_color(canvas_light, color); @@ -176,20 +102,6 @@ float Light2D::get_energy() const { return energy; } -void Light2D::set_texture_scale(float p_scale) { - _scale = p_scale; - // Avoid having 0 scale values, can lead to errors in physics and rendering. - if (_scale == 0) { - _scale = CMP_EPSILON; - } - RS::get_singleton()->canvas_light_set_scale(canvas_light, _scale); - item_rect_changed(); -} - -float Light2D::get_texture_scale() const { - return _scale; -} - void Light2D::set_z_range_min(int p_min_z) { z_min = p_min_z; RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max); @@ -244,15 +156,6 @@ int Light2D::get_item_shadow_cull_mask() const { return item_shadow_mask; } -void Light2D::set_mode(Mode p_mode) { - mode = p_mode; - RS::get_singleton()->canvas_light_set_mode(canvas_light, RS::CanvasLightMode(p_mode)); -} - -Light2D::Mode Light2D::get_mode() const { - return mode; -} - void Light2D::set_shadow_enabled(bool p_enabled) { shadow = p_enabled; RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow); @@ -281,6 +184,15 @@ Color Light2D::get_shadow_color() const { return shadow_color; } +void Light2D::set_blend_mode(BlendMode p_mode) { + blend_mode = p_mode; + RS::get_singleton()->canvas_light_set_blend_mode(_get_light(), RS::CanvasLightBlendMode(p_mode)); +} + +Light2D::BlendMode Light2D::get_blend_mode() const { + return blend_mode; +} + void Light2D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas()); @@ -300,19 +212,6 @@ void Light2D::_notification(int p_what) { } } -String Light2D::get_configuration_warning() const { - String warning = Node2D::get_configuration_warning(); - - if (!texture.is_valid()) { - if (!warning.empty()) { - warning += "\n\n"; - } - warning += TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); - } - - return warning; -} - void Light2D::set_shadow_smooth(float p_amount) { shadow_smooth = p_amount; RS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth); @@ -329,24 +228,12 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light2D::set_editor_only); ClassDB::bind_method(D_METHOD("is_editor_only"), &Light2D::is_editor_only); - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Light2D::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &Light2D::get_texture); - - ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Light2D::set_texture_offset); - ClassDB::bind_method(D_METHOD("get_texture_offset"), &Light2D::get_texture_offset); - ClassDB::bind_method(D_METHOD("set_color", "color"), &Light2D::set_color); ClassDB::bind_method(D_METHOD("get_color"), &Light2D::get_color); - ClassDB::bind_method(D_METHOD("set_height", "height"), &Light2D::set_height); - ClassDB::bind_method(D_METHOD("get_height"), &Light2D::get_height); - ClassDB::bind_method(D_METHOD("set_energy", "energy"), &Light2D::set_energy); ClassDB::bind_method(D_METHOD("get_energy"), &Light2D::get_energy); - ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &Light2D::set_texture_scale); - ClassDB::bind_method(D_METHOD("get_texture_scale"), &Light2D::get_texture_scale); - ClassDB::bind_method(D_METHOD("set_z_range_min", "z"), &Light2D::set_z_range_min); ClassDB::bind_method(D_METHOD("get_z_range_min"), &Light2D::get_z_range_min); @@ -365,9 +252,6 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_shadow_cull_mask", "item_shadow_cull_mask"), &Light2D::set_item_shadow_cull_mask); ClassDB::bind_method(D_METHOD("get_item_shadow_cull_mask"), &Light2D::get_item_shadow_cull_mask); - ClassDB::bind_method(D_METHOD("set_mode", "mode"), &Light2D::set_mode); - ClassDB::bind_method(D_METHOD("get_mode"), &Light2D::get_mode); - ClassDB::bind_method(D_METHOD("set_shadow_enabled", "enabled"), &Light2D::set_shadow_enabled); ClassDB::bind_method(D_METHOD("is_shadow_enabled"), &Light2D::is_shadow_enabled); @@ -380,16 +264,18 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_color", "shadow_color"), &Light2D::set_shadow_color); ClassDB::bind_method(D_METHOD("get_shadow_color"), &Light2D::get_shadow_color); + ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &Light2D::set_blend_mode); + ClassDB::bind_method(D_METHOD("get_blend_mode"), &Light2D::get_blend_mode); + + ClassDB::bind_method(D_METHOD("set_height", "height"), &Light2D::set_height); + ClassDB::bind_method(D_METHOD("get_height"), &Light2D::get_height); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix,Mask"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix"), "set_blend_mode", "get_blend_mode"); ADD_GROUP("Range", "range_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_height", PROPERTY_HINT_RANGE, "-2048,2048,0.1,or_lesser,or_greater"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_min", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_min", "get_z_range_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_max", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_layer_min", PROPERTY_HINT_RANGE, "-512,512,1"), "set_layer_range_min", "get_layer_range_min"); @@ -403,14 +289,13 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); - BIND_ENUM_CONSTANT(MODE_ADD); - BIND_ENUM_CONSTANT(MODE_SUB); - BIND_ENUM_CONSTANT(MODE_MIX); - BIND_ENUM_CONSTANT(MODE_MASK); - BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13); + + BIND_ENUM_CONSTANT(BLEND_MODE_ADD); + BIND_ENUM_CONSTANT(BLEND_MODE_SUB); + BIND_ENUM_CONSTANT(BLEND_MODE_MIX); } Light2D::Light2D() { @@ -420,22 +305,168 @@ Light2D::Light2D() { shadow = false; color = Color(1, 1, 1); height = 0; - _scale = 1.0; z_min = -1024; z_max = 1024; layer_min = 0; layer_max = 0; item_mask = 1; item_shadow_mask = 1; - mode = MODE_ADD; energy = 1.0; shadow_color = Color(0, 0, 0, 0); shadow_filter = SHADOW_FILTER_NONE; shadow_smooth = 0; - + blend_mode = BLEND_MODE_ADD; set_notify_transform(true); } Light2D::~Light2D() { RenderingServer::get_singleton()->free(canvas_light); } + +////////////////////////////// + +#ifdef TOOLS_ENABLED + +Dictionary PointLight2D::_edit_get_state() const { + Dictionary state = Node2D::_edit_get_state(); + state["offset"] = get_texture_offset(); + return state; +} + +void PointLight2D::_edit_set_state(const Dictionary &p_state) { + Node2D::_edit_set_state(p_state); + set_texture_offset(p_state["offset"]); +} + +void PointLight2D::_edit_set_pivot(const Point2 &p_pivot) { + set_position(get_transform().xform(p_pivot)); + set_texture_offset(get_texture_offset() - p_pivot); +} + +Point2 PointLight2D::_edit_get_pivot() const { + return Vector2(); +} + +bool PointLight2D::_edit_use_pivot() const { + return true; +} + +Rect2 PointLight2D::_edit_get_rect() const { + if (texture.is_null()) { + return Rect2(); + } + + Size2 s = texture->get_size() * _scale; + return Rect2(texture_offset - s / 2.0, s); +} + +bool PointLight2D::_edit_use_rect() const { + return !texture.is_null(); +} +#endif + +Rect2 PointLight2D::get_anchorable_rect() const { + if (texture.is_null()) { + return Rect2(); + } + + Size2 s = texture->get_size() * _scale; + return Rect2(texture_offset - s / 2.0, s); +} + +void PointLight2D::set_texture(const Ref<Texture2D> &p_texture) { + texture = p_texture; + if (texture.is_valid()) { + RS::get_singleton()->canvas_light_set_texture(_get_light(), texture->get_rid()); + } else { + RS::get_singleton()->canvas_light_set_texture(_get_light(), RID()); + } + + update_configuration_warning(); +} + +Ref<Texture2D> PointLight2D::get_texture() const { + return texture; +} + +void PointLight2D::set_texture_offset(const Vector2 &p_offset) { + texture_offset = p_offset; + RS::get_singleton()->canvas_light_set_texture_offset(_get_light(), texture_offset); + item_rect_changed(); + _change_notify("offset"); +} + +Vector2 PointLight2D::get_texture_offset() const { + return texture_offset; +} + +String PointLight2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); + + if (!texture.is_valid()) { + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); + } + + return warning; +} + +void PointLight2D::set_texture_scale(float p_scale) { + _scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. + if (_scale == 0) { + _scale = CMP_EPSILON; + } + RS::get_singleton()->canvas_light_set_texture_scale(_get_light(), _scale); + item_rect_changed(); +} + +float PointLight2D::get_texture_scale() const { + return _scale; +} + +void PointLight2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &PointLight2D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &PointLight2D::get_texture); + + ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &PointLight2D::set_texture_offset); + ClassDB::bind_method(D_METHOD("get_texture_offset"), &PointLight2D::get_texture_offset); + + ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &PointLight2D::set_texture_scale); + ClassDB::bind_method(D_METHOD("get_texture_scale"), &PointLight2D::get_texture_scale); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1024,1,or_greater"), "set_height", "get_height"); +} + +PointLight2D::PointLight2D() { + RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_POINT); +} + +////////// + +void DirectionalLight2D::set_max_distance(float p_distance) { + max_distance = p_distance; + RS::get_singleton()->canvas_light_set_directional_distance(_get_light(), max_distance); +} + +float DirectionalLight2D::get_max_distance() const { + return max_distance; +} + +void DirectionalLight2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_max_distance", "pixels"), &DirectionalLight2D::set_max_distance); + ClassDB::bind_method(D_METHOD("get_max_distance"), &DirectionalLight2D::get_max_distance); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384.0,1.0,or_greater"), "set_max_distance", "get_max_distance"); +} + +DirectionalLight2D::DirectionalLight2D() { + RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_DIRECTIONAL); + set_max_distance(max_distance); // Update RenderingServer. +} diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 095cb05635..7dfeddc8e5 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -37,13 +37,6 @@ class Light2D : public Node2D { GDCLASS(Light2D, Node2D); public: - enum Mode { - MODE_ADD, - MODE_SUB, - MODE_MIX, - MODE_MASK, - }; - enum ShadowFilter { SHADOW_FILTER_NONE, SHADOW_FILTER_PCF5, @@ -51,6 +44,12 @@ public: SHADOW_FILTER_MAX }; + enum BlendMode { + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MIX, + }; + private: RID canvas_light; bool enabled; @@ -59,7 +58,6 @@ private: Color color; Color shadow_color; float height; - float _scale; float energy; int z_min; int z_max; @@ -68,43 +66,25 @@ private: int item_mask; int item_shadow_mask; float shadow_smooth; - Mode mode; Ref<Texture2D> texture; Vector2 texture_offset; ShadowFilter shadow_filter; + BlendMode blend_mode; void _update_light_visibility(); protected: + _FORCE_INLINE_ RID _get_light() const { return canvas_light; } void _notification(int p_what); static void _bind_methods(); public: -#ifdef TOOLS_ENABLED - virtual Dictionary _edit_get_state() const override; - virtual void _edit_set_state(const Dictionary &p_state) override; - - virtual void _edit_set_pivot(const Point2 &p_pivot) override; - virtual Point2 _edit_get_pivot() const override; - virtual bool _edit_use_pivot() const override; - virtual Rect2 _edit_get_rect() const override; - virtual bool _edit_use_rect() const override; -#endif - - virtual Rect2 get_anchorable_rect() const override; - void set_enabled(bool p_enabled); bool is_enabled() const; void set_editor_only(bool p_editor_only); bool is_editor_only() const; - void set_texture(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_texture() const; - - void set_texture_offset(const Vector2 &p_offset); - Vector2 get_texture_offset() const; - void set_color(const Color &p_color); Color get_color() const; @@ -114,9 +94,6 @@ public: void set_energy(float p_energy); float get_energy() const; - void set_texture_scale(float p_scale); - float get_texture_scale() const; - void set_z_range_min(int p_min_z); int get_z_range_min() const; @@ -135,9 +112,6 @@ public: void set_item_shadow_cull_mask(int p_mask); int get_item_shadow_cull_mask() const; - void set_mode(Mode p_mode); - Mode get_mode() const; - void set_shadow_enabled(bool p_enabled); bool is_shadow_enabled() const; @@ -150,13 +124,68 @@ public: void set_shadow_smooth(float p_amount); float get_shadow_smooth() const; - String get_configuration_warning() const override; + void set_blend_mode(BlendMode p_mode); + BlendMode get_blend_mode() const; Light2D(); ~Light2D(); }; -VARIANT_ENUM_CAST(Light2D::Mode); VARIANT_ENUM_CAST(Light2D::ShadowFilter); +VARIANT_ENUM_CAST(Light2D::BlendMode); + +class PointLight2D : public Light2D { + GDCLASS(PointLight2D, Light2D); + +private: + float _scale = 1.0; + Ref<Texture2D> texture; + Vector2 texture_offset; + +protected: + static void _bind_methods(); + +public: +#ifdef TOOLS_ENABLED + virtual Dictionary _edit_get_state() const override; + virtual void _edit_set_state(const Dictionary &p_state) override; + + virtual void _edit_set_pivot(const Point2 &p_pivot) override; + virtual Point2 _edit_get_pivot() const override; + virtual bool _edit_use_pivot() const override; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; +#endif + + virtual Rect2 get_anchorable_rect() const override; + + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; + + void set_texture_offset(const Vector2 &p_offset); + Vector2 get_texture_offset() const; + + void set_texture_scale(float p_scale); + float get_texture_scale() const; + + String get_configuration_warning() const override; + + PointLight2D(); +}; + +class DirectionalLight2D : public Light2D { + GDCLASS(DirectionalLight2D, Light2D); + + float max_distance = 10000.0; + +protected: + static void _bind_methods(); + +public: + void set_max_distance(float p_distance); + float get_max_distance() const; + + DirectionalLight2D(); +}; #endif // LIGHT_2D_H diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index b2ea60f895..0531762ed8 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -31,7 +31,7 @@ #include "light_occluder_2d.h" #include "core/math/geometry_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #define LINE_GRAB_WIDTH 8 diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index 9e3dbbd6c1..0e033d9be1 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -31,7 +31,7 @@ #ifndef LINE_BUILDER_H #define LINE_BUILDER_H -#include "core/color.h" +#include "core/math/color.h" #include "core/math/vector2.h" #include "line_2d.h" #include "scene/resources/gradient.h" diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 9949ac6228..1c7063d0d3 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -30,7 +30,7 @@ #include "navigation_agent_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/math/geometry_2d.h" #include "scene/2d/navigation_2d.h" #include "servers/navigation_server_2d.h" diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 9474392ddf..1f2377837b 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -31,7 +31,7 @@ #ifndef NAVIGATION_AGENT_2D_H #define NAVIGATION_AGENT_2D_H -#include "core/vector.h" +#include "core/templates/vector.h" #include "scene/main/node.h" class Node2D; diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 67e7176e6e..98817ec03e 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -30,8 +30,8 @@ #include "navigation_region_2d.h" +#include "core/config/engine.h" #include "core/core_string_names.h" -#include "core/engine.h" #include "core/math/geometry_2d.h" #include "core/os/mutex.h" #include "navigation_2d.h" diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 72250e96b3..42c2585487 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -30,7 +30,7 @@ #include "node_2d.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/gui/control.h" #include "scene/main/window.h" #include "servers/rendering_server.h" diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index ec1f1f40fa..01aa5838b4 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -30,7 +30,7 @@ #include "parallax_layer.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "parallax_background.h" void ParallaxLayer::set_motion_scale(const Size2 &p_scale) { diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index d5994422e7..d305f2805e 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -30,7 +30,7 @@ #include "path_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/math/geometry_2d.h" #include "scene/scene_string_names.h" diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 402eac644f..300799ff9d 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -30,12 +30,12 @@ #include "physics_body_2d.h" -#include "core/class_db.h" +#include "core/config/engine.h" #include "core/core_string_names.h" -#include "core/engine.h" -#include "core/list.h" #include "core/math/math_funcs.h" -#include "core/rid.h" +#include "core/object/class_db.h" +#include "core/templates/list.h" +#include "core/templates/rid.h" #include "scene/scene_string_names.h" void PhysicsBody2D::_notification(int p_what) { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index aefea56fa3..1db2d23bb8 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_BODY_2D_H #define PHYSICS_BODY_2D_H -#include "core/vset.h" +#include "core/templates/vset.h" #include "scene/2d/collision_object_2d.h" #include "scene/resources/physics_material.h" #include "servers/physics_server_2d.h" diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index a94a9f7085..8e4165cf50 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -30,7 +30,7 @@ #include "position_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/resources/texture.h" const float DEFAULT_GIZMO_EXTENTS = 10.0; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index a00db36077..e53f89c46d 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -31,7 +31,7 @@ #include "ray_cast_2d.h" #include "collision_object_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "physics_body_2d.h" #include "servers/physics_server_2d.h" diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index b9dd8f5405..22b615a379 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -31,8 +31,8 @@ #ifndef TILE_MAP_H #define TILE_MAP_H -#include "core/self_list.h" -#include "core/vset.h" +#include "core/templates/self_list.h" +#include "core/templates/vset.h" #include "scene/2d/navigation_2d.h" #include "scene/2d/node_2d.h" #include "scene/resources/tile_set.h" diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 9cec589cfb..e217f2a394 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -30,7 +30,7 @@ #include "visibility_notifier_2d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "gpu_particles_2d.h" #include "scene/2d/animated_sprite_2d.h" #include "scene/2d/physics_body_2d.h" diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index 07d24f39a7..7d1f030baf 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -31,7 +31,7 @@ #ifndef AREA_3D_H #define AREA_3D_H -#include "core/vset.h" +#include "core/templates/vset.h" #include "scene/3d/collision_object_3d.h" class Area3D : public CollisionObject3D { diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 6e4db8f382..b093788d75 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -30,7 +30,7 @@ #include "audio_stream_player_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/3d/area_3d.h" #include "scene/3d/camera_3d.h" #include "scene/3d/listener_3d.h" diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index e867891ec0..38c9e96fbc 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -37,7 +37,7 @@ #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/sort_array.h" +#include "core/templates/sort_array.h" #include "lightmap_probe.h" void BakedLightmapData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance) { diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index bebb579252..8808569215 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -31,7 +31,7 @@ #ifndef BAKED_LIGHTMAP_H #define BAKED_LIGHTMAP_H -#include "core/local_vector.h" +#include "core/templates/local_vector.h" #include "scene/3d/light_3d.h" #include "scene/3d/lightmapper.h" #include "scene/3d/mesh_instance_3d.h" diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index ecbaca7bd1..a6433f8f58 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -31,7 +31,7 @@ #include "camera_3d.h" #include "collision_object_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/math/camera_matrix.h" #include "scene/resources/material.h" #include "scene/resources/surface_tool.h" diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index f44d0dfcfa..078861011b 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -31,7 +31,7 @@ #ifndef CPU_PARTICLES_H #define CPU_PARTICLES_H -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/3d/visual_instance_3d.h" class CPUParticles3D : public GeometryInstance3D { diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index b68acef21c..f0e5f05e5b 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -31,7 +31,7 @@ #ifndef PARTICLES_H #define PARTICLES_H -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/3d/visual_instance_3d.h" #include "scene/resources/material.h" diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index baaaa23185..1f0d5d587d 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -30,7 +30,7 @@ #include "gpu_particles_collision_3d.h" -#include "core/thread_work_pool.h" +#include "core/templates/thread_work_pool.h" #include "mesh_instance_3d.h" #include "scene/3d/camera_3d.h" #include "scene/main/viewport.h" diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 4c73c7bcb2..9b644ade6b 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -31,8 +31,8 @@ #ifndef GPU_PARTICLES_COLLISION_3D_H #define GPU_PARTICLES_COLLISION_3D_H -#include "core/local_vector.h" -#include "core/rid.h" +#include "core/templates/local_vector.h" +#include "core/templates/rid.h" #include "scene/3d/visual_instance_3d.h" #include "scene/resources/material.h" diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 46c3f18c38..2dc3cd3230 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -30,8 +30,8 @@ #include "light_3d.h" -#include "core/engine.h" -#include "core/project_settings.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "scene/resources/surface_tool.h" bool Light3D::_can_gizmo_scale() const { diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 422b566867..f9f8f276a3 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -30,7 +30,7 @@ #include "navigation_agent_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/3d/navigation_3d.h" #include "servers/navigation_server_3d.h" diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index e80367ea50..dcfd302561 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -31,7 +31,7 @@ #ifndef NAVIGATION_AGENT_H #define NAVIGATION_AGENT_H -#include "core/vector.h" +#include "core/templates/vector.h" #include "scene/main/node.h" class Node3D; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 138788cf2d..e8005f38ed 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -30,8 +30,8 @@ #include "node_3d.h" -#include "core/engine.h" -#include "core/message_queue.h" +#include "core/config/engine.h" +#include "core/object/message_queue.h" #include "scene/main/scene_tree.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index d0d2d6f9f4..f25a64c567 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -30,7 +30,7 @@ #include "path_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/scene_string_names.h" void Path3D::_notification(int p_what) { diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 579088b835..a3e00d2cc3 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -30,11 +30,11 @@ #include "physics_body_3d.h" -#include "core/class_db.h" +#include "core/config/engine.h" #include "core/core_string_names.h" -#include "core/engine.h" -#include "core/list.h" -#include "core/rid.h" +#include "core/object/class_db.h" +#include "core/templates/list.h" +#include "core/templates/rid.h" #include "scene/3d/collision_shape_3d.h" #include "scene/scene_string_names.h" #include "servers/navigation_server_3d.h" diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index d3dddeae55..da947ba02e 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_BODY_3D_H #define PHYSICS_BODY_3D_H -#include "core/vset.h" +#include "core/templates/vset.h" #include "scene/3d/collision_object_3d.h" #include "scene/resources/physics_material.h" #include "servers/physics_server_3d.h" diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 69f09ef569..811e8a331b 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -31,7 +31,7 @@ #include "ray_cast_3d.h" #include "collision_object_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "mesh_instance_3d.h" #include "servers/physics_server_3d.h" diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 6723ca04b9..0ae1c0e3b6 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -30,10 +30,10 @@ #include "skeleton_3d.h" -#include "core/engine.h" -#include "core/message_queue.h" -#include "core/project_settings.h" -#include "core/type_info.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/object/message_queue.h" +#include "core/variant/type_info.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/surface_tool.h" #include "scene/scene_string_names.h" diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index a21891a32e..95c49750fa 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -31,7 +31,7 @@ #ifndef SKELETON_3D_H #define SKELETON_3D_H -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/3d/node_3d.h" #include "scene/resources/skin.h" diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 3b5c328e43..132c35771b 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -30,10 +30,10 @@ #include "soft_body_3d.h" -#include "core/class_db.h" -#include "core/list.h" +#include "core/object/class_db.h" #include "core/os/os.h" -#include "core/rid.h" +#include "core/templates/list.h" +#include "core/templates/rid.h" #include "scene/3d/collision_object_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/skeleton_3d.h" diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 9775ecc6c6..287d760db0 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -30,7 +30,7 @@ #include "spring_arm_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/3d/collision_object_3d.h" #include "scene/resources/sphere_shape_3d.h" #include "servers/physics_server_3d.h" diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp index db10f3273b..eba7d44c16 100644 --- a/scene/3d/velocity_tracker_3d.cpp +++ b/scene/3d/velocity_tracker_3d.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "velocity_tracker_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" void VelocityTracker3D::set_track_physics_step(bool p_track_physics_step) { physics_step = p_track_physics_step; diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp index a64b0df1cc..9f5c40caf4 100644 --- a/scene/3d/visibility_notifier_3d.cpp +++ b/scene/3d/visibility_notifier_3d.cpp @@ -30,7 +30,7 @@ #include "visibility_notifier_3d.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/3d/camera_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/animation/animation_player.h" diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 195674f62d..51bcb411da 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -32,7 +32,7 @@ #define VISUAL_INSTANCE_H #include "core/math/face3.h" -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/3d/node_3d.h" #include "scene/resources/material.h" diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 30757d2d80..e9e17148d6 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -30,8 +30,8 @@ #include "animation_player.h" -#include "core/engine.h" -#include "core/message_queue.h" +#include "core/config/engine.h" +#include "core/object/message_queue.h" #include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" @@ -762,12 +762,10 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f next_pos = len; } - // fix delta - delta = next_pos - cd.pos; + bool backwards = signbit(delta); // Negative zero means playing backwards too + delta = next_pos - cd.pos; // Fix delta (after determination of backwards because negative zero is lost here) if (&cd == &playback.current) { - bool backwards = delta < 0; - if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) { //playback finished end_reached = true; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index bb5d536600..2ef3ba87b2 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -31,7 +31,7 @@ #include "animation_tree.h" #include "animation_blend_tree.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 48f70e88cb..14aae9c7bf 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -30,7 +30,7 @@ #include "audio_stream_player.h" -#include "core/engine.h" +#include "core/config/engine.h" void AudioStreamPlayer::_mix_to_bus(const AudioFrame *p_frames, int p_amount) { int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus); diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index f57c8e58db..f848fc3e68 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -32,7 +32,7 @@ #include "core/debugger/engine_debugger.h" #include "core/io/marshalls.h" -#include "core/script_language.h" +#include "core/object/script_language.h" #include "scene/main/scene_tree.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index 80e329f1f2..af2d8904b5 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -31,10 +31,10 @@ #ifndef SCENE_DEBUGGER_H #define SCENE_DEBUGGER_H -#include "core/array.h" -#include "core/class_db.h" -#include "core/pair.h" -#include "core/ustring.h" +#include "core/object/class_db.h" +#include "core/string/ustring.h" +#include "core/templates/pair.h" +#include "core/variant/array.h" class Script; diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index e400801b66..e86ad09aa6 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -30,7 +30,7 @@ #include "button.h" -#include "core/translation.h" +#include "core/string/translation.h" #include "servers/rendering_server.h" Size2 Button::get_minimum_size() const { diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index 1ddc730dd1..790faeb4fd 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -30,7 +30,7 @@ #include "check_button.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "servers/rendering_server.h" Size2 CheckButton::get_icon_size() const { diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 470a7db2dc..5643110b89 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "container.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/scene_string_names.h" void Container::_child_minsize_changed() { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 476dccab7e..3414b04978 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -30,12 +30,12 @@ #include "control.h" +#include "core/config/project_settings.h" #include "core/math/geometry_2d.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/string/print_string.h" #include "scene/gui/label.h" #include "scene/gui/panel.h" #include "scene/main/canvas_layer.h" @@ -2738,7 +2738,9 @@ void Control::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data"))); BIND_VMETHOD(MethodInfo("drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data"))); - BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text"))); + BIND_VMETHOD(MethodInfo( + PropertyInfo(Variant::OBJECT, "control", PROPERTY_HINT_RESOURCE_TYPE, "Control"), + "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text"))); BIND_VMETHOD(MethodInfo(Variant::BOOL, "_clips_input")); ADD_GROUP("Anchor", "anchor_"); diff --git a/scene/gui/control.h b/scene/gui/control.h index 83e79f908f..f2f558cf4f 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -32,7 +32,7 @@ #define CONTROL_H #include "core/math/transform_2d.h" -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/gui/shortcut.h" #include "scene/main/canvas_item.h" #include "scene/main/node.h" diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 430e98d50e..4f59f4a36a 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -31,8 +31,8 @@ #include "dialogs.h" #include "core/os/keyboard.h" -#include "core/print_string.h" -#include "core/translation.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" #include "line_edit.h" #ifdef TOOLS_ENABLED diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 2da61bdde7..7ce4e90f28 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -31,7 +31,7 @@ #include "file_dialog.h" #include "core/os/keyboard.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "scene/gui/label.h" FileDialog::GetIconFunc FileDialog::get_icon_func = nullptr; diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index ecd4ad17ea..53d7ead548 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -357,7 +357,7 @@ void GradientEdit::_notification(int p_what) { //Draw point markers for (int i = 0; i < points.size(); i++) { - Color col = points[i].color.contrasted(); + Color col = points[i].color.inverted(); col.a = 0.9; draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 54150d130d..6708b18e0a 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "item_list.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) { Item item; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 9e3418a5c9..9df63a3c71 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -30,9 +30,9 @@ #include "label.h" -#include "core/print_string.h" -#include "core/project_settings.h" -#include "core/translation.h" +#include "core/config/project_settings.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" void Label::set_autowrap(bool p_autowrap) { if (autowrap == p_autowrap) { diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 1b8f04297d..649f5a5f66 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -30,11 +30,11 @@ #include "line_edit.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/translation.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" #include "label.h" #include "servers/display_server.h" #ifdef TOOLS_ENABLED @@ -679,7 +679,7 @@ void LineEdit::_notification(int p_what) { } break; #endif case NOTIFICATION_RESIZED: { - window_pos = 0; + scroll_offset = 0; set_cursor_position(get_cursor_position()); } break; @@ -735,7 +735,7 @@ void LineEdit::_notification(int p_what) { x_ofs = style->get_offset().x; } break; case ALIGN_CENTER: { - if (window_pos != 0) { + if (scroll_offset != 0) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - (cached_text_width)) / 2); @@ -747,7 +747,7 @@ void LineEdit::_notification(int p_what) { } int ofs_max = width - style->get_margin(MARGIN_RIGHT); - int char_ofs = window_pos; + int char_ofs = scroll_offset; int y_area = height - style->get_minimum_size().height; int y_ofs = style->get_offset().y + (y_area - font->get_height()) / 2; @@ -780,7 +780,7 @@ void LineEdit::_notification(int p_what) { r_icon->draw(ci, Point2(width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT), height / 2 - r_icon->get_height() / 2), color_icon); if (align == ALIGN_CENTER) { - if (window_pos == 0) { + if (scroll_offset == 0) { x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - cached_text_width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT) * 2) / 2); } } else { @@ -1023,7 +1023,7 @@ void LineEdit::undo() { TextOperation op = undo_stack_pos->get(); text = op.text; cached_width = op.cached_width; - window_pos = op.window_pos; + scroll_offset = op.scroll_offset; set_cursor_position(op.cursor_pos); if (expand_to_text_length) { @@ -1044,7 +1044,7 @@ void LineEdit::redo() { TextOperation op = undo_stack_pos->get(); text = op.text; cached_width = op.cached_width; - window_pos = op.window_pos; + scroll_offset = op.scroll_offset; set_cursor_position(op.cursor_pos); if (expand_to_text_length) { @@ -1071,7 +1071,7 @@ void LineEdit::shift_selection_check_post(bool p_shift) { void LineEdit::set_cursor_at_pixel_pos(int p_x) { Ref<Font> font = get_theme_font("font"); - int ofs = window_pos; + int ofs = scroll_offset; Ref<StyleBox> style = get_theme_stylebox("normal"); int pixel_ofs = 0; Size2 size = get_size(); @@ -1084,7 +1084,7 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) { pixel_ofs = int(style->get_offset().x); } break; case ALIGN_CENTER: { - if (window_pos != 0) { + if (scroll_offset != 0) { pixel_ofs = int(style->get_offset().x); } else { pixel_ofs = int(size.width - (cached_width)) / 2; @@ -1122,7 +1122,7 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) { int LineEdit::get_cursor_pixel_pos() { Ref<Font> font = get_theme_font("font"); - int ofs = window_pos; + int ofs = scroll_offset; Ref<StyleBox> style = get_theme_stylebox("normal"); int pixel_ofs = 0; Size2 size = get_size(); @@ -1135,7 +1135,7 @@ int LineEdit::get_cursor_pixel_pos() { pixel_ofs = int(style->get_offset().x); } break; case ALIGN_CENTER: { - if (window_pos != 0) { + if (scroll_offset != 0) { pixel_ofs = int(style->get_offset().x); } else { pixel_ofs = int(size.width - (cached_width)) / 2; @@ -1236,7 +1236,7 @@ void LineEdit::delete_char() { set_cursor_position(get_cursor_position() - 1); if (align == ALIGN_CENTER || align == ALIGN_RIGHT) { - window_pos = CLAMP(window_pos - 1, 0, MAX(text.length() - 1, 0)); + scroll_offset = CLAMP(scroll_offset - 1, 0, MAX(text.length() - 1, 0)); } _text_changed(); @@ -1262,12 +1262,12 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) { if (cursor_pos >= text.length()) { cursor_pos = text.length(); } - if (window_pos > cursor_pos) { - window_pos = cursor_pos; + if (scroll_offset > cursor_pos) { + scroll_offset = cursor_pos; } if (align == ALIGN_CENTER || align == ALIGN_RIGHT) { - window_pos = CLAMP(window_pos - (p_to_column - p_from_column), 0, MAX(text.length() - 1, 0)); + scroll_offset = CLAMP(scroll_offset - (p_to_column - p_from_column), 0, MAX(text.length() - 1, 0)); } if (!text_changed_dirty) { @@ -1288,7 +1288,7 @@ void LineEdit::set_text(String p_text) { update(); cursor_pos = 0; - window_pos = 0; + scroll_offset = 0; } void LineEdit::clear() { @@ -1332,16 +1332,16 @@ void LineEdit::set_cursor_position(int p_pos) { cursor_pos = p_pos; if (!is_inside_tree()) { - window_pos = cursor_pos; + scroll_offset = cursor_pos; return; } Ref<StyleBox> style = get_theme_stylebox("normal"); Ref<Font> font = get_theme_font("font"); - if (cursor_pos <= window_pos) { + if (cursor_pos <= scroll_offset) { // Adjust window if cursor goes too much to the left. - set_window_pos(MAX(0, cursor_pos - 1)); + set_scroll_offset(MAX(0, cursor_pos - 1)); } else { // Adjust window if cursor goes too much to the right. int window_width = get_size().width - style->get_minimum_size().width; @@ -1354,12 +1354,12 @@ void LineEdit::set_cursor_position(int p_pos) { if (window_width < 0) { return; } - int wp = window_pos; + int wp = scroll_offset; if (font.is_valid()) { int accum_width = 0; - for (int i = cursor_pos; i >= window_pos; i--) { + for (int i = cursor_pos; i >= scroll_offset; i--) { if (i >= text.length()) { // Do not do this, because if the cursor is at the end, its just fine that it takes no space. // accum_width = font->get_char_size(' ').width; @@ -1378,8 +1378,8 @@ void LineEdit::set_cursor_position(int p_pos) { } } - if (wp != window_pos) { - set_window_pos(wp); + if (wp != scroll_offset) { + set_scroll_offset(wp); } } update(); @@ -1389,13 +1389,17 @@ int LineEdit::get_cursor_position() const { return cursor_pos; } -void LineEdit::set_window_pos(int p_pos) { - window_pos = p_pos; - if (window_pos < 0) { - window_pos = 0; +void LineEdit::set_scroll_offset(int p_pos) { + scroll_offset = p_pos; + if (scroll_offset < 0) { + scroll_offset = 0; } } +int LineEdit::get_scroll_offset() const { + return scroll_offset; +} + void LineEdit::append_at_cursor(String p_text) { if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) { String pre = text.substr(0, cursor_pos); @@ -1413,7 +1417,7 @@ void LineEdit::clear_internal() { _clear_undo_stack(); cached_width = 0; cursor_pos = 0; - window_pos = 0; + scroll_offset = 0; undo_text = ""; text = ""; update(); @@ -1644,7 +1648,7 @@ void LineEdit::_editor_settings_changed() { void LineEdit::set_expand_to_text_length(bool p_enabled) { expand_to_text_length = p_enabled; minimum_size_changed(); - set_window_pos(0); + set_scroll_offset(0); } bool LineEdit::get_expand_to_text_length() const { @@ -1771,7 +1775,7 @@ void LineEdit::_create_undo_state() { op.text = text; op.cached_width = cached_width; op.cursor_pos = cursor_pos; - op.window_pos = window_pos; + op.scroll_offset = scroll_offset; undo_stack.push_back(op); } @@ -1816,6 +1820,7 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_placeholder_alpha"), &LineEdit::get_placeholder_alpha); ClassDB::bind_method(D_METHOD("set_cursor_position", "position"), &LineEdit::set_cursor_position); ClassDB::bind_method(D_METHOD("get_cursor_position"), &LineEdit::get_cursor_position); + ClassDB::bind_method(D_METHOD("get_scroll_offset"), &LineEdit::get_scroll_offset); ClassDB::bind_method(D_METHOD("set_expand_to_text_length", "enabled"), &LineEdit::set_expand_to_text_length); ClassDB::bind_method(D_METHOD("get_expand_to_text_length"), &LineEdit::get_expand_to_text_length); ClassDB::bind_method(D_METHOD("cursor_set_blink_enabled", "enabled"), &LineEdit::cursor_set_blink_enabled); @@ -1898,7 +1903,7 @@ LineEdit::LineEdit() { cached_width = 0; cached_placeholder_width = 0; cursor_pos = 0; - window_pos = 0; + scroll_offset = 0; window_has_focus = true; max_length = 0; pass = false; diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index d6cc1f1f11..a5e5b6988f 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -80,7 +80,7 @@ private: PopupMenu *menu; int cursor_pos; - int window_pos; + int scroll_offset; int max_length; // 0 for no maximum. int cached_width; @@ -106,7 +106,7 @@ private: struct TextOperation { int cursor_pos; - int window_pos; + int scroll_offset; int cached_width; String text; }; @@ -144,7 +144,8 @@ private: void shift_selection_check_post(bool); void selection_fill_at_cursor(); - void set_window_pos(int p_pos); + void set_scroll_offset(int p_pos); + int get_scroll_offset() const; void set_cursor_at_pixel_pos(int p_x); int get_cursor_pixel_pos(); diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 5780cc5e71..f0e69a94a4 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -30,7 +30,7 @@ #include "option_button.h" -#include "core/print_string.h" +#include "core/string/print_string.h" Size2 OptionButton::get_minimum_size() const { Size2 minsize = Button::get_minimum_size(); diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp index d8d9beca2b..acbb6d7ab5 100644 --- a/scene/gui/panel.cpp +++ b/scene/gui/panel.cpp @@ -30,7 +30,7 @@ #include "panel.h" -#include "core/print_string.h" +#include "core/string/print_string.h" void Panel::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index de866fa956..49ddd5c3ee 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -30,7 +30,7 @@ #include "popup.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/os/keyboard.h" #include "scene/gui/panel.h" diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 3e5b89ccf3..44577811ff 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -33,7 +33,7 @@ #include "scene/main/window.h" -#include "core/local_vector.h" +#include "core/templates/local_vector.h" class Popup : public Window { GDCLASS(Popup, Window); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 578d8a96e8..0a469d8373 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -33,8 +33,8 @@ #include "core/input/input.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/translation.h" +#include "core/string/print_string.h" +#include "core/string/translation.h" String PopupMenu::_get_accel_text(int p_item) const { ERR_FAIL_INDEX_V(p_item, items.size(), String()); diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp index 32ec0049f0..773acb2713 100644 --- a/scene/gui/reference_rect.cpp +++ b/scene/gui/reference_rect.cpp @@ -30,7 +30,7 @@ #include "reference_rect.h" -#include "core/engine.h" +#include "core/config/engine.h" void ReferenceRect::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp index 2628e5ab0f..76ca8abcc7 100644 --- a/scene/gui/rich_text_effect.cpp +++ b/scene/gui/rich_text_effect.cpp @@ -30,7 +30,7 @@ #include "rich_text_effect.h" -#include "core/script_language.h" +#include "core/object/script_language.h" void RichTextEffect::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::BOOL, "_process_custom_fx", PropertyInfo(Variant::OBJECT, "char_fx", PROPERTY_HINT_RESOURCE_TYPE, "CharFXTransform"))); diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h index a5401f7eaa..e6b9f09e4d 100644 --- a/scene/gui/rich_text_effect.h +++ b/scene/gui/rich_text_effect.h @@ -31,7 +31,7 @@ #ifndef RICH_TEXT_EFFECT_H #define RICH_TEXT_EFFECT_H -#include "core/resource.h" +#include "core/io/resource.h" class RichTextEffect : public Resource { GDCLASS(RichTextEffect, Resource); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 0e9ef71892..9340d98ede 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -32,7 +32,7 @@ #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "scene/main/window.h" bool ScrollBar::focus_by_default = false; diff --git a/scene/gui/shortcut.h b/scene/gui/shortcut.h index 0d7809e5cf..176958b397 100644 --- a/scene/gui/shortcut.h +++ b/scene/gui/shortcut.h @@ -32,7 +32,7 @@ #define SHORTCUT_H #include "core/input/input_event.h" -#include "core/resource.h" +#include "core/io/resource.h" class Shortcut : public Resource { GDCLASS(Shortcut, Resource); diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index 4e1ad2ae05..c5f56fe8e2 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -30,7 +30,7 @@ #include "subviewport_container.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "scene/main/viewport.h" Size2 SubViewportContainer::get_minimum_size() const { diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index bd9c2da5bc..d92f41af2d 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -30,7 +30,7 @@ #include "tab_container.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/gui/box_container.h" #include "scene/gui/label.h" #include "scene/gui/texture_rect.h" diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index d47f771d1d..eefe8cc3bc 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -30,7 +30,7 @@ #include "tabs.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/gui/box_container.h" #include "scene/gui/label.h" #include "scene/gui/texture_rect.h" diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index fb397759aa..cbe6c6bdb9 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -30,12 +30,12 @@ #include "text_edit.h" +#include "core/config/project_settings.h" #include "core/input/input.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" +#include "core/object/script_language.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/project_settings.h" -#include "core/script_language.h" #include "scene/main/window.h" #ifdef TOOLS_ENABLED diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp index 484b14d11c..e0d98d1c22 100644 --- a/scene/gui/texture_progress.cpp +++ b/scene/gui/texture_progress.cpp @@ -30,7 +30,7 @@ #include "texture_progress.h" -#include "core/engine.h" +#include "core/config/engine.h" void TextureProgress::set_under_texture(const Ref<Texture2D> &p_texture) { under = p_texture; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 318496df70..bcb375d786 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -30,12 +30,12 @@ #include "tree.h" +#include "core/config/project_settings.h" #include "core/input/input.h" #include "core/math/math_funcs.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/string/print_string.h" #include "scene/main/window.h" #include "box_container.h" diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 740374d09e..e6c35352f5 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -31,7 +31,7 @@ #include "canvas_item.h" #include "core/input/input.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/2d/canvas_group.h" #include "scene/main/canvas_layer.h" #include "scene/main/viewport.h" diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index da0169b60b..f484d25dc1 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -30,7 +30,7 @@ #include "http_request.h" #include "core/io/compression.h" -#include "core/ustring.h" +#include "core/string/ustring.h" void HTTPRequest::_redirect_request(const String &p_new_url) { } diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e7753089c7..36c3f03f70 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -32,8 +32,8 @@ #include "core/core_string_names.h" #include "core/io/resource_loader.h" -#include "core/message_queue.h" -#include "core/print_string.h" +#include "core/object/message_queue.h" +#include "core/string/print_string.h" #include "instance_placeholder.h" #include "scene/debugger/scene_debugger.h" #include "scene/resources/packed_scene.h" diff --git a/scene/main/node.h b/scene/main/node.h index 09943d0626..2f8a0673e9 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -31,12 +31,12 @@ #ifndef NODE_H #define NODE_H -#include "core/class_db.h" -#include "core/map.h" -#include "core/node_path.h" -#include "core/project_settings.h" -#include "core/script_language.h" -#include "core/typed_array.h" +#include "core/config/project_settings.h" +#include "core/object/class_db.h" +#include "core/object/script_language.h" +#include "core/string/node_path.h" +#include "core/templates/map.h" +#include "core/variant/typed_array.h" #include "scene/main/scene_tree.h" class Viewport; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 40479a796f..cffd1126ee 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -30,16 +30,16 @@ #include "scene_tree.h" +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/input/input.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "core/os/dir_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/string/print_string.h" #include "node.h" #include "scene/debugger/scene_debugger.h" #include "scene/resources/dynamic_font.h" diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index e5ab4f9958..3e5802ce2e 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -34,7 +34,7 @@ #include "core/io/multiplayer_api.h" #include "core/os/main_loop.h" #include "core/os/thread_safe.h" -#include "core/self_list.h" +#include "core/templates/self_list.h" #include "scene/resources/mesh.h" #include "scene/resources/world_2d.h" #include "scene/resources/world_3d.h" diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 86c08ca6e9..432fb5b4fb 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -202,7 +202,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const Override o; o.in_use = false; Callable::CallError ce; - o.override = Variant::construct(pinfo.type, nullptr, 0, ce); + Variant::construct(pinfo.type, o.override, nullptr, 0, ce); overrides[variables[i]] = o; } diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index fb55892b54..c9fce2f6c2 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -30,7 +30,7 @@ #include "timer.h" -#include "core/engine.h" +#include "core/config/engine.h" void Timer::_notification(int p_what) { switch (p_what) { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index b9a913edb4..17411bb490 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -30,11 +30,11 @@ #include "viewport.h" +#include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" #include "core/input/input.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/2d/collision_object_2d.h" #include "scene/3d/camera_3d.h" #include "scene/3d/collision_object_3d.h" @@ -161,6 +161,11 @@ ViewportTexture::~ViewportTexture() { ///////////////////////////////////// +// Aliases used to provide custom styles to tooltips in the default +// theme and editor theme. +// TooltipPanel is also used for custom tooltips, while TooltipLabel +// is only relevant for default tooltips. + class TooltipPanel : public PopupPanel { GDCLASS(TooltipPanel, PopupPanel); @@ -175,6 +180,8 @@ public: TooltipLabel() {} }; +///////////////////////////////////// + Viewport::GUI::GUI() { embed_subwindows_hint = false; embedding_subwindows = false; @@ -188,7 +195,7 @@ Viewport::GUI::GUI() { mouse_over = nullptr; drag_mouse_over = nullptr; - tooltip = nullptr; + tooltip_control = nullptr; tooltip_popup = nullptr; tooltip_label = nullptr; } @@ -814,7 +821,14 @@ void Viewport::_notification(int p_what) { } } break; - case NOTIFICATION_WM_MOUSE_EXIT: + case NOTIFICATION_WM_MOUSE_EXIT: { + _drop_physics_mouseover(); + + // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not + // drop the gui mouseover here, as a scrollbar may be dragged while the + // mouse is outside the window (without the window having lost focus). + // See bug #39634 + } break; case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { _drop_physics_mouseover(); @@ -1465,7 +1479,7 @@ void Viewport::_gui_sort_roots() { } void Viewport::_gui_cancel_tooltip() { - gui.tooltip = nullptr; + gui.tooltip_control = nullptr; gui.tooltip_timer = -1; if (gui.tooltip_popup) { gui.tooltip_popup->queue_delete(); @@ -1474,21 +1488,23 @@ void Viewport::_gui_cancel_tooltip() { } } -String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which) { +String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_tooltip_owner) { Vector2 pos = p_pos; String tooltip; while (p_control) { tooltip = p_control->get_tooltip(pos); - if (r_which) { - *r_which = p_control; + if (r_tooltip_owner) { + *r_tooltip_owner = p_control; } - if (tooltip != String()) { + // If we found a tooltip, we stop here. + if (!tooltip.empty()) { break; } - pos = p_control->get_transform().xform(pos); + + // Otherwise, we check parent controls unless some conditions prevent it. if (p_control->data.mouse_filter == Control::MOUSE_FILTER_STOP) { break; @@ -1497,6 +1513,9 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont break; } + // Transform cursor pos for parent control. + pos = p_control->get_transform().xform(pos); + p_control = p_control->get_parent_control(); } @@ -1504,34 +1523,40 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont } void Viewport::_gui_show_tooltip() { - if (!gui.tooltip) { + if (!gui.tooltip_control) { return; } - Control *which = nullptr; - String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.last_mouse_pos), &which); - tooltip = tooltip.strip_edges(); - if (tooltip.length() == 0) { - return; // bye + // Get the Control under cursor and the relevant tooltip text, if any. + Control *tooltip_owner = nullptr; + String tooltip_text = _gui_get_tooltip( + gui.tooltip_control, + gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos), + &tooltip_owner); + tooltip_text.strip_edges(); + if (tooltip_text.empty()) { + return; // Nothing to show. } + // Remove previous popup if we change something. if (gui.tooltip_popup) { memdelete(gui.tooltip_popup); gui.tooltip_popup = nullptr; gui.tooltip_label = nullptr; } - if (!which) { + if (!tooltip_owner) { return; } - Control *rp = which; - - Control *base_tooltip = which->make_custom_tooltip(tooltip); + // Controls can implement `make_custom_tooltip` to provide their own tooltip. + // This should be a Control node which will be added as child to a TooltipPanel. + Control *base_tooltip = tooltip_owner->make_custom_tooltip(tooltip_text); + // If no custom tooltip is given, use a default implementation. if (!base_tooltip) { gui.tooltip_label = memnew(TooltipLabel); - gui.tooltip_label->set_text(tooltip); + gui.tooltip_label->set_text(tooltip_text); base_tooltip = gui.tooltip_label; } @@ -1545,10 +1570,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_popup = panel; - rp->add_child(gui.tooltip_popup); - - //if (gui.tooltip) // Avoids crash when rapidly switching controls. - // gui.tooltip_popup->set_scale(gui.tooltip->get_global_transform().get_scale()); + tooltip_owner->add_child(gui.tooltip_popup); Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset"); Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size()); @@ -1794,6 +1816,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (mb.is_valid()) { gui.key_event_accepted = false; + Control *over = nullptr; + Point2 mpos = mb->get_position(); if (mb->is_pressed()) { Size2 pos = mpos; @@ -1897,8 +1921,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } _gui_cancel_tooltip(); - //gui.tooltip_popup->hide(); - } else { if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) { if (gui.drag_mouse_over) { @@ -1948,6 +1970,31 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.drag_data=Variant(); //always clear }*/ + // In case the mouse was released after for example dragging a scrollbar, + // check whether the current control is different from the stored one. If + // it is different, rather than wait for it to be updated the next time the + // mouse is moved, notify the control so that it can e.g. drop the highlight. + // This code is duplicated from the mm.is_valid()-case further below. + if (gui.mouse_focus) { + over = gui.mouse_focus; + } else { + over = _gui_find_control(mpos); + } + + if (gui.mouse_focus_mask == 0 && over != gui.mouse_over) { + if (gui.mouse_over) { + _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); + } + + _gui_cancel_tooltip(); + + if (over) { + _gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER); + } + } + + gui.mouse_over = over; + set_input_as_handled(); } } @@ -2008,10 +2055,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } + // These sections of code are reused in the mb.is_valid() case further up + // for the purpose of notifying controls about potential changes in focus + // when the mousebutton is released. if (gui.mouse_focus) { over = gui.mouse_focus; - //recompute focus_inv_xform again here - } else { over = _gui_find_control(mpos); } @@ -2052,8 +2100,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { bool is_tooltip_shown = false; if (gui.tooltip_popup) { - if (can_tooltip && gui.tooltip) { - String tooltip = _gui_get_tooltip(over, gui.tooltip->get_global_transform().xform_inv(mpos)); + if (can_tooltip && gui.tooltip_control) { + String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform().xform_inv(mpos)); if (tooltip.length() == 0) { _gui_cancel_tooltip(); @@ -2078,14 +2126,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } if (can_tooltip && !is_tooltip_shown) { - gui.tooltip = over; - gui.tooltip_pos = over->get_screen_transform().xform(pos); //(parent_xform * get_transform()).affine_inverse().xform(pos); + gui.tooltip_control = over; + gui.tooltip_pos = over->get_screen_transform().xform(pos); gui.tooltip_timer = gui.tooltip_delay; } } - //pos = gui.focus_inv_xform.xform(pos); - mm->set_position(pos); Control::CursorShape cursor_shape = Control::CURSOR_ARROW; @@ -2436,7 +2482,7 @@ void Viewport::_gui_hide_control(Control *p_control) { if (gui.drag_mouse_over == p_control) { gui.drag_mouse_over = nullptr; } - if (gui.tooltip == p_control) { + if (gui.tooltip_control == p_control) { _gui_cancel_tooltip(); } } @@ -2459,8 +2505,8 @@ void Viewport::_gui_remove_control(Control *p_control) { if (gui.drag_mouse_over == p_control) { gui.drag_mouse_over = nullptr; } - if (gui.tooltip == p_control) { - gui.tooltip = nullptr; + if (gui.tooltip_control == p_control) { + gui.tooltip_control = nullptr; } } @@ -3579,14 +3625,13 @@ Viewport::Viewport() { disable_input = false; - //window tooltip + // Window tooltip. gui.tooltip_timer = -1; - //gui.tooltip_timer->force_parent_owned(); gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers - gui.tooltip = nullptr; + gui.tooltip_control = nullptr; gui.tooltip_label = nullptr; gui.drag_preview = nullptr; gui.drag_attempted = false; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index b6efd7aa4c..8e7f2cecdc 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -323,7 +323,7 @@ private: Control *mouse_over; Control *drag_mouse_over; Vector2 drag_mouse_over_pos; - Control *tooltip; + Control *tooltip_control; Window *tooltip_popup; Label *tooltip_label; Point2 tooltip_pos; @@ -382,7 +382,7 @@ private: void _gui_remove_root_control(List<Control *>::Element *RI); - String _gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which = nullptr); + String _gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_tooltip_owner = nullptr); void _gui_cancel_tooltip(); void _gui_show_tooltip(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index f1dcc8e8a5..7997dc12e1 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -30,9 +30,9 @@ #include "register_scene_types.h" -#include "core/class_db.h" +#include "core/config/project_settings.h" +#include "core/object/class_db.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/2d/animated_sprite_2d.h" #include "scene/2d/area_2d.h" #include "scene/2d/audio_stream_player_2d.h" @@ -628,7 +628,9 @@ void register_scene_types() { ClassDB::register_class<Polygon2D>(); ClassDB::register_class<Skeleton2D>(); ClassDB::register_class<Bone2D>(); - ClassDB::register_class<Light2D>(); + ClassDB::register_virtual_class<Light2D>(); + ClassDB::register_class<PointLight2D>(); + ClassDB::register_class<DirectionalLight2D>(); ClassDB::register_class<LightOccluder2D>(); ClassDB::register_class<OccluderPolygon2D>(); ClassDB::register_class<YSort>(); @@ -917,6 +919,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("World", "World3D"); ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); + ClassDB::add_compatibility_class("Light2D", "PointLight2D"); #endif diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 722a400fd6..c52431f5f6 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -31,7 +31,7 @@ #ifndef ANIMATION_H #define ANIMATION_H -#include "core/resource.h" +#include "core/io/resource.h" class Animation : public Resource { GDCLASS(Animation, Resource); diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index 59f3b4dc3c..56ff72c094 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -31,9 +31,9 @@ #ifndef BIT_MAP_H #define BIT_MAP_H -#include "core/image.h" +#include "core/io/image.h" +#include "core/io/resource.h" #include "core/io/resource_loader.h" -#include "core/resource.h" class BitMap : public Resource { GDCLASS(BitMap, Resource); diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h index 99fd4eb37c..9a26f3d0b2 100644 --- a/scene/resources/camera_effects.h +++ b/scene/resources/camera_effects.h @@ -31,8 +31,8 @@ #ifndef CAMERA_EFFECTS_H #define CAMERA_EFFECTS_H -#include "core/resource.h" -#include "core/rid.h" +#include "core/io/resource.h" +#include "core/templates/rid.h" class CameraEffects : public Resource { GDCLASS(CameraEffects, Resource); diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 57ddaf897d..6c5f4b7057 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -31,7 +31,7 @@ #ifndef CURVE_H #define CURVE_H -#include "core/resource.h" +#include "core/io/resource.h" // y(x) curve class Curve : public Resource { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index a881e21da8..73ba42f8a7 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -37,7 +37,7 @@ #include "core/io/resource_loader.h" #include "core/os/mutex.h" #include "core/os/thread_safe.h" -#include "core/pair.h" +#include "core/templates/pair.h" #include "scene/resources/font.h" #include <ft2build.h> diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index f4edab07b5..bacdb6be54 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -30,7 +30,7 @@ #include "environment.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "servers/rendering_server.h" #include "texture.h" diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 9b7247b58d..23c7f5180c 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -31,7 +31,7 @@ #ifndef ENVIRONMENT_H #define ENVIRONMENT_H -#include "core/resource.h" +#include "core/io/resource.h" #include "scene/resources/sky.h" #include "scene/resources/texture.h" #include "servers/rendering_server.h" diff --git a/scene/resources/font.h b/scene/resources/font.h index c739520da3..d8c350bb41 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -31,8 +31,8 @@ #ifndef FONT_H #define FONT_H -#include "core/map.h" -#include "core/resource.h" +#include "core/io/resource.h" +#include "core/templates/map.h" #include "scene/resources/texture.h" class Font : public Resource { diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h index 6518b13ee8..e839909770 100644 --- a/scene/resources/gradient.h +++ b/scene/resources/gradient.h @@ -31,7 +31,7 @@ #ifndef GRADIENT_H #define GRADIENT_H -#include "core/resource.h" +#include "core/io/resource.h" class Gradient : public Resource { GDCLASS(Gradient, Resource); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 1e95a35726..35c967ce27 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -30,7 +30,7 @@ #include "material.h" -#include "core/engine.h" +#include "core/config/engine.h" #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" @@ -324,7 +324,6 @@ void BaseMaterial3D::init_shaders() { shader_names->rim_texture_channel = "rim_texture_channel"; shader_names->heightmap_texture_channel = "heightmap_texture_channel"; shader_names->refraction_texture_channel = "refraction_texture_channel"; - shader_names->alpha_scissor_threshold = "alpha_scissor_threshold"; shader_names->transmittance_color = "transmittance_color"; shader_names->transmittance_curve = "transmittance_curve"; @@ -349,6 +348,12 @@ void BaseMaterial3D::init_shaders() { shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo"; shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal"; shader_names->texture_names[TEXTURE_ORM] = "texture_orm"; + + shader_names->alpha_scissor_threshold = "alpha_scissor_threshold"; + shader_names->alpha_hash_scale = "alpha_hash_scale"; + + shader_names->alpha_antialiasing_edge = "alpha_antialiasing_edge"; + shader_names->albedo_texture_size = "albedo_texture_size"; } Ref<StandardMaterial3D> BaseMaterial3D::materials_for_2d[BaseMaterial3D::MAX_MATERIALS_FOR_2D]; @@ -435,6 +440,8 @@ void BaseMaterial3D::_update_shader() { case BLEND_MODE_MUL: code += "blend_mul"; break; + case BLEND_MODE_MAX: + break; // Internal value, skip. } DepthDrawMode ddm = depth_draw_mode; @@ -452,10 +459,8 @@ void BaseMaterial3D::_update_shader() { case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break; - } - - if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) { - code += ",depth_prepass_alpha"; + case DEPTH_DRAW_MAX: + break; // Internal value, skip. } switch (cull_mode) { @@ -468,6 +473,8 @@ void BaseMaterial3D::_update_shader() { case CULL_DISABLED: code += ",cull_disabled"; break; + case CULL_MAX: + break; // Internal value, skip. } switch (diffuse_mode) { case DIFFUSE_BURLEY: @@ -485,6 +492,8 @@ void BaseMaterial3D::_update_shader() { case DIFFUSE_TOON: code += ",diffuse_toon"; break; + case DIFFUSE_MAX: + break; // Internal value, skip. } switch (specular_mode) { case SPECULAR_SCHLICK_GGX: @@ -502,6 +511,8 @@ void BaseMaterial3D::_update_shader() { case SPECULAR_DISABLED: code += ",specular_disabled"; break; + case SPECULAR_MAX: + break; // Internal value, skip. } if (features[FEATURE_SUBSURFACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) { code += ",sss_mode_skin"; @@ -525,6 +536,23 @@ void BaseMaterial3D::_update_shader() { if (flags[FLAG_USE_SHADOW_TO_OPACITY]) { code += ",shadow_to_opacity"; } + + if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) { + code += ",depth_prepass_alpha"; + } + + // Although its technically possible to do alpha antialiasing without using alpha hash or alpha scissor, + // it is restricted in the base material because it has no use, and abusing it with regular Alpha blending can + // saturate the MSAA mask + if (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR) { + // alpha antialiasing is only useful in ALPHA_HASH or ALPHA_SCISSOR + if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) { + code += ",alpha_to_coverage"; + } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) { + code += ",alpha_to_coverage_and_one"; + } + } + code += ";\n"; code += "uniform vec4 albedo : hint_color;\n"; @@ -541,8 +569,18 @@ void BaseMaterial3D::_update_shader() { code += "uniform float distance_fade_max;\n"; } + // alpha scissor is only valid if there is not antialiasing edge + // alpha hash is valid whenever, but not with alpha scissor if (transparency == TRANSPARENCY_ALPHA_SCISSOR) { code += "uniform float alpha_scissor_threshold;\n"; + } else if (transparency == TRANSPARENCY_ALPHA_HASH) { + code += "uniform float alpha_hash_scale;\n"; + } + // if alpha antialiasing isn't off, add in the edge variable + if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF && + (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH)) { + code += "uniform float alpha_antialiasing_edge;\n"; + code += "uniform ivec2 albedo_texture_size;\n"; } code += "uniform float point_size : hint_range(0,128);\n"; @@ -568,6 +606,8 @@ void BaseMaterial3D::_update_shader() { case TEXTURE_CHANNEL_GRAYSCALE: { code += "uniform sampler2D texture_roughness : hint_roughness_gray," + texfilter_str + ";\n"; } break; + case TEXTURE_CHANNEL_MAX: + break; // Internal value, skip. } code += "uniform float specular;\n"; @@ -731,6 +771,8 @@ void BaseMaterial3D::_update_shader() { code += "\tUV /= vec2(h_frames, v_frames);\n"; code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; } break; + case BILLBOARD_MAX: + break; // Internal value, skip. } if (flags[FLAG_FIXED_SIZE]) { @@ -903,6 +945,8 @@ void BaseMaterial3D::_update_shader() { case TEXTURE_CHANNEL_GRAYSCALE: { code += "\tvec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n"; } break; + case TEXTURE_CHANNEL_MAX: + break; // Internal value, skip. } if (flags[FLAG_UV1_USE_TRIPLANAR]) { @@ -970,10 +1014,17 @@ void BaseMaterial3D::_update_shader() { code += "\tALBEDO *= 1.0 - ref_amount;\n"; code += "\tALPHA = 1.0;\n"; - } else if (transparency == TRANSPARENCY_ALPHA || transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) { + } else if (transparency != TRANSPARENCY_DISABLED || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) { code += "\tALPHA = albedo.a * albedo_tex.a;\n"; + } + if (transparency == TRANSPARENCY_ALPHA_HASH) { + code += "\tALPHA_HASH_SCALE = alpha_hash_scale;\n"; } else if (transparency == TRANSPARENCY_ALPHA_SCISSOR) { - code += "\tif (albedo.a * albedo_tex.a < alpha_scissor_threshold) discard;\n"; + code += "\tALPHA_SCISSOR_THRESHOLD = alpha_scissor_threshold;\n"; + } + if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF && (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR)) { + code += "\tALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge;\n"; + code += "\tALPHA_TEXTURE_COORDINATE = UV * vec2(albedo_texture_size);\n"; } if (proximity_fade_enabled) { @@ -1143,6 +1194,8 @@ void BaseMaterial3D::_update_shader() { case BLEND_MODE_MUL: { code += "\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb*detail_tex.rgb,detail_tex.a);\n"; } break; + case BLEND_MODE_MAX: + break; // Internal value, skip. } code += "\tvec3 detail_norm = mix(NORMALMAP,detail_norm_tex.rgb,detail_tex.a);\n"; @@ -1424,6 +1477,20 @@ BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const { return transparency; } +void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) { + if (alpha_antialiasing_mode == p_alpha_aa) { + return; + } + + alpha_antialiasing_mode = p_alpha_aa; + _queue_shader_change(); + _change_notify(); +} + +BaseMaterial3D::AlphaAntiAliasing BaseMaterial3D::get_alpha_antialiasing() const { + return alpha_antialiasing_mode; +} + void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) { if (shading_mode == p_shading_mode) { return; @@ -1530,6 +1597,10 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t textures[p_param] = p_texture; RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); + if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) { + RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size, + Vector2i(p_texture->get_width(), p_texture->get_height())); + } _change_notify(); _queue_shader_change(); } @@ -1605,10 +1676,34 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { property.usage = 0; } + // you can only enable anti-aliasing (in mataerials) on alpha scissor and alpha hash + const bool can_select_aa = (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH); + // alpha anti aliasiasing is only enabled when you can select aa + const bool alpha_aa_enabled = (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) && can_select_aa; + + // alpha scissor slider isn't needed when alpha antialiasing is enabled if (property.name == "alpha_scissor_threshold" && transparency != TRANSPARENCY_ALPHA_SCISSOR) { property.usage = 0; } + // alpha hash scale slider is only needed if transparency is alpha hash + if (property.name == "alpha_hash_scale" && transparency != TRANSPARENCY_ALPHA_HASH) { + property.usage = 0; + } + + if (property.name == "alpha_antialiasing_mode" && !can_select_aa) { + property.usage = 0; + } + + // we cant choose an antialiasing mode if alpha isnt possible + if (property.name == "alpha_antialiasing_edge" && !alpha_aa_enabled) { + property.usage = 0; + } + + if (property.name == "blend_mode" && alpha_aa_enabled) { + property.usage = 0; + } + if ((property.name == "heightmap_min_layers" || property.name == "heightmap_max_layers") && !deep_parallax) { property.usage = 0; } @@ -1845,6 +1940,24 @@ float BaseMaterial3D::get_alpha_scissor_threshold() const { return alpha_scissor_threshold; } +void BaseMaterial3D::set_alpha_hash_scale(float p_scale) { + alpha_hash_scale = p_scale; + RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_hash_scale, p_scale); +} + +float BaseMaterial3D::get_alpha_hash_scale() const { + return alpha_hash_scale; +} + +void BaseMaterial3D::set_alpha_antialiasing_edge(float p_edge) { + alpha_antialiasing_edge = p_edge; + RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_antialiasing_edge, p_edge); +} + +float BaseMaterial3D::get_alpha_antialiasing_edge() const { + return alpha_antialiasing_edge; +} + void BaseMaterial3D::set_grow(float p_grow) { grow = p_grow; RS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow); @@ -2033,6 +2146,12 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &BaseMaterial3D::set_transparency); ClassDB::bind_method(D_METHOD("get_transparency"), &BaseMaterial3D::get_transparency); + ClassDB::bind_method(D_METHOD("set_alpha_antialiasing", "alpha_aa"), &BaseMaterial3D::set_alpha_antialiasing); + ClassDB::bind_method(D_METHOD("get_alpha_antialiasing"), &BaseMaterial3D::get_alpha_antialiasing); + + ClassDB::bind_method(D_METHOD("set_alpha_antialiasing_edge", "edge"), &BaseMaterial3D::set_alpha_antialiasing_edge); + ClassDB::bind_method(D_METHOD("get_alpha_antialiasing_edge"), &BaseMaterial3D::get_alpha_antialiasing_edge); + ClassDB::bind_method(D_METHOD("set_shading_mode", "shading_mode"), &BaseMaterial3D::set_shading_mode); ClassDB::bind_method(D_METHOD("get_shading_mode"), &BaseMaterial3D::get_shading_mode); @@ -2186,6 +2305,9 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &BaseMaterial3D::set_alpha_scissor_threshold); ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &BaseMaterial3D::get_alpha_scissor_threshold); + ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &BaseMaterial3D::set_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &BaseMaterial3D::get_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &BaseMaterial3D::set_grow_enabled); ClassDB::bind_method(D_METHOD("is_grow_enabled"), &BaseMaterial3D::is_grow_enabled); @@ -2217,8 +2339,11 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance); ADD_GROUP("Transparency", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,AlphaScissor,DepthPrePass"), "set_transparency", "get_transparency"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth PrePass"), "set_transparency", "get_transparency"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge"); ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode"); @@ -2414,6 +2539,7 @@ void BaseMaterial3D::_bind_methods() { BIND_ENUM_CONSTANT(TRANSPARENCY_DISABLED); BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA); BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_SCISSOR); + BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_HASH); BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); BIND_ENUM_CONSTANT(TRANSPARENCY_MAX); @@ -2441,6 +2567,10 @@ void BaseMaterial3D::_bind_methods() { BIND_ENUM_CONSTANT(BLEND_MODE_SUB); BIND_ENUM_CONSTANT(BLEND_MODE_MUL); + BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_OFF); + BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE); + BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE); + BIND_ENUM_CONSTANT(DEPTH_DRAW_OPAQUE_ONLY); BIND_ENUM_CONSTANT(DEPTH_DRAW_ALWAYS); BIND_ENUM_CONSTANT(DEPTH_DRAW_DISABLED); @@ -2506,8 +2636,9 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : element(this) { orm = p_orm; // Initialize to the same values as the shader - transparency = TRANSPARENCY_DISABLED; shading_mode = SHADING_MODE_PER_PIXEL; + transparency = TRANSPARENCY_DISABLED; + alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; set_albedo(Color(1.0, 1.0, 1.0, 1.0)); set_specular(0.5); set_roughness(1.0); @@ -2539,9 +2670,14 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_particles_anim_h_frames(1); set_particles_anim_v_frames(1); set_particles_anim_loop(false); - set_alpha_scissor_threshold(0.98); emission_op = EMISSION_OP_ADD; + set_transparency(TRANSPARENCY_DISABLED); + set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF); + set_alpha_scissor_threshold(0.05); + set_alpha_hash_scale(1.0); + set_alpha_antialiasing_edge(0.3); + proximity_fade_enabled = false; distance_fade = DISTANCE_FADE_DISABLED; set_proximity_fade_distance(1); @@ -2582,10 +2718,8 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : features[i] = false; } - current_key.key0 = 0; - current_key.key1 = 0; - current_key.invalid_key = 1; texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; + _queue_shader_change(); } @@ -2633,6 +2767,12 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) set_transparency(TRANSPARENCY_ALPHA_SCISSOR); } return true; + } else if (p_name == "params_use_alpha_hash") { + bool use_hash = p_value; + if (use_hash) { + set_transparency(TRANSPARENCY_ALPHA_HASH); + } + return true; } else if (p_name == "params_depth_draw_mode") { int mode = p_value; if (mode == 3) { @@ -2667,6 +2807,8 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) { "params_grow", "grow" }, { "params_grow_amount", "grow_amount" }, { "params_alpha_scissor_threshold", "alpha_scissor_threshold" }, + { "params_alpha_hash_scale", "alpha_hash_scale" }, + { "params_alpha_antialiasing_edge", "alpha_antialiasing_edge" }, { "depth_scale", "heightmap_scale" }, { "depth_deep_parallax", "heightmap_deep_parallax" }, diff --git a/scene/resources/material.h b/scene/resources/material.h index b5bdd77eb5..caf28eea18 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -31,8 +31,8 @@ #ifndef MATERIAL_H #define MATERIAL_H -#include "core/resource.h" -#include "core/self_list.h" +#include "core/io/resource.h" +#include "core/templates/self_list.h" #include "scene/resources/shader.h" #include "scene/resources/texture.h" #include "servers/rendering/shader_language.h" @@ -145,17 +145,26 @@ public: enum DetailUV { DETAIL_UV_1, - DETAIL_UV_2 + DETAIL_UV_2, + DETAIL_UV_MAX }; enum Transparency { TRANSPARENCY_DISABLED, TRANSPARENCY_ALPHA, TRANSPARENCY_ALPHA_SCISSOR, + TRANSPARENCY_ALPHA_HASH, TRANSPARENCY_ALPHA_DEPTH_PRE_PASS, TRANSPARENCY_MAX, }; + enum AlphaAntiAliasing { + ALPHA_ANTIALIASING_OFF, + ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE, + ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE, + ALPHA_ANTIALIASING_MAX + }; + enum ShadingMode { SHADING_MODE_UNSHADED, SHADING_MODE_PER_PIXEL, @@ -184,18 +193,21 @@ public: BLEND_MODE_ADD, BLEND_MODE_SUB, BLEND_MODE_MUL, + BLEND_MODE_MAX }; enum DepthDrawMode { DEPTH_DRAW_OPAQUE_ONLY, DEPTH_DRAW_ALWAYS, DEPTH_DRAW_DISABLED, + DEPTH_DRAW_MAX }; enum CullMode { CULL_BACK, CULL_FRONT, - CULL_DISABLED + CULL_DISABLED, + CULL_MAX }; enum Flags { @@ -227,6 +239,7 @@ public: DIFFUSE_LAMBERT_WRAP, DIFFUSE_OREN_NAYAR, DIFFUSE_TOON, + DIFFUSE_MAX }; enum SpecularMode { @@ -235,6 +248,7 @@ public: SPECULAR_PHONG, SPECULAR_TOON, SPECULAR_DISABLED, + SPECULAR_MAX }; enum BillboardMode { @@ -242,6 +256,7 @@ public: BILLBOARD_ENABLED, BILLBOARD_FIXED_Y, BILLBOARD_PARTICLES, + BILLBOARD_MAX }; enum TextureChannel { @@ -249,12 +264,14 @@ public: TEXTURE_CHANNEL_GREEN, TEXTURE_CHANNEL_BLUE, TEXTURE_CHANNEL_ALPHA, - TEXTURE_CHANNEL_GRAYSCALE + TEXTURE_CHANNEL_GRAYSCALE, + TEXTURE_CHANNEL_MAX }; enum EmissionOperator { EMISSION_OP_ADD, - EMISSION_OP_MULTIPLY + EMISSION_OP_MULTIPLY, + EMISSION_OP_MAX }; enum DistanceFadeMode { @@ -262,43 +279,47 @@ public: DISTANCE_FADE_PIXEL_ALPHA, DISTANCE_FADE_PIXEL_DITHER, DISTANCE_FADE_OBJECT_DITHER, + DISTANCE_FADE_MAX }; private: - union MaterialKey { - struct { - uint64_t feature_mask : FEATURE_MAX; - uint64_t detail_uv : 1; - uint64_t blend_mode : 2; - uint64_t depth_draw_mode : 2; - uint64_t cull_mode : 2; - uint64_t flags : FLAG_MAX; - uint64_t detail_blend_mode : 2; - uint64_t diffuse_mode : 3; - uint64_t specular_mode : 3; - uint64_t invalid_key : 1; - uint64_t deep_parallax : 1; - uint64_t billboard_mode : 2; - uint64_t grow : 1; - uint64_t proximity_fade : 1; - uint64_t distance_fade : 2; - uint64_t emission_op : 1; - uint64_t texture_filter : 3; - uint64_t transparency : 2; - uint64_t shading_mode : 2; - uint64_t roughness_channel : 3; - }; - - struct { - uint64_t key0; - uint64_t key1; - }; + struct MaterialKey { + // enum values + uint64_t texture_filter : get_num_bits(TEXTURE_FILTER_MAX - 1); + uint64_t detail_uv : get_num_bits(DETAIL_UV_MAX - 1); + uint64_t transparency : get_num_bits(TRANSPARENCY_MAX - 1); + uint64_t alpha_antialiasing_mode : get_num_bits(ALPHA_ANTIALIASING_MAX - 1); + uint64_t shading_mode : get_num_bits(SHADING_MODE_MAX - 1); + uint64_t blend_mode : get_num_bits(BLEND_MODE_MAX - 1); + uint64_t depth_draw_mode : get_num_bits(DEPTH_DRAW_MAX - 1); + uint64_t cull_mode : get_num_bits(CULL_MAX - 1); + uint64_t diffuse_mode : get_num_bits(DIFFUSE_MAX - 1); + uint64_t specular_mode : get_num_bits(SPECULAR_MAX - 1); + uint64_t billboard_mode : get_num_bits(BILLBOARD_MAX - 1); + uint64_t detail_blend_mode : get_num_bits(BLEND_MODE_MAX - 1); + uint64_t roughness_channel : get_num_bits(TEXTURE_CHANNEL_MAX - 1); + uint64_t emission_op : get_num_bits(EMISSION_OP_MAX - 1); + uint64_t distance_fade : get_num_bits(DISTANCE_FADE_MAX - 1); + + // flag bitfield + uint64_t feature_mask : FEATURE_MAX - 1; + uint64_t flags : FLAG_MAX - 1; + + // booleans + uint64_t deep_parallax : 1; + uint64_t grow : 1; + uint64_t proximity_fade : 1; + + MaterialKey() { + memset(this, 0, sizeof(MaterialKey)); + } bool operator==(const MaterialKey &p_key) const { - return (key0 == p_key.key0) && (key1 == p_key.key1); + return memcmp(this, &p_key, sizeof(MaterialKey)) == 0; } + bool operator<(const MaterialKey &p_key) const { - return (key0 == p_key.key0) ? (key1 < p_key.key1) : (key0 < p_key.key0); + return memcmp(this, &p_key, sizeof(MaterialKey)) < 0; } }; @@ -313,13 +334,7 @@ private: _FORCE_INLINE_ MaterialKey _compute_key() const { MaterialKey mk; - mk.key0 = 0; - mk.key1 = 0; - for (int i = 0; i < FEATURE_MAX; i++) { - if (features[i]) { - mk.feature_mask |= ((uint64_t)1 << i); - } - } + mk.detail_uv = detail_uv; mk.blend_mode = blend_mode; mk.depth_draw_mode = depth_draw_mode; @@ -328,20 +343,28 @@ private: mk.transparency = transparency; mk.shading_mode = shading_mode; mk.roughness_channel = roughness_texture_channel; - for (int i = 0; i < FLAG_MAX; i++) { - if (flags[i]) { - mk.flags |= ((uint64_t)1 << i); - } - } mk.detail_blend_mode = detail_blend_mode; mk.diffuse_mode = diffuse_mode; mk.specular_mode = specular_mode; mk.billboard_mode = billboard_mode; - mk.deep_parallax = deep_parallax ? 1 : 0; + mk.deep_parallax = deep_parallax; mk.grow = grow_enabled; mk.proximity_fade = proximity_fade_enabled; mk.distance_fade = distance_fade; mk.emission_op = emission_op; + mk.alpha_antialiasing_mode = alpha_antialiasing_mode; + + for (int i = 0; i < FEATURE_MAX; i++) { + if (features[i]) { + mk.feature_mask |= ((uint64_t)1 << i); + } + } + + for (int i = 0; i < FLAG_MAX; i++) { + if (flags[i]) { + mk.flags |= ((uint64_t)1 << i); + } + } return mk; } @@ -392,9 +415,14 @@ private: StringName rim_texture_channel; StringName heightmap_texture_channel; StringName refraction_texture_channel; - StringName alpha_scissor_threshold; StringName texture_names[TEXTURE_MAX]; + + StringName alpha_scissor_threshold; + StringName alpha_hash_scale; + + StringName alpha_antialiasing_edge; + StringName albedo_texture_size; }; static Mutex material_mutex; @@ -433,6 +461,8 @@ private: float refraction; float point_size; float alpha_scissor_threshold; + float alpha_hash_scale; + float alpha_antialiasing_edge; bool grow_enabled; float ao_light_affect; float grow; @@ -482,6 +512,8 @@ private: TextureChannel ao_texture_channel; TextureChannel refraction_texture_channel; + AlphaAntiAliasing alpha_antialiasing_mode; + bool features[FEATURE_MAX]; Ref<Texture2D> textures[TEXTURE_MAX]; @@ -584,6 +616,12 @@ public: void set_transparency(Transparency p_transparency); Transparency get_transparency() const; + void set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa); + AlphaAntiAliasing get_alpha_antialiasing() const; + + void set_alpha_antialiasing_edge(float p_edge); + float get_alpha_antialiasing_edge() const; + void set_shading_mode(ShadingMode p_shading_mode); ShadingMode get_shading_mode() const; @@ -660,6 +698,9 @@ public: void set_alpha_scissor_threshold(float p_threshold); float get_alpha_scissor_threshold() const; + void set_alpha_hash_scale(float p_scale); + float get_alpha_hash_scale() const; + void set_on_top_of_alpha(); void set_proximity_fade(bool p_enable); @@ -707,6 +748,7 @@ VARIANT_ENUM_CAST(BaseMaterial3D::TextureParam) VARIANT_ENUM_CAST(BaseMaterial3D::TextureFilter) VARIANT_ENUM_CAST(BaseMaterial3D::ShadingMode) VARIANT_ENUM_CAST(BaseMaterial3D::Transparency) +VARIANT_ENUM_CAST(BaseMaterial3D::AlphaAntiAliasing) VARIANT_ENUM_CAST(BaseMaterial3D::DetailUV) VARIANT_ENUM_CAST(BaseMaterial3D::Feature) VARIANT_ENUM_CAST(BaseMaterial3D::BlendMode) diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index e9606e03e6..060846d5b6 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -30,7 +30,7 @@ #include "mesh.h" -#include "core/pair.h" +#include "core/templates/pair.h" #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" #include "surface_tool.h" diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b0a30a5627..81c18eea2d 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -31,9 +31,9 @@ #ifndef MESH_H #define MESH_H +#include "core/io/resource.h" #include "core/math/face3.h" #include "core/math/triangle_mesh.h" -#include "core/resource.h" #include "scene/resources/material.h" #include "scene/resources/shape_3d.h" #include "servers/rendering_server.h" diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 450e2c16e3..0d5fb3005b 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -31,8 +31,8 @@ #ifndef MESH_LIBRARY_H #define MESH_LIBRARY_H -#include "core/map.h" -#include "core/resource.h" +#include "core/io/resource.h" +#include "core/templates/map.h" #include "mesh.h" #include "scene/3d/navigation_region_3d.h" #include "shape_3d.h" diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 5e8bfd9387..5ce253f970 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -30,10 +30,10 @@ #include "packed_scene.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "core/core_string_names.h" -#include "core/engine.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "scene/2d/node_2d.h" #include "scene/3d/node_3d.h" #include "scene/gui/control.h" diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 004758afa5..b8b3f84ecc 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -31,7 +31,7 @@ #ifndef PACKED_SCENE_H #define PACKED_SCENE_H -#include "core/resource.h" +#include "core/io/resource.h" #include "scene/main/node.h" class SceneState : public Reference { diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 7aca708889..12fa53ef29 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/resources/material.h" #ifndef PARTICLES_MATERIAL_H diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h index 34aa7066df..e9222ffa1b 100644 --- a/scene/resources/physics_material.h +++ b/scene/resources/physics_material.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_MATERIAL_H #define PHYSICS_MATERIAL_H -#include "core/resource.h" +#include "core/io/resource.h" #include "servers/physics_server_3d.h" class PhysicsMaterial : public Resource { diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h index baee4dc20d..44a97b4294 100644 --- a/scene/resources/polygon_path_finder.h +++ b/scene/resources/polygon_path_finder.h @@ -31,7 +31,7 @@ #ifndef POLYGON_PATH_FINDER_H #define POLYGON_PATH_FINDER_H -#include "core/resource.h" +#include "core/io/resource.h" class PolygonPathFinder : public Resource { GDCLASS(PolygonPathFinder, Resource); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index ba39593690..1d5f29ab14 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -30,9 +30,9 @@ #include "resource_format_text.h" +#include "core/config/project_settings.h" #include "core/io/resource_format_binary.h" #include "core/os/dir_access.h" -#include "core/project_settings.h" #include "core/version.h" //version 2: changed names for basis, aabb, Vectors, etc. diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index cf522c9364..ca7b0b021f 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -34,7 +34,7 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/file_access.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" #include "scene/resources/packed_scene.h" class ResourceLoaderText { diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 92f0353abf..76d37eaa71 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "shader.h" + #include "core/os/file_access.h" #include "scene/scene_string_names.h" #include "servers/rendering/shader_language.h" @@ -80,7 +81,7 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const { params_cache[pi.name] = E->get().name; if (p_params) { //small little hack - if (pi.type == Variant::_RID) { + if (pi.type == Variant::RID) { pi.type = Variant::OBJECT; } p_params->push_back(pi); diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 7dcec7811a..f2ea582ff0 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -31,9 +31,9 @@ #ifndef SHADER_H #define SHADER_H +#include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/resource.h" #include "scene/resources/texture.h" class Shader : public Resource { diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index bb4688a02d..495ffdd38b 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -31,7 +31,7 @@ #ifndef SHAPE_2D_H #define SHAPE_2D_H -#include "core/resource.h" +#include "core/io/resource.h" class Shape2D : public Resource { GDCLASS(Shape2D, Resource); diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h index eb9607e3a6..5a9c2e3b9c 100644 --- a/scene/resources/shape_3d.h +++ b/scene/resources/shape_3d.h @@ -31,7 +31,7 @@ #ifndef SHAPE_3D_H #define SHAPE_3D_H -#include "core/resource.h" +#include "core/io/resource.h" class ArrayMesh; diff --git a/scene/resources/skin.h b/scene/resources/skin.h index 57aaf1afd4..e6ed4f1768 100644 --- a/scene/resources/skin.h +++ b/scene/resources/skin.h @@ -31,7 +31,7 @@ #ifndef SKIN_H #define SKIN_H -#include "core/resource.h" +#include "core/io/resource.h" class Skin : public Resource { GDCLASS(Skin, Resource) diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 5e23020d66..5411994b7d 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/rid.h" +#include "core/templates/rid.h" #include "scene/resources/material.h" #ifndef SKY_MATERIAL_H diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index c5caab1b5a..a1237776c6 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -31,7 +31,7 @@ #ifndef STYLE_BOX_H #define STYLE_BOX_H -#include "core/resource.h" +#include "core/io/resource.h" #include "scene/resources/texture.h" #include "servers/rendering_server.h" diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index e7b49892d8..e3e4373fa9 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -30,7 +30,7 @@ #include "syntax_highlighter.h" -#include "core/script_language.h" +#include "core/object/script_language.h" #include "scene/gui/text_edit.h" Dictionary SyntaxHighlighter::get_line_syntax_highlighting(int p_line) { diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index 720227a256..62865920d3 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -31,7 +31,7 @@ #ifndef SYNTAX_HIGHLIGHTER_H #define SYNTAX_HIGHLIGHTER_H -#include "core/resource.h" +#include "core/io/resource.h" class TextEdit; diff --git a/scene/resources/texture.h b/scene/resources/texture.h index fd48afccda..3bc1ca8463 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -31,13 +31,13 @@ #ifndef TEXTURE_H #define TEXTURE_H +#include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/math/rect2.h" #include "core/os/file_access.h" #include "core/os/mutex.h" #include "core/os/rw_lock.h" #include "core/os/thread_safe.h" -#include "core/resource.h" #include "scene/resources/curve.h" #include "scene/resources/gradient.h" #include "servers/camera_server.h" diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 6a85d357ff..a05abbb4c0 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -30,7 +30,7 @@ #include "theme.h" #include "core/os/file_access.h" -#include "core/print_string.h" +#include "core/string/print_string.h" void Theme::_emit_theme_changed() { emit_changed(); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 3c72ddd8a2..5f46ce6303 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -31,8 +31,8 @@ #ifndef THEME_H #define THEME_H +#include "core/io/resource.h" #include "core/io/resource_loader.h" -#include "core/resource.h" #include "scene/resources/font.h" #include "scene/resources/shader.h" #include "scene/resources/style_box.h" diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index dcd8f11400..4581763e9c 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -30,9 +30,9 @@ #include "tile_set.h" -#include "core/array.h" -#include "core/engine.h" +#include "core/config/engine.h" #include "core/math/geometry_2d.h" +#include "core/variant/array.h" bool TileSet::_set(const StringName &p_name, const Variant &p_value) { String n = p_name; diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index aab428aa21..79f1b4aa95 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -31,8 +31,8 @@ #ifndef TILE_SET_H #define TILE_SET_H -#include "core/array.h" -#include "core/resource.h" +#include "core/io/resource.h" +#include "core/variant/array.h" #include "scene/2d/light_occluder_2d.h" #include "scene/2d/navigation_region_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index ac68b6a079..141d4b09f5 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -30,7 +30,7 @@ #include "visual_shader.h" -#include "core/vmap.h" +#include "core/templates/vmap.h" #include "servers/rendering/shader_types.h" #include "visual_shader_nodes.h" diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index e3d8dae032..41c4642ee3 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -31,7 +31,7 @@ #ifndef VISUAL_SHADER_H #define VISUAL_SHADER_H -#include "core/string_builder.h" +#include "core/string/string_builder.h" #include "scene/gui/control.h" #include "scene/resources/shader.h" diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index d2bc2bea31..41d3fe20be 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -30,7 +30,7 @@ #include "world_2d.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "scene/2d/camera_2d.h" #include "scene/2d/visibility_notifier_2d.h" #include "scene/main/window.h" @@ -341,8 +341,8 @@ void World2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state); - ADD_PROPERTY(PropertyInfo(Variant::_RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas"); - ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", 0), "", "get_direct_space_state"); } diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index c330719104..11614f9aa4 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -31,8 +31,8 @@ #ifndef WORLD_2D_H #define WORLD_2D_H -#include "core/project_settings.h" -#include "core/resource.h" +#include "core/config/project_settings.h" +#include "core/io/resource.h" #include "servers/physics_server_2d.h" class VisibilityNotifier2D; diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp index 8100f150ef..b8fb3825ce 100644 --- a/scene/resources/world_3d.cpp +++ b/scene/resources/world_3d.cpp @@ -321,8 +321,8 @@ void World3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects"); - ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); - ADD_PROPERTY(PropertyInfo(Variant::_RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState3D", 0), "", "get_direct_space_state"); } diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h index 02a821637f..93e9c72e59 100644 --- a/scene/resources/world_3d.h +++ b/scene/resources/world_3d.h @@ -31,7 +31,7 @@ #ifndef WORLD_3D_H #define WORLD_3D_H -#include "core/resource.h" +#include "core/io/resource.h" #include "scene/resources/camera_effects.h" #include "scene/resources/environment.h" #include "servers/physics_server_3d.h" diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 1ae244492e..b1168c84b9 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -31,8 +31,8 @@ #ifndef SCENE_STRING_NAMES_H #define SCENE_STRING_NAMES_H -#include "core/node_path.h" -#include "core/string_name.h" +#include "core/string/node_path.h" +#include "core/string/string_name.h" class SceneStringNames { friend void register_scene_types(); diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index ff0d2cad65..a2abbeb686 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -30,8 +30,8 @@ #include "audio_driver_dummy.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" Error AudioDriverDummy::init() { active = false; diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h index 76cb8a209c..b1be5dfea1 100644 --- a/servers/audio/audio_effect.h +++ b/servers/audio/audio_effect.h @@ -31,8 +31,8 @@ #ifndef AUDIOEFFECT_H #define AUDIOEFFECT_H +#include "core/io/resource.h" #include "core/math/audio_frame.h" -#include "core/resource.h" class AudioEffectInstance : public Reference { GDCLASS(AudioEffectInstance, Reference); diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 2cc2f5c291..a7c9443dcf 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -30,8 +30,8 @@ #include "audio_stream.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" ////////////////////////////// diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 9720196cc2..0bbb29b15c 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -31,8 +31,8 @@ #ifndef AUDIO_STREAM_H #define AUDIO_STREAM_H -#include "core/image.h" -#include "core/resource.h" +#include "core/io/image.h" +#include "core/io/resource.h" #include "servers/audio/audio_filter_sw.h" #include "servers/audio_server.h" diff --git a/servers/audio/effects/audio_stream_generator.h b/servers/audio/effects/audio_stream_generator.h index c90983a66f..49bda0fcf9 100644 --- a/servers/audio/effects/audio_stream_generator.h +++ b/servers/audio/effects/audio_stream_generator.h @@ -31,7 +31,7 @@ #ifndef AUDIO_STREAM_GENERATOR_H #define AUDIO_STREAM_GENERATOR_H -#include "core/ring_buffer.h" +#include "core/templates/ring_buffer.h" #include "servers/audio/audio_stream.h" class AudioStreamGenerator : public AudioStream { diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp index 08a6cf55fa..15abeea5f3 100644 --- a/servers/audio/effects/eq.cpp +++ b/servers/audio/effects/eq.cpp @@ -31,7 +31,7 @@ // Author: reduzio@gmail.com (C) 2006 #include "eq.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #include "core/math/math_funcs.h" #include <math.h> diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h index 391a7aa24b..720c4dfcaf 100644 --- a/servers/audio/effects/eq.h +++ b/servers/audio/effects/eq.h @@ -33,8 +33,8 @@ #ifndef EQ_FILTER_H #define EQ_FILTER_H +#include "core/templates/vector.h" #include "core/typedefs.h" -#include "core/vector.h" /** @author Juan Linietsky diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 6b70f41e57..bea5e9e432 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -30,11 +30,11 @@ #include "audio_server.h" +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/io/resource_loader.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "scene/resources/audio_stream_sample.h" #include "servers/audio/audio_driver_dummy.h" #include "servers/audio/effects/audio_effect_compressor.h" @@ -905,6 +905,8 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const { } void AudioServer::set_global_rate_scale(float p_scale) { + ERR_FAIL_COND(p_scale <= 0); + global_rate_scale = p_scale; } diff --git a/servers/audio_server.h b/servers/audio_server.h index 31537e8326..507aea7b89 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -31,10 +31,10 @@ #ifndef AUDIO_SERVER_H #define AUDIO_SERVER_H -#include "core/class_db.h" #include "core/math/audio_frame.h" +#include "core/object/class_db.h" #include "core/os/os.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "servers/audio/audio_effect.h" class AudioDriverDummy; diff --git a/servers/camera/camera_feed.h b/servers/camera/camera_feed.h index 52a737cd8d..dca583c9de 100644 --- a/servers/camera/camera_feed.h +++ b/servers/camera/camera_feed.h @@ -31,7 +31,7 @@ #ifndef CAMERA_FEED_H #define CAMERA_FEED_H -#include "core/image.h" +#include "core/io/image.h" #include "core/math/transform_2d.h" #include "servers/camera_server.h" #include "servers/rendering_server.h" diff --git a/servers/camera_server.h b/servers/camera_server.h index 7723e30974..54acce006a 100644 --- a/servers/camera_server.h +++ b/servers/camera_server.h @@ -31,11 +31,11 @@ #ifndef CAMERA_SERVER_H #define CAMERA_SERVER_H -#include "core/class_db.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" #include "core/os/thread_safe.h" -#include "core/reference.h" -#include "core/rid.h" -#include "core/variant.h" +#include "core/templates/rid.h" +#include "core/variant/variant.h" /** @author Bastiaan Olij <mux213@gmail.com> diff --git a/servers/display_server.h b/servers/display_server.h index 3ee0da709b..c2ffb23531 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -31,10 +31,10 @@ #ifndef DISPLAY_SERVER_H #define DISPLAY_SERVER_H -#include "core/callable.h" #include "core/input/input.h" +#include "core/io/resource.h" #include "core/os/os.h" -#include "core/resource.h" +#include "core/variant/callable.h" class Texture2D; diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 6575426e73..895e41558a 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -35,8 +35,8 @@ #ifndef NAVIGATION_2D_SERVER_H #define NAVIGATION_2D_SERVER_H -#include "core/class_db.h" -#include "core/rid.h" +#include "core/object/class_db.h" +#include "core/templates/rid.h" #include "scene/2d/navigation_region_2d.h" // This server exposes the `NavigationServer3D` features in the 2D world. diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 7a3e4f5f8f..e6421462b0 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -35,8 +35,8 @@ #ifndef NAVIGATION_SERVER_H #define NAVIGATION_SERVER_H -#include "core/class_db.h" -#include "core/rid.h" +#include "core/object/class_db.h" +#include "core/templates/rid.h" #include "scene/3d/navigation_region_3d.h" /// This server uses the concept of internal mutability. diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h index f14466f582..d6b358a657 100644 --- a/servers/physics_2d/area_2d_sw.h +++ b/servers/physics_2d/area_2d_sw.h @@ -32,7 +32,7 @@ #define AREA_2D_SW_H #include "collision_object_2d_sw.h" -#include "core/self_list.h" +#include "core/templates/self_list.h" #include "servers/physics_server_2d.h" //#include "servers/physics_3d/query_sw.h" diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index 4a3ef718ec..bbc22a67df 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -33,7 +33,7 @@ #include "area_2d_sw.h" #include "collision_object_2d_sw.h" -#include "core/vset.h" +#include "core/templates/vset.h" class Constraint2DSW; diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_basic.h index ec5cfdbf1d..97e1c900b9 100644 --- a/servers/physics_2d/broad_phase_2d_basic.h +++ b/servers/physics_2d/broad_phase_2d_basic.h @@ -31,7 +31,7 @@ #ifndef BROAD_PHASE_2D_BASIC_H #define BROAD_PHASE_2D_BASIC_H -#include "core/map.h" +#include "core/templates/map.h" #include "space_2d_sw.h" class BroadPhase2DBasic : public BroadPhase2DSW { struct Element { diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp index ec74507e03..c8b3d193c9 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp +++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp @@ -30,7 +30,7 @@ #include "broad_phase_2d_hash_grid.h" #include "collision_object_2d_sw.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #define LARGE_ELEMENT_FI 1.01239812 diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h index de1ada0932..54994992c9 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.h +++ b/servers/physics_2d/broad_phase_2d_hash_grid.h @@ -32,7 +32,7 @@ #define BROAD_PHASE_2D_HASH_GRID_H #include "broad_phase_2d_sw.h" -#include "core/map.h" +#include "core/templates/map.h" class BroadPhase2DHashGrid : public BroadPhase2DSW { struct PairData { diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 8caa53680d..36b7073a5c 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -32,7 +32,7 @@ #define COLLISION_OBJECT_2D_SW_H #include "broad_phase_2d_sw.h" -#include "core/self_list.h" +#include "core/templates/self_list.h" #include "servers/physics_server_2d.h" #include "shape_2d_sw.h" diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 1b396190e9..9d00d01759 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -33,9 +33,9 @@ #include "broad_phase_2d_basic.h" #include "broad_phase_2d_hash_grid.h" #include "collision_solver_2d_sw.h" +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/os/os.h" -#include "core/project_settings.h" #define FLUSH_QUERY_CHECK(m_object) \ ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index e88db28056..9bd9655e2c 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_2D_SERVER_SW #define PHYSICS_2D_SERVER_SW -#include "core/rid_owner.h" +#include "core/templates/rid_owner.h" #include "joints_2d_sw.h" #include "servers/physics_server_2d.h" #include "shape_2d_sw.h" diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index 586dbe9e12..1269cadd33 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -31,9 +31,9 @@ #ifndef PHYSICS2DSERVERWRAPMT_H #define PHYSICS2DSERVERWRAPMT_H -#include "core/command_queue_mt.h" +#include "core/config/project_settings.h" #include "core/os/thread.h" -#include "core/project_settings.h" +#include "core/templates/command_queue_mt.h" #include "servers/physics_server_2d.h" #ifdef DEBUG_SYNC diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 87e22ef1c9..afb1112fc0 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -31,7 +31,7 @@ #include "shape_2d_sw.h" #include "core/math/geometry_2d.h" -#include "core/sort_array.h" +#include "core/templates/sort_array.h" void Shape2DSW::configure(const Rect2 &p_aabb) { aabb = p_aabb; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 966dcbd651..a8ab731ead 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -32,7 +32,7 @@ #include "collision_solver_2d_sw.h" #include "core/os/os.h" -#include "core/pair.h" +#include "core/templates/pair.h" #include "physics_server_2d_sw.h" _FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (!(p_object->get_collision_layer() & p_collision_mask)) { diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index 1eee83dfe9..5c5144ae22 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -37,8 +37,8 @@ #include "body_pair_2d_sw.h" #include "broad_phase_2d_sw.h" #include "collision_object_2d_sw.h" -#include "core/hash_map.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/templates/hash_map.h" #include "core/typedefs.h" class PhysicsDirectSpaceState2DSW : public PhysicsDirectSpaceState2D { diff --git a/servers/physics_3d/area_3d_sw.h b/servers/physics_3d/area_3d_sw.h index 6af3976167..a2efe6af51 100644 --- a/servers/physics_3d/area_3d_sw.h +++ b/servers/physics_3d/area_3d_sw.h @@ -32,7 +32,7 @@ #define AREA_SW_H #include "collision_object_3d_sw.h" -#include "core/self_list.h" +#include "core/templates/self_list.h" #include "servers/physics_server_3d.h" //#include "servers/physics_3d/query_sw.h" diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h index b642729404..6dbda8670a 100644 --- a/servers/physics_3d/body_3d_sw.h +++ b/servers/physics_3d/body_3d_sw.h @@ -33,7 +33,7 @@ #include "area_3d_sw.h" #include "collision_object_3d_sw.h" -#include "core/vset.h" +#include "core/templates/vset.h" class Constraint3DSW; diff --git a/servers/physics_3d/broad_phase_3d_basic.cpp b/servers/physics_3d/broad_phase_3d_basic.cpp index f5ea1897a9..15a5968087 100644 --- a/servers/physics_3d/broad_phase_3d_basic.cpp +++ b/servers/physics_3d/broad_phase_3d_basic.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "broad_phase_3d_basic.h" -#include "core/list.h" -#include "core/print_string.h" +#include "core/string/print_string.h" +#include "core/templates/list.h" BroadPhase3DSW::ID BroadPhase3DBasic::create(CollisionObject3DSW *p_object, int p_subindex) { ERR_FAIL_COND_V(p_object == nullptr, 0); diff --git a/servers/physics_3d/broad_phase_3d_basic.h b/servers/physics_3d/broad_phase_3d_basic.h index 4b644bf818..361d322e14 100644 --- a/servers/physics_3d/broad_phase_3d_basic.h +++ b/servers/physics_3d/broad_phase_3d_basic.h @@ -32,7 +32,7 @@ #define BROAD_PHASE_BASIC_H #include "broad_phase_3d_sw.h" -#include "core/map.h" +#include "core/templates/map.h" class BroadPhase3DBasic : public BroadPhase3DSW { struct Element { diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/collision_object_3d_sw.h index a3a5787ced..e1220f8855 100644 --- a/servers/physics_3d/collision_object_3d_sw.h +++ b/servers/physics_3d/collision_object_3d_sw.h @@ -32,7 +32,7 @@ #define COLLISION_OBJECT_SW_H #include "broad_phase_3d_sw.h" -#include "core/self_list.h" +#include "core/templates/self_list.h" #include "servers/physics_server_3d.h" #include "shape_3d_sw.h" diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index d9c86312cc..a45ee7c2c8 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_SERVER_SW #define PHYSICS_SERVER_SW -#include "core/rid_owner.h" +#include "core/templates/rid_owner.h" #include "joints_3d_sw.h" #include "servers/physics_server_3d.h" #include "shape_3d_sw.h" diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index ca33241d29..b8b01de3c3 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -32,7 +32,7 @@ #include "core/math/geometry_3d.h" #include "core/math/quick_hull.h" -#include "core/sort_array.h" +#include "core/templates/sort_array.h" #define _POINT_SNAP 0.001953125 #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002 diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index 48f250ba35..d9170cd986 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -31,7 +31,7 @@ #include "space_3d_sw.h" #include "collision_solver_3d_sw.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "physics_server_3d_sw.h" _FORCE_INLINE_ static bool _can_collide_with(CollisionObject3DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { diff --git a/servers/physics_3d/space_3d_sw.h b/servers/physics_3d/space_3d_sw.h index 4aba80c8f3..6380bcc6dc 100644 --- a/servers/physics_3d/space_3d_sw.h +++ b/servers/physics_3d/space_3d_sw.h @@ -37,8 +37,8 @@ #include "body_pair_3d_sw.h" #include "broad_phase_3d_sw.h" #include "collision_object_3d_sw.h" -#include "core/hash_map.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/templates/hash_map.h" #include "core/typedefs.h" class PhysicsDirectSpaceState3DSW : public PhysicsDirectSpaceState3D { diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 4338a6938a..1ea8985543 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -30,8 +30,8 @@ #include "physics_server_2d.h" -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/string/print_string.h" PhysicsServer2D *PhysicsServer2D::singleton = nullptr; @@ -245,11 +245,11 @@ void PhysicsShapeQueryParameters2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); - ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled"); @@ -504,7 +504,7 @@ void PhysicsTestMotionResult2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collision_normal"), "", "get_collision_normal"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id", PROPERTY_HINT_OBJECT_ID), "", "get_collider_id"); - ADD_PROPERTY(PropertyInfo(Variant::_RID, "collider_rid"), "", "get_collider_rid"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "collider_rid"), "", "get_collider_rid"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape"), "", "get_collider_shape"); } diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 40773e4ced..283a2ab58c 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -31,9 +31,9 @@ #ifndef PHYSICS_2D_SERVER_H #define PHYSICS_2D_SERVER_H -#include "core/class_db.h" -#include "core/reference.h" -#include "core/resource.h" +#include "core/io/resource.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" class PhysicsDirectSpaceState2D; diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index d0266f95b5..fabd661970 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -30,8 +30,8 @@ #include "physics_server_3d.h" -#include "core/print_string.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" +#include "core/string/print_string.h" PhysicsServer3D *PhysicsServer3D::singleton = nullptr; @@ -238,10 +238,10 @@ void PhysicsShapeQueryParameters3D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape"); - ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled"); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index d79dc6fec0..90ef2bb8dd 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -31,8 +31,8 @@ #ifndef PHYSICS_SERVER_H #define PHYSICS_SERVER_H -#include "core/class_db.h" -#include "core/resource.h" +#include "core/io/resource.h" +#include "core/object/class_db.h" class PhysicsDirectSpaceState3D; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index adca7b8055..34980aaf66 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -30,8 +30,8 @@ #include "register_server_types.h" -#include "core/engine.h" -#include "core/project_settings.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "audio/audio_effect.h" #include "audio/audio_stream.h" diff --git a/servers/rendering/rasterizer.cpp b/servers/rendering/rasterizer.cpp index 566a14b655..32084c8a3e 100644 --- a/servers/rendering/rasterizer.cpp +++ b/servers/rendering/rasterizer.cpp @@ -31,7 +31,7 @@ #include "rasterizer.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" Rasterizer *(*Rasterizer::_create_func)() = nullptr; diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index b2b2b4977b..efaa8f138a 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -32,8 +32,8 @@ #define RASTERIZER_H #include "core/math/camera_matrix.h" -#include "core/pair.h" -#include "core/self_list.h" +#include "core/templates/pair.h" +#include "core/templates/self_list.h" #include "servers/rendering_server.h" class RasterizerScene { @@ -832,7 +832,9 @@ public: int layer_max; int item_mask; int item_shadow_mask; + float directional_distance; RS::CanvasLightMode mode; + RS::CanvasLightBlendMode blend_mode; RID texture; Vector2 texture_offset; RID canvas; @@ -854,7 +856,7 @@ public: Light *shadows_next_ptr; Light *filter_next_ptr; Light *next_ptr; - Light *mask_next_ptr; + Light *directional_next_ptr; RID light_internal; uint64_t version; @@ -875,16 +877,18 @@ public: scale = 1.0; energy = 1.0; item_shadow_mask = 1; - mode = RS::CANVAS_LIGHT_MODE_ADD; + mode = RS::CANVAS_LIGHT_MODE_POINT; + blend_mode = RS::CANVAS_LIGHT_BLEND_MODE_ADD; // texture_cache = nullptr; next_ptr = nullptr; - mask_next_ptr = nullptr; + directional_next_ptr = nullptr; filter_next_ptr = nullptr; use_shadow = false; shadow_buffer_size = 2048; shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE; shadow_smooth = 0.0; render_index_cache = -1; + directional_distance = 10000.0; } }; @@ -1322,7 +1326,7 @@ public: } }; - virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) = 0; + virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) = 0; virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; struct LightOccluderInstance { @@ -1350,6 +1354,7 @@ public: virtual void light_set_texture(RID p_rid, RID p_texture) = 0; virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0; virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0; + virtual void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) = 0; virtual RID occluder_polygon_create() = 0; virtual void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index da30291353..5d9e68f2b4 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "rasterizer_canvas_rd.h" +#include "core/config/project_settings.h" #include "core/math/math_funcs.h" -#include "core/project_settings.h" #include "rasterizer_rd.h" void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) { @@ -328,7 +328,7 @@ void RasterizerCanvasRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_ bool use_normal; bool use_specular; - bool success = storage->canvas_texture_get_unifom_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular); + bool success = storage->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular); //something odd happened if (!success) { _bind_canvas_texture(p_draw_list, default_canvas_texture, p_base_filter, p_base_repeat, r_last_texture, push_constant, r_texpixel_size); @@ -416,10 +416,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ light_count++; - if (light->mode == RS::CANVAS_LIGHT_MODE_MASK) { - base_flags |= FLAGS_USING_LIGHT_MASK; - } - if (light_count == MAX_LIGHTS_PER_ITEM) { break; } @@ -430,7 +426,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ base_flags |= light_count << FLAGS_LIGHT_COUNT_SHIFT; } - light_mode = light_count > 0 ? PIPELINE_LIGHT_MODE_ENABLED : PIPELINE_LIGHT_MODE_DISABLED; + light_mode = (light_count > 0 || using_directional_lights) ? PIPELINE_LIGHT_MODE_ENABLED : PIPELINE_LIGHT_MODE_DISABLED; PipelineVariants *pipeline_variants = p_pipeline_variants; @@ -1194,51 +1190,83 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, RD::get_singleton()->draw_list_end(); } -void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { +void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { int item_count = 0; //setup canvas state uniforms if needed Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse(); + //setup directional lights if exist + + uint32_t light_count = 0; + uint32_t directional_light_count = 0; { - //update canvas state uniform buffer - State::Buffer state_buffer; + Light *l = p_directional_light_list; + uint32_t index = 0; - Size2i ssize = storage->render_target_get_size(p_to_render_target); + while (l) { + if (index == state.max_lights_per_render) { + l->render_index_cache = -1; + l = l->next_ptr; + continue; + } - Transform screen_transform; - screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); - screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); - _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); - _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); + CanvasLight *clight = canvas_light_owner.getornull(l->light_internal); + if (!clight) { //unused or invalid texture + l->render_index_cache = -1; + l = l->next_ptr; + ERR_CONTINUE(!clight); + } - Transform2D normal_transform = p_canvas_transform; - normal_transform.elements[0].normalize(); - normal_transform.elements[1].normalize(); - normal_transform.elements[2] = Vector2(); - _update_transform_2d_to_mat4(normal_transform, state_buffer.canvas_normal_transform); + Vector2 canvas_light_dir = l->xform_cache.elements[1].normalized(); - state_buffer.canvas_modulate[0] = p_modulate.r; - state_buffer.canvas_modulate[1] = p_modulate.g; - state_buffer.canvas_modulate[2] = p_modulate.b; - state_buffer.canvas_modulate[3] = p_modulate.a; + state.light_uniforms[index].position[0] = -canvas_light_dir.x; + state.light_uniforms[index].position[1] = -canvas_light_dir.y; - Size2 render_target_size = storage->render_target_get_size(p_to_render_target); - state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; - state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; + _update_transform_2d_to_mat2x4(clight->shadow.directional_xform, state.light_uniforms[index].shadow_matrix); - state_buffer.time = state.time; - state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; + state.light_uniforms[index].height = l->height; //0..1 here - RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true); + for (int i = 0; i < 4; i++) { + state.light_uniforms[index].shadow_color[i] = uint8_t(CLAMP(int32_t(l->shadow_color[i] * 255.0), 0, 255)); + state.light_uniforms[index].color[i] = l->color[i]; + } + + state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate + + if (state.shadow_fb.is_valid()) { + state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth); + state.light_uniforms[index].shadow_z_far_inv = 1.0 / clight->shadow.z_far; + state.light_uniforms[index].shadow_y_ofs = clight->shadow.y_offset; + } else { + state.light_uniforms[index].shadow_pixel_size = 1.0; + state.light_uniforms[index].shadow_z_far_inv = 1.0; + state.light_uniforms[index].shadow_y_ofs = 0; + } + + state.light_uniforms[index].flags = l->blend_mode << LIGHT_FLAGS_BLEND_SHIFT; + state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT; + if (clight->shadow.enabled) { + state.light_uniforms[index].flags |= LIGHT_FLAGS_HAS_SHADOW; + } + + l->render_index_cache = index; + + index++; + l = l->next_ptr; + } + + light_count = index; + directional_light_count = light_count; + using_directional_lights = directional_light_count > 0; } //setup lights if exist { Light *l = p_light_list; - uint32_t index = 0; + uint32_t index = light_count; while (l) { if (index == state.max_lights_per_render) { @@ -1280,7 +1308,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite state.light_uniforms[index].shadow_y_ofs = 0; } - state.light_uniforms[index].flags |= l->mode << LIGHT_FLAGS_BLEND_SHIFT; + state.light_uniforms[index].flags = l->blend_mode << LIGHT_FLAGS_BLEND_SHIFT; state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT; if (clight->shadow.enabled) { state.light_uniforms[index].flags |= LIGHT_FLAGS_HAS_SHADOW; @@ -1306,9 +1334,46 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite l = l->next_ptr; } - if (index > 0) { - RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * index, &state.light_uniforms[0], true); - } + light_count = index; + } + + if (light_count > 0) { + RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * light_count, &state.light_uniforms[0], true); + } + + { + //update canvas state uniform buffer + State::Buffer state_buffer; + + Size2i ssize = storage->render_target_get_size(p_to_render_target); + + Transform screen_transform; + screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); + _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); + _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); + + Transform2D normal_transform = p_canvas_transform; + normal_transform.elements[0].normalize(); + normal_transform.elements[1].normalize(); + normal_transform.elements[2] = Vector2(); + _update_transform_2d_to_mat4(normal_transform, state_buffer.canvas_normal_transform); + + state_buffer.canvas_modulate[0] = p_modulate.r; + state_buffer.canvas_modulate[1] = p_modulate.g; + state_buffer.canvas_modulate[2] = p_modulate.b; + state_buffer.canvas_modulate[3] = p_modulate.a; + + Size2 render_target_size = storage->render_target_get_size(p_to_render_target); + state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; + state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; + + state_buffer.time = state.time; + state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; + + state_buffer.directional_light_count = directional_light_count; + + RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true); } { //default filter/repeat @@ -1439,10 +1504,7 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable) { cl->shadow.enabled = p_enable; } -void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); - ERR_FAIL_COND(!cl->shadow.enabled); - +void RasterizerCanvasRD::_update_shadow_atlas() { if (state.shadow_fb == RID()) { //ah, we lack the shadow texture.. RD::get_singleton()->free(state.shadow_texture); //erase placeholder @@ -1474,6 +1536,12 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, cons state.shadow_fb = RD::get_singleton()->framebuffer_create(fb_textures); } +} +void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { + CanvasLight *cl = canvas_light_owner.getornull(p_rid); + ERR_FAIL_COND(!cl->shadow.enabled); + + _update_shadow_atlas(); cl->shadow.z_far = p_far; cl->shadow.y_offset = float(p_shadow_index * 2 + 1) / float(state.max_lights_per_render * 2); @@ -1547,6 +1615,86 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, cons } } +void RasterizerCanvasRD::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) { + CanvasLight *cl = canvas_light_owner.getornull(p_rid); + ERR_FAIL_COND(!cl->shadow.enabled); + + _update_shadow_atlas(); + + Vector2 light_dir = p_light_xform.elements[1].normalized(); + + Vector2 center = p_clip_rect.position + p_clip_rect.size * 0.5; + + float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(light_dir)) - light_dir.dot(center)); + + Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance); + float distance = to_edge_distance * 2.0 + p_cull_distance; + float half_size = p_clip_rect.size.length() * 0.5; //shadow length, must keep this no matter the angle + + cl->shadow.z_far = distance; + cl->shadow.y_offset = float(p_shadow_index * 2 + 1) / float(state.max_lights_per_render * 2); + + Transform2D to_light_xform; + + to_light_xform[2] = from_pos; + to_light_xform[1] = light_dir; + to_light_xform[0] = -light_dir.tangent(); + + to_light_xform.invert(); + + Vector<Color> cc; + cc.push_back(Color(1, 1, 1, 1)); + + Rect2i rect(0, p_shadow_index * 2, state.shadow_texture_size, 2); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); + + CameraMatrix projection; + projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance); + projection = projection * CameraMatrix(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); + + ShadowRenderPushConstant push_constant; + for (int y = 0; y < 4; y++) { + for (int x = 0; x < 4; x++) { + push_constant.projection[y * 4 + x] = projection.matrix[y][x]; + } + } + + push_constant.direction[0] = 0.0; + push_constant.direction[1] = 1.0; + push_constant.z_far = distance; + push_constant.pad = 0; + + LightOccluderInstance *instance = p_occluders; + + while (instance) { + OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder); + + if (!co || co->index_array.is_null() || !(p_light_mask & instance->light_mask)) { + instance = instance->next; + continue; + } + + _update_transform_2d_to_mat2x4(to_light_xform * instance->xform_cache, push_constant.modelview); + + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, shadow_render.render_pipelines[co->cull_mode]); + RD::get_singleton()->draw_list_bind_vertex_array(draw_list, co->vertex_array); + RD::get_singleton()->draw_list_bind_index_array(draw_list, co->index_array); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ShadowRenderPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + + instance = instance->next; + } + + RD::get_singleton()->draw_list_end(); + + Transform2D to_shadow; + to_shadow.elements[0].x = 1.0 / -(half_size * 2.0); + to_shadow.elements[2].x = 0.5; + + cl->shadow.directional_xform = to_shadow * to_light_xform; +} + RID RasterizerCanvasRD::occluder_polygon_create() { OccluderPolygon occluder; occluder.point_count = 0; @@ -2419,6 +2567,4 @@ RasterizerCanvasRD::~RasterizerCanvasRD() { storage->free(default_canvas_texture); //pipelines don't need freeing, they are all gone after shaders are gone - - RD::get_singleton()->free(state.default_transforms_uniform_set); } diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h index 3412435367..b516f63cbf 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h @@ -75,7 +75,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { FLAGS_CLIP_RECT_UV = (1 << 9), FLAGS_TRANSPOSE_RECT = (1 << 10), - FLAGS_USING_LIGHT_MASK = (1 << 11), FLAGS_NINEPACH_DRAW_CENTER = (1 << 12), FLAGS_USING_PARTICLES = (1 << 13), @@ -269,6 +268,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { bool enabled = false; float z_far; float y_offset; + Transform2D directional_xform; } shadow; }; @@ -331,12 +331,13 @@ class RasterizerCanvasRD : public RasterizerCanvas { float screen_transform[16]; float canvas_normal_transform[16]; float canvas_modulate[4]; + float screen_pixel_size[2]; float time; uint32_t use_pixel_snap; - //uint32_t light_count; - //uint32_t pad[3]; + uint32_t directional_light_count; + uint32_t pad[3]; }; LightUniform *light_uniforms; @@ -355,6 +356,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { uint32_t max_lights_per_item; double time; + } state; struct PushConstant { @@ -388,6 +390,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { Item *items[MAX_RENDER_ITEMS]; + bool using_directional_lights = false; RID default_canvas_texture; RID default_canvas_group_shader; @@ -408,6 +411,8 @@ class RasterizerCanvasRD : public RasterizerCanvas { _FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4); _FORCE_INLINE_ void _update_transform_to_mat4(const Transform &p_transform, float *p_mat4); + void _update_shadow_atlas(); + public: PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()); void free_polygon(PolygonID p_polygon); @@ -416,12 +421,13 @@ public: void light_set_texture(RID p_rid, RID p_texture); void light_set_use_shadow(RID p_rid, bool p_enable); void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders); + void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders); RID occluder_polygon_create(); void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines); void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode); - void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); + void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {} diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp index d669db1b4b..97c1e7ba70 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp @@ -30,8 +30,8 @@ #include "rasterizer_effects_rd.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "thirdparty/misc/cubemap_coeffs.h" diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp index 509bd3ee73..5f8cf0ee8c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp @@ -30,7 +30,7 @@ #include "rasterizer_rd.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" void RasterizerRD::prepare_for_blitting_render_targets() { RD::get_singleton()->prepare_screen_for_drawing(); diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.h b/servers/rendering/rasterizer_rd/rasterizer_rd.h index cdcc6bfd73..59fb8d2049 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_rd.h @@ -32,7 +32,7 @@ #define RASTERIZER_RD_H #include "core/os/os.h" -#include "core/thread_work_pool.h" +#include "core/templates/thread_work_pool.h" #include "servers/rendering/rasterizer.h" #include "servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h" #include "servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h" diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index 35b0591289..a275e46473 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "rasterizer_scene_high_end_rd.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/rendering_server_raster.h" @@ -51,6 +51,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { int blend_mode = BLEND_MODE_MIX; int depth_testi = DEPTH_TEST_ENABLED; + int alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; int cull = CULL_BACK; uses_point_size = false; @@ -82,6 +83,9 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { actions.render_mode_values["blend_sub"] = Pair<int *, int>(&blend_mode, BLEND_MODE_SUB); actions.render_mode_values["blend_mul"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MUL); + actions.render_mode_values["alpha_to_coverage"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE); + actions.render_mode_values["alpha_to_coverage_and_one"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE); + actions.render_mode_values["depth_draw_never"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_DISABLED); actions.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_OPAQUE); actions.render_mode_values["depth_draw_always"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_ALWAYS); @@ -154,6 +158,11 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { //blend modes + // if any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage + if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) { + blend_mode = BLEND_MODE_ALPHA_TO_COVERAGE; + } + RD::PipelineColorBlendState::Attachment blend_attachment; switch (blend_mode) { @@ -199,6 +208,15 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO; uses_blend_alpha = true; //force alpha used because of blend } break; + case BLEND_MODE_ALPHA_TO_COVERAGE: { + blend_attachment.enable_blend = true; + blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD; + blend_attachment.color_blend_op = RD::BLEND_OP_ADD; + blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE; + blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO; + } } RD::PipelineColorBlendState blend_state_blend; @@ -245,8 +263,17 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { RD::PipelineColorBlendState blend_state; RD::PipelineDepthStencilState depth_stencil = depth_stencil_state; + RD::PipelineMultisampleState multisample_state; if (uses_alpha || uses_blend_alpha) { + // only allow these flags to go through if we have some form of msaa + if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) { + multisample_state.enable_alpha_to_coverage = true; + } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) { + multisample_state.enable_alpha_to_coverage = true; + multisample_state.enable_alpha_to_one = true; + } + if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) { blend_state = blend_state_blend; if (depth_draw == DEPTH_DRAW_OPAQUE) { @@ -286,7 +313,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } RID shader_variant = scene_singleton->shader.scene_shader.version_get_shader(version, k); - pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, RD::PipelineMultisampleState(), depth_stencil, blend_state, 0); + pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0); } } } @@ -2725,6 +2752,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.renames["POINT_SIZE"] = "gl_PointSize"; actions.renames["INSTANCE_ID"] = "gl_InstanceIndex"; + actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold"; + actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale"; + actions.renames["ALPHA_ANTIALIASING_EDGE"] = "alpha_antialiasing_edge"; + actions.renames["ALPHA_TEXTURE_COORDINATE"] = "alpha_texture_coordinate"; + //builtins actions.renames["TIME"] = "scene_data.time"; @@ -2793,6 +2825,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; + actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n"; + actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n"; + actions.usage_defines["ALPHA_ANTIALIASING_EDGE"] = "#define ALPHA_ANTIALIASING_EDGE_USED\n"; + actions.usage_defines["ALPHA_TEXTURE_COORDINATE"] = "@ALPHA_ANTIALIASING_EDGE"; + actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n"; actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n"; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h index 566022ae5b..db083a75cc 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h @@ -83,6 +83,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { BLEND_MODE_ADD, BLEND_MODE_SUB, BLEND_MODE_MUL, + BLEND_MODE_ALPHA_TO_COVERAGE }; enum DepthDraw { @@ -110,6 +111,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { }; + enum AlphaAntiAliasing { + ALPHA_ANTIALIASING_OFF, + ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE, + ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE + }; + bool valid; RID version; uint32_t vertex_input_mask; @@ -132,6 +139,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { bool uses_point_size; bool uses_alpha; bool uses_blend_alpha; + bool uses_alpha_clip; bool uses_depth_pre_pass; bool uses_discard; bool uses_roughness; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 0cae141138..e1be9b0ef4 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -30,8 +30,8 @@ #include "rasterizer_scene_rd.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "rasterizer_rd.h" #include "servers/rendering/rendering_server_raster.h" diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index 2ad712a9d3..3d5310bb7e 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -31,8 +31,8 @@ #ifndef RASTERIZER_SCENE_RD_H #define RASTERIZER_SCENE_RD_H -#include "core/local_vector.h" -#include "core/rid_owner.h" +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" #include "servers/rendering/rasterizer.h" #include "servers/rendering/rasterizer_rd/light_cluster_builder.h" #include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h" diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index 10c9293d67..8bd4362637 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -30,9 +30,9 @@ #include "rasterizer_storage_rd.h" -#include "core/engine.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "core/project_settings.h" #include "rasterizer_rd.h" #include "servers/rendering/shader_language.h" @@ -1265,7 +1265,7 @@ void RasterizerStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture ct->clear_sets(); } -bool RasterizerStorageRD::canvas_texture_get_unifom_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) { +bool RasterizerStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) { CanvasTexture *ct = nullptr; Texture *t = texture_owner.getornull(p_texture); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h index 321bff9fdd..05cb1b4a73 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h @@ -31,7 +31,7 @@ #ifndef RASTERIZER_STORAGE_RD_H #define RASTERIZER_STORAGE_RD_H -#include "core/rid_owner.h" +#include "core/templates/rid_owner.h" #include "servers/rendering/rasterizer.h" #include "servers/rendering/rasterizer_rd/rasterizer_effects_rd.h" #include "servers/rendering/rasterizer_rd/shader_compiler_rd.h" @@ -1185,7 +1185,7 @@ public: virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter); virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat); - bool canvas_texture_get_unifom_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular); + bool canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular); /* SHADER API */ diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h index cf15e79586..6a72dbc77c 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h +++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h @@ -31,7 +31,7 @@ #ifndef RENDER_PIPELINE_CACHE_RD_H #define RENDER_PIPELINE_CACHE_RD_H -#include "core/spin_lock.h" +#include "core/os/spin_lock.h" #include "servers/rendering/rendering_device.h" class RenderPipelineVertexFormatCacheRD { diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp index 0a0c343e57..1a33e9a567 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp @@ -30,8 +30,8 @@ #include "shader_compiler_rd.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "rasterizer_storage_rd.h" #include "servers/rendering_server.h" diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h index 565520ec65..694f8fff91 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h @@ -31,7 +31,7 @@ #ifndef SHADER_COMPILER_RD_H #define SHADER_COMPILER_RD_H -#include "core/pair.h" +#include "core/templates/pair.h" #include "servers/rendering/shader_language.h" #include "servers/rendering/shader_types.h" #include "servers/rendering_server.h" diff --git a/servers/rendering/rasterizer_rd/shader_rd.cpp b/servers/rendering/rasterizer_rd/shader_rd.cpp index 8c57651263..865a1e1bbe 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_rd.cpp @@ -30,7 +30,7 @@ #include "shader_rd.h" -#include "core/string_builder.h" +#include "core/string/string_builder.h" #include "rasterizer_rd.h" #include "servers/rendering/rendering_device.h" diff --git a/servers/rendering/rasterizer_rd/shader_rd.h b/servers/rendering/rasterizer_rd/shader_rd.h index d9bb068ba6..0c379db6f2 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.h +++ b/servers/rendering/rasterizer_rd/shader_rd.h @@ -31,11 +31,11 @@ #ifndef SHADER_RD_H #define SHADER_RD_H -#include "core/hash_map.h" -#include "core/map.h" #include "core/os/mutex.h" -#include "core/rid_owner.h" -#include "core/variant.h" +#include "core/templates/hash_map.h" +#include "core/templates/map.h" +#include "core/templates/rid_owner.h" +#include "core/variant/variant.h" #include <stdio.h> /** diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl index b382c0d85f..2a0f94e733 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl @@ -249,7 +249,7 @@ vec4 light_compute( inout vec4 shadow_modulate, vec2 screen_uv, vec2 uv, - vec4 color) { + vec4 color, bool is_directional) { vec4 light = vec4(0.0); /* clang-format off */ LIGHT_SHADER_CODE @@ -302,6 +302,99 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo #endif +#ifdef USE_LIGHTING + +vec3 light_normal_compute(vec3 light_vec, vec3 normal, vec3 base_color, vec3 light_color, vec4 specular_shininess, bool specular_shininess_used) { + float cNdotL = max(0.0, dot(normal, light_vec)); + + if (specular_shininess_used) { + //blinn + vec3 view = vec3(0.0, 0.0, 1.0); // not great but good enough + vec3 half_vec = normalize(view + light_vec); + + float cNdotV = max(dot(normal, view), 0.0); + float cNdotH = max(dot(normal, half_vec), 0.0); + float cVdotH = max(dot(view, half_vec), 0.0); + float cLdotH = max(dot(light_vec, half_vec), 0.0); + float shininess = exp2(15.0 * specular_shininess.a + 1.0) * 0.25; + float blinn = pow(cNdotH, shininess); + blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); + float s = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); + + return specular_shininess.rgb * light_color * s + light_color * base_color * cNdotL; + } else { + return light_color * base_color * cNdotL; + } +} + +//float distance = length(shadow_pos); +vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv +#ifdef LIGHT_SHADER_CODE_USED + , + vec3 shadow_modulate +#endif +) { + float shadow; + uint shadow_mode = light_array.data[light_base].flags & LIGHT_FLAGS_FILTER_MASK; + + if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) { + shadow = textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; + } else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) { + vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); + shadow = 0.0; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; + shadow /= 5.0; + } else { //PCF13 + vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); + shadow = 0.0; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 6.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 5.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 4.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 3.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 3.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 4.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 5.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 6.0, 0.0).x; + shadow /= 13.0; + } + + vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color); +#ifdef LIGHT_SHADER_CODE_USED + shadow_color *= shadow_modulate; +#endif + + shadow_color.a *= light_color.a; //respect light alpha + + return mix(light_color, shadow_color, shadow); +} + +void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) { + uint blend_mode = light_array.data[light_base].flags & LIGHT_FLAGS_BLEND_MASK; + + switch (blend_mode) { + case LIGHT_FLAGS_BLEND_MODE_ADD: { + color.rgb += light_color.rgb * light_color.a; + } break; + case LIGHT_FLAGS_BLEND_MODE_SUB: { + color.rgb -= light_color.rgb * light_color.a; + } break; + case LIGHT_FLAGS_BLEND_MODE_MIX: { + color.rgb = mix(color.rgb, light_color.rgb, light_color.a); + } break; + } +} + +#endif + void main() { vec4 color = color_interp; vec2 uv = uv_interp; @@ -332,6 +425,7 @@ void main() { color *= texture(sampler2D(color_texture, texture_sampler), uv); uint light_count = (draw_data.flags >> FLAGS_LIGHT_COUNT_SHIFT) & 0xF; //max 16 lights + bool using_light = light_count > 0 || canvas_data.directional_light_count > 0; vec3 normal; @@ -341,7 +435,7 @@ void main() { bool normal_used = false; #endif - if (normal_used || (light_count > 0 && bool(draw_data.flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { + if (normal_used || (using_light && bool(draw_data.flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { normal.xy = texture(sampler2D(normal_texture, texture_sampler), uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); normal_used = true; @@ -358,7 +452,7 @@ void main() { bool specular_shininess_used = false; #endif - if (specular_shininess_used || (light_count > 0 && normal_used && bool(draw_data.flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { + if (specular_shininess_used || (using_light && normal_used && bool(draw_data.flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { specular_shininess = texture(sampler2D(specular_texture, texture_sampler), uv); specular_shininess *= unpackUnorm4x8(draw_data.specular_shininess); specular_shininess_used = true; @@ -401,13 +495,52 @@ FRAGMENT_SHADER_CODE normal = normalize((canvas_data.canvas_normal_transform * vec4(normal, 0.0)).xyz); } - vec4 base_color = color; + vec3 base_color = color.rgb; if (bool(draw_data.flags & FLAGS_USING_LIGHT_MASK)) { color = vec4(0.0); //invisible by default due to using light mask } color *= canvas_data.canvas_modulation; #ifdef USE_LIGHTING + + // Directional Lights + + for (uint i = 0; i < canvas_data.directional_light_count; i++) { + uint light_base = i; + + vec2 direction = light_array.data[light_base].position; + vec4 light_color = light_array.data[light_base].color; + +#ifdef LIGHT_SHADER_CODE_USED + + vec4 shadow_modulate = vec4(1.0); + light_color = light_compute(light_vertex, direction, normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, true); +#else + + if (normal_used) { + vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_array.data[light_base].height)); + light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + } +#endif + + if (bool(light_array.data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { + vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_array.data[light_base].shadow_matrix[0], light_array.data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. + + vec4 shadow_uv = vec4(shadow_pos.x, light_array.data[light_base].shadow_y_ofs, shadow_pos.y * light_array.data[light_base].shadow_zfar_inv, 1.0); + + light_color = light_shadow_compute(light_base, light_color, shadow_uv +#ifdef LIGHT_SHADER_CODE_USED + , + shadow_modulate +#endif + ); + } + + light_blend_compute(light_base, light_color, color.rgb); + } + + // Positional Lights + for (uint i = 0; i < MAX_LIGHTS_PER_ITEM; i++) { if (i >= light_count) { break; @@ -440,7 +573,7 @@ FRAGMENT_SHADER_CODE vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height); light_color.rgb *= light_base_color.rgb; - light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv); + light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, false); #else light_color.rgb *= light_base_color.rgb * light_base_color.a; @@ -451,24 +584,7 @@ FRAGMENT_SHADER_CODE vec3 light_vec = normalize(light_pos - pos); float cNdotL = max(0.0, dot(normal, light_vec)); - if (specular_shininess_used) { - //blinn - vec3 view = vec3(0.0, 0.0, 1.0); // not great but good enough - vec3 half_vec = normalize(view + light_vec); - - float cNdotV = max(dot(normal, view), 0.0); - float cNdotH = max(dot(normal, half_vec), 0.0); - float cVdotH = max(dot(view, half_vec), 0.0); - float cLdotH = max(dot(light_vec, half_vec), 0.0); - float shininess = exp2(15.0 * specular_shininess.a + 1.0) * 0.25; - float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); - float s = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); - - light_color.rgb = specular_shininess.rgb * light_base_color.rgb * s + light_color.rgb * cNdotL; - } else { - light_color.rgb *= cNdotL; - } + light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); } #endif if (any(lessThan(tex_uv, vec2(0.0, 0.0))) || any(greaterThanEqual(tex_uv, vec2(1.0, 1.0)))) { @@ -506,69 +622,17 @@ FRAGMENT_SHADER_CODE distance *= light_array.data[light_base].shadow_zfar_inv; //float distance = length(shadow_pos); - float shadow; - uint shadow_mode = light_array.data[light_base].flags & LIGHT_FLAGS_FILTER_MASK; - vec4 shadow_uv = vec4(tex_ofs, light_array.data[light_base].shadow_y_ofs, distance, 1.0); - if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) { - shadow = textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; - } else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) { - vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); - shadow = 0.0; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; - shadow /= 5.0; - } else { //PCF13 - vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); - shadow = 0.0; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 6.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 5.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 4.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 3.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 3.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 4.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 5.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 6.0, 0.0).x; - shadow /= 13.0; - } - - vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color); + light_color = light_shadow_compute(light_base, light_color, shadow_uv #ifdef LIGHT_SHADER_CODE_USED - shadow_color *= shadow_modulate; + , + shadow_modulate #endif - - shadow_color.a *= light_color.a; //respect light alpha - - light_color = mix(light_color, shadow_color, shadow); - //light_color = mix(light_color, shadow_color, shadow); + ); } - uint blend_mode = light_array.data[light_base].flags & LIGHT_FLAGS_BLEND_MASK; - - switch (blend_mode) { - case LIGHT_FLAGS_BLEND_MODE_ADD: { - color.rgb += light_color.rgb * light_color.a; - } break; - case LIGHT_FLAGS_BLEND_MODE_SUB: { - color.rgb -= light_color.rgb * light_color.a; - } break; - case LIGHT_FLAGS_BLEND_MODE_MIX: { - color.rgb = mix(color.rgb, light_color.rgb, light_color.a); - } break; - case LIGHT_FLAGS_BLEND_MODE_MASK: { - light_color.a *= base_color.a; - color.rgb = mix(color.rgb, light_color.rgb, light_color.a); - } break; - } + light_blend_compute(light_base, light_color, color.rgb); } #endif diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl index 1a226a87d3..bb39584cbb 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl @@ -68,7 +68,10 @@ layout(set = 0, binding = 1, std140) uniform CanvasData { float time; bool use_pixel_snap; - //uint light_count; + uint directional_light_count; + uint pad0; + uint pad1; + uint pad2; } canvas_data; diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl index 455a3d4a3a..da3c60af04 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl @@ -361,6 +361,65 @@ layout(location = 0) out vec4 frag_color; #endif // RENDER DEPTH +#ifdef ALPHA_HASH_USED + +float hash_2d(vec2 p) { + return fract(1.0e4 * sin(17.0 * p.x + 0.1 * p.y) * + (0.1 + abs(sin(13.0 * p.y + p.x)))); +} + +float hash_3d(vec3 p) { + return hash_2d(vec2(hash_2d(p.xy), p.z)); +} + +float compute_alpha_hash_threshold(vec3 pos, float hash_scale) { + vec3 dx = dFdx(pos); + vec3 dy = dFdx(pos); + float delta_max_sqr = max(length(dx), length(dy)); + float pix_scale = 1.0 / (hash_scale * delta_max_sqr); + + vec2 pix_scales = + vec2(exp2(floor(log2(pix_scale))), exp2(ceil(log2(pix_scale)))); + + vec2 a_thresh = vec2(hash_3d(floor(pix_scales.x * pos.xyz)), + hash_3d(floor(pix_scales.y * pos.xyz))); + + float lerp_factor = fract(log2(pix_scale)); + + float a_interp = (1.0 - lerp_factor) * a_thresh.x + lerp_factor * a_thresh.y; + + float min_lerp = min(lerp_factor, 1.0 - lerp_factor); + + vec3 cases = vec3(a_interp * a_interp / (2.0 * min_lerp * (1.0 - min_lerp)), + (a_interp - 0.5 * min_lerp) / (1.0 - min_lerp), + 1.0 - ((1.0 - a_interp) * (1.0 - a_interp) / + (2.0 * min_lerp * (1.0 - min_lerp)))); + + float alpha_hash_threshold = + (lerp_factor < (1.0 - min_lerp)) ? ((lerp_factor < min_lerp) ? cases.x : cases.y) : cases.z; + + return clamp(alpha_hash_threshold, 0.0, 1.0); +} + +#endif // ALPHA_HASH_USED + +#ifdef ALPHA_ANTIALIASING_EDGE_USED + +float calc_mip_level(vec2 texture_coord) { + vec2 dx = dFdx(texture_coord); + vec2 dy = dFdy(texture_coord); + float delta_max_sqr = max(dot(dx, dx), dot(dy, dy)); + return max(0.0, 0.5 * log2(delta_max_sqr)); +} + +float compute_alpha_antialiasing_edge(float input_alpha, vec2 texture_coord, float alpha_edge) { + input_alpha *= 1.0 + max(0, calc_mip_level(texture_coord)) * 0.25; // 0.25 mip scale, magic number + input_alpha = (input_alpha - alpha_edge) / max(fwidth(input_alpha), 0.0001) + 0.5; + return clamp(input_alpha, 0.0, 1.0); +} + +#endif // ALPHA_ANTIALIASING_USED + // This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V. // We're dividing this factor off because the overall term we'll end up looks like // (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012): @@ -1709,10 +1768,6 @@ void main() { float alpha = 1.0; -#if defined(ALPHA_SCISSOR_USED) - float alpha_scissor = 0.5; -#endif - #if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED) vec3 binormal = normalize(binormal_interp); vec3 tangent = normalize(tangent_interp); @@ -1749,6 +1804,19 @@ void main() { float sss_strength = 0.0; +#ifdef ALPHA_SCISSOR_USED + float alpha_scissor_threshold = 1.0; +#endif // ALPHA_SCISSOR_USED + +#ifdef ALPHA_HASH_USED + float alpha_hash_scale = 1.0; +#endif // ALPHA_HASH_USED + +#ifdef ALPHA_ANTIALIASING_EDGE_USED + float alpha_antialiasing_edge = 0.0; + vec2 alpha_texture_coordinate = vec2(0.0, 0.0); +#endif // ALPHA_ANTIALIASING_EDGE_USED + { /* clang-format off */ @@ -1757,7 +1825,7 @@ FRAGMENT_SHADER_CODE /* clang-format on */ } -#if defined(LIGHT_TRANSMITTANCE_USED) +#ifdef LIGHT_TRANSMITTANCE_USED #ifdef SSS_MODE_SKIN transmittance_color.a = sss_strength; #else @@ -1765,25 +1833,43 @@ FRAGMENT_SHADER_CODE #endif #endif -#if !defined(USE_SHADOW_TO_OPACITY) +#ifndef USE_SHADOW_TO_OPACITY -#if defined(ALPHA_SCISSOR_USED) - if (alpha < alpha_scissor) { +#ifdef ALPHA_SCISSOR_USED + if (alpha < alpha_scissor_threshold) { discard; } #endif // ALPHA_SCISSOR_USED -#ifdef USE_OPAQUE_PREPASS +// alpha hash can be used in unison with alpha antialiasing +#ifdef ALPHA_HASH_USED + if (alpha < compute_alpha_hash_threshold(vertex, alpha_hash_scale)) { + discard; + } +#endif // ALPHA_HASH_USED + +// If we are not edge antialiasing, we need to remove the output alpha channel from scissor and hash +#if (defined(ALPHA_SCISSOR_USED) || defined(ALPHA_HASH_USED)) && !defined(ALPHA_ANTIALIASING_EDGE_USED) + alpha = 1.0; +#endif + +#ifdef ALPHA_ANTIALIASING_EDGE_USED +// If alpha scissor is used, we must further the edge threshold, otherwise we wont get any edge feather +#ifdef ALPHA_SCISSOR_USED + alpha_antialiasing_edge = clamp(alpha_scissor_threshold + alpha_antialiasing_edge, 0.0, 1.0); +#endif + alpha = compute_alpha_antialiasing_edge(alpha, alpha_texture_coordinate, alpha_antialiasing_edge); +#endif // ALPHA_ANTIALIASING_EDGE_USED +#ifdef USE_OPAQUE_PREPASS if (alpha < opaque_prepass_threshold) { discard; } - #endif // USE_OPAQUE_PREPASS #endif // !USE_SHADOW_TO_OPACITY -#if defined(NORMALMAP_USED) +#ifdef NORMALMAP_USED normalmap.xy = normalmap.xy * 2.0 - 1.0; normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. @@ -1792,7 +1878,7 @@ FRAGMENT_SHADER_CODE #endif -#if defined(LIGHT_ANISOTROPY_USED) +#ifdef LIGHT_ANISOTROPY_USED if (anisotropy > 0.01) { //rotation matrix diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 6df66e7b20..f1f8b3cda0 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -31,8 +31,8 @@ #ifndef RENDERING_DEVICE_H #define RENDERING_DEVICE_H -#include "core/class_db.h" -#include "core/typed_array.h" +#include "core/object/class_db.h" +#include "core/variant/typed_array.h" #include "servers/display_server.h" class RDTextureFormat; diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp index fd7c022d62..4480b79f75 100644 --- a/servers/rendering/rendering_server_canvas.cpp +++ b/servers/rendering/rendering_server_canvas.cpp @@ -37,7 +37,7 @@ static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1; -void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { +void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { RENDER_TIMESTAMP("Cull CanvasItem Tree"); memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); @@ -68,7 +68,7 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can RENDER_TIMESTAMP("Render Canvas Items"); - RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_directional_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transform2D p_transform, RenderingServerCanvas::Item *p_material_owner, RenderingServerCanvas::Item **r_items, int &r_index) { @@ -298,28 +298,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } } -void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights) { - if (!p_masked_lights) { - return; - } - - RasterizerCanvas::Item *ci = p_canvas_item; - - while (ci) { - RasterizerCanvas::Light *light = p_masked_lights; - while (light) { - if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { - ci->light_masked = true; - } - - light = light->mask_next_ptr; - } - - ci = ci->next; - } -} - -void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { +void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { RENDER_TIMESTAMP(">Render Canvas"); snapping_2d_transforms_to_pixel = p_snap_2d_transforms_to_pixel; @@ -341,26 +320,26 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, } if (!has_mirror) { - _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } else { //used for parallaxlayer mirroring for (int i = 0; i < l; i++) { const Canvas::ChildItem &ci2 = p_canvas->child_items[i]; - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); //mirroring (useful for scrolling backgrounds) if (ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0)); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } if (ci2.mirror.y != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y)); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } if (ci2.mirror.y != 0 && ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } } } @@ -1040,13 +1019,38 @@ RID RenderingServerCanvas::canvas_light_create() { return canvas_light_owner.make_rid(clight); } +void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { + RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); + ERR_FAIL_COND(!clight); + + if (clight->mode == p_mode) { + return; + } + + RID canvas = clight->canvas; + + if (canvas.is_valid()) { + canvas_light_attach_to_canvas(p_light, RID()); + } + + clight->mode = p_mode; + + if (canvas.is_valid()) { + canvas_light_attach_to_canvas(p_light, canvas); + } +} + void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->canvas.is_valid()) { Canvas *canvas = canvas_owner.getornull(clight->canvas); - canvas->lights.erase(clight); + if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) { + canvas->lights.erase(clight); + } else { + canvas->directional_lights.erase(clight); + } } if (!canvas_owner.owns(p_canvas)) { @@ -1057,7 +1061,11 @@ void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_can if (clight->canvas.is_valid()) { Canvas *canvas = canvas_owner.getornull(clight->canvas); - canvas->lights.insert(clight); + if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) { + canvas->lights.insert(clight); + } else { + canvas->directional_lights.insert(clight); + } } } @@ -1068,7 +1076,7 @@ void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled clight->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) { +void RenderingServerCanvas::canvas_light_set_texture_scale(RID p_light, float p_scale) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1152,11 +1160,18 @@ void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, clight->item_shadow_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { +void RenderingServerCanvas::canvas_light_set_directional_distance(RID p_light, float p_distance) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); - clight->mode = p_mode; + clight->directional_distance = p_distance; +} + +void RenderingServerCanvas::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) { + RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); + ERR_FAIL_COND(!clight); + + clight->blend_mode = p_mode; } void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) { diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h index a9a81888aa..36e2f77e95 100644 --- a/servers/rendering/rendering_server_canvas.h +++ b/servers/rendering/rendering_server_canvas.h @@ -116,6 +116,7 @@ public: }; Set<RasterizerCanvas::Light *> lights; + Set<RasterizerCanvas::Light *> directional_lights; Set<RasterizerCanvas::LightOccluderInstance *> occluders; @@ -155,15 +156,14 @@ public: bool snapping_2d_transforms_to_pixel = false; private: - void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); + void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner); - void _light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights); RasterizerCanvas::Item **z_list; RasterizerCanvas::Item **z_last_list; public: - void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel); + void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel); RID canvas_create(); void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring); @@ -220,9 +220,10 @@ public: void canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin = 5.0, bool p_fit_empty = false, float p_fit_margin = 0.0, bool p_blur_mipmaps = false); RID canvas_light_create(); + void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode); void canvas_light_attach_to_canvas(RID p_light, RID p_canvas); void canvas_light_set_enabled(RID p_light, bool p_enabled); - void canvas_light_set_scale(RID p_light, float p_scale); + void canvas_light_set_texture_scale(RID p_light, float p_scale); void canvas_light_set_transform(RID p_light, const Transform2D &p_transform); void canvas_light_set_texture(RID p_light, RID p_texture); void canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset); @@ -233,8 +234,9 @@ public: void canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer); void canvas_light_set_item_cull_mask(RID p_light, int p_mask); void canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask); + void canvas_light_set_directional_distance(RID p_light, float p_distance); - void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode); + void canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode); void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled); void canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter); diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_raster.cpp index cbc91497ba..94cfb6b752 100644 --- a/servers/rendering/rendering_server_raster.cpp +++ b/servers/rendering/rendering_server_raster.cpp @@ -30,10 +30,10 @@ #include "rendering_server_raster.h" +#include "core/config/project_settings.h" #include "core/io/marshalls.h" #include "core/os/os.h" -#include "core/project_settings.h" -#include "core/sort_array.h" +#include "core/templates/sort_array.h" #include "rendering_server_canvas.h" #include "rendering_server_globals.h" #include "rendering_server_scene.h" diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index a89d4db1f8..daad706f8e 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -748,9 +748,12 @@ public: BIND6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) BIND0R(RID, canvas_light_create) + + BIND2(canvas_light_set_mode, RID, CanvasLightMode) + BIND2(canvas_light_attach_to_canvas, RID, RID) BIND2(canvas_light_set_enabled, RID, bool) - BIND2(canvas_light_set_scale, RID, float) + BIND2(canvas_light_set_texture_scale, RID, float) BIND2(canvas_light_set_transform, RID, const Transform2D &) BIND2(canvas_light_set_texture, RID, RID) BIND2(canvas_light_set_texture_offset, RID, const Vector2 &) @@ -761,8 +764,9 @@ public: BIND3(canvas_light_set_layer_range, RID, int, int) BIND2(canvas_light_set_item_cull_mask, RID, int) BIND2(canvas_light_set_item_shadow_cull_mask, RID, int) + BIND2(canvas_light_set_directional_distance, RID, float) - BIND2(canvas_light_set_mode, RID, CanvasLightMode) + BIND2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) BIND2(canvas_light_set_shadow_enabled, RID, bool) BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h index 1b0a617627..a30aac3bb1 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/rendering_server_scene.h @@ -33,13 +33,13 @@ #include "servers/rendering/rasterizer.h" -#include "core/local_vector.h" #include "core/math/geometry_3d.h" #include "core/math/octree.h" #include "core/os/semaphore.h" #include "core/os/thread.h" -#include "core/rid_owner.h" -#include "core/self_list.h" +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" #include "servers/xr/xr_interface.h" class RenderingServerScene { diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp index b5d8f0da40..c6682b1fcd 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/rendering_server_viewport.cpp @@ -30,7 +30,7 @@ #include "rendering_server_viewport.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "rendering_server_canvas.h" #include "rendering_server_globals.h" #include "rendering_server_scene.h" @@ -142,11 +142,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); RasterizerCanvas::Light *lights = nullptr; RasterizerCanvas::Light *lights_with_shadow = nullptr; - RasterizerCanvas::Light *lights_with_mask = nullptr; + + RasterizerCanvas::Light *directional_lights = nullptr; + RasterizerCanvas::Light *directional_lights_with_shadow = nullptr; + Rect2 shadow_rect; int light_count = 0; int shadow_count = 0; + int directional_light_count = 0; RENDER_TIMESTAMP("Cull Canvas Lights"); for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { @@ -186,10 +190,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: lights_with_shadow = cl; cl->radius_cache = cl->rect_cache.size.length(); } - if (cl->mode == RS::CANVAS_LIGHT_MODE_MASK) { - cl->mask_next_ptr = lights_with_mask; - lights_with_mask = cl; - } light_count++; } @@ -199,6 +199,26 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } } + for (Set<RasterizerCanvas::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) { + RasterizerCanvas::Light *cl = F->get(); + if (cl->enabled) { + cl->filter_next_ptr = directional_lights; + directional_lights = cl; + cl->xform_cache = xf * cl->xform; + cl->xform_cache.elements[2] = Vector2(); //translation is pointless + if (cl->use_shadow) { + cl->shadows_next_ptr = directional_lights_with_shadow; + directional_lights_with_shadow = cl; + } + + directional_light_count++; + + if (directional_light_count == RS::MAX_2D_DIRECTIONAL_LIGHTS) { + break; + } + } + } + canvas_map[Viewport::CanvasKey(E->key(), E->get().layer, E->get().sublayer)] = &E->get(); } @@ -240,6 +260,90 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: RENDER_TIMESTAMP("<End rendering 2D Shadows"); } + if (directional_lights_with_shadow) { + //update shadows if any + RasterizerCanvas::Light *light = directional_lights_with_shadow; + while (light) { + Vector2 light_dir = -light->xform_cache.elements[1].normalized(); // Y is light direction + float cull_distance = light->directional_distance; + + Vector2 light_dir_sign; + light_dir_sign.x = (ABS(light_dir.x) < CMP_EPSILON) ? 0.0 : ((light_dir.x > 0.0) ? 1.0 : -1.0); + light_dir_sign.y = (ABS(light_dir.y) < CMP_EPSILON) ? 0.0 : ((light_dir.y > 0.0) ? 1.0 : -1.0); + + Vector2 points[6]; + int point_count = 0; + + for (int j = 0; j < 4; j++) { + static const Vector2 signs[4] = { Vector2(1, 1), Vector2(1, 0), Vector2(0, 0), Vector2(0, 1) }; + Vector2 sign_cmp = signs[j] * 2.0 - Vector2(1.0, 1.0); + Vector2 point = clip_rect.position + clip_rect.size * signs[j]; + + if (sign_cmp == light_dir_sign) { + //both point in same direction, plot offseted + points[point_count++] = point + light_dir * cull_distance; + } else if (sign_cmp.x == light_dir_sign.x || sign_cmp.y == light_dir_sign.y) { + int next_j = (j + 1) % 4; + Vector2 next_sign_cmp = signs[next_j] * 2.0 - Vector2(1.0, 1.0); + + //one point in the same direction, plot segment + + if (next_sign_cmp.x == light_dir_sign.x || next_sign_cmp.y == light_dir_sign.y) { + if (light_dir_sign.x != 0.0 || light_dir_sign.y != 0.0) { + points[point_count++] = point; + } + points[point_count++] = point + light_dir * cull_distance; + } else { + points[point_count++] = point + light_dir * cull_distance; + if (light_dir_sign.x != 0.0 || light_dir_sign.y != 0.0) { + points[point_count++] = point; + } + } + } else { + //plot normally + points[point_count++] = point; + } + } + + Vector2 xf_points[6]; + + RasterizerCanvas::LightOccluderInstance *occluders = nullptr; + + RENDER_TIMESTAMP(">Render Directional 2D Shadows"); + + //make list of occluders + int occ_cullded = 0; + for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { + RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + + for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { + if (!F->get()->enabled) { + continue; + } + F->get()->xform_cache = xf * F->get()->xform; + Transform2D localizer = F->get()->xform_cache.affine_inverse(); + + for (int j = 0; j < point_count; j++) { + xf_points[j] = localizer.xform(points[j]); + } + if (F->get()->aabb_cache.intersects_filled_polygon(xf_points, point_count)) { + F->get()->next = occluders; + occluders = F->get(); + occ_cullded++; + } + } + } + + RSG::canvas_render->light_update_directional_shadow(light->light_internal, shadow_count++, light->xform_cache, light->item_shadow_mask, cull_distance, clip_rect, occluders); + + light = light->shadows_next_ptr; + } + + //RSG::canvas_render->reset_canvas(); + RENDER_TIMESTAMP("<Render Directional 2D Shadows"); + } + if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { if (!can_draw_3d) { RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); @@ -255,6 +359,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); RasterizerCanvas::Light *canvas_lights = nullptr; + RasterizerCanvas::Light *canvas_directional_lights = nullptr; RasterizerCanvas::Light *ptr = lights; while (ptr) { @@ -265,7 +370,16 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: ptr = ptr->filter_next_ptr; } - RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, lights_with_mask, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel); + ptr = directional_lights; + while (ptr) { + if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) { + ptr->next_ptr = canvas_directional_lights; + canvas_directional_lights = ptr; + } + ptr = ptr->filter_next_ptr; + } + + RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel); i++; if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) { diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h index d00a06c5ee..081f63690b 100644 --- a/servers/rendering/rendering_server_viewport.h +++ b/servers/rendering/rendering_server_viewport.h @@ -31,8 +31,8 @@ #ifndef VISUALSERVERVIEWPORT_H #define VISUALSERVERVIEWPORT_H -#include "core/rid_owner.h" -#include "core/self_list.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" #include "rasterizer.h" #include "servers/rendering_server.h" #include "servers/xr/xr_interface.h" diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp index ab9856e06e..40ad228fd0 100644 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ b/servers/rendering/rendering_server_wrap_mt.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "rendering_server_wrap_mt.h" +#include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "servers/display_server.h" void RenderingServerWrapMT::thread_exit() { diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 42f1b5bcc8..d27b851d1d 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -31,8 +31,8 @@ #ifndef RENDERING_SERVER_WRAP_MT_H #define RENDERING_SERVER_WRAP_MT_H -#include "core/command_queue_mt.h" #include "core/os/thread.h" +#include "core/templates/command_queue_mt.h" #include "servers/rendering_server.h" class RenderingServerWrapMT : public RenderingServer { @@ -647,9 +647,12 @@ public: FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) FUNC0R(RID, canvas_light_create) + + FUNC2(canvas_light_set_mode, RID, CanvasLightMode) + FUNC2(canvas_light_attach_to_canvas, RID, RID) FUNC2(canvas_light_set_enabled, RID, bool) - FUNC2(canvas_light_set_scale, RID, float) + FUNC2(canvas_light_set_texture_scale, RID, float) FUNC2(canvas_light_set_transform, RID, const Transform2D &) FUNC2(canvas_light_set_texture, RID, RID) FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &) @@ -660,8 +663,9 @@ public: FUNC3(canvas_light_set_layer_range, RID, int, int) FUNC2(canvas_light_set_item_cull_mask, RID, int) FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int) + FUNC2(canvas_light_set_directional_distance, RID, float) - FUNC2(canvas_light_set_mode, RID, CanvasLightMode) + FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) FUNC2(canvas_light_set_shadow_enabled, RID, bool) FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 1883b6b338..046c6ba580 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -30,7 +30,7 @@ #include "shader_language.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "servers/rendering_server.h" static bool _is_text_char(char32_t c) { diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 3c0a10809b..3a9f408dc0 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -31,13 +31,13 @@ #ifndef SHADER_LANGUAGE_H #define SHADER_LANGUAGE_H -#include "core/list.h" -#include "core/map.h" -#include "core/script_language.h" -#include "core/string_name.h" +#include "core/object/script_language.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/templates/list.h" +#include "core/templates/map.h" #include "core/typedefs.h" -#include "core/ustring.h" -#include "core/variant.h" +#include "core/variant/variant.h" class ShaderLanguage { public: diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 48eaf1dd13..4d21807735 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -134,6 +134,11 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["IRRADIANCE"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].can_discard = true; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR_THRESHOLD"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_HASH_SCALE"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_ANTIALIASING_EDGE"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_TEXTURE_COORDINATE"] = ShaderLanguage::TYPE_VEC2; + shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); @@ -206,6 +211,9 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].modes.push_back("vertex_lighting"); + shader_modes[RS::SHADER_SPATIAL].modes.push_back("alpha_to_coverage"); + shader_modes[RS::SHADER_SPATIAL].modes.push_back("alpha_to_coverage_and_one"); + /************ CANVAS ITEM **************************/ shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h index 7d8057a5c6..50f910babb 100644 --- a/servers/rendering/shader_types.h +++ b/servers/rendering/shader_types.h @@ -31,7 +31,7 @@ #ifndef SHADERTYPES_H #define SHADERTYPES_H -#include "core/ordered_hash_map.h" +#include "core/templates/ordered_hash_map.h" #include "servers/rendering_server.h" #include "shader_language.h" diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 42a77101f7..cc959afdaa 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -30,7 +30,7 @@ #include "rendering_server.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" RenderingServer *RenderingServer::singleton = nullptr; RenderingServer *(*RenderingServer::create_func)() = nullptr; @@ -1833,7 +1833,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_light_create"), &RenderingServer::canvas_light_create); ClassDB::bind_method(D_METHOD("canvas_light_attach_to_canvas", "light", "canvas"), &RenderingServer::canvas_light_attach_to_canvas); ClassDB::bind_method(D_METHOD("canvas_light_set_enabled", "light", "enabled"), &RenderingServer::canvas_light_set_enabled); - ClassDB::bind_method(D_METHOD("canvas_light_set_scale", "light", "scale"), &RenderingServer::canvas_light_set_scale); + ClassDB::bind_method(D_METHOD("canvas_light_set_texture_scale", "light", "scale"), &RenderingServer::canvas_light_set_texture_scale); ClassDB::bind_method(D_METHOD("canvas_light_set_transform", "light", "transform"), &RenderingServer::canvas_light_set_transform); ClassDB::bind_method(D_METHOD("canvas_light_set_texture", "light", "texture"), &RenderingServer::canvas_light_set_texture); ClassDB::bind_method(D_METHOD("canvas_light_set_texture_offset", "light", "offset"), &RenderingServer::canvas_light_set_texture_offset); @@ -2190,10 +2190,16 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); BIND_ENUM_CONSTANT(CANVAS_ITEM_TEXTURE_REPEAT_MAX); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_ADD); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_SUB); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_MIX); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_MASK); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_DISABLED); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_OPAQUE); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_TRANSPARENT); + + BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_POINT); + BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_DIRECTIONAL); + + BIND_ENUM_CONSTANT(CANVAS_LIGHT_BLEND_MODE_ADD); + BIND_ENUM_CONSTANT(CANVAS_LIGHT_BLEND_MODE_SUB); + BIND_ENUM_CONSTANT(CANVAS_LIGHT_BLEND_MODE_MIX); BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_NONE); BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_PCF5); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index a33215a882..d676a1ba01 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -31,13 +31,13 @@ #ifndef RENDERING_SERVER_H #define RENDERING_SERVER_H -#include "core/class_db.h" -#include "core/image.h" +#include "core/io/image.h" #include "core/math/geometry_3d.h" #include "core/math/transform_2d.h" -#include "core/rid.h" -#include "core/typed_array.h" -#include "core/variant.h" +#include "core/object/class_db.h" +#include "core/templates/rid.h" +#include "core/variant/typed_array.h" +#include "core/variant/variant.h" #include "servers/display_server.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/shader_language.h" @@ -77,6 +77,7 @@ public: CANVAS_ITEM_Z_MAX = 4096, MAX_GLOW_LEVELS = 7, MAX_CURSORS = 8, + MAX_2D_DIRECTIONAL_LIGHTS = 8 }; /* TEXTURE API */ @@ -1195,12 +1196,17 @@ public: virtual void canvas_item_set_canvas_group_mode(RID p_item, CanvasGroupMode p_mode, float p_clear_margin = 5.0, bool p_fit_empty = false, float p_fit_margin = 0.0, bool p_blur_mipmaps = false) = 0; virtual RID canvas_light_create() = 0; + + enum CanvasLightMode { + CANVAS_LIGHT_MODE_POINT, + CANVAS_LIGHT_MODE_DIRECTIONAL, + }; + + virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode) = 0; + virtual void canvas_light_attach_to_canvas(RID p_light, RID p_canvas) = 0; virtual void canvas_light_set_enabled(RID p_light, bool p_enabled) = 0; - virtual void canvas_light_set_scale(RID p_light, float p_scale) = 0; virtual void canvas_light_set_transform(RID p_light, const Transform2D &p_transform) = 0; - virtual void canvas_light_set_texture(RID p_light, RID p_texture) = 0; - virtual void canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) = 0; virtual void canvas_light_set_color(RID p_light, const Color &p_color) = 0; virtual void canvas_light_set_height(RID p_light, float p_height) = 0; virtual void canvas_light_set_energy(RID p_light, float p_energy) = 0; @@ -1209,14 +1215,19 @@ public: virtual void canvas_light_set_item_cull_mask(RID p_light, int p_mask) = 0; virtual void canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) = 0; - enum CanvasLightMode { - CANVAS_LIGHT_MODE_ADD, - CANVAS_LIGHT_MODE_SUB, - CANVAS_LIGHT_MODE_MIX, - CANVAS_LIGHT_MODE_MASK, + virtual void canvas_light_set_directional_distance(RID p_light, float p_distance) = 0; + + virtual void canvas_light_set_texture_scale(RID p_light, float p_scale) = 0; + virtual void canvas_light_set_texture(RID p_light, RID p_texture) = 0; + virtual void canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) = 0; + + enum CanvasLightBlendMode { + CANVAS_LIGHT_BLEND_MODE_ADD, + CANVAS_LIGHT_BLEND_MODE_SUB, + CANVAS_LIGHT_BLEND_MODE_MIX, }; - virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode) = 0; + virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_mode) = 0; enum CanvasLightShadowFilter { CANVAS_LIGHT_FILTER_NONE, @@ -1434,7 +1445,9 @@ VARIANT_ENUM_CAST(RenderingServer::ShadowCastingSetting); VARIANT_ENUM_CAST(RenderingServer::NinePatchAxisMode); VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureRepeat); +VARIANT_ENUM_CAST(RenderingServer::CanvasGroupMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightMode); +VARIANT_ENUM_CAST(RenderingServer::CanvasLightBlendMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode); VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index 09800443b7..45199edd24 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "xr_server.h" -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "xr/xr_interface.h" #include "xr/xr_positional_tracker.h" diff --git a/servers/xr_server.h b/servers/xr_server.h index e04c7b3592..d66d4e778a 100644 --- a/servers/xr_server.h +++ b/servers/xr_server.h @@ -31,11 +31,11 @@ #ifndef XR_SERVER_H #define XR_SERVER_H +#include "core/object/reference.h" #include "core/os/os.h" #include "core/os/thread_safe.h" -#include "core/reference.h" -#include "core/rid.h" -#include "core/variant.h" +#include "core/templates/rid.h" +#include "core/variant/variant.h" class XRInterface; class XRPositionalTracker; diff --git a/tests/test_basis.h b/tests/test_basis.h index 05efe33788..db4e0b347f 100644 --- a/tests/test_basis.h +++ b/tests/test_basis.h @@ -33,7 +33,7 @@ #include "core/math/random_number_generator.h" #include "core/os/os.h" -#include "core/ustring.h" +#include "core/string/ustring.h" #include "tests/test_macros.h" diff --git a/tests/test_class_db.h b/tests/test_class_db.h index d0d8136874..29fe837587 100644 --- a/tests/test_class_db.h +++ b/tests/test_class_db.h @@ -33,12 +33,12 @@ #include "core/register_core_types.h" -#include "core/global_constants.h" -#include "core/ordered_hash_map.h" +#include "core/core_constants.h" #include "core/os/os.h" -#include "core/string_name.h" -#include "core/ustring.h" -#include "core/variant.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/templates/ordered_hash_map.h" +#include "core/variant/variant.h" #include "tests/test_macros.h" @@ -255,7 +255,7 @@ bool arg_default_value_is_assignable_to_type(const Context &p_context, const Var case Variant::VECTOR2: case Variant::RECT2: case Variant::VECTOR3: - case Variant::_RID: + case Variant::RID: case Variant::ARRAY: case Variant::DICTIONARY: case Variant::PACKED_BYTE_ARRAY: @@ -769,16 +769,16 @@ void add_builtin_types(Context &r_context) { } void add_global_enums(Context &r_context) { - int global_constants_count = GlobalConstants::get_global_constant_count(); + int global_constants_count = CoreConstants::get_global_constant_count(); if (global_constants_count > 0) { for (int i = 0; i < global_constants_count; i++) { - StringName enum_name = GlobalConstants::get_global_constant_enum(i); + StringName enum_name = CoreConstants::get_global_constant_enum(i); if (enum_name != StringName()) { ConstantData constant; - constant.name = GlobalConstants::get_global_constant_name(i); - constant.value = GlobalConstants::get_global_constant_value(i); + constant.name = CoreConstants::get_global_constant_name(i); + constant.value = CoreConstants::get_global_constant_value(i); EnumData enum_; enum_.name = enum_name; diff --git a/tests/test_color.h b/tests/test_color.h index dfdc29ec7d..04b66811e3 100644 --- a/tests/test_color.h +++ b/tests/test_color.h @@ -31,7 +31,7 @@ #ifndef TEST_COLOR_H #define TEST_COLOR_H -#include "core/color.h" +#include "core/math/color.h" #include "thirdparty/doctest/doctest.h" @@ -185,9 +185,6 @@ TEST_CASE("[Color] Manipulation methods") { CHECK_MESSAGE( blue.inverted().is_equal_approx(Color(1, 1, 0, 0.4)), "Inverted color should have its red, green and blue components inverted."); - CHECK_MESSAGE( - blue.contrasted().is_equal_approx(Color(0.5, 0.5, 0.5, 0.4)), - "Contrasted pure blue should be fully gray."); const Color purple = Color(0.5, 0.2, 0.5, 0.25); diff --git a/tests/test_command_queue.h b/tests/test_command_queue.h index a66fd3c86e..c3cfa08b61 100644 --- a/tests/test_command_queue.h +++ b/tests/test_command_queue.h @@ -33,12 +33,12 @@ #include "test_command_queue.h" -#include "core/command_queue_mt.h" +#include "core/config/project_settings.h" #include "core/os/mutex.h" #include "core/os/os.h" #include "core/os/semaphore.h" #include "core/os/thread.h" -#include "core/project_settings.h" +#include "core/templates/command_queue_mt.h" #if !defined(NO_THREADS) diff --git a/tests/test_expression.h b/tests/test_expression.h index a3d4877d52..c9cb0158f3 100644 --- a/tests/test_expression.h +++ b/tests/test_expression.h @@ -381,7 +381,7 @@ TEST_CASE("[Expression] Unusual expressions") { ERR_PRINT_OFF; CHECK_MESSAGE( - expression.parse("$1.00 + €5") == OK, + expression.parse("$1.00 + ???5") == OK, "The expression should parse successfully."); CHECK_MESSAGE( int(expression.execute()) == 0, @@ -410,8 +410,8 @@ TEST_CASE("[Expression] Unusual expressions") { "The expression should parse successfully."); ERR_PRINT_OFF; CHECK_MESSAGE( - Math::is_zero_approx(float(expression.execute())), - "`-25.4 / 0` should return 0."); + Math::is_inf(float(expression.execute())), + "`-25.4 / 0` should return inf."); ERR_PRINT_ON; CHECK_MESSAGE( diff --git a/tests/test_gradient.h b/tests/test_gradient.h index 88fe06b3ec..8f28dfd9b4 100644 --- a/tests/test_gradient.h +++ b/tests/test_gradient.h @@ -31,8 +31,8 @@ #ifndef TEST_GRADIENT_H #define TEST_GRADIENT_H -#include "core/class_db.h" -#include "core/color.h" +#include "core/math/color.h" +#include "core/object/class_db.h" #include "scene/resources/gradient.h" #include "thirdparty/doctest/doctest.h" diff --git a/tests/test_gui.cpp b/tests/test_gui.cpp index d46a13d2c0..03c9dfd2ba 100644 --- a/tests/test_gui.cpp +++ b/tests/test_gui.cpp @@ -34,7 +34,7 @@ #include "core/io/image_loader.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "scene/2d/sprite_2d.h" #include "scene/gui/button.h" #include "scene/gui/control.h" diff --git a/tests/test_list.h b/tests/test_list.h index 7412fbc3c8..adeedaaf3e 100644 --- a/tests/test_list.h +++ b/tests/test_list.h @@ -31,7 +31,7 @@ #ifndef TEST_LIST_H #define TEST_LIST_H -#include "core/list.h" +#include "core/templates/list.h" #include "tests/test_macros.h" diff --git a/tests/test_macros.h b/tests/test_macros.h index 3486c68bb7..05fae128b3 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -31,8 +31,8 @@ #ifndef TEST_MACROS_H #define TEST_MACROS_H -#include "core/map.h" -#include "core/variant.h" +#include "core/templates/map.h" +#include "core/variant/variant.h" // See documentation for doctest at: // https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md#reference diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 871c796513..b4ddf0f1c1 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -30,7 +30,7 @@ #include "test_main.h" -#include "core/list.h" +#include "core/templates/list.h" #include "test_astar.h" #include "test_basis.h" diff --git a/tests/test_math.cpp b/tests/test_math.cpp index 862535b57e..e745d1609e 100644 --- a/tests/test_math.cpp +++ b/tests/test_math.cpp @@ -36,14 +36,14 @@ #include "core/math/geometry_2d.h" #include "core/math/math_funcs.h" #include "core/math/transform.h" -#include "core/method_ptrcall.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/print_string.h" -#include "core/ustring.h" -#include "core/variant.h" -#include "core/vmap.h" +#include "core/string/print_string.h" +#include "core/string/ustring.h" +#include "core/templates/vmap.h" +#include "core/variant/method_ptrcall.h" +#include "core/variant/variant.h" #include "scene/main/node.h" #include "scene/resources/texture.h" #include "servers/rendering/shader_language.h" diff --git a/tests/test_method_bind.h b/tests/test_method_bind.h index f4004c2090..9507a10d3e 100644 --- a/tests/test_method_bind.h +++ b/tests/test_method_bind.h @@ -31,7 +31,7 @@ #ifndef TEST_METHOD_BIND_H #define TEST_METHOD_BIND_H -#include "core/class_db.h" +#include "core/object/class_db.h" #include "tests/test_macros.h" diff --git a/tests/test_oa_hash_map.cpp b/tests/test_oa_hash_map.cpp index 9182f66b61..44717e5690 100644 --- a/tests/test_oa_hash_map.cpp +++ b/tests/test_oa_hash_map.cpp @@ -30,8 +30,8 @@ #include "test_oa_hash_map.h" -#include "core/oa_hash_map.h" #include "core/os/os.h" +#include "core/templates/oa_hash_map.h" namespace TestOAHashMap { diff --git a/tests/test_ordered_hash_map.h b/tests/test_ordered_hash_map.h index 3182c391cb..9f987e8833 100644 --- a/tests/test_ordered_hash_map.h +++ b/tests/test_ordered_hash_map.h @@ -31,10 +31,10 @@ #ifndef TEST_ORDERED_HASH_MAP_H #define TEST_ORDERED_HASH_MAP_H -#include "core/ordered_hash_map.h" #include "core/os/os.h" -#include "core/pair.h" -#include "core/vector.h" +#include "core/templates/ordered_hash_map.h" +#include "core/templates/pair.h" +#include "core/templates/vector.h" #include "tests/test_macros.h" diff --git a/tests/test_physics_2d.cpp b/tests/test_physics_2d.cpp index c82ae920bc..54d373b454 100644 --- a/tests/test_physics_2d.cpp +++ b/tests/test_physics_2d.cpp @@ -30,10 +30,10 @@ #include "test_physics_2d.h" -#include "core/map.h" #include "core/os/main_loop.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" +#include "core/templates/map.h" #include "scene/resources/texture.h" #include "servers/display_server.h" #include "servers/physics_server_2d.h" diff --git a/tests/test_physics_3d.cpp b/tests/test_physics_3d.cpp index 72de2041e4..1b453be76d 100644 --- a/tests/test_physics_3d.cpp +++ b/tests/test_physics_3d.cpp @@ -30,12 +30,12 @@ #include "test_physics_3d.h" -#include "core/map.h" #include "core/math/math_funcs.h" #include "core/math/quick_hull.h" #include "core/os/main_loop.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" +#include "core/templates/map.h" #include "servers/display_server.h" #include "servers/physics_server_3d.h" #include "servers/rendering_server.h" diff --git a/tests/test_render.cpp b/tests/test_render.cpp index d936dd72e7..8c5cac694c 100644 --- a/tests/test_render.cpp +++ b/tests/test_render.cpp @@ -35,7 +35,7 @@ #include "core/os/keyboard.h" #include "core/os/main_loop.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "servers/display_server.h" #include "servers/rendering_server.h" diff --git a/tests/test_shader_lang.cpp b/tests/test_shader_lang.cpp index d363ee22b5..4bfd593279 100644 --- a/tests/test_shader_lang.cpp +++ b/tests/test_shader_lang.cpp @@ -34,7 +34,7 @@ #include "core/os/main_loop.h" #include "core/os/os.h" -#include "core/print_string.h" +#include "core/string/print_string.h" #include "scene/gui/control.h" #include "scene/gui/text_edit.h" #include "servers/rendering/shader_language.h" diff --git a/tests/test_string.h b/tests/test_string.h index b041cb2f49..acdcaccecd 100644 --- a/tests/test_string.h +++ b/tests/test_string.h @@ -38,7 +38,7 @@ #include "core/io/ip_address.h" #include "core/os/main_loop.h" #include "core/os/os.h" -#include "core/ustring.h" +#include "core/string/ustring.h" #ifdef MODULE_REGEX_ENABLED #include "modules/regex/regex.h" diff --git a/tests/test_variant.h b/tests/test_variant.h index a384a3e91f..b7421c29a5 100644 --- a/tests/test_variant.h +++ b/tests/test_variant.h @@ -31,8 +31,8 @@ #ifndef TEST_VARIANT_H #define TEST_VARIANT_H -#include "core/variant.h" -#include "core/variant_parser.h" +#include "core/variant/variant.h" +#include "core/variant/variant_parser.h" #include "tests/test_macros.h" diff --git a/thirdparty/README.md b/thirdparty/README.md index ac1ce6d5fc..f590acaa0b 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -378,7 +378,7 @@ Collection of single-file libraries used in Godot components. * License: Apache 2.0 - `open-simplex-noise.{c,h}` * Upstream: https://github.com/smcameron/open-simplex-noise-in-c - * Version: git (0d555e7f40527d0870906fe9469a3b1bb4020b7f, 2015) + custom changes + * Version: git (0fef0dbedd76f767da7e3c894822729d0f07e54d, 2020) + custom changes * License: Unlicense - `pcg.{cpp,h}` * Upstream: http://www.pcg-random.org diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp index baf6ea0484..d6b5d96aac 100644 --- a/thirdparty/jpeg-compressor/jpgd.cpp +++ b/thirdparty/jpeg-compressor/jpgd.cpp @@ -1669,7 +1669,7 @@ namespace jpgd { int row = m_max_mcu_y_size - m_mcu_lines_left; uint8* d0 = m_pScan_line_0; - const int half_image_x_size = (m_image_x_size >> 1) - 1; + const int half_image_x_size = (m_image_x_size == 1) ? 0 : (m_image_x_size >> 1) - 1; const int row_x8 = row * 8; for (int x = 0; x < m_image_x_size; x++) @@ -1762,7 +1762,7 @@ namespace jpgd { int y = m_image_y_size - m_total_lines_left; int row = y & 15; - const int half_image_y_size = (m_image_y_size >> 1) - 1; + const int half_image_y_size = (m_image_y_size == 1) ? 0 : (m_image_y_size >> 1) - 1; uint8* d0 = m_pScan_line_0; @@ -1891,7 +1891,7 @@ namespace jpgd { int y = m_image_y_size - m_total_lines_left; int row = y & 15; - const int half_image_y_size = (m_image_y_size >> 1) - 1; + const int half_image_y_size = (m_image_y_size == 1) ? 0 : (m_image_y_size >> 1) - 1; uint8* d0 = m_pScan_line_0; @@ -1915,7 +1915,7 @@ namespace jpgd { const int y0_base = (c_y0 & 7) * 8 + 256; const int y1_base = (c_y1 & 7) * 8 + 256; - const int half_image_x_size = (m_image_x_size >> 1) - 1; + const int half_image_x_size = (m_image_x_size == 1) ? 0 : (m_image_x_size >> 1) - 1; static const uint8_t s_muls[2][2][4] = { diff --git a/thirdparty/libogg/ogg/config_types.h b/thirdparty/libogg/ogg/config_types.h index 3574a8ad44..4dc8393fdc 100644 --- a/thirdparty/libogg/ogg/config_types.h +++ b/thirdparty/libogg/ogg/config_types.h @@ -1,7 +1,7 @@ #ifndef __CONFIG_TYPES_H__ #define __CONFIG_TYPES_H__ -#include "core/int_types.h" +#include <stdint.h> typedef int16_t ogg_int16_t; typedef uint16_t ogg_uint16_t; diff --git a/thirdparty/misc/open-simplex-noise.c b/thirdparty/misc/open-simplex-noise.c index 42f2fbb5be..88fbd3e51d 100644 --- a/thirdparty/misc/open-simplex-noise.c +++ b/thirdparty/misc/open-simplex-noise.c @@ -189,14 +189,15 @@ int open_simplex_noise(int64_t seed, struct osn_context *ctx) permGradIndex3D = ctx->permGradIndex3D; // -- GODOT end -- + uint64_t seedU = seed; for (i = 0; i < 256; i++) source[i] = (int16_t) i; - seed = seed * 6364136223846793005LL + 1442695040888963407LL; - seed = seed * 6364136223846793005LL + 1442695040888963407LL; - seed = seed * 6364136223846793005LL + 1442695040888963407LL; + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; for (i = 255; i >= 0; i--) { - seed = seed * 6364136223846793005LL + 1442695040888963407LL; - r = (int)((seed + 31) % (i + 1)); + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; + r = (int)((seedU + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; diff --git a/thirdparty/misc/pcg.cpp b/thirdparty/misc/pcg.cpp index 5f4bf40460..914a353874 100644 --- a/thirdparty/misc/pcg.cpp +++ b/thirdparty/misc/pcg.cpp @@ -25,8 +25,31 @@ void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) } // Source from https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.c +// pcg32_boundedrand_r(rng, bound): +// Generate a uniformly distributed number, r, where 0 <= r < bound uint32_t pcg32_boundedrand_r(pcg32_random_t *rng, uint32_t bound) { + // To avoid bias, we need to make the range of the RNG a multiple of + // bound, which we do by dropping output less than a threshold. + // A naive scheme to calculate the threshold would be to do + // + // uint32_t threshold = 0x100000000ull % bound; + // + // but 64-bit div/mod is slower than 32-bit div/mod (especially on + // 32-bit platforms). In essence, we do + // + // uint32_t threshold = (0x100000000ull-bound) % bound; + // + // because this version will calculate the same modulus, but the LHS + // value is less than 2^32. uint32_t threshold = -bound % bound; + + // Uniformity guarantees that this loop will terminate. In practice, it + // should usually terminate quickly; on average (assuming all bounds are + // equally likely), 82.25% of the time, we can expect it to require just + // one iteration. In the worst case, someone passes a bound of 2^31 + 1 + // (i.e., 2147483649), which invalidates almost 50% of the range. In + // practice, bounds are typically small and only a tiny amount of the range + // is eliminated. for (;;) { uint32_t r = pcg32_random_r(rng); if (r >= threshold) diff --git a/thirdparty/misc/triangulator.h b/thirdparty/misc/triangulator.h index c85792fd50..24b79e7d34 100644 --- a/thirdparty/misc/triangulator.h +++ b/thirdparty/misc/triangulator.h @@ -21,9 +21,9 @@ #ifndef TRIANGULATOR_H #define TRIANGULATOR_H -#include "core/list.h" +#include "core/templates/list.h" #include "core/math/vector2.h" -#include "core/set.h" +#include "core/templates/set.h" //2D point structure |