diff --git a/.gitignore b/.gitignore index b8680775..f843c64c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,3 @@ config.log .sconf_temp engine/.github -project/.godot -build/PROJECT.pck -build/PROJECT.x86_64 -build/PROJECT.exe -build.zip diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 1b15f551..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "engine"] - path = engine - url = https://github.com/godotengine/godot.git diff --git a/build/.gitkeep b/build/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/engine/.clangd b/engine/.clangd index 3c9792ea..95a1e907 100644 --- a/engine/.clangd +++ b/engine/.clangd @@ -5,6 +5,7 @@ Diagnostics: Includes: IgnoreHeader: + - core/typedefs\.h # Our "main" header, featuring transitive includes; allow everywhere. - \.compat\.inc --- # Header-specific conditions. diff --git a/engine/.editorconfig b/engine/.editorconfig index c79c816e..a2f93af3 100644 --- a/engine/.editorconfig +++ b/engine/.editorconfig @@ -16,6 +16,5 @@ indent_style = space indent_size = 2 indent_style = space -[{*.props,*.vcxproj}] -indent_size = 2 -indent_style = space +[*.svg] +insert_final_newline = false diff --git a/engine/.git-blame-ignore-revs b/engine/.git-blame-ignore-revs index 3203caf8..d54ff309 100644 --- a/engine/.git-blame-ignore-revs +++ b/engine/.git-blame-ignore-revs @@ -66,9 +66,3 @@ bb5f390fb9b466be35a5df7651323d7e66afca31 # Style: Enforce `AllowShortFunctionsOnASingleLine` e06d83860d798b6766b23d6eae48557387a7db85 - -# Style: Enforce trailing newlines on svgs -7e5baa042639ffa835271703c720e2595e90afb8 - -# Style: Replace header guards with `#pragma once` -324512e11c1b7663c3cf47bec6ddbe65c6b8db2b diff --git a/engine/.gitignore b/engine/.gitignore index 8adc7b78..2c3bf742 100644 --- a/engine/.gitignore +++ b/engine/.gitignore @@ -263,11 +263,6 @@ bld/ !thirdparty/**/arm/ !thirdparty/**/arm64/ -thirdparty/swappy-frame-pacing/arm64-v8a/abi.json -thirdparty/swappy-frame-pacing/armeabi-v7a/abi.json -thirdparty/swappy-frame-pacing/x86/abi.json -thirdparty/swappy-frame-pacing/x86_64/abi.json - # Visual Studio 2015/2017 cache/options directory .vs/ diff --git a/engine/.pre-commit-config.yaml b/engine/.pre-commit-config.yaml index 8c9f033a..5627d750 100644 --- a/engine/.pre-commit-config.yaml +++ b/engine/.pre-commit-config.yaml @@ -4,22 +4,24 @@ default_language_version: exclude: | (?x)^( .*thirdparty/.*| - .*-(dll|dylib|so)_wrap\.[ch]| + .*-so_wrap\.(h|c)| platform/android/java/editor/src/main/java/com/android/.*| platform/android/java/lib/src/com/google/.* )$ repos: - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v20.1.0 + rev: v19.1.3 hooks: - id: clang-format files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java)$ types_or: [text] + exclude: ^tests/python_build/.* - id: clang-format name: clang-format-glsl files: \.glsl$ types_or: [text] + exclude: ^tests/python_build/.* args: [-style=file:misc/utility/clang_format_glsl.yml] - repo: https://github.com/pocc/pre-commit-hooks @@ -29,12 +31,13 @@ repos: files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java|glsl)$ args: [--fix, --quiet, --use-color] types_or: [text] - additional_dependencies: [clang-tidy==20.1.0] + exclude: ^tests/python_build/.* + additional_dependencies: [clang-tidy==19.1.0] require_serial: true stages: [manual] # Not automatically triggered, invoked via `pre-commit run --hook-stage manual clang-tidy` - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.11.4 + rev: v0.9.4 hooks: - id: ruff args: [--fix] @@ -45,14 +48,14 @@ repos: types_or: [text] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.14.1 # Latest version that supports Python 3.8 + rev: v1.14.1 hooks: - id: mypy files: \.py$ types_or: [text] - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 + rev: v2.3.0 hooks: - id: codespell additional_dependencies: [tomli] @@ -85,13 +88,6 @@ repos: pass_filenames: false files: ^(doc/classes|.*/doc_classes)/.*\.xml$ - - id: validate-builders - name: validate-builders - language: python - entry: python tests/python_build/validate_builders.py - pass_filenames: false - files: ^(gles3|glsl)_builders\.py$ - - id: eslint name: eslint language: node @@ -158,6 +154,7 @@ repos: language: python entry: python misc/scripts/header_guards.py files: \.(h|hpp|hh|hxx)$ + exclude: ^.*/(dummy|thread|platform_config|platform_gl)\.h$ - id: file-format name: file-format diff --git a/engine/COPYRIGHT.txt b/engine/COPYRIGHT.txt index 38009093..34aa95ed 100644 --- a/engine/COPYRIGHT.txt +++ b/engine/COPYRIGHT.txt @@ -163,11 +163,6 @@ Comment: Temporal Anti-Aliasing resolve implementation Copyright: 2016, Panos Karabelas License: Expat -Files: thirdparty/accesskit/* -Comment: AccessKit -Copyright: 2023, The AccessKit Authors. -License: Expat - Files: thirdparty/amd-fsr/* Comment: AMD FidelityFX Super Resolution Copyright: 2021, Advanced Micro Devices, Inc. @@ -205,7 +200,7 @@ License: MPL-2.0 Files: thirdparty/clipper2/* Comment: Clipper2 -Copyright: 2010-2025, Angus Johnson +Copyright: 2010-2024, Angus Johnson License: BSL-1.0 Files: thirdparty/cvtt/* diff --git a/engine/SConstruct b/engine/SConstruct index 03990864..f4500d75 100644 --- a/engine/SConstruct +++ b/engine/SConstruct @@ -14,7 +14,6 @@ from importlib.util import module_from_spec, spec_from_file_location from types import ModuleType from SCons import __version__ as scons_raw_version -from SCons.Builder import ListEmitter # Explicitly resolve the helper modules, this is done to avoid clash with # modules of the same name that might be randomly added (e.g. someone adding @@ -58,7 +57,7 @@ import gles3_builders import glsl_builders import methods import scu_builders -from misc.utility.color import is_stderr_color, print_error, print_info, print_warning +from misc.utility.color import STDERR_COLOR, print_error, print_info, print_warning from platform_methods import architecture_aliases, architectures, compatibility_platform_aliases if ARGUMENTS.get("target", "editor") == "editor": @@ -167,7 +166,7 @@ opts.Add( "optimize", "Optimization level (by default inferred from 'target' and 'dev_build')", "auto", - ("auto", "none", "custom", "debug", "speed", "speed_trace", "size", "size_extra"), + ("auto", "none", "custom", "debug", "speed", "speed_trace", "size"), ) ) opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", False)) @@ -187,12 +186,11 @@ opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True)) opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True)) opts.Add(BoolVariable("d3d12", "Enable the Direct3D 12 rendering driver on supported platforms", False)) opts.Add(BoolVariable("metal", "Enable the Metal rendering driver on supported platforms (Apple arm64 only)", False)) +opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True)) opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True)) opts.Add(BoolVariable("disable_exceptions", "Force disabling exception handling code", True)) opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "") opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True)) -opts.Add(BoolVariable("accesskit", "Use AccessKit C SDK", True)) -opts.Add(("accesskit_sdk_path", "Path to the AccessKit C SDK", "")) # Advanced options opts.Add( @@ -222,11 +220,6 @@ opts.Add("vsproj_name", "Name of the Visual Studio solution", "godot") opts.Add("import_env_vars", "A comma-separated list of environment variables to copy from the outer environment.", "") opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False)) opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False)) -opts.Add(BoolVariable("disable_physics_2d", "Disable 2D physics nodes and server", False)) -opts.Add(BoolVariable("disable_physics_3d", "Disable 3D physics nodes and server", False)) -opts.Add(BoolVariable("disable_navigation_2d", "Disable 2D navigation features", False)) -opts.Add(BoolVariable("disable_navigation_3d", "Disable 3D navigation features", False)) -opts.Add(BoolVariable("disable_xr", "Disable XR nodes and server", False)) opts.Add("build_profile", "Path to a file containing a feature build profile", "") opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True)) opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True)) @@ -243,13 +236,6 @@ opts.Add(BoolVariable("engine_update_check", "Enable engine update checks in the opts.Add(BoolVariable("steamapi", "Enable minimal SteamAPI integration for usage time tracking (editor only)", False)) opts.Add("cache_path", "Path to a directory where SCons cache files will be stored. No value disables the cache.", "") opts.Add("cache_limit", "Max size (in GiB) for the SCons cache. 0 means no limit.", "0") -opts.Add( - BoolVariable( - "redirect_build_objects", - "Enable redirecting built objects/libraries to `bin/obj/` to declutter the repository.", - True, - ) -) # Thirdparty libraries opts.Add(BoolVariable("builtin_brotli", "Use the built-in Brotli library", True)) @@ -447,18 +433,9 @@ for tool in custom_tools: env.Tool(tool) -# Add default include paths. -env.Prepend(CPPPATH=["#"]) +# add default include paths -# Allow marking includes as external/system to avoid raising warnings. -env["_CCCOMCOM"] += " $_CPPEXTINCFLAGS" -env["CPPEXTPATH"] = [] -if env.scons_version < (4, 2): - env["_CPPEXTINCFLAGS"] = "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}" -else: - env["_CPPEXTINCFLAGS"] = ( - "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}" - ) +env.Prepend(CPPPATH=["#"]) # configure ENV for platform env.platform_exporters = platform_exporters @@ -719,84 +696,83 @@ if env["arch"] == "x86_32": # Explicitly specify colored output. if methods.using_gcc(env): - env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if is_stderr_color() else "-fno-diagnostics-color"]) + env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if STDERR_COLOR else "-fno-diagnostics-color"]) elif methods.using_clang(env) or methods.using_emcc(env): - env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if is_stderr_color() else "-fno-color-diagnostics"]) + env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if STDERR_COLOR else "-fno-color-diagnostics"]) if sys.platform == "win32": env.AppendUnique(CCFLAGS=["-fansi-escape-codes"]) # Set optimize and debug_symbols flags. # "custom" means do nothing and let users set their own optimization flags. # Needs to happen after configure to have `env.msvc` defined. -env.AppendUnique(CCFLAGS=["$OPTIMIZELEVEL"]) if env.msvc: if env["debug_symbols"]: - env.AppendUnique(CCFLAGS=["/Zi", "/FS"]) - env.AppendUnique(LINKFLAGS=["/DEBUG:FULL"]) + env.Append(CCFLAGS=["/Zi", "/FS"]) + env.Append(LINKFLAGS=["/DEBUG:FULL"]) else: - env.AppendUnique(LINKFLAGS=["/DEBUG:NONE"]) + env.Append(LINKFLAGS=["/DEBUG:NONE"]) if env["optimize"].startswith("speed"): - env["OPTIMIZELEVEL"] = "/O2" - env.AppendUnique(LINKFLAGS=["/OPT:REF"]) + env.Append(CCFLAGS=["/O2"]) + env.Append(LINKFLAGS=["/OPT:REF"]) if env["optimize"] == "speed_trace": - env.AppendUnique(LINKFLAGS=["/OPT:NOICF"]) - elif env["optimize"].startswith("size"): - env["OPTIMIZELEVEL"] = "/O1" - env.AppendUnique(LINKFLAGS=["/OPT:REF"]) - if env["optimize"] == "size_extra": - env.AppendUnique(CPPDEFINES=["SIZE_EXTRA"]) + env.Append(LINKFLAGS=["/OPT:NOICF"]) + elif env["optimize"] == "size": + env.Append(CCFLAGS=["/O1"]) + env.Append(LINKFLAGS=["/OPT:REF"]) elif env["optimize"] == "debug" or env["optimize"] == "none": - env["OPTIMIZELEVEL"] = "/Od" + env.Append(CCFLAGS=["/Od"]) else: if env["debug_symbols"]: if env["platform"] == "windows": if methods.using_clang(env): - env.AppendUnique(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows. + env.Append(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows. else: - env.AppendUnique(CCFLAGS=["-gdwarf-5"]) # For gcc, only dwarf-5 symbols seem usable by libbacktrace. + env.Append(CCFLAGS=["-gdwarf-5"]) # For gcc, only dwarf-5 symbols seem usable by libbacktrace. else: # Adding dwarf-4 explicitly makes stacktraces work with clang builds, # otherwise addr2line doesn't understand them - env.AppendUnique(CCFLAGS=["-gdwarf-4"]) + env.Append(CCFLAGS=["-gdwarf-4"]) if methods.using_emcc(env): # Emscripten only produces dwarf symbols when using "-g3". - env.AppendUnique(CCFLAGS=["-g3"]) + env.Append(CCFLAGS=["-g3"]) # Emscripten linker needs debug symbols options too. - env.AppendUnique(LINKFLAGS=["-gdwarf-4"]) - env.AppendUnique(LINKFLAGS=["-g3"]) + env.Append(LINKFLAGS=["-gdwarf-4"]) + env.Append(LINKFLAGS=["-g3"]) elif env.dev_build: - env.AppendUnique(CCFLAGS=["-g3"]) + env.Append(CCFLAGS=["-g3"]) else: - env.AppendUnique(CCFLAGS=["-g2"]) + env.Append(CCFLAGS=["-g2"]) if env["debug_paths_relative"]: # Remap absolute paths to relative paths for debug symbols. project_path = Dir("#").abspath - env.AppendUnique(CCFLAGS=[f"-ffile-prefix-map={project_path}=."]) + env.Append(CCFLAGS=[f"-ffile-prefix-map={project_path}=."]) else: if methods.is_apple_clang(env): # Apple Clang, its linker doesn't like -s. - env.AppendUnique(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"]) + env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"]) else: - env.AppendUnique(LINKFLAGS=["-s"]) + env.Append(LINKFLAGS=["-s"]) # Linker needs optimization flags too, at least for Emscripten. # For other toolchains, this _may_ be useful for LTO too to disambiguate. - env.AppendUnique(LINKFLAGS=["$OPTIMIZELEVEL"]) if env["optimize"] == "speed": - env["OPTIMIZELEVEL"] = "-O3" + env.Append(CCFLAGS=["-O3"]) + env.Append(LINKFLAGS=["-O3"]) # `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces. elif env["optimize"] == "speed_trace": - env["OPTIMIZELEVEL"] = "-O2" - elif env["optimize"].startswith("size"): - env["OPTIMIZELEVEL"] = "-Os" - if env["optimize"] == "size_extra": - env.AppendUnique(CPPDEFINES=["SIZE_EXTRA"]) + env.Append(CCFLAGS=["-O2"]) + env.Append(LINKFLAGS=["-O2"]) + elif env["optimize"] == "size": + env.Append(CCFLAGS=["-Os"]) + env.Append(LINKFLAGS=["-Os"]) elif env["optimize"] == "debug": - env["OPTIMIZELEVEL"] = "-Og" + env.Append(CCFLAGS=["-Og"]) + env.Append(LINKFLAGS=["-Og"]) elif env["optimize"] == "none": - env["OPTIMIZELEVEL"] = "-O0" + env.Append(CCFLAGS=["-O0"]) + env.Append(LINKFLAGS=["-O0"]) # Needs to happen after configure to handle "auto". if env["lto"] != "none": @@ -837,7 +813,6 @@ elif env.msvc: env.Append(CXXFLAGS=["/EHsc"]) # Configure compiler warnings -env.AppendUnique(CCFLAGS=["$WARNLEVEL"]) if env.msvc and not methods.using_clang(env): # MSVC # Disable warnings which we don't plan to fix. disabled_warnings = [ @@ -855,23 +830,19 @@ if env.msvc and not methods.using_clang(env): # MSVC ] if env["warnings"] == "extra": - env["WARNLEVEL"] = "/W4" - env.AppendUnique(CCFLAGS=disabled_warnings) + env.Append(CCFLAGS=["/W4"] + disabled_warnings) elif env["warnings"] == "all": - env["WARNLEVEL"] = "/W3" # C4458 is like -Wshadow. Part of /W4 but let's apply it for the default /W3 too. - env.AppendUnique(CCFLAGS=["/w34458"] + disabled_warnings) + env.Append(CCFLAGS=["/W3", "/w34458"] + disabled_warnings) elif env["warnings"] == "moderate": - env["WARNLEVEL"] = "/W2" - env.AppendUnique(CCFLAGS=disabled_warnings) + env.Append(CCFLAGS=["/W2"] + disabled_warnings) else: # 'no' - env["WARNLEVEL"] = "/w" # C4267 is particularly finicky & needs to be explicitly disabled. - env.AppendUnique(CCFLAGS=["/wd4267"]) + env.Append(CCFLAGS=["/w", "/wd4267"]) if env["werror"]: - env.AppendUnique(CCFLAGS=["/WX"]) - env.AppendUnique(LINKFLAGS=["/WX"]) + env.Append(CCFLAGS=["/WX"]) + env.Append(LINKFLAGS=["/WX"]) else: # GCC, Clang common_warnings = [] @@ -890,14 +861,14 @@ else: # GCC, Clang # for putting them in `Set` or `Map`. We don't mind about unreliable ordering. common_warnings += ["-Wno-ordered-compare-function-pointers"] - # clang-cl will interpret `-Wall` as `-Weverything`, workaround with compatibility cast. - env["WARNLEVEL"] = "-Wall" if not env.msvc else "-W3" + # clang-cl will interpret `-Wall` as `-Weverything`, workaround with compatibility cast + W_ALL = "-Wall" if not env.msvc else "-W3" if env["warnings"] == "extra": - env.AppendUnique(CCFLAGS=["-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings) - env.AppendUnique(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"]) + env.Append(CCFLAGS=[W_ALL, "-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings) + env.Append(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"]) if methods.using_gcc(env): - env.AppendUnique( + env.Append( CCFLAGS=[ "-Walloc-zero", "-Wduplicated-branches", @@ -905,38 +876,25 @@ else: # GCC, Clang "-Wstringop-overflow=4", ] ) - env.AppendUnique(CXXFLAGS=["-Wplacement-new=1", "-Wvirtual-inheritance"]) + env.Append(CXXFLAGS=["-Wplacement-new=1"]) # Need to fix a warning with AudioServer lambdas before enabling. # if cc_version_major != 9: # GCC 9 had a regression (GH-36325). # env.Append(CXXFLAGS=["-Wnoexcept"]) if cc_version_major >= 9: - env.AppendUnique(CCFLAGS=["-Wattribute-alias=2"]) + env.Append(CCFLAGS=["-Wattribute-alias=2"]) if cc_version_major >= 11: # Broke on MethodBind templates before GCC 11. - env.AppendUnique(CCFLAGS=["-Wlogical-op"]) + env.Append(CCFLAGS=["-Wlogical-op"]) elif methods.using_clang(env) or methods.using_emcc(env): - env.AppendUnique(CCFLAGS=["-Wimplicit-fallthrough"]) + env.Append(CCFLAGS=["-Wimplicit-fallthrough"]) elif env["warnings"] == "all": - env.AppendUnique(CCFLAGS=common_warnings) + env.Append(CCFLAGS=[W_ALL] + common_warnings) elif env["warnings"] == "moderate": - env.AppendUnique(CCFLAGS=["-Wno-unused"] + common_warnings) + env.Append(CCFLAGS=[W_ALL, "-Wno-unused"] + common_warnings) else: # 'no' - env["WARNLEVEL"] = "-w" + env.Append(CCFLAGS=["-w"]) if env["werror"]: - env.AppendUnique(CCFLAGS=["-Werror"]) - -# Configure external includes. -if env.msvc: - if not methods.using_clang(env): - if cc_version_major < 16 or (cc_version_major == 16 and cc_version_minor < 10): - env.AppendUnique(CCFLAGS=["/experimental:external"]) - env.AppendUnique(CCFLAGS=["/external:anglebrackets"]) - env.AppendUnique(CCFLAGS=["/external:W0"]) - env["EXTINCPREFIX"] = "/external:I" - env["EXTINCSUFFIX"] = "" -else: - env["EXTINCPREFIX"] = "-isystem " - env["EXTINCSUFFIX"] = "" + env.Append(CCFLAGS=["-Werror"]) if hasattr(detect, "get_program_suffix"): suffix = "." + detect.get_program_suffix() @@ -960,51 +918,6 @@ suffix += env.extra_suffix sys.path.remove(tmppath) sys.modules.pop("detect") -if env.editor_build: - unsupported_opts = [] - for disable_opt in [ - "disable_3d", - "disable_advanced_gui", - "disable_physics_2d", - "disable_physics_3d", - "disable_navigation_2d", - "disable_navigation_3d", - ]: - if env[disable_opt]: - unsupported_opts.append(disable_opt) - if unsupported_opts != []: - print_error( - "The following build option(s) cannot be used for editor builds, but only for export template builds: {}.".format( - ", ".join(unsupported_opts) - ) - ) - Exit(255) - -if env["disable_3d"]: - env.Append(CPPDEFINES=["_3D_DISABLED"]) - env["disable_navigation_3d"] = True - env["disable_physics_3d"] = True - env["disable_xr"] = True -if env["disable_advanced_gui"]: - env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"]) -if env["disable_physics_2d"]: - env.Append(CPPDEFINES=["PHYSICS_2D_DISABLED"]) -if env["disable_physics_3d"]: - env.Append(CPPDEFINES=["PHYSICS_3D_DISABLED"]) -if env["disable_navigation_2d"]: - env.Append(CPPDEFINES=["NAVIGATION_2D_DISABLED"]) -if env["disable_navigation_3d"]: - env.Append(CPPDEFINES=["NAVIGATION_3D_DISABLED"]) -if env["disable_xr"]: - env.Append(CPPDEFINES=["XR_DISABLED"]) -if env["minizip"]: - env.Append(CPPDEFINES=["MINIZIP_ENABLED"]) -if env["brotli"]: - env.Append(CPPDEFINES=["BROTLI_ENABLED"]) - -if not env["verbose"]: - methods.no_verbose(env) - modules_enabled = OrderedDict() env.module_dependencies = {} env.module_icons_paths = [] @@ -1055,6 +968,8 @@ if env.editor_build: print_error("Not all modules required by editor builds are enabled.") Exit(255) +env.version_info = methods.get_version_info(env.module_version_string) + env["PROGSUFFIX_WRAP"] = suffix + env.module_version_string + ".console" + env["PROGSUFFIX"] env["PROGSUFFIX"] = suffix + env.module_version_string + env["PROGSUFFIX"] env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"] @@ -1074,6 +989,28 @@ env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"] env["OBJPREFIX"] = env["object_prefix"] env["SHOBJPREFIX"] = env["object_prefix"] +if env["disable_3d"]: + if env.editor_build: + print_error("Build option `disable_3d=yes` cannot be used for editor builds, only for export template builds.") + Exit(255) + else: + env.Append(CPPDEFINES=["_3D_DISABLED"]) +if env["disable_advanced_gui"]: + if env.editor_build: + print_error( + "Build option `disable_advanced_gui=yes` cannot be used for editor builds, only for export template builds." + ) + Exit(255) + else: + env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"]) +if env["minizip"]: + env.Append(CPPDEFINES=["MINIZIP_ENABLED"]) +if env["brotli"]: + env.Append(CPPDEFINES=["BROTLI_ENABLED"]) + +if not env["verbose"]: + methods.no_verbose(env) + GLSL_BUILDERS = { "RD_GLSL": env.Builder( action=env.Run(glsl_builders.build_rd_headers), @@ -1114,14 +1051,6 @@ if env["ninja"]: if env["threads"]: env.Append(CPPDEFINES=["THREADS_ENABLED"]) -# Ensure build objects are put in their own folder if `redirect_build_objects` is enabled. -env.Prepend(LIBEMITTER=[methods.redirect_emitter]) -env.Prepend(SHLIBEMITTER=[methods.redirect_emitter]) -for key in (emitters := env.StaticObject.builder.emitter): - emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key])) -for key in (emitters := env.SharedObject.builder.emitter): - emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key])) - # Build subdirs, the build order is dependent on link order. Export("env") @@ -1153,11 +1082,11 @@ if "check_c_headers" in env: for header in headers: if conf.CheckCHeader(header): env.AppendUnique(CPPDEFINES=[headers[header]]) -conf.Finish() -# Miscellaneous & post-build methods. -if not env.GetOption("clean") and not env.GetOption("help"): - methods.dump(env) - methods.show_progress(env) - methods.prepare_purge(env) - methods.prepare_timer() + +methods.show_progress(env) +# TODO: replace this with `env.Dump(format="json")` +# once we start requiring SCons 4.0 as min version. +methods.dump(env) +methods.prepare_purge(env) +methods.prepare_timer() diff --git a/engine/core/SCsub b/engine/core/SCsub index a252a074..f055a75c 100644 --- a/engine/core/SCsub +++ b/engine/core/SCsub @@ -51,8 +51,8 @@ if env["brotli"] and env["builtin_brotli"]: ] thirdparty_brotli_sources = [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] - env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_brotli_dir + "include"]) - env.Prepend(CPPEXTPATH=[thirdparty_brotli_dir + "include"]) + env_thirdparty.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) + env.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) if env.get("use_ubsan") or env.get("use_asan") or env.get("use_tsan") or env.get("use_lsan") or env.get("use_msan"): env_thirdparty.Append(CPPDEFINES=["BROTLI_BUILD_PORTABLE"]) @@ -69,8 +69,8 @@ if env["builtin_clipper2"]: ] thirdparty_clipper_sources = [thirdparty_clipper_dir + file for file in thirdparty_clipper_sources] - env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_clipper_dir + "include"]) - env.Prepend(CPPEXTPATH=[thirdparty_clipper_dir + "include"]) + env_thirdparty.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"]) + env.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"]) env_thirdparty.Append(CPPDEFINES=["CLIPPER2_ENABLED"]) env.Append(CPPDEFINES=["CLIPPER2_ENABLED"]) @@ -94,9 +94,9 @@ if env["builtin_zlib"]: ] thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources] - env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zlib_dir]) + env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir]) # Needs to be available in main env too - env.Prepend(CPPEXTPATH=[thirdparty_zlib_dir]) + env.Prepend(CPPPATH=[thirdparty_zlib_dir]) if env.dev_build: env_thirdparty.Append(CPPDEFINES=["ZLIB_DEBUG"]) # Affects headers so it should also be defined for Godot code @@ -148,9 +148,9 @@ if env["builtin_zstd"]: thirdparty_zstd_sources.append("decompress/huf_decompress_amd64.S") thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] - env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) + env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) - env.Prepend(CPPEXTPATH=thirdparty_zstd_dir) + env.Prepend(CPPPATH=thirdparty_zstd_dir) # Also needed in main env includes will trigger warnings env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) @@ -167,9 +167,10 @@ env.add_source_files(env.core_sources, "*.cpp") # Generate disabled classes def disabled_class_builder(target, source, env): - with methods.generated_wrapper(str(target[0])) as file: + with methods.generated_wrapper(target) as file: for c in source[0].read(): - if cs := c.strip(): + cs = c.strip() + if cs != "": file.write(f"#define ClassDB_Disable_{cs} 1\n") @@ -178,51 +179,49 @@ env.CommandNoCache("disabled_classes.gen.h", env.Value(env.disabled_classes), en # Generate version info def version_info_builder(target, source, env): - with methods.generated_wrapper(str(target[0])) as file: + with methods.generated_wrapper(target) as file: file.write( """\ -#define GODOT_VERSION_SHORT_NAME "{short_name}" -#define GODOT_VERSION_NAME "{name}" -#define GODOT_VERSION_MAJOR {major} -#define GODOT_VERSION_MINOR {minor} -#define GODOT_VERSION_PATCH {patch} -#define GODOT_VERSION_STATUS "{status}" -#define GODOT_VERSION_BUILD "{build}" -#define GODOT_VERSION_MODULE_CONFIG "{module_config}" -#define GODOT_VERSION_WEBSITE "{website}" -#define GODOT_VERSION_DOCS_BRANCH "{docs_branch}" -#define GODOT_VERSION_DOCS_URL "https://docs.godotengine.org/en/" GODOT_VERSION_DOCS_BRANCH -""".format(**source[0].read()) +#define VERSION_SHORT_NAME "{short_name}" +#define VERSION_NAME "{name}" +#define VERSION_MAJOR {major} +#define VERSION_MINOR {minor} +#define VERSION_PATCH {patch} +#define VERSION_STATUS "{status}" +#define VERSION_BUILD "{build}" +#define VERSION_MODULE_CONFIG "{module_config}" +#define VERSION_WEBSITE "{website}" +#define VERSION_DOCS_BRANCH "{docs_branch}" +#define VERSION_DOCS_URL "https://docs.godotengine.org/en/" VERSION_DOCS_BRANCH +""".format(**env.version_info) ) -env.CommandNoCache( - "version_generated.gen.h", - env.Value(methods.get_version_info(env.module_version_string)), - env.Run(version_info_builder), -) +env.CommandNoCache("version_generated.gen.h", env.Value(env.version_info), env.Run(version_info_builder)) # Generate version hash def version_hash_builder(target, source, env): - with methods.generated_wrapper(str(target[0])) as file: + with methods.generated_wrapper(target) as file: file.write( """\ #include "core/version.h" -const char *const GODOT_VERSION_HASH = "{git_hash}"; -const uint64_t GODOT_VERSION_TIMESTAMP = {git_timestamp}; -""".format(**source[0].read()) +const char *const VERSION_HASH = "{git_hash}"; +const uint64_t VERSION_TIMESTAMP = {git_timestamp}; +""".format(**env.version_info) ) -gen_hash = env.CommandNoCache("version_hash.gen.cpp", env.Value(methods.get_git_info()), env.Run(version_hash_builder)) +gen_hash = env.CommandNoCache( + "version_hash.gen.cpp", env.Value(env.version_info["git_hash"]), env.Run(version_hash_builder) +) env.add_source_files(env.core_sources, gen_hash) # Generate AES256 script encryption key def encryption_key_builder(target, source, env): - with methods.generated_wrapper(str(target[0])) as file: + with methods.generated_wrapper(target) as file: file.write( f"""\ #include "core/config/project_settings.h" @@ -252,21 +251,30 @@ env.add_source_files(env.core_sources, gen_encrypt) # Certificates -env.CommandNoCache( +env.Depends( "#core/io/certs_compressed.gen.h", ["#thirdparty/certs/ca-certificates.crt", env.Value(env["builtin_certs"]), env.Value(env["system_certs_path"])], +) +env.CommandNoCache( + "#core/io/certs_compressed.gen.h", + "#thirdparty/certs/ca-certificates.crt", env.Run(core_builders.make_certs_header), ) # Authors -env.CommandNoCache("#core/authors.gen.h", "#AUTHORS.md", env.Run(core_builders.make_authors_header)) +env.Depends("#core/authors.gen.h", "../AUTHORS.md") +env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header)) # Donors -env.CommandNoCache("#core/donors.gen.h", "#DONORS.md", env.Run(core_builders.make_donors_header)) +env.Depends("#core/donors.gen.h", "../DONORS.md") +env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header)) # License +env.Depends("#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"]) env.CommandNoCache( - "#core/license.gen.h", ["#COPYRIGHT.txt", "#LICENSE.txt"], env.Run(core_builders.make_license_header) + "#core/license.gen.h", + ["../COPYRIGHT.txt", "../LICENSE.txt"], + env.Run(core_builders.make_license_header), ) # Chain load SCsubs diff --git a/engine/core/config/engine.cpp b/engine/core/config/engine.cpp index 0f7ead2f..402e6281 100644 --- a/engine/core/config/engine.cpp +++ b/engine/core/config/engine.cpp @@ -125,17 +125,17 @@ double Engine::get_unfrozen_time_scale() const { Dictionary Engine::get_version_info() const { Dictionary dict; - dict["major"] = GODOT_VERSION_MAJOR; - dict["minor"] = GODOT_VERSION_MINOR; - dict["patch"] = GODOT_VERSION_PATCH; - dict["hex"] = GODOT_VERSION_HEX; - dict["status"] = GODOT_VERSION_STATUS; - dict["build"] = GODOT_VERSION_BUILD; + dict["major"] = VERSION_MAJOR; + dict["minor"] = VERSION_MINOR; + dict["patch"] = VERSION_PATCH; + dict["hex"] = VERSION_HEX; + dict["status"] = VERSION_STATUS; + dict["build"] = VERSION_BUILD; - String hash = String(GODOT_VERSION_HASH); + String hash = String(VERSION_HASH); dict["hash"] = hash.is_empty() ? String("unknown") : hash; - dict["timestamp"] = GODOT_VERSION_TIMESTAMP; + dict["timestamp"] = VERSION_TIMESTAMP; String stringver = String(dict["major"]) + "." + String(dict["minor"]); if ((int)dict["patch"] != 0) { diff --git a/engine/core/config/engine.h b/engine/core/config/engine.h index 701cfda5..ec5fb955 100644 --- a/engine/core/config/engine.h +++ b/engine/core/config/engine.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef ENGINE_H +#define ENGINE_H #include "core/os/main_loop.h" #include "core/string/ustring.h" @@ -213,3 +214,5 @@ public: Engine(); virtual ~Engine(); }; + +#endif // ENGINE_H diff --git a/engine/core/config/project_settings.cpp b/engine/core/config/project_settings.cpp index 565a9734..e4cc0f9c 100644 --- a/engine/core/config/project_settings.cpp +++ b/engine/core/config/project_settings.cpp @@ -77,7 +77,7 @@ String ProjectSettings::get_imported_files_path() const { // This is used by the project manager to provide the initial_settings for config/features. const PackedStringArray ProjectSettings::get_required_features() { PackedStringArray features; - features.append(GODOT_VERSION_BRANCH); + features.append(VERSION_BRANCH); #ifdef REAL_T_IS_DOUBLE features.append("Double Precision"); #endif @@ -92,9 +92,9 @@ const PackedStringArray ProjectSettings::_get_supported_features() { #endif // Allow pinning to a specific patch number or build type by marking // them as supported. They're only used if the user adds them manually. - features.append(GODOT_VERSION_BRANCH "." _MKSTR(GODOT_VERSION_PATCH)); - features.append(GODOT_VERSION_FULL_CONFIG); - features.append(GODOT_VERSION_FULL_BUILD); + features.append(VERSION_BRANCH "." _MKSTR(VERSION_PATCH)); + features.append(VERSION_FULL_CONFIG); + features.append(VERSION_FULL_BUILD); #ifdef RD_ENABLED features.append("Forward Plus"); @@ -173,7 +173,7 @@ String ProjectSettings::localize_path(const String &p_path) const { if (dir->change_dir(path) == OK) { String cwd = dir->get_current_dir(); - cwd = cwd.replace_char('\\', '/'); + cwd = cwd.replace("\\", "/"); // Ensure that we end with a '/'. // This is important to ensure that we do not wrongly localize the resource path @@ -208,7 +208,7 @@ String ProjectSettings::localize_path(const String &p_path) const { if (plocal[plocal.length() - 1] == '/') { sep += 1; } - return plocal + path.substr(sep); + return plocal + path.substr(sep, path.size() - sep); } } @@ -289,7 +289,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { remove_autoload(node_name); } } else if (p_name.operator String().begins_with("global_group/")) { - String group_name = p_name.operator String().get_slicec('/', 1); + String group_name = p_name.operator String().get_slice("/", 1); if (global_groups.has(group_name)) { remove_global_group(group_name); } @@ -340,7 +340,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { } add_autoload(autoload); } else if (p_name.operator String().begins_with("global_group/")) { - String group_name = p_name.operator String().get_slicec('/', 1); + String group_name = p_name.operator String().get_slice("/", 1); add_global_group(group_name, p_value); } } @@ -359,14 +359,14 @@ bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const { return true; } -Variant ProjectSettings::get_setting_with_override_and_custom_features(const StringName &p_name, const Vector &p_features) const { +Variant ProjectSettings::get_setting_with_override(const StringName &p_name) const { _THREAD_SAFE_METHOD_ StringName name = p_name; if (feature_overrides.has(name)) { const LocalVector> &overrides = feature_overrides[name]; for (uint32_t i = 0; i < overrides.size(); i++) { - if (p_features.has(String(overrides[i].first).to_lower())) { + if (OS::get_singleton()->has_feature(overrides[i].first)) { // Custom features are checked in OS.has_feature() already. No need to check twice. if (props.has(overrides[i].second)) { name = overrides[i].second; break; @@ -376,39 +376,12 @@ Variant ProjectSettings::get_setting_with_override_and_custom_features(const Str } if (!props.has(name)) { - WARN_PRINT("Property not found: " + String(name)); + WARN_PRINT(vformat("Property not found: '%s'.", String(name))); return Variant(); } return props[name].variant; } -Variant ProjectSettings::get_setting_with_override(const StringName &p_name) const { - _THREAD_SAFE_METHOD_ - - const LocalVector> *overrides = feature_overrides.getptr(p_name); - if (overrides) { - for (uint32_t i = 0; i < overrides->size(); i++) { - if (!OS::get_singleton()->has_feature((*overrides)[i].first)) { - continue; - } - - // Custom features are checked in OS.has_feature() already. No need to check twice. - const RBMap::Element *override_prop = props.find((*overrides)[i].second); - if (override_prop) { - return override_prop->get().variant; - } - } - } - - const RBMap::Element *prop = props.find(p_name); - if (!prop) { - WARN_PRINT(vformat("Property not found: '%s'.", p_name)); - return Variant(); - } - - return prop->get().variant; -} - struct _VCSort { String name; Variant::Type type = Variant::VARIANT_MAX; @@ -591,7 +564,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b if (!OS::get_singleton()->get_resource_dir().is_empty()) { // OS will call ProjectSettings->get_resource_path which will be empty if not overridden! // If the OS would rather use a specific location, then it will not be empty. - resource_path = OS::get_singleton()->get_resource_dir().replace_char('\\', '/'); + resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/"); if (!resource_path.is_empty() && resource_path[resource_path.length() - 1] == '/') { resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end. } @@ -712,7 +685,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b while (true) { // Set the resource path early so things can be resolved when loading. resource_path = current_dir; - resource_path = resource_path.replace_char('\\', '/'); // Windows path to Unix path just in case. + resource_path = resource_path.replace("\\", "/"); // Windows path to Unix path just in case. err = _load_settings_text_or_binary(current_dir.path_join("project.godot"), current_dir.path_join("project.binary")); if (err == OK && !p_ignore_override) { // Optional, we don't mind if it fails. @@ -797,7 +770,8 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) { cs.resize(slen + 1); cs[slen] = 0; f->get_buffer((uint8_t *)cs.ptr(), slen); - String key = String::utf8(cs.ptr(), slen); + String key; + key.parse_utf8(cs.ptr(), slen); uint32_t vlen = f->get_32(); Vector d; @@ -1155,7 +1129,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust category = ""; } else { category = category.substr(0, div); - name = name.substr(div + 1); + name = name.substr(div + 1, name.size()); } save_props[category].push_back(name); } @@ -1167,7 +1141,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust save_features += ","; } - String f = p_custom_features[i].strip_edges().remove_char('\"'); + String f = p_custom_features[i].strip_edges().replace("\"", ""); save_features += f; } @@ -1434,7 +1408,6 @@ void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("get_setting", "name", "default_value"), &ProjectSettings::get_setting, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("get_setting_with_override", "name"), &ProjectSettings::get_setting_with_override); ClassDB::bind_method(D_METHOD("get_global_class_list"), &ProjectSettings::get_global_class_list); - ClassDB::bind_method(D_METHOD("get_setting_with_override_and_custom_features", "name", "features"), &ProjectSettings::get_setting_with_override_and_custom_features); ClassDB::bind_method(D_METHOD("set_order", "name", "position"), &ProjectSettings::set_order); ClassDB::bind_method(D_METHOD("get_order", "name"), &ProjectSettings::get_order); ClassDB::bind_method(D_METHOD("set_initial_value", "name", "value"), &ProjectSettings::set_initial_value); @@ -1461,8 +1434,8 @@ void ProjectSettings::_add_builtin_input_map() { Array events; // Convert list of input events into array - for (const Ref &event : E.value) { - events.push_back(event); + for (List>::Element *I = E.value.front(); I; I = I->next()) { + events.push_back(I->get()); } Dictionary action; @@ -1515,9 +1488,6 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("application/config/auto_accept_quit", true); GLOBAL_DEF("application/config/quit_on_go_back", true); - GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "accessibility/general/accessibility_support", PROPERTY_HINT_ENUM, "Auto (When Screen Reader is Running),Always Active,Disabled"), 0); - GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "accessibility/general/updates_per_second", PROPERTY_HINT_RANGE, "1,100,1"), 60); - // The default window size is tuned to: // - Have a 16:9 aspect ratio, // - Have both dimensions divisible by 8 to better play along with video recording, @@ -1527,10 +1497,9 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen,Exclusive Fullscreen"), 0); - // Keep the enum values in sync with the `Window::WINDOW_INITIAL_POSITION_` enum. - GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/initial_position_type", PROPERTY_HINT_ENUM, "Absolute:0,Center of Primary Screen:1,Center of Other Screen:3,Center of Screen With Mouse Pointer:4,Center of Screen With Keyboard Focus:5"), 1); - GLOBAL_DEF_BASIC(PropertyInfo(Variant::VECTOR2I, "display/window/size/initial_position"), Vector2i()); // Keep the enum values in sync with the `DisplayServer::SCREEN_` enum. + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/initial_position_type", PROPERTY_HINT_ENUM, "Absolute,Center of Primary Screen,Center of Other Screen,Center of Screen With Mouse Pointer,Center of Screen With Keyboard Focus"), 1); + GLOBAL_DEF_BASIC(PropertyInfo(Variant::VECTOR2I, "display/window/size/initial_position"), Vector2i()); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/initial_screen", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), 0); GLOBAL_DEF_BASIC("display/window/size/resizable", true); @@ -1540,8 +1509,6 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("display/window/size/extend_to_title", false); GLOBAL_DEF("display/window/size/no_focus", false); GLOBAL_DEF("display/window/size/sharp_corners", false); - GLOBAL_DEF("display/window/size/minimize_disabled", false); - GLOBAL_DEF("display/window/size/maximize_disabled", false); GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution @@ -1576,13 +1543,8 @@ ProjectSettings::ProjectSettings() { #else custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Unsafe (deprecated),Safe,Separate"); #endif - -#ifndef PHYSICS_2D_DISABLED GLOBAL_DEF("physics/2d/run_on_separate_thread", false); -#endif // PHYSICS_2D_DISABLED -#ifndef PHYSICS_3D_DISABLED GLOBAL_DEF("physics/3d/run_on_separate_thread", false); -#endif // PHYSICS_3D_DISABLED GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,canvas_items,viewport"), "disabled"); GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height,expand"), "keep"); @@ -1650,8 +1612,6 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false); GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1); - GLOBAL_DEF("input_devices/pointing/android/override_volume_buttons", false); - GLOBAL_DEF_BASIC("input_devices/pointing/android/disable_scroll_deadzone", false); // These properties will not show up in the dialog. If you want to exclude whole groups, use add_hidden_prefix(). GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray()); @@ -1660,19 +1620,6 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_INTERNAL("internationalization/locale/translations_pot_files", PackedStringArray()); GLOBAL_DEF_INTERNAL("internationalization/locale/translation_add_builtin_strings_to_pot", false); -#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) - GLOBAL_DEF("navigation/world/map_use_async_iterations", true); - - GLOBAL_DEF("navigation/avoidance/thread_model/avoidance_use_multiple_threads", true); - GLOBAL_DEF("navigation/avoidance/thread_model/avoidance_use_high_priority_threads", true); - - GLOBAL_DEF("navigation/pathfinding/max_threads", 4); - - GLOBAL_DEF("navigation/baking/use_crash_prevention_checks", true); - GLOBAL_DEF("navigation/baking/thread_model/baking_use_multiple_threads", true); - GLOBAL_DEF("navigation/baking/thread_model/baking_use_high_priority_threads", true); -#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) - ProjectSettings::get_singleton()->add_hidden_prefix("input/"); } diff --git a/engine/core/config/project_settings.h b/engine/core/config/project_settings.h index 65fa72ea..02049290 100644 --- a/engine/core/config/project_settings.h +++ b/engine/core/config/project_settings.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PROJECT_SETTINGS_H +#define PROJECT_SETTINGS_H #include "core/object/class_db.h" @@ -193,7 +194,6 @@ public: List get_input_presets() const { return input_presets; } Variant get_setting_with_override(const StringName &p_name) const; - Variant get_setting_with_override_and_custom_features(const StringName &p_name, const Vector &p_features) const; bool is_using_datapack() const; bool is_project_loaded() const; @@ -243,3 +243,5 @@ Variant _GLOBAL_DEF(const PropertyInfo &p_info, const Variant &p_default, bool p #define GLOBAL_DEF_RST_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true, true) #define GLOBAL_DEF_INTERNAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, false, true) + +#endif // PROJECT_SETTINGS_H diff --git a/engine/core/core_bind.compat.inc b/engine/core/core_bind.compat.inc index 8bfa66e4..22c78623 100644 --- a/engine/core/core_bind.compat.inc +++ b/engine/core/core_bind.compat.inc @@ -30,7 +30,7 @@ #ifndef DISABLE_DEPRECATED -namespace CoreBind { +namespace core_bind { // Semaphore @@ -53,12 +53,10 @@ Dictionary OS::_execute_with_pipe_bind_compat_94434(const String &p_path, const } void OS::_bind_compatibility_methods() { - ClassDB::bind_compatibility_method(D_METHOD("read_string_from_stdin", "buffer_size"), &OS::read_string_from_stdin); - ClassDB::bind_compatibility_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin); ClassDB::bind_compatibility_method(D_METHOD("read_string_from_stdin"), &OS::_read_string_from_stdin_bind_compat_91201); ClassDB::bind_compatibility_method(D_METHOD("execute_with_pipe", "path", "arguments"), &OS::_execute_with_pipe_bind_compat_94434); } -} // namespace CoreBind +} // namespace core_bind #endif // DISABLE_DEPRECATED diff --git a/engine/core/core_bind.cpp b/engine/core/core_bind.cpp index d55305b2..acd58978 100644 --- a/engine/core/core_bind.cpp +++ b/engine/core/core_bind.cpp @@ -42,7 +42,7 @@ #include "core/os/thread_safe.h" #include "core/variant/typed_array.h" -namespace CoreBind { +namespace core_bind { ////// ResourceLoader ////// @@ -466,8 +466,8 @@ bool OS::is_restart_on_exit_set() const { Vector OS::get_restart_on_exit_arguments() const { List args = ::OS::get_singleton()->get_restart_on_exit_arguments(); Vector args_vector; - for (const String &arg : args) { - args_vector.push_back(arg); + for (List::Element *E = args.front(); E; E = E->next()) { + args_vector.push_back(E->get()); } return args_vector; @@ -657,8 +657,8 @@ void OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_system_font_path_for_text", "font_name", "text", "locale", "script", "weight", "stretch", "italic"), &OS::get_system_font_path_for_text, DEFVAL(String()), DEFVAL(String()), DEFVAL(400), DEFVAL(100), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path); - ClassDB::bind_method(D_METHOD("read_string_from_stdin", "buffer_size"), &OS::read_string_from_stdin, DEFVAL(1024)); - ClassDB::bind_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin, DEFVAL(1024)); + ClassDB::bind_method(D_METHOD("read_string_from_stdin", "buffer_size"), &OS::read_string_from_stdin); + ClassDB::bind_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin); ClassDB::bind_method(D_METHOD("get_stdin_type"), &OS::get_stdin_type); ClassDB::bind_method(D_METHOD("get_stdout_type"), &OS::get_stdout_type); ClassDB::bind_method(D_METHOD("get_stderr_type"), &OS::get_stderr_type); @@ -806,11 +806,13 @@ Vector Geometry2D::get_closest_points_between_segments(const Vector2 &p } Vector2 Geometry2D::get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { - return ::Geometry2D::get_closest_point_to_segment(p_point, p_a, p_b); + Vector2 s[2] = { p_a, p_b }; + return ::Geometry2D::get_closest_point_to_segment(p_point, s); } Vector2 Geometry2D::get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { - return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b); + Vector2 s[2] = { p_a, p_b }; + return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, s); } bool Geometry2D::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const { @@ -1067,11 +1069,13 @@ Vector Geometry3D::get_closest_points_between_segments(const Vector3 &p } Vector3 Geometry3D::get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { - return ::Geometry3D::get_closest_point_to_segment(p_point, p_a, p_b); + Vector3 s[2] = { p_a, p_b }; + return ::Geometry3D::get_closest_point_to_segment(p_point, s); } Vector3 Geometry3D::get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { - return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b); + Vector3 s[2] = { p_a, p_b }; + return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, s); } Vector3 Geometry3D::get_triangle_barycentric_coords(const Vector3 &p_point, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { @@ -1237,9 +1241,6 @@ Vector Marshalls::base64_to_raw(const String &p_str) { } String Marshalls::utf8_to_base64(const String &p_str) { - if (p_str.is_empty()) { - return String(); - } CharString cstr = p_str.utf8(); String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length()); ERR_FAIL_COND_V(ret.is_empty(), ret); @@ -1339,7 +1340,6 @@ void Thread::_start_func(void *ud) { // When the call returns, we will reference the thread again if possible. ObjectID th_instance_id = t->get_instance_id(); Callable target_callable = t->target_callable; - String id = t->get_id(); t = Ref(); Callable::CallError ce; @@ -1347,7 +1347,7 @@ void Thread::_start_func(void *ud) { target_callable.callp(nullptr, 0, ret, ce); // If script properly kept a reference to the thread, we should be able to re-reference it now // (well, or if the call failed, since we had to break chains anyway because the outcome isn't known upfront). - t = ObjectDB::get_ref(th_instance_id); + t = Ref(ObjectDB::get_instance(th_instance_id)); if (t.is_valid()) { t->ret = ret; t->running.clear(); @@ -1357,7 +1357,7 @@ void Thread::_start_func(void *ud) { } if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_MSG(vformat("Could not call function '%s' to start thread %s: %s.", func_name, id, Variant::get_callable_error_text(target_callable, nullptr, 0, ce))); + ERR_FAIL_MSG(vformat("Could not call function '%s' to start thread %d: %s.", func_name, t->get_id(), Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce))); } } @@ -1419,7 +1419,7 @@ void Thread::_bind_methods() { BIND_ENUM_CONSTANT(PRIORITY_HIGH); } -namespace Special { +namespace special { ////// ClassDB ////// @@ -1438,8 +1438,8 @@ PackedStringArray ClassDB::get_class_list() const { } PackedStringArray ClassDB::get_inheriters_from_class(const StringName &p_class) const { - LocalVector classes; - ::ClassDB::get_inheriters_from_class(p_class, classes); + List classes; + ::ClassDB::get_inheriters_from_class(p_class, &classes); PackedStringArray ret; ret.resize(classes.size()); @@ -1746,7 +1746,7 @@ void ClassDB::_bind_methods() { BIND_ENUM_CONSTANT(API_NONE); } -} // namespace Special +} // namespace special ////// Engine ////// @@ -1876,8 +1876,8 @@ Vector Engine::get_singleton_list() const { List<::Engine::Singleton> singletons; ::Engine::get_singleton()->get_singletons(&singletons); Vector ret; - for (const ::Engine::Singleton &E : singletons) { - ret.push_back(E.name); + for (List<::Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { + ret.push_back(E->get().name); } return ret; } @@ -2190,4 +2190,4 @@ void EngineDebugger::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_breakpoints"), &EngineDebugger::clear_breakpoints); } -} // namespace CoreBind +} // namespace core_bind diff --git a/engine/core/core_bind.h b/engine/core/core_bind.h index ec74c53d..b96dc56b 100644 --- a/engine/core/core_bind.h +++ b/engine/core/core_bind.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CORE_BIND_H +#define CORE_BIND_H #include "core/debugger/engine_profiler.h" #include "core/io/resource_loader.h" @@ -41,7 +42,7 @@ class MainLoop; template class TypedArray; -namespace CoreBind { +namespace core_bind { class ResourceLoader : public Object { GDCLASS(ResourceLoader, Object); @@ -457,7 +458,7 @@ public: static void set_thread_safety_checks_enabled(bool p_enabled); }; -namespace Special { +namespace special { class ClassDB : public Object { GDCLASS(ClassDB, Object); @@ -523,7 +524,7 @@ public: ~ClassDB() {} }; -} // namespace Special +} // namespace special class Engine : public Object { GDCLASS(Engine, Object); @@ -651,21 +652,23 @@ public: ~EngineDebugger(); }; -} // namespace CoreBind +} // namespace core_bind -VARIANT_ENUM_CAST(CoreBind::ResourceLoader::ThreadLoadStatus); -VARIANT_ENUM_CAST(CoreBind::ResourceLoader::CacheMode); +VARIANT_ENUM_CAST(core_bind::ResourceLoader::ThreadLoadStatus); +VARIANT_ENUM_CAST(core_bind::ResourceLoader::CacheMode); -VARIANT_BITFIELD_CAST(CoreBind::ResourceSaver::SaverFlags); +VARIANT_BITFIELD_CAST(core_bind::ResourceSaver::SaverFlags); -VARIANT_ENUM_CAST(CoreBind::OS::RenderingDriver); -VARIANT_ENUM_CAST(CoreBind::OS::SystemDir); -VARIANT_ENUM_CAST(CoreBind::OS::StdHandleType); +VARIANT_ENUM_CAST(core_bind::OS::RenderingDriver); +VARIANT_ENUM_CAST(core_bind::OS::SystemDir); +VARIANT_ENUM_CAST(core_bind::OS::StdHandleType); -VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyBooleanOperation); -VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyJoinType); -VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyEndType); +VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyBooleanOperation); +VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyJoinType); +VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyEndType); -VARIANT_ENUM_CAST(CoreBind::Thread::Priority); +VARIANT_ENUM_CAST(core_bind::Thread::Priority); -VARIANT_ENUM_CAST(CoreBind::Special::ClassDB::APIType); +VARIANT_ENUM_CAST(core_bind::special::ClassDB::APIType); + +#endif // CORE_BIND_H diff --git a/engine/core/core_builders.py b/engine/core/core_builders.py index 5eaac237..d7c0603c 100644 --- a/engine/core/core_builders.py +++ b/engine/core/core_builders.py @@ -1,104 +1,171 @@ """Functions used to generate source files during build time""" -from collections import OrderedDict -from io import TextIOWrapper +import zlib -import methods + +def escape_string(s): + def charcode_to_c_escapes(c): + rev_result = [] + while c >= 256: + c, low = (c // 256, c % 256) + rev_result.append("\\%03o" % low) + rev_result.append("\\%03o" % c) + return "".join(reversed(rev_result)) + + result = "" + if isinstance(s, str): + s = s.encode("utf-8") + for c in s: + if not (32 <= c < 127) or c in (ord("\\"), ord('"')): + result += charcode_to_c_escapes(c) + else: + result += chr(c) + return result def make_certs_header(target, source, env): - buffer = methods.get_buffer(str(source[0])) - decomp_size = len(buffer) - buffer = methods.compress_buffer(buffer) + src = str(source[0]) + dst = str(target[0]) + with open(src, "rb") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: + buf = f.read() + decomp_size = len(buf) + + # Use maximum zlib compression level to further reduce file size + # (at the cost of initial build times). + buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION) + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef CERTS_COMPRESSED_GEN_H\n") + g.write("#define CERTS_COMPRESSED_GEN_H\n") - with methods.generated_wrapper(str(target[0])) as file: # System certs path. Editor will use them if defined. (for package maintainers) - file.write('#define _SYSTEM_CERTS_PATH "{}"\n'.format(env["system_certs_path"])) + path = env["system_certs_path"] + g.write('#define _SYSTEM_CERTS_PATH "%s"\n' % str(path)) if env["builtin_certs"]: # Defined here and not in env so changing it does not trigger a full rebuild. - file.write(f"""\ -#define BUILTIN_CERTS_ENABLED - -inline constexpr int _certs_compressed_size = {len(buffer)}; -inline constexpr int _certs_uncompressed_size = {decomp_size}; -inline constexpr unsigned char _certs_compressed[] = {{ - {methods.format_buffer(buffer, 1)} -}}; -""") + g.write("#define BUILTIN_CERTS_ENABLED\n") + g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n") + g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n") + g.write("static const unsigned char _certs_compressed[] = {\n") + for i in range(len(buf)): + g.write("\t" + str(buf[i]) + ",\n") + g.write("};\n") + g.write("#endif // CERTS_COMPRESSED_GEN_H") def make_authors_header(target, source, env): - SECTIONS = { - "Project Founders": "AUTHORS_FOUNDERS", - "Lead Developer": "AUTHORS_LEAD_DEVELOPERS", - "Project Manager": "AUTHORS_PROJECT_MANAGERS", - "Developers": "AUTHORS_DEVELOPERS", - } - buffer = methods.get_buffer(str(source[0])) - reading = False + sections = [ + "Project Founders", + "Lead Developer", + "Project Manager", + "Developers", + ] + sections_id = [ + "AUTHORS_FOUNDERS", + "AUTHORS_LEAD_DEVELOPERS", + "AUTHORS_PROJECT_MANAGERS", + "AUTHORS_DEVELOPERS", + ] - with methods.generated_wrapper(str(target[0])) as file: + src = str(source[0]) + dst = str(target[0]) + with open(src, "r", encoding="utf-8") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef AUTHORS_GEN_H\n") + g.write("#define AUTHORS_GEN_H\n") + + reading = False def close_section(): - file.write("\tnullptr,\n};\n\n") + g.write("\t0\n") + g.write("};\n") - for line in buffer.decode().splitlines(): - if line.startswith(" ") and reading: - file.write(f'\t"{methods.to_escaped_cstring(line).strip()}",\n') - elif line.startswith("## "): + for line in f: + if reading: + if line.startswith(" "): + g.write('\t"' + escape_string(line.strip()) + '",\n') + continue + if line.startswith("## "): if reading: close_section() reading = False - section = SECTIONS[line[3:].strip()] - if section: - file.write(f"inline constexpr const char *{section}[] = {{\n") - reading = True + for section, section_id in zip(sections, sections_id): + if line.strip().endswith(section): + current_section = escape_string(section_id) + reading = True + g.write("const char *const " + current_section + "[] = {\n") + break if reading: close_section() + g.write("#endif // AUTHORS_GEN_H\n") + def make_donors_header(target, source, env): - SECTIONS = { - "Patrons": "DONORS_PATRONS", - "Platinum sponsors": "DONORS_SPONSORS_PLATINUM", - "Gold sponsors": "DONORS_SPONSORS_GOLD", - "Silver sponsors": "DONORS_SPONSORS_SILVER", - "Diamond members": "DONORS_MEMBERS_DIAMOND", - "Titanium members": "DONORS_MEMBERS_TITANIUM", - "Platinum members": "DONORS_MEMBERS_PLATINUM", - "Gold members": "DONORS_MEMBERS_GOLD", - } - buffer = methods.get_buffer(str(source[0])) - reading = False + sections = [ + "Patrons", + "Platinum sponsors", + "Gold sponsors", + "Silver sponsors", + "Diamond members", + "Titanium members", + "Platinum members", + "Gold members", + ] + sections_id = [ + "DONORS_PATRONS", + "DONORS_SPONSORS_PLATINUM", + "DONORS_SPONSORS_GOLD", + "DONORS_SPONSORS_SILVER", + "DONORS_MEMBERS_DIAMOND", + "DONORS_MEMBERS_TITANIUM", + "DONORS_MEMBERS_PLATINUM", + "DONORS_MEMBERS_GOLD", + ] - with methods.generated_wrapper(str(target[0])) as file: + src = str(source[0]) + dst = str(target[0]) + with open(src, "r", encoding="utf-8") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef DONORS_GEN_H\n") + g.write("#define DONORS_GEN_H\n") + + reading = False def close_section(): - file.write("\tnullptr,\n};\n\n") + g.write("\t0\n") + g.write("};\n") - for line in buffer.decode().splitlines(): - if line.startswith(" ") and reading: - file.write(f'\t"{methods.to_escaped_cstring(line).strip()}",\n') - elif line.startswith("## "): + for line in f: + if reading >= 0: + if line.startswith(" "): + g.write('\t"' + escape_string(line.strip()) + '",\n') + continue + if line.startswith("## "): if reading: close_section() reading = False - section = SECTIONS.get(line[3:].strip()) - if section: - file.write(f"inline constexpr const char *{section}[] = {{\n") - reading = True + for section, section_id in zip(sections, sections_id): + if line.strip().endswith(section): + current_section = escape_string(section_id) + reading = True + g.write("const char *const " + current_section + "[] = {\n") + break if reading: close_section() + g.write("#endif // DONORS_GEN_H\n") + def make_license_header(target, source, env): src_copyright = str(source[0]) src_license = str(source[1]) + dst = str(target[0]) class LicenseReader: - def __init__(self, license_file: TextIOWrapper): + def __init__(self, license_file): self._license_file = license_file self.line_num = 0 self.current = self.next_line() @@ -121,7 +188,9 @@ def make_license_header(target, source, env): lines.append(self.current.strip()) return (tag, lines) - projects = OrderedDict() + from collections import OrderedDict + + projects: dict = OrderedDict() license_list = [] with open(src_copyright, "r", encoding="utf-8") as copyright_file: @@ -143,7 +212,7 @@ def make_license_header(target, source, env): part = {} reader.next_line() - data_list = [] + data_list: list = [] for project in iter(projects.values()): for part in project: part["file_index"] = len(data_list) @@ -151,76 +220,96 @@ def make_license_header(target, source, env): part["copyright_index"] = len(data_list) data_list += part["Copyright"] - with open(src_license, "r", encoding="utf-8") as file: - license_text = file.read() + with open(dst, "w", encoding="utf-8", newline="\n") as f: + f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + f.write("#ifndef LICENSE_GEN_H\n") + f.write("#define LICENSE_GEN_H\n") + f.write("const char *const GODOT_LICENSE_TEXT =") - with methods.generated_wrapper(str(target[0])) as file: - file.write(f"""\ -inline constexpr const char *GODOT_LICENSE_TEXT = {{ -{methods.to_raw_cstring(license_text)} -}}; + with open(src_license, "r", encoding="utf-8") as license_file: + for line in license_file: + escaped_string = escape_string(line.strip()) + f.write('\n\t\t"' + escaped_string + '\\n"') + f.write(";\n\n") -struct ComponentCopyrightPart {{ - const char *license; - const char *const *files; - const char *const *copyright_statements; - int file_count; - int copyright_count; -}}; + f.write( + "struct ComponentCopyrightPart {\n" + "\tconst char *license;\n" + "\tconst char *const *files;\n" + "\tconst char *const *copyright_statements;\n" + "\tint file_count;\n" + "\tint copyright_count;\n" + "};\n\n" + ) -struct ComponentCopyright {{ - const char *name; - const ComponentCopyrightPart *parts; - int part_count; -}}; + f.write( + "struct ComponentCopyright {\n" + "\tconst char *name;\n" + "\tconst ComponentCopyrightPart *parts;\n" + "\tint part_count;\n" + "};\n\n" + ) -""") - - file.write("inline constexpr const char *COPYRIGHT_INFO_DATA[] = {\n") + f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n") for line in data_list: - file.write(f'\t"{methods.to_escaped_cstring(line)}",\n') - file.write("};\n\n") + f.write('\t"' + escape_string(line) + '",\n') + f.write("};\n\n") - file.write("inline constexpr ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n") + f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n") part_index = 0 part_indexes = {} for project_name, project in iter(projects.items()): part_indexes[project_name] = part_index for part in project: - file.write( - f'\t{{ "{methods.to_escaped_cstring(part["License"][0])}", ' - + f"©RIGHT_INFO_DATA[{part['file_index']}], " - + f"©RIGHT_INFO_DATA[{part['copyright_index']}], " - + f"{len(part['Files'])}, {len(part['Copyright'])} }},\n" + f.write( + '\t{ "' + + escape_string(part["License"][0]) + + '", ' + + "©RIGHT_INFO_DATA[" + + str(part["file_index"]) + + "], " + + "©RIGHT_INFO_DATA[" + + str(part["copyright_index"]) + + "], " + + str(len(part["Files"])) + + ", " + + str(len(part["Copyright"])) + + " },\n" ) part_index += 1 - file.write("};\n\n") + f.write("};\n\n") - file.write(f"inline constexpr int COPYRIGHT_INFO_COUNT = {len(projects)};\n") + f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n") - file.write("inline constexpr ComponentCopyright COPYRIGHT_INFO[] = {\n") + f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n") for project_name, project in iter(projects.items()): - file.write( - f'\t{{ "{methods.to_escaped_cstring(project_name)}", ' - + f"©RIGHT_PROJECT_PARTS[{part_indexes[project_name]}], " - + f"{len(project)} }},\n" + f.write( + '\t{ "' + + escape_string(project_name) + + '", ' + + "©RIGHT_PROJECT_PARTS[" + + str(part_indexes[project_name]) + + "], " + + str(len(project)) + + " },\n" ) - file.write("};\n\n") + f.write("};\n\n") - file.write(f"inline constexpr int LICENSE_COUNT = {len(license_list)};\n") + f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n") - file.write("inline constexpr const char *LICENSE_NAMES[] = {\n") + f.write("const char *const LICENSE_NAMES[] = {\n") for license in license_list: - file.write(f'\t"{methods.to_escaped_cstring(license[0])}",\n') - file.write("};\n\n") + f.write('\t"' + escape_string(license[0]) + '",\n') + f.write("};\n\n") - file.write("inline constexpr const char *LICENSE_BODIES[] = {\n\n") + f.write("const char *const LICENSE_BODIES[] = {\n\n") for license in license_list: - to_raw = [] for line in license[1:]: if line == ".": - to_raw += [""] + f.write('\t"\\n"\n') else: - to_raw += [line] - file.write(f"{methods.to_raw_cstring(to_raw)},\n\n") - file.write("};\n\n") + f.write('\t"' + escape_string(line) + '\\n"\n') + f.write('\t"",\n\n') + f.write("};\n\n") + + f.write("#endif // LICENSE_GEN_H\n") diff --git a/engine/core/core_constants.h b/engine/core/core_constants.h index c432fdca..8ab4a78a 100644 --- a/engine/core/core_constants.h +++ b/engine/core/core_constants.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CORE_CONSTANTS_H +#define CORE_CONSTANTS_H #include "core/string/string_name.h" #include "core/templates/hash_map.h" @@ -46,3 +47,5 @@ public: static bool is_global_enum(const StringName &p_enum); static void get_enum_values(const StringName &p_enum, HashMap *p_values); }; + +#endif // CORE_CONSTANTS_H diff --git a/engine/core/core_globals.h b/engine/core/core_globals.h index 63a6a5b1..ebb1f41a 100644 --- a/engine/core/core_globals.h +++ b/engine/core/core_globals.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CORE_GLOBALS_H +#define CORE_GLOBALS_H // Home for state needed from global functions // that cannot be stored in Engine or OS due to e.g. circular includes @@ -39,3 +40,5 @@ public: static bool print_line_enabled; static bool print_error_enabled; }; + +#endif // CORE_GLOBALS_H diff --git a/engine/core/core_string_names.h b/engine/core/core_string_names.h index 33203c5b..be3bc38e 100644 --- a/engine/core/core_string_names.h +++ b/engine/core/core_string_names.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CORE_STRING_NAMES_H +#define CORE_STRING_NAMES_H #include "core/string/string_name.h" @@ -86,3 +87,5 @@ public: }; #define CoreStringName(m_name) CoreStringNames::get_singleton()->m_name + +#endif // CORE_STRING_NAMES_H diff --git a/engine/core/crypto/SCsub b/engine/core/crypto/SCsub index d33d119f..3cea6bfb 100644 --- a/engine/core/crypto/SCsub +++ b/engine/core/crypto/SCsub @@ -13,7 +13,7 @@ if is_builtin or not has_module: # Use our headers for builtin or if the module is not going to be compiled. # We decided not to depend on system mbedtls just for these few files that can # be easily extracted. - env_crypto.Prepend(CPPEXTPATH=["#thirdparty/mbedtls/include"]) + env_crypto.Prepend(CPPPATH=["#thirdparty/mbedtls/include"]) # MbedTLS core functions (for CryptoCore). # If the mbedtls module is compiled we don't need to add the .c files with our diff --git a/engine/core/crypto/aes_context.h b/engine/core/crypto/aes_context.h index 2ae62c84..ab0792ac 100644 --- a/engine/core/crypto/aes_context.h +++ b/engine/core/crypto/aes_context.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef AES_CONTEXT_H +#define AES_CONTEXT_H #include "core/crypto/crypto_core.h" #include "core/object/ref_counted.h" @@ -63,3 +64,5 @@ public: }; VARIANT_ENUM_CAST(AESContext::Mode); + +#endif // AES_CONTEXT_H diff --git a/engine/core/crypto/crypto.h b/engine/core/crypto/crypto.h index 9c752e77..dc4441c9 100644 --- a/engine/core/crypto/crypto.h +++ b/engine/core/crypto/crypto.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CRYPTO_H +#define CRYPTO_H #include "core/crypto/hashing_context.h" #include "core/io/resource.h" @@ -166,3 +167,5 @@ public: virtual void get_recognized_extensions(const Ref &p_resource, List *p_extensions) const override; virtual bool recognize(const Ref &p_resource) const override; }; + +#endif // CRYPTO_H diff --git a/engine/core/crypto/crypto_core.cpp b/engine/core/crypto/crypto_core.cpp index 9d2c346e..13852d51 100644 --- a/engine/core/crypto/crypto_core.cpp +++ b/engine/core/crypto/crypto_core.cpp @@ -214,8 +214,8 @@ Error CryptoCore::AESContext::decrypt_cfb(size_t p_length, uint8_t p_iv[16], con } // CryptoCore -String CryptoCore::b64_encode_str(const uint8_t *p_src, size_t p_src_len) { - size_t b64len = p_src_len / 3 * 4 + 4 + 1; +String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { + int b64len = p_src_len / 3 * 4 + 4 + 1; Vector b64buff; b64buff.resize(b64len); uint8_t *w64 = b64buff.ptrw(); @@ -225,27 +225,27 @@ String CryptoCore::b64_encode_str(const uint8_t *p_src, size_t p_src_len) { return ret ? String() : (const char *)&w64[0]; } -Error CryptoCore::b64_encode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len) { +Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len); return ret ? FAILED : OK; } -Error CryptoCore::b64_decode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len) { +Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len); return ret ? FAILED : OK; } -Error CryptoCore::md5(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[16]) { +Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) { int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash); return ret ? FAILED : OK; } -Error CryptoCore::sha1(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[20]) { +Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) { int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash); return ret ? FAILED : OK; } -Error CryptoCore::sha256(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[32]) { +Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) { int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0); return ret ? FAILED : OK; } diff --git a/engine/core/crypto/crypto_core.h b/engine/core/crypto/crypto_core.h index 8ef50fbc..4a9ffda8 100644 --- a/engine/core/crypto/crypto_core.h +++ b/engine/core/crypto/crypto_core.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CRYPTO_CORE_H +#define CRYPTO_CORE_H #include "core/object/ref_counted.h" @@ -106,11 +107,13 @@ public: Error decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst); }; - static String b64_encode_str(const uint8_t *p_src, size_t p_src_len); - static Error b64_encode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len); - static Error b64_decode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len); + static String b64_encode_str(const uint8_t *p_src, int p_src_len); + static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); + static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); - static Error md5(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[16]); - static Error sha1(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[20]); - static Error sha256(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[32]); + static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]); + static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]); + static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]); }; + +#endif // CRYPTO_CORE_H diff --git a/engine/core/crypto/hashing_context.h b/engine/core/crypto/hashing_context.h index 6c9de6a8..436afd83 100644 --- a/engine/core/crypto/hashing_context.h +++ b/engine/core/crypto/hashing_context.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef HASHING_CONTEXT_H +#define HASHING_CONTEXT_H #include "core/object/ref_counted.h" @@ -61,3 +62,5 @@ public: }; VARIANT_ENUM_CAST(HashingContext::HashType); + +#endif // HASHING_CONTEXT_H diff --git a/engine/core/debugger/debugger_marshalls.cpp b/engine/core/debugger/debugger_marshalls.cpp index 55b61f1c..cc36ca48 100644 --- a/engine/core/debugger/debugger_marshalls.cpp +++ b/engine/core/debugger/debugger_marshalls.cpp @@ -36,7 +36,8 @@ #define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size())) Array DebuggerMarshalls::ScriptStackDump::serialize() { - Array arr = { frames.size() * 3 }; + Array arr; + arr.push_back(frames.size() * 3); for (const ScriptLanguage::StackInfo &frame : frames) { arr.push_back(frame.file); arr.push_back(frame.line); @@ -63,7 +64,10 @@ bool DebuggerMarshalls::ScriptStackDump::deserialize(const Array &p_arr) { } Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) { - Array arr = { name, type, value.get_type() }; + Array arr; + arr.push_back(name); + arr.push_back(type); + arr.push_back(value.get_type()); Variant var = value; if (value.get_type() == Variant::OBJECT && value.get_validated_object() == nullptr) { @@ -95,20 +99,20 @@ bool DebuggerMarshalls::ScriptStackVariable::deserialize(const Array &p_arr) { } Array DebuggerMarshalls::OutputError::serialize() { + Array arr; + arr.push_back(hr); + arr.push_back(min); + arr.push_back(sec); + arr.push_back(msec); + arr.push_back(source_file); + arr.push_back(source_func); + arr.push_back(source_line); + arr.push_back(error); + arr.push_back(error_descr); + arr.push_back(warning); unsigned int size = callstack.size(); - Array arr = { - hr, - min, - sec, msec, - source_file, - source_func, - source_line, - error, - error_descr, - warning, - size * 3 - }; const ScriptLanguage::StackInfo *r = callstack.ptr(); + arr.push_back(size * 3); for (int i = 0; i < callstack.size(); i++) { arr.push_back(r[i].file); arr.push_back(r[i].func); diff --git a/engine/core/debugger/debugger_marshalls.h b/engine/core/debugger/debugger_marshalls.h index c661ef39..1072ddae 100644 --- a/engine/core/debugger/debugger_marshalls.h +++ b/engine/core/debugger/debugger_marshalls.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DEBUGGER_MARSHALLS_H +#define DEBUGGER_MARSHALLS_H #include "core/input/shortcut.h" #include "core/object/script_language.h" @@ -72,3 +73,5 @@ struct DebuggerMarshalls { static Array serialize_key_shortcut(const Ref &p_shortcut); static Ref deserialize_key_shortcut(const Array &p_keys); }; + +#endif // DEBUGGER_MARSHALLS_H diff --git a/engine/core/debugger/engine_debugger.cpp b/engine/core/debugger/engine_debugger.cpp index 8d0f5261..a9f87ad8 100644 --- a/engine/core/debugger/engine_debugger.cpp +++ b/engine/core/debugger/engine_debugger.cpp @@ -127,7 +127,7 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, singleton->poll_events(true); } -void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()) { +void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()) { register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more. if (p_uri.is_empty()) { return; @@ -149,7 +149,8 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, bo singleton = memnew(RemoteDebugger(Ref(peer))); script_debugger = memnew(ScriptDebugger); // Notify editor of our pid (to allow focus stealing). - Array msg = { OS::get_singleton()->get_process_id() }; + Array msg; + msg.push_back(OS::get_singleton()->get_process_id()); singleton->send_message("set_pid", msg); } if (!singleton) { @@ -159,14 +160,13 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, bo // There is a debugger, parse breakpoints. ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger(); singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints); - singleton_script_debugger->set_ignore_error_breaks(p_ignore_error_breaks); for (int i = 0; i < p_breakpoints.size(); i++) { const String &bp = p_breakpoints[i]; int sp = bp.rfind_char(':'); ERR_CONTINUE_MSG(sp == -1, vformat("Invalid breakpoint: '%s', expected file:line format.", bp)); - singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1).to_int(), bp.substr(0, sp)); + singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp)); } allow_focus_steal_fn = p_allow_focus_steal_fn; diff --git a/engine/core/debugger/engine_debugger.h b/engine/core/debugger/engine_debugger.h index cfe1b6e3..1822915f 100644 --- a/engine/core/debugger/engine_debugger.h +++ b/engine/core/debugger/engine_debugger.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef ENGINE_DEBUGGER_H +#define ENGINE_DEBUGGER_H #include "core/string/string_name.h" #include "core/string/ustring.h" @@ -106,7 +107,7 @@ public: _FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; } - static void initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()); + static void initialize(const String &p_uri, bool p_skip_breakpoints, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()); static void deinitialize(); static void register_profiler(const StringName &p_name, const Profiler &p_profiler); static void unregister_profiler(const StringName &p_name); @@ -139,3 +140,5 @@ public: virtual ~EngineDebugger(); }; + +#endif // ENGINE_DEBUGGER_H diff --git a/engine/core/debugger/engine_profiler.h b/engine/core/debugger/engine_profiler.h index f74d20b8..d3d0021e 100644 --- a/engine/core/debugger/engine_profiler.h +++ b/engine/core/debugger/engine_profiler.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef ENGINE_PROFILER_H +#define ENGINE_PROFILER_H #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" @@ -58,3 +59,5 @@ public: EngineProfiler() {} virtual ~EngineProfiler(); }; + +#endif // ENGINE_PROFILER_H diff --git a/engine/core/debugger/local_debugger.cpp b/engine/core/debugger/local_debugger.cpp index 47a6d15d..a5d807f6 100644 --- a/engine/core/debugger/local_debugger.cpp +++ b/engine/core/debugger/local_debugger.cpp @@ -242,7 +242,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } else if (line.begins_with("br") || line.begins_with("break")) { if (line.get_slice_count(" ") <= 1) { const HashMap> &breakpoints = script_debugger->get_breakpoints(); - if (breakpoints.is_empty()) { + if (breakpoints.size() == 0) { print_line("No Breakpoints."); continue; } diff --git a/engine/core/debugger/local_debugger.h b/engine/core/debugger/local_debugger.h index 5c603e5f..13c975c4 100644 --- a/engine/core/debugger/local_debugger.h +++ b/engine/core/debugger/local_debugger.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef LOCAL_DEBUGGER_H +#define LOCAL_DEBUGGER_H #include "core/debugger/engine_debugger.h" #include "core/object/script_language.h" @@ -54,3 +55,5 @@ public: LocalDebugger(); ~LocalDebugger(); }; + +#endif // LOCAL_DEBUGGER_H diff --git a/engine/core/debugger/remote_debugger.cpp b/engine/core/debugger/remote_debugger.cpp index d14ea59a..f8e42e6d 100644 --- a/engine/core/debugger/remote_debugger.cpp +++ b/engine/core/debugger/remote_debugger.cpp @@ -95,7 +95,10 @@ public: }; Error RemoteDebugger::_put_msg(const String &p_message, const Array &p_data) { - Array msg = { p_message, Thread::get_caller_id(), p_data }; + Array msg; + msg.push_back(p_message); + msg.push_back(Thread::get_caller_id()); + msg.push_back(p_data); Error err = peer->put_message(msg); if (err != OK) { n_messages_dropped++; @@ -232,7 +235,9 @@ void RemoteDebugger::flush_output() { types.push_back(MESSAGE_TYPE_LOG); } - Array arr = { strings, types }; + Array arr; + arr.push_back(strings); + arr.push_back(types); _put_msg("output", arr); output_strings.clear(); } @@ -408,25 +413,17 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } ScriptLanguage *script_lang = script_debugger->get_break_language(); - ERR_FAIL_NULL(script_lang); - const bool can_break = !(p_is_error_breakpoint && script_debugger->is_ignoring_error_breaks()); const String error_str = script_lang ? script_lang->debug_get_error() : ""; - - if (can_break) { - Array msg = { - p_can_continue, - error_str, - script_lang->debug_get_stack_level_count() > 0, - Thread::get_caller_id() - }; - if (allow_focus_steal_fn) { - allow_focus_steal_fn(); - } - send_message("debug_enter", msg); - } else { - ERR_PRINT(error_str); - return; + Array msg; + msg.push_back(p_can_continue); + msg.push_back(error_str); + ERR_FAIL_NULL(script_lang); + msg.push_back(script_lang->debug_get_stack_level_count() > 0); + msg.push_back(Thread::get_caller_id() == Thread::get_main_id() ? String(RTR("Main Thread")) : itos(Thread::get_caller_id())); + if (allow_focus_steal_fn) { + allow_focus_steal_fn(); } + send_message("debug_enter", msg); Input::MouseMode mouse_mode = Input::MOUSE_MODE_VISIBLE; @@ -510,7 +507,8 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { script_lang->debug_get_globals(&globals, &globals_vals); ERR_FAIL_COND(globals.size() != globals_vals.size()); - Array var_size = { local_vals.size() + member_vals.size() + globals_vals.size() }; + Array var_size; + var_size.push_back(local_vals.size() + member_vals.size() + globals_vals.size()); send_message("stack_frame_vars", var_size); _send_stack_vars(locals, local_vals, 0); _send_stack_vars(members, member_vals, 1); @@ -532,9 +530,6 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } else if (command == "set_skip_breakpoints") { ERR_FAIL_COND(data.is_empty()); script_debugger->set_skip_breakpoints(data[0]); - } else if (command == "set_ignore_error_breaks") { - ERR_FAIL_COND(data.is_empty()); - script_debugger->set_ignore_error_breaks(data[0]); } else if (command == "evaluate") { String expression_str = data[0]; int frame = data[1]; @@ -674,9 +669,6 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo } else if (p_cmd == "set_skip_breakpoints") { ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA); script_debugger->set_skip_breakpoints(p_data[0]); - } else if (p_cmd == "set_ignore_error_breaks") { - ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA); - script_debugger->set_ignore_error_breaks(p_data[0]); } else if (p_cmd == "break") { script_debugger->debug(script_debugger->get_break_language()); } else { diff --git a/engine/core/debugger/remote_debugger.h b/engine/core/debugger/remote_debugger.h index cbac2257..e91d09be 100644 --- a/engine/core/debugger/remote_debugger.h +++ b/engine/core/debugger/remote_debugger.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef REMOTE_DEBUGGER_H +#define REMOTE_DEBUGGER_H #include "core/debugger/debugger_marshalls.h" #include "core/debugger/engine_debugger.h" @@ -121,3 +122,5 @@ public: explicit RemoteDebugger(Ref p_peer); ~RemoteDebugger(); }; + +#endif // REMOTE_DEBUGGER_H diff --git a/engine/core/debugger/remote_debugger_peer.cpp b/engine/core/debugger/remote_debugger_peer.cpp index 011e6722..1afb7fe0 100644 --- a/engine/core/debugger/remote_debugger_peer.cpp +++ b/engine/core/debugger/remote_debugger_peer.cpp @@ -96,7 +96,7 @@ void RemoteDebuggerPeerTCP::_write_out() { while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED && tcp_client->wait(NetSocket::POLL_TYPE_OUT) == OK) { uint8_t *buf = out_buf.ptrw(); if (out_left <= 0) { - if (out_queue.is_empty()) { + if (out_queue.size() == 0) { break; // Nothing left to send } mutex.lock(); diff --git a/engine/core/debugger/remote_debugger_peer.h b/engine/core/debugger/remote_debugger_peer.h index 3b171e4b..37da0a92 100644 --- a/engine/core/debugger/remote_debugger_peer.h +++ b/engine/core/debugger/remote_debugger_peer.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef REMOTE_DEBUGGER_PEER_H +#define REMOTE_DEBUGGER_PEER_H #include "core/io/stream_peer_tcp.h" #include "core/object/ref_counted.h" @@ -91,3 +92,5 @@ public: RemoteDebuggerPeerTCP(Ref p_stream = Ref()); ~RemoteDebuggerPeerTCP(); }; + +#endif // REMOTE_DEBUGGER_PEER_H diff --git a/engine/core/debugger/script_debugger.cpp b/engine/core/debugger/script_debugger.cpp index e522d9ba..e7d8654a 100644 --- a/engine/core/debugger/script_debugger.cpp +++ b/engine/core/debugger/script_debugger.cpp @@ -58,7 +58,7 @@ void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) { } breakpoints[p_line].erase(p_source); - if (breakpoints[p_line].is_empty()) { + if (breakpoints[p_line].size() == 0) { breakpoints.erase(p_line); } } @@ -79,14 +79,6 @@ bool ScriptDebugger::is_skipping_breakpoints() { return skip_breakpoints; } -void ScriptDebugger::set_ignore_error_breaks(bool p_ignore) { - ignore_error_breaks = p_ignore; -} - -bool ScriptDebugger::is_ignoring_error_breaks() { - return ignore_error_breaks; -} - void ScriptDebugger::debug(ScriptLanguage *p_lang, bool p_can_continue, bool p_is_error_breakpoint) { ScriptLanguage *prev = break_lang; break_lang = p_lang; diff --git a/engine/core/debugger/script_debugger.h b/engine/core/debugger/script_debugger.h index 0a5ffe78..fb786f1b 100644 --- a/engine/core/debugger/script_debugger.h +++ b/engine/core/debugger/script_debugger.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef SCRIPT_DEBUGGER_H +#define SCRIPT_DEBUGGER_H #include "core/object/script_language.h" #include "core/string/string_name.h" @@ -39,7 +40,6 @@ class ScriptDebugger { typedef ScriptLanguage::StackInfo StackInfo; bool skip_breakpoints = false; - bool ignore_error_breaks = false; HashMap> breakpoints; @@ -64,8 +64,6 @@ public: ScriptLanguage *get_break_language() { return break_lang; } void set_skip_breakpoints(bool p_skip_breakpoints); bool is_skipping_breakpoints(); - void set_ignore_error_breaks(bool p_ignore); - bool is_ignoring_error_breaks(); void insert_breakpoint(int p_line, const StringName &p_source); void remove_breakpoint(int p_line, const StringName &p_source); _ALWAYS_INLINE_ bool is_breakpoint(int p_line, const StringName &p_source) const { @@ -84,3 +82,5 @@ public: Vector get_error_stack_info() const; ScriptDebugger() {} }; + +#endif // SCRIPT_DEBUGGER_H diff --git a/engine/core/doc_data.cpp b/engine/core/doc_data.cpp index d1904025..28814435 100644 --- a/engine/core/doc_data.cpp +++ b/engine/core/doc_data.cpp @@ -32,11 +32,11 @@ String DocData::get_default_value_string(const Variant &p_value) { if (p_value.get_type() == Variant::ARRAY) { - return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string().replace_char('\n', ' '); + return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string().replace("\n", " "); } else if (p_value.get_type() == Variant::DICTIONARY) { - return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace_char('\n', ' '); + return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace("\n", " "); } else { - return p_value.get_construct_string().replace_char('\n', ' '); + return p_value.get_construct_string().replace("\n", " "); } } @@ -51,7 +51,7 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper } else if (p_retinfo.type == Variant::INT && p_retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) { p_method.return_enum = p_retinfo.class_name; if (p_method.return_enum.begins_with("_")) { //proxy class - p_method.return_enum = p_method.return_enum.substr(1); + p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length()); } p_method.return_is_bitfield = p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD; p_method.return_type = "int"; @@ -85,7 +85,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const } else if (p_arginfo.type == Variant::INT && p_arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) { p_argument.enumeration = p_arginfo.class_name; if (p_argument.enumeration.begins_with("_")) { //proxy class - p_argument.enumeration = p_argument.enumeration.substr(1); + p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length()); } p_argument.is_bitfield = p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD; p_argument.type = "int"; @@ -136,10 +136,11 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met return_doc_from_retinfo(p_method, p_methodinfo.return_val); - for (int64_t i = 0; i < p_methodinfo.arguments.size(); ++i) { + int i = 0; + for (List::ConstIterator itr = p_methodinfo.arguments.begin(); itr != p_methodinfo.arguments.end(); ++itr, ++i) { DocData::ArgumentDoc argument; - argument_doc_from_arginfo(argument, p_methodinfo.arguments[i]); - int64_t default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); + argument_doc_from_arginfo(argument, *itr); + int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); if (default_arg_index >= 0) { Variant default_arg = p_methodinfo.default_arguments[default_arg_index]; argument.default_value = get_default_value_string(default_arg); diff --git a/engine/core/doc_data.h b/engine/core/doc_data.h index 50e67ec7..49f9c3aa 100644 --- a/engine/core/doc_data.h +++ b/engine/core/doc_data.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DOC_DATA_H +#define DOC_DATA_H #include "core/io/xml_parser.h" #include "core/variant/variant.h" @@ -114,7 +115,7 @@ public: // Must be an operator or a constructor since there is no other overloading if (name.left(8) == "operator") { if (arguments.size() == p_method.arguments.size()) { - if (arguments.is_empty()) { + if (arguments.size() == 0) { return false; } return arguments[0].type < p_method.arguments[0].type; @@ -126,7 +127,7 @@ public: // - 1. Default constructor: Foo() // - 2. Copy constructor: Foo(Foo) // - 3+. Other constructors Foo(Bar, ...) based on first argument's name - if (arguments.is_empty() || p_method.arguments.is_empty()) { // 1. + 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. @@ -794,8 +795,8 @@ public: if (p_dict.has("enums")) { enums = p_dict["enums"]; } - for (const KeyValue &kv : enums) { - doc.enums[kv.key] = EnumDoc::from_dict(kv.value); + for (int i = 0; i < enums.size(); i++) { + doc.enums[enums.get_key_at_index(i)] = EnumDoc::from_dict(enums.get_value_at_index(i)); } Array properties; @@ -979,3 +980,5 @@ public: static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo); static void method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc); }; + +#endif // DOC_DATA_H diff --git a/engine/core/error/error_list.cpp b/engine/core/error/error_list.cpp index 13e560c3..f14cc84b 100644 --- a/engine/core/error/error_list.cpp +++ b/engine/core/error/error_list.cpp @@ -30,8 +30,6 @@ #include "error_list.h" -#include - const char *error_names[] = { "OK", // OK "Failed", // FAILED @@ -84,4 +82,4 @@ const char *error_names[] = { "Printer on fire", // ERR_PRINTER_ON_FIRE }; -static_assert(std::size(error_names) == ERR_MAX); +static_assert(sizeof(error_names) / sizeof(*error_names) == ERR_MAX); diff --git a/engine/core/error/error_list.h b/engine/core/error/error_list.h index cdc31ecd..cdf06eb0 100644 --- a/engine/core/error/error_list.h +++ b/engine/core/error/error_list.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef ERROR_LIST_H +#define ERROR_LIST_H /** Error List. Please never compare an error against FAILED * Either do result != OK , or !result. This way, Error fail @@ -97,3 +98,5 @@ enum Error { }; extern const char *error_names[]; + +#endif // ERROR_LIST_H diff --git a/engine/core/error/error_macros.cpp b/engine/core/error/error_macros.cpp index 74dc9336..a2369992 100644 --- a/engine/core/error/error_macros.cpp +++ b/engine/core/error/error_macros.cpp @@ -31,7 +31,6 @@ #include "error_macros.h" #include "core/io/logger.h" -#include "core/object/object_id.h" #include "core/os/os.h" #include "core/string/ustring.h" @@ -188,7 +187,7 @@ void _physics_interpolation_warning(const char *p_function, const char *p_file, } else { String node_name; if (p_id.is_valid()) { - Node *node = ObjectDB::get_instance(p_id); + Node *node = Object::cast_to(ObjectDB::get_instance(p_id)); if (node && node->is_inside_tree()) { node_name = "\"" + String(node->get_path()) + "\""; } else { diff --git a/engine/core/error/error_macros.h b/engine/core/error/error_macros.h index bedb84b4..752fd605 100644 --- a/engine/core/error/error_macros.h +++ b/engine/core/error/error_macros.h @@ -28,14 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef ERROR_MACROS_H +#define ERROR_MACROS_H +#include "core/object/object_id.h" #include "core/typedefs.h" -#include // IWYU pragma: keep // Used in macro. We'd normally use `safe_refcount.h`, but that would cause circular includes. +#include // We'd normally use safe_refcount.h, but that would cause circular includes. class String; -class ObjectID; enum ErrorHandlerType { ERR_HANDLER_ERROR, @@ -61,16 +62,16 @@ void add_error_handler(ErrorHandlerList *p_handler); void remove_error_handler(const ErrorHandlerList *p_handler); // Functions used by the error macros. -_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); void _err_print_error_asap(const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -_NO_INLINE_ void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool p_editor_notify = false, bool fatal = false); -_NO_INLINE_ void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify = false, bool fatal = false); -_NO_INLINE_ void _err_flush_stdout(); +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool p_editor_notify = false, bool fatal = false); +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify = false, bool fatal = false); +void _err_flush_stdout(); void _physics_interpolation_warning(const char *p_function, const char *p_file, int p_line, ObjectID p_id, const char *p_warn_string); @@ -844,3 +845,5 @@ void _physics_interpolation_warning(const char *p_function, const char *p_file, #define PHYSICS_INTERPOLATION_WARNING(m_string) \ _physics_interpolation_warning(FUNCTION_STR, __FILE__, __LINE__, ObjectID(UINT64_MAX), m_string) + +#endif // ERROR_MACROS_H diff --git a/engine/core/extension/extension_api_dump.cpp b/engine/core/extension/extension_api_dump.cpp index 93b1b272..52f1672a 100644 --- a/engine/core/extension/extension_api_dump.cpp +++ b/engine/core/extension/extension_api_dump.cpp @@ -96,7 +96,8 @@ static String fix_doc_description(const String &p_bbcode) { // Based on what EditorHelp does. return p_bbcode.dedent() - .remove_chars("\t\r") + .replace("\t", "") + .replace("\r", "") .strip_edges(); } @@ -106,22 +107,16 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { { //header Dictionary header; - header["version_major"] = GODOT_VERSION_MAJOR; - header["version_minor"] = GODOT_VERSION_MINOR; -#if GODOT_VERSION_PATCH - header["version_patch"] = GODOT_VERSION_PATCH; + header["version_major"] = VERSION_MAJOR; + header["version_minor"] = VERSION_MINOR; +#if VERSION_PATCH + header["version_patch"] = VERSION_PATCH; #else header["version_patch"] = 0; #endif - header["version_status"] = GODOT_VERSION_STATUS; - header["version_build"] = GODOT_VERSION_BUILD; - header["version_full_name"] = GODOT_VERSION_FULL_NAME; - -#if REAL_T_IS_DOUBLE - header["precision"] = "double"; -#else - header["precision"] = "single"; -#endif + header["version_status"] = VERSION_STATUS; + header["version_build"] = VERSION_BUILD; + header["version_full_name"] = VERSION_FULL_NAME; api_dump["header"] = header; } @@ -283,43 +278,43 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { #define REAL_MEMBER_OFFSET(type, member) \ { \ type, \ - member, \ - "float", \ - sizeof(float), \ - "float", \ - sizeof(float), \ - "double", \ - sizeof(double), \ - "double", \ - sizeof(double), \ + member, \ + "float", \ + sizeof(float), \ + "float", \ + sizeof(float), \ + "double", \ + sizeof(double), \ + "double", \ + sizeof(double), \ } #define INT32_MEMBER_OFFSET(type, member) \ { \ type, \ - member, \ - "int32", \ - sizeof(int32_t), \ - "int32", \ - sizeof(int32_t), \ - "int32", \ - sizeof(int32_t), \ - "int32", \ - sizeof(int32_t), \ + member, \ + "int32", \ + sizeof(int32_t), \ + "int32", \ + sizeof(int32_t), \ + "int32", \ + sizeof(int32_t), \ + "int32", \ + sizeof(int32_t), \ } #define INT32_BASED_BUILTIN_MEMBER_OFFSET(type, member, member_type, member_elems) \ { \ type, \ - member, \ - member_type, \ - sizeof(int32_t) * member_elems, \ - member_type, \ - sizeof(int32_t) * member_elems, \ - member_type, \ - sizeof(int32_t) * member_elems, \ - member_type, \ - sizeof(int32_t) * member_elems, \ + member, \ + member_type, \ + sizeof(int32_t) * member_elems, \ + member_type, \ + sizeof(int32_t) * member_elems, \ + member_type, \ + sizeof(int32_t) * member_elems, \ + member_type, \ + sizeof(int32_t) * member_elems, \ } #define REAL_BASED_BUILTIN_MEMBER_OFFSET(type, member, member_type, member_elems) \ @@ -975,14 +970,14 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { Array values; List enum_constant_list; ClassDB::get_enum_constants(class_name, F, &enum_constant_list, true); - for (const StringName &enum_constant : enum_constant_list) { + for (List::Element *G = enum_constant_list.front(); G; G = G->next()) { Dictionary d3; - d3["name"] = String(enum_constant); - d3["value"] = ClassDB::get_integer_constant(class_name, enum_constant); + d3["name"] = String(G->get()); + d3["value"] = ClassDB::get_integer_constant(class_name, G->get()); if (p_include_docs) { for (const DocData::ConstantDoc &constant_doc : class_doc->constants) { - if (constant_doc.name == enum_constant) { + if (constant_doc.name == G->get()) { d3["description"] = fix_doc_description(constant_doc.description); break; } @@ -1053,8 +1048,9 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { } Array arguments; - for (int64_t i = 0; i < mi.arguments.size(); ++i) { - const PropertyInfo &pinfo = mi.arguments[i]; + int i = 0; + for (List::ConstIterator itr = mi.arguments.begin(); itr != mi.arguments.end(); ++itr, ++i) { + const PropertyInfo &pinfo = *itr; Dictionary d3; d3["name"] = pinfo.name; @@ -1179,10 +1175,11 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { Array arguments; - for (int64_t i = 0; i < F.arguments.size(); ++i) { + int i = 0; + for (List::ConstIterator itr = F.arguments.begin(); itr != F.arguments.end(); ++itr, ++i) { Dictionary d3; - d3["name"] = F.arguments[i].name; - d3["type"] = get_property_info_type_name(F.arguments[i]); + d3["name"] = itr->name; + d3["type"] = get_property_info_type_name(*itr); if (F.get_argument_meta(i) > 0) { d3["meta"] = get_type_meta_name((GodotTypeInfo::Metadata)F.get_argument_meta(i)); } @@ -1343,16 +1340,16 @@ static bool compare_value(const String &p_path, const String &p_field, const Var } else if (p_old_value.get_type() == Variant::DICTIONARY && p_new_value.get_type() == Variant::DICTIONARY) { Dictionary old_dict = p_old_value; Dictionary new_dict = p_new_value; - for (const KeyValue &kv : old_dict) { - if (!new_dict.has(kv.key)) { + for (const Variant &key : old_dict.keys()) { + if (!new_dict.has(key)) { failed = true; - print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, kv.key)); + print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, key)); continue; } - if (p_allow_name_change && kv.key == "name") { + if (p_allow_name_change && key == "name") { continue; } - if (!compare_value(path, kv.key, kv.value, new_dict[kv.key], p_allow_name_change)) { + if (!compare_value(path, key, old_dict[key], new_dict[key], p_allow_name_change)) { failed = true; } } @@ -1423,25 +1420,25 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_ bool optional = field.begins_with("*"); if (optional) { // This is an optional field, but if exists it has to exist in both. - field = field.substr(1); + field = field.substr(1, field.length()); } bool added = field.begins_with("+"); if (added) { // Meaning this field must either exist or contents may not exist. - field = field.substr(1); + field = field.substr(1, field.length()); } bool enum_values = field.begins_with("$"); if (enum_values) { // Meaning this field is a list of enum values. - field = field.substr(1); + field = field.substr(1, field.length()); } bool allow_name_change = field.begins_with("@"); if (allow_name_change) { // Meaning that when structurally comparing the old and new value, the dictionary entry 'name' may change. - field = field.substr(1); + field = field.substr(1, field.length()); } Variant old_value; @@ -1601,8 +1598,8 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) { int major = header["version_major"]; int minor = header["version_minor"]; - ERR_FAIL_COND_V_MSG(major != GODOT_VERSION_MAJOR, ERR_INVALID_DATA, vformat("JSON API dump is for a different engine version (%d) than this one (%d)", major, GODOT_VERSION_MAJOR)); - ERR_FAIL_COND_V_MSG(minor > GODOT_VERSION_MINOR, ERR_INVALID_DATA, vformat("JSON API dump is for a newer version of the engine: %d.%d", major, minor)); + ERR_FAIL_COND_V_MSG(major != VERSION_MAJOR, ERR_INVALID_DATA, vformat("JSON API dump is for a different engine version (%d) than this one (%d)", major, VERSION_MAJOR)); + ERR_FAIL_COND_V_MSG(minor > VERSION_MINOR, ERR_INVALID_DATA, vformat("JSON API dump is for a newer version of the engine: %d.%d", major, minor)); } bool failed = false; diff --git a/engine/core/extension/extension_api_dump.h b/engine/core/extension/extension_api_dump.h index 027a8d91..204a115f 100644 --- a/engine/core/extension/extension_api_dump.h +++ b/engine/core/extension/extension_api_dump.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef EXTENSION_API_DUMP_H +#define EXTENSION_API_DUMP_H #include "core/extension/gdextension.h" @@ -41,3 +42,5 @@ public: static Error validate_extension_json_file(const String &p_path); }; #endif + +#endif // EXTENSION_API_DUMP_H diff --git a/engine/core/extension/gdextension.cpp b/engine/core/extension/gdextension.cpp index ea314b71..f40612ec 100644 --- a/engine/core/extension/gdextension.cpp +++ b/engine/core/extension/gdextension.cpp @@ -679,13 +679,6 @@ void GDExtension::_get_library_path(GDExtensionClassLibraryPtr p_library, GDExte memnew_placement(r_path, String(library_path)); } -void GDExtension::_register_get_classes_used_callback(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback) { -#ifdef TOOLS_ENABLED - GDExtension *self = reinterpret_cast(p_library); - self->get_classes_used_callback = p_callback; -#endif -} - HashMap GDExtension::gdextension_interface_functions; void GDExtension::register_interface_function(const StringName &p_function_name, GDExtensionInterfaceFunctionPtr p_function_pointer) { @@ -806,7 +799,6 @@ void GDExtension::initialize_gdextensions() { register_interface_function("classdb_register_extension_class_signal", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_signal); register_interface_function("classdb_unregister_extension_class", (GDExtensionInterfaceFunctionPtr)&GDExtension::_unregister_extension_class); register_interface_function("get_library_path", (GDExtensionInterfaceFunctionPtr)&GDExtension::_get_library_path); - register_interface_function("editor_register_get_classes_used_callback", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_get_classes_used_callback); } void GDExtension::finalize_gdextensions() { @@ -1042,14 +1034,6 @@ void GDExtension::_untrack_instance(void *p_user_data, void *p_instance) { extension->instances.erase(obj->get_instance_id()); } -PackedStringArray GDExtension::get_classes_used() const { - PackedStringArray ret; - if (get_classes_used_callback) { - get_classes_used_callback((GDExtensionTypePtr)&ret); - } - return ret; -} - Vector GDExtensionEditorPlugins::extension_classes; GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_add_plugin = nullptr; GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_remove_plugin = nullptr; diff --git a/engine/core/extension/gdextension.h b/engine/core/extension/gdextension.h index a40f7af4..bfed8424 100644 --- a/engine/core/extension/gdextension.h +++ b/engine/core/extension/gdextension.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GDEXTENSION_H +#define GDEXTENSION_H #include "core/extension/gdextension_interface.h" #include "core/extension/gdextension_loader.h" @@ -93,7 +94,6 @@ class GDExtension : public Resource { static void _register_extension_class_signal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_signal_name, const GDExtensionPropertyInfo *p_argument_info, GDExtensionInt p_argument_count); static void _unregister_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name); static void _get_library_path(GDExtensionClassLibraryPtr p_library, GDExtensionStringPtr r_path); - static void _register_get_classes_used_callback(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback); GDExtensionInitialization initialization; int32_t level_initialized = -1; @@ -102,7 +102,6 @@ class GDExtension : public Resource { bool is_reloading = false; Vector invalid_methods; Vector instance_bindings; - GDExtensionEditorGetClassesUsedCallback get_classes_used_callback = nullptr; static void _track_instance(void *p_user_data, void *p_instance); static void _untrack_instance(void *p_user_data, void *p_instance); @@ -157,8 +156,6 @@ public: void track_instance_binding(Object *p_object); void untrack_instance_binding(Object *p_object); - - PackedStringArray get_classes_used() const; #endif InitializationLevel get_minimum_library_initialization_level() const; @@ -229,3 +226,5 @@ public: }; #endif // TOOLS_ENABLED + +#endif // GDEXTENSION_H diff --git a/engine/core/extension/gdextension_interface.cpp b/engine/core/extension/gdextension_interface.cpp index 725475d9..30f0ce98 100644 --- a/engine/core/extension/gdextension_interface.cpp +++ b/engine/core/extension/gdextension_interface.cpp @@ -241,25 +241,11 @@ GDExtensionInterfaceFunctionPtr gdextension_get_proc_address(const char *p_name) return GDExtension::get_interface_function(p_name); } -#ifndef DISABLE_DEPRECATED static void gdextension_get_godot_version(GDExtensionGodotVersion *r_godot_version) { - r_godot_version->major = GODOT_VERSION_MAJOR; - r_godot_version->minor = GODOT_VERSION_MINOR; - r_godot_version->patch = GODOT_VERSION_PATCH; - r_godot_version->string = GODOT_VERSION_FULL_NAME; -} -#endif - -static void gdextension_get_godot_version2(GDExtensionGodotVersion2 *r_godot_version) { - r_godot_version->major = GODOT_VERSION_MAJOR; - r_godot_version->minor = GODOT_VERSION_MINOR; - r_godot_version->patch = GODOT_VERSION_PATCH; - r_godot_version->hex = GODOT_VERSION_HEX; - r_godot_version->status = GODOT_VERSION_STATUS; - r_godot_version->build = GODOT_VERSION_BUILD; - r_godot_version->hash = GODOT_VERSION_HASH; - r_godot_version->timestamp = GODOT_VERSION_TIMESTAMP; - r_godot_version->string = GODOT_VERSION_FULL_NAME; + r_godot_version->major = VERSION_MAJOR; + r_godot_version->minor = VERSION_MINOR; + r_godot_version->patch = VERSION_PATCH; + r_godot_version->string = VERSION_FULL_NAME; } // Memory Functions @@ -872,82 +858,84 @@ static GDExtensionPtrUtilityFunction gdextension_variant_get_ptr_utility_functio //string helpers static void gdextension_string_new_with_latin1_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) { - String *dest = memnew_placement(r_dest, String); - dest->append_latin1(Span(p_contents, p_contents ? strlen(p_contents) : 0)); + memnew_placement(r_dest, String(p_contents)); } static void gdextension_string_new_with_utf8_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) { - String *dest = memnew_placement(r_dest, String); - dest->append_utf8(p_contents); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + dest->parse_utf8(p_contents); } static void gdextension_string_new_with_utf16_chars(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents) { - String *dest = memnew_placement(r_dest, String); - dest->append_utf16(p_contents); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + dest->parse_utf16(p_contents); } static void gdextension_string_new_with_utf32_chars(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents) { - String *dest = memnew_placement(r_dest, String); - dest->append_utf32(Span(p_contents, p_contents ? strlen(p_contents) : 0)); + memnew_placement(r_dest, String((const char32_t *)p_contents)); } static void gdextension_string_new_with_wide_chars(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents) { if constexpr (sizeof(wchar_t) == 2) { - // wchar_t is 16 bit (UTF-16). - String *dest = memnew_placement(r_dest, String); - dest->append_utf16((const char16_t *)p_contents); + // wchar_t is 16 bit, parse. + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + dest->parse_utf16((const char16_t *)p_contents); } else { - // wchar_t is 32 bit (UTF-32). - String *string = memnew_placement(r_dest, String); - string->append_utf32(Span((const char32_t *)p_contents, p_contents ? strlen(p_contents) : 0)); + // wchar_t is 32 bit, copy. + memnew_placement(r_dest, String((const char32_t *)p_contents)); } } static void gdextension_string_new_with_latin1_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - String *dest = memnew_placement(r_dest, String); - dest->append_latin1(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_size) : 0)); + memnew_placement(r_dest, String(p_contents, p_size)); } static void gdextension_string_new_with_utf8_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - String *dest = memnew_placement(r_dest, String); - dest->append_utf8(p_contents, p_size); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + dest->parse_utf8(p_contents, p_size); } static GDExtensionInt gdextension_string_new_with_utf8_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - String *dest = memnew_placement(r_dest, String); - return (GDExtensionInt)dest->append_utf8(p_contents, p_size); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + return (GDExtensionInt)dest->parse_utf8(p_contents, p_size); } static void gdextension_string_new_with_utf16_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count) { - String *dest = memnew_placement(r_dest, String); - dest->append_utf16(p_contents, p_char_count); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + dest->parse_utf16(p_contents, p_char_count); } static GDExtensionInt gdextension_string_new_with_utf16_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count, GDExtensionBool p_default_little_endian) { - String *dest = memnew_placement(r_dest, String); - return (GDExtensionInt)dest->append_utf16(p_contents, p_char_count, p_default_little_endian); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + return (GDExtensionInt)dest->parse_utf16(p_contents, p_char_count, p_default_little_endian); } static void gdextension_string_new_with_utf32_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count) { - String *string = memnew_placement(r_dest, String); - string->append_utf32(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_char_count) : 0)); + memnew_placement(r_dest, String((const char32_t *)p_contents, p_char_count)); } static void gdextension_string_new_with_wide_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_char_count) { if constexpr (sizeof(wchar_t) == 2) { - // wchar_t is 16 bit (UTF-16). - String *dest = memnew_placement(r_dest, String); - dest->append_utf16((const char16_t *)p_contents, p_char_count); + // wchar_t is 16 bit, parse. + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); + dest->parse_utf16((const char16_t *)p_contents, p_char_count); } else { - // wchar_t is 32 bit (UTF-32). - String *string = memnew_placement(r_dest, String); - string->append_utf32(Span((const char32_t *)p_contents, p_contents ? _strlen_clipped((const char32_t *)p_contents, p_char_count) : 0)); + // wchar_t is 32 bit, copy. + memnew_placement(r_dest, String((const char32_t *)p_contents, p_char_count)); } } static GDExtensionInt gdextension_string_to_latin1_chars(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length) { String *self = (String *)p_self; - CharString cs = self->latin1(); + CharString cs = self->ascii(true); GDExtensionInt len = cs.length(); if (r_text) { const char *s_text = cs.ptr(); @@ -1052,12 +1040,16 @@ static void gdextension_string_name_new_with_latin1_chars(GDExtensionUninitializ } static void gdextension_string_name_new_with_utf8_chars(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents) { - String tmp = String::utf8(p_contents); + String tmp; + tmp.parse_utf8(p_contents); + memnew_placement(r_dest, StringName(tmp)); } static void gdextension_string_name_new_with_utf8_chars_and_len(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size) { - String tmp = String::utf8(p_contents, p_size); + String tmp; + tmp.parse_utf8(p_contents, p_size); + memnew_placement(r_dest, StringName(tmp)); } @@ -1551,8 +1543,11 @@ static void gdextension_placeholder_script_instance_update(GDExtensionScriptInst properties_list.push_back(PropertyInfo::from_dict(d)); } - for (const KeyValue &kv : values) { - values_map.insert(kv.key, kv.value); + List keys; + values.get_key_list(&keys); + + for (const Variant &E : keys) { + values_map.insert(E, values[E]); } placeholder->update(properties_list, values_map); @@ -1577,15 +1572,6 @@ static GDExtensionScriptInstancePtr gdextension_object_get_script_instance(GDExt return script_instance_extension->instance; } -static void gdextension_object_set_script_instance(GDExtensionObjectPtr p_object, GDExtensionScriptInstancePtr p_script_instance) { - ERR_FAIL_NULL(p_object); - - Object *o = (Object *)p_object; - ScriptInstance *script_instance = (ScriptInstanceExtension *)p_script_instance; - - o->set_script_instance(script_instance); -} - #ifndef DISABLE_DEPRECATED static void gdextension_callable_custom_create(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_custom_callable_info) { memnew_placement(r_callable, Callable(memnew(CallableCustomExtension(p_custom_callable_info)))); @@ -1680,10 +1666,7 @@ static void gdextension_editor_help_load_xml_from_utf8_chars(const char *p_data) #define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr) & gdextension_##m_name) void gdextension_setup_interface() { -#ifndef DISABLE_DEPRECATED REGISTER_INTERFACE_FUNC(get_godot_version); -#endif // DISABLE_DEPRECATED - REGISTER_INTERFACE_FUNC(get_godot_version2); REGISTER_INTERFACE_FUNC(mem_alloc); REGISTER_INTERFACE_FUNC(mem_realloc); REGISTER_INTERFACE_FUNC(mem_free); @@ -1826,7 +1809,6 @@ void gdextension_setup_interface() { REGISTER_INTERFACE_FUNC(placeholder_script_instance_create); REGISTER_INTERFACE_FUNC(placeholder_script_instance_update); REGISTER_INTERFACE_FUNC(object_get_script_instance); - REGISTER_INTERFACE_FUNC(object_set_script_instance); #ifndef DISABLE_DEPRECATED REGISTER_INTERFACE_FUNC(callable_custom_create); #endif // DISABLE_DEPRECATED diff --git a/engine/core/extension/gdextension_interface.h b/engine/core/extension/gdextension_interface.h index ecd40c86..ac0181e0 100644 --- a/engine/core/extension/gdextension_interface.h +++ b/engine/core/extension/gdextension_interface.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GDEXTENSION_INTERFACE_H +#define GDEXTENSION_INTERFACE_H /* This is a C class header, you can copy it and use it directly in your own binders. * Together with the JSON file, you should be able to generate any binder. @@ -400,9 +401,6 @@ typedef struct { typedef void *GDExtensionClassLibraryPtr; -/* Passed a pointer to a PackedStringArray that should be filled with the classes that may be used by the GDExtension. */ -typedef void (*GDExtensionEditorGetClassesUsedCallback)(GDExtensionTypePtr p_packed_string_array); - /* Method */ typedef enum { @@ -792,22 +790,9 @@ typedef struct { const char *string; } GDExtensionGodotVersion; -typedef struct { - uint32_t major; - uint32_t minor; - uint32_t patch; - uint32_t hex; // Full version encoded as hexadecimal with one byte (2 hex digits) per number (e.g. for "3.1.12" it would be 0x03010C) - const char *status; // (e.g. "stable", "beta", "rc1", "rc2") - const char *build; // (e.g. "custom_build") - const char *hash; // Full Git commit hash. - uint64_t timestamp; // Git commit date UNIX timestamp in seconds, or 0 if unavailable. - const char *string; // (e.g. "Godot v3.1.4.stable.official.mono") -} GDExtensionGodotVersion2; - /** * @name get_godot_version * @since 4.1 - * @deprecated in Godot 4.5. Use `get_godot_version2` instead. * * Gets the Godot version that the GDExtension was loaded into. * @@ -815,16 +800,6 @@ typedef struct { */ typedef void (*GDExtensionInterfaceGetGodotVersion)(GDExtensionGodotVersion *r_godot_version); -/** - * @name get_godot_version2 - * @since 4.5 - * - * Gets the Godot version that the GDExtension was loaded into. - * - * @param r_godot_version A pointer to the structure to write the version information into. - */ -typedef void (*GDExtensionInterfaceGetGodotVersion2)(GDExtensionGodotVersion2 *r_godot_version); - /* INTERFACE: Memory */ /** @@ -2746,17 +2721,6 @@ typedef void (*GDExtensionInterfacePlaceHolderScriptInstanceUpdate)(GDExtensionS */ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptInstance)(GDExtensionConstObjectPtr p_object, GDExtensionObjectPtr p_language); -/** - * @name object_set_script_instance - * @since 4.5 - * - * Set the script instance data attached to this object. - * - * @param p_object A pointer to the Object. - * @param p_script_instance A pointer to the script instance data to attach to this object. - */ -typedef void (*GDExtensionInterfaceObjectSetScriptInstance)(GDExtensionObjectPtr p_object, GDExtensionScriptInstanceDataPtr p_script_instance); - /* INTERFACE: Callable */ /** @@ -3114,22 +3078,8 @@ typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char * */ typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size); -/** - * @name editor_register_get_classes_used_callback - * @since 4.5 - * - * Registers a callback that Godot can call to get the list of all classes (from ClassDB) that may be used by the calling GDExtension. - * - * This is used by the editor to generate a build profile (in "Tools" > "Engine Compilation Configuration Editor..." > "Detect from project"), - * in order to recompile Godot with only the classes used. - * In the provided callback, the GDExtension should provide the list of classes that _may_ be used statically, thus the time of invocation shouldn't matter. - * If a GDExtension doesn't register a callback, Godot will assume that it could be using any classes. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_callback The callback to retrieve the list of classes used. - */ -typedef void (*GDExtensionInterfaceEditorRegisterGetClassesUsedCallback)(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback); - #ifdef __cplusplus } #endif + +#endif // GDEXTENSION_INTERFACE_H diff --git a/engine/core/extension/gdextension_library_loader.cpp b/engine/core/extension/gdextension_library_loader.cpp index 1d6be752..17200916 100644 --- a/engine/core/extension/gdextension_library_loader.cpp +++ b/engine/core/extension/gdextension_library_loader.cpp @@ -307,12 +307,12 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) { bool compatible = true; // Check version lexicographically. - if (GODOT_VERSION_MAJOR != compatibility_minimum[0]) { - compatible = GODOT_VERSION_MAJOR > compatibility_minimum[0]; - } else if (GODOT_VERSION_MINOR != compatibility_minimum[1]) { - compatible = GODOT_VERSION_MINOR > compatibility_minimum[1]; + if (VERSION_MAJOR != compatibility_minimum[0]) { + compatible = VERSION_MAJOR > compatibility_minimum[0]; + } else if (VERSION_MINOR != compatibility_minimum[1]) { + compatible = VERSION_MINOR > compatibility_minimum[1]; } else { - compatible = GODOT_VERSION_PATCH >= compatibility_minimum[2]; + compatible = VERSION_PATCH >= compatibility_minimum[2]; } if (!compatible) { ERR_PRINT(vformat("GDExtension only compatible with Godot version %d.%d.%d or later: %s", compatibility_minimum[0], compatibility_minimum[1], compatibility_minimum[2], p_path)); @@ -334,15 +334,15 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) { } compatible = true; - if (GODOT_VERSION_MAJOR != compatibility_maximum[0]) { - compatible = GODOT_VERSION_MAJOR < compatibility_maximum[0]; - } else if (GODOT_VERSION_MINOR != compatibility_maximum[1]) { - compatible = GODOT_VERSION_MINOR < compatibility_maximum[1]; + if (VERSION_MAJOR != compatibility_maximum[0]) { + compatible = VERSION_MAJOR < compatibility_maximum[0]; + } else if (VERSION_MINOR != compatibility_maximum[1]) { + compatible = VERSION_MINOR < compatibility_maximum[1]; } -#if GODOT_VERSION_PATCH +#if VERSION_PATCH // #if check to avoid -Wtype-limits warning when 0. else { - compatible = GODOT_VERSION_PATCH <= compatibility_maximum[2]; + compatible = VERSION_PATCH <= compatibility_maximum[2]; } #endif diff --git a/engine/core/extension/gdextension_library_loader.h b/engine/core/extension/gdextension_library_loader.h index 75ad0ebe..f781611b 100644 --- a/engine/core/extension/gdextension_library_loader.h +++ b/engine/core/extension/gdextension_library_loader.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GDEXTENSION_LIBRARY_LOADER_H +#define GDEXTENSION_LIBRARY_LOADER_H #include @@ -37,8 +38,6 @@ #include "core/os/shared_object.h" class GDExtensionLibraryLoader : public GDExtensionLoader { - GDSOFTCLASS(GDExtensionLibraryLoader, GDExtensionLoader); - friend class GDExtensionManager; friend class GDExtension; @@ -82,3 +81,5 @@ public: Error parse_gdextension_file(const String &p_path); }; + +#endif // GDEXTENSION_LIBRARY_LOADER_H diff --git a/engine/core/extension/gdextension_loader.h b/engine/core/extension/gdextension_loader.h index 5d212779..22895503 100644 --- a/engine/core/extension/gdextension_loader.h +++ b/engine/core/extension/gdextension_loader.h @@ -28,15 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GDEXTENSION_LOADER_H +#define GDEXTENSION_LOADER_H #include "core/object/ref_counted.h" class GDExtension; class GDExtensionLoader : public RefCounted { - GDSOFTCLASS(GDExtensionLoader, GDExtensionLoader); - public: virtual Error open_library(const String &p_path) = 0; virtual Error initialize(GDExtensionInterfaceGetProcAddress p_get_proc_address, const Ref &p_extension, GDExtensionInitialization *r_initialization) = 0; @@ -45,3 +44,5 @@ public: virtual bool has_library_changed() const = 0; virtual bool library_exists() const = 0; }; + +#endif // GDEXTENSION_LOADER_H diff --git a/engine/core/extension/gdextension_manager.h b/engine/core/extension/gdextension_manager.h index 1523c07c..39a60047 100644 --- a/engine/core/extension/gdextension_manager.h +++ b/engine/core/extension/gdextension_manager.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GDEXTENSION_MANAGER_H +#define GDEXTENSION_MANAGER_H #include "core/extension/gdextension.h" @@ -91,3 +92,5 @@ public: }; VARIANT_ENUM_CAST(GDExtensionManager::LoadStatus) + +#endif // GDEXTENSION_MANAGER_H diff --git a/engine/core/extension/gdextension_special_compat_hashes.h b/engine/core/extension/gdextension_special_compat_hashes.h index 9cfb9208..0d447897 100644 --- a/engine/core/extension/gdextension_special_compat_hashes.h +++ b/engine/core/extension/gdextension_special_compat_hashes.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GDEXTENSION_SPECIAL_COMPAT_HASHES_H +#define GDEXTENSION_SPECIAL_COMPAT_HASHES_H #ifndef DISABLE_DEPRECATED @@ -57,3 +58,5 @@ public: }; #endif // DISABLE_DEPRECATED + +#endif // GDEXTENSION_SPECIAL_COMPAT_HASHES_H diff --git a/engine/core/extension/make_interface_dumper.py b/engine/core/extension/make_interface_dumper.py index 45f257a3..af356882 100644 --- a/engine/core/extension/make_interface_dumper.py +++ b/engine/core/extension/make_interface_dumper.py @@ -1,37 +1,55 @@ -import methods +import zlib def run(target, source, env): - buffer = methods.get_buffer(str(source[0])) - decomp_size = len(buffer) - buffer = methods.compress_buffer(buffer) + src = str(source[0]) + dst = str(target[0]) + with open(src, "rb") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: + buf = f.read() + decomp_size = len(buf) + + # Use maximum zlib compression level to further reduce file size + # (at the cost of initial build times). + buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION) + + g.write( + """/* THIS FILE IS GENERATED DO NOT EDIT */ +#ifndef GDEXTENSION_INTERFACE_DUMP_H +#define GDEXTENSION_INTERFACE_DUMP_H - with methods.generated_wrapper(str(target[0])) as file: - file.write(f"""\ #ifdef TOOLS_ENABLED #include "core/io/compression.h" #include "core/io/file_access.h" #include "core/string/ustring.h" -inline constexpr int _gdextension_interface_data_compressed_size = {len(buffer)}; -inline constexpr int _gdextension_interface_data_uncompressed_size = {decomp_size}; -inline constexpr unsigned char _gdextension_interface_data_compressed[] = {{ - {methods.format_buffer(buffer, 1)} -}}; +""" + ) -class GDExtensionInterfaceDump {{ - public: - static void generate_gdextension_interface_file(const String &p_path) {{ - Ref fa = FileAccess::open(p_path, FileAccess::WRITE); - ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); - Vector data; - data.resize(_gdextension_interface_data_uncompressed_size); - int ret = Compression::decompress(data.ptrw(), _gdextension_interface_data_uncompressed_size, _gdextension_interface_data_compressed, _gdextension_interface_data_compressed_size, Compression::MODE_DEFLATE); - ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt."); - fa->store_buffer(data.ptr(), data.size()); - }}; -}}; + g.write("static const int _gdextension_interface_data_compressed_size = " + str(len(buf)) + ";\n") + g.write("static const int _gdextension_interface_data_uncompressed_size = " + str(decomp_size) + ";\n") + g.write("static const unsigned char _gdextension_interface_data_compressed[] = {\n") + for i in range(len(buf)): + g.write("\t" + str(buf[i]) + ",\n") + g.write("};\n") + + g.write( + """ +class GDExtensionInterfaceDump { + public: + static void generate_gdextension_interface_file(const String &p_path) { + Ref fa = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); + Vector data; + data.resize(_gdextension_interface_data_uncompressed_size); + int ret = Compression::decompress(data.ptrw(), _gdextension_interface_data_uncompressed_size, _gdextension_interface_data_compressed, _gdextension_interface_data_compressed_size, Compression::MODE_DEFLATE); + ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt."); + fa->store_buffer(data.ptr(), data.size()); + }; +}; #endif // TOOLS_ENABLED -""") + +#endif // GDEXTENSION_INTERFACE_DUMP_H +""" + ) diff --git a/engine/core/extension/make_wrappers.py b/engine/core/extension/make_wrappers.py index 96936d8c..665b6f0f 100644 --- a/engine/core/extension/make_wrappers.py +++ b/engine/core/extension/make_wrappers.py @@ -119,7 +119,10 @@ def generate_ex_version(argcount, const=False, returns=False): def run(target, source, env): max_versions = 12 - txt = "#pragma once" + txt = """ +#ifndef GDEXTENSION_WRAPPERS_GEN_H +#define GDEXTENSION_WRAPPERS_GEN_H +""" for i in range(max_versions + 1): txt += "\n/* Extension Wrapper " + str(i) + " Arguments */\n" @@ -135,5 +138,7 @@ def run(target, source, env): txt += generate_mod_version(i, True, False) txt += generate_mod_version(i, True, True) + txt += "\n#endif\n" + with open(str(target[0]), "w", encoding="utf-8", newline="\n") as f: f.write(txt) diff --git a/engine/core/input/default_controller_mappings.h b/engine/core/input/default_controller_mappings.h index 6d7c807a..34e7d5d8 100644 --- a/engine/core/input/default_controller_mappings.h +++ b/engine/core/input/default_controller_mappings.h @@ -28,9 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DEFAULT_CONTROLLER_MAPPINGS_H +#define DEFAULT_CONTROLLER_MAPPINGS_H class DefaultControllerMappings { public: static const char *mappings[]; }; + +#endif // DEFAULT_CONTROLLER_MAPPINGS_H diff --git a/engine/core/input/input.cpp b/engine/core/input/input.cpp index 6b9fec6f..f03b9c05 100644 --- a/engine/core/input/input.cpp +++ b/engine/core/input/input.cpp @@ -219,7 +219,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, Listpush_back(name.quote()); } } @@ -1594,8 +1594,8 @@ void Input::parse_mapping(const String &p_mapping) { continue; } - String output = entry[idx].get_slicec(':', 0).remove_char(' '); - String input = entry[idx].get_slicec(':', 1).remove_char(' '); + String output = entry[idx].get_slice(":", 0).replace(" ", ""); + String input = entry[idx].get_slice(":", 1).replace(" ", ""); if (output.length() < 1 || input.length() < 2) { continue; } diff --git a/engine/core/input/input.h b/engine/core/input/input.h index 8d3b7ae3..bbe185de 100644 --- a/engine/core/input/input.h +++ b/engine/core/input/input.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef INPUT_H +#define INPUT_H #include "core/input/input_event.h" #include "core/object/object.h" @@ -85,7 +86,7 @@ public: typedef void (*EventDispatchFunc)(const Ref &p_event); private: - BitField mouse_button_mask = MouseButtonMask::NONE; + BitField mouse_button_mask; RBSet key_label_pressed; RBSet physical_keys_pressed; @@ -402,3 +403,5 @@ public: VARIANT_ENUM_CAST(Input::MouseMode); VARIANT_ENUM_CAST(Input::CursorShape); + +#endif // INPUT_H diff --git a/engine/core/input/input_builders.py b/engine/core/input/input_builders.py index c63f595f..3685e726 100644 --- a/engine/core/input/input_builders.py +++ b/engine/core/input/input_builders.py @@ -2,22 +2,18 @@ from collections import OrderedDict -import methods - def make_default_controller_mappings(target, source, env): - with methods.generated_wrapper(str(target[0])) as file: - file.write("""\ -#include "core/input/default_controller_mappings.h" - -#include "core/typedefs.h" - -""") + dst = str(target[0]) + with open(dst, "w", encoding="utf-8", newline="\n") as g: + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write('#include "core/typedefs.h"\n') + g.write('#include "core/input/default_controller_mappings.h"\n') # ensure mappings have a consistent order - platform_mappings = OrderedDict() - for src_path in map(str, source): - with open(src_path, "r", encoding="utf-8") as f: + platform_mappings: dict = OrderedDict() + for src_path in source: + with open(str(src_path), "r", encoding="utf-8") as f: # read mapping file and skip header mapping_file_lines = f.readlines()[2:] @@ -36,28 +32,28 @@ def make_default_controller_mappings(target, source, env): line_parts = line.split(",") guid = line_parts[0] if guid in platform_mappings[current_platform]: - file.write( + g.write( "// WARNING: DATABASE {} OVERWROTE PRIOR MAPPING: {} {}\n".format( src_path, current_platform, platform_mappings[current_platform][guid] ) ) platform_mappings[current_platform][guid] = line - PLATFORM_VARIABLES = { - "Linux": "LINUXBSD", - "Windows": "WINDOWS", - "Mac OS X": "MACOS", - "Android": "ANDROID", - "iOS": "IOS", - "Web": "WEB", + platform_variables = { + "Linux": "#ifdef LINUXBSD_ENABLED", + "Windows": "#ifdef WINDOWS_ENABLED", + "Mac OS X": "#ifdef MACOS_ENABLED", + "Android": "#ifdef ANDROID_ENABLED", + "iOS": "#ifdef IOS_ENABLED", + "Web": "#ifdef WEB_ENABLED", } - file.write("const char *DefaultControllerMappings::mappings[] = {\n") + g.write("const char* DefaultControllerMappings::mappings[] = {\n") for platform, mappings in platform_mappings.items(): - variable = PLATFORM_VARIABLES[platform] - file.write(f"#ifdef {variable}_ENABLED\n") + variable = platform_variables[platform] + g.write("{}\n".format(variable)) for mapping in mappings.values(): - file.write(f'\t"{mapping}",\n') - file.write(f"#endif // {variable}_ENABLED\n") + g.write('\t"{}",\n'.format(mapping)) + g.write("#endif\n") - file.write("\tnullptr\n};\n") + g.write("\tnullptr\n};\n") diff --git a/engine/core/input/input_enums.h b/engine/core/input/input_enums.h index d4efb3d8..182a5aab 100644 --- a/engine/core/input/input_enums.h +++ b/engine/core/input/input_enums.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef INPUT_ENUMS_H +#define INPUT_ENUMS_H #include "core/error/error_macros.h" @@ -137,10 +138,4 @@ inline MouseButtonMask mouse_button_to_mask(MouseButton button) { return MouseButtonMask(1 << ((int)button - 1)); } -constexpr MouseButtonMask operator|(MouseButtonMask p_a, MouseButtonMask p_b) { - return static_cast(static_cast(p_a) | static_cast(p_b)); -} - -constexpr MouseButtonMask &operator|=(MouseButtonMask &p_a, MouseButtonMask p_b) { - return p_a = p_a | p_b; -} +#endif // INPUT_ENUMS_H diff --git a/engine/core/input/input_event.cpp b/engine/core/input/input_event.cpp index 85c35c05..6e8cdc4b 100644 --- a/engine/core/input/input_event.cpp +++ b/engine/core/input/input_event.cpp @@ -230,7 +230,7 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif } BitField InputEventWithModifiers::get_modifiers_mask() const { - BitField mask = {}; + BitField mask; if (is_ctrl_pressed()) { mask.set_flag(KeyModifierMask::CTRL); } @@ -385,11 +385,11 @@ bool InputEventKey::is_echo() const { } Key InputEventKey::get_keycode_with_modifiers() const { - return keycode | get_modifiers_mask(); + return keycode | (int64_t)get_modifiers_mask(); } Key InputEventKey::get_physical_keycode_with_modifiers() const { - return physical_keycode | get_modifiers_mask(); + return physical_keycode | (int64_t)get_modifiers_mask(); } Key InputEventKey::get_key_label_with_modifiers() const { diff --git a/engine/core/input/input_event.h b/engine/core/input/input_event.h index 6e308f6c..19176f74 100644 --- a/engine/core/input/input_event.h +++ b/engine/core/input/input_event.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef INPUT_EVENT_H +#define INPUT_EVENT_H #include "core/input/input_enums.h" #include "core/io/resource.h" @@ -208,7 +209,7 @@ public: class InputEventMouse : public InputEventWithModifiers { GDCLASS(InputEventMouse, InputEventWithModifiers); - BitField button_mask = MouseButtonMask::NONE; + BitField button_mask; Vector2 pos; Vector2 global_pos; @@ -594,3 +595,5 @@ public: InputEventShortcut(); }; + +#endif // INPUT_EVENT_H diff --git a/engine/core/input/input_map.cpp b/engine/core/input/input_map.cpp index ea03c25c..bcd3b63a 100644 --- a/engine/core/input/input_map.cpp +++ b/engine/core/input/input_map.cpp @@ -47,8 +47,6 @@ void InputMap::_bind_methods() { ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(DEFAULT_DEADZONE)); ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action); - ClassDB::bind_method(D_METHOD("get_action_description", "action"), &InputMap::get_action_description); - ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone); ClassDB::bind_method(D_METHOD("action_get_deadzone", "action"), &InputMap::action_get_deadzone); ClassDB::bind_method(D_METHOD("action_add_event", "action", "event"), &InputMap::action_add_event); @@ -108,7 +106,7 @@ void InputMap::get_argument_options(const StringName &p_function, int p_idx, Lis continue; } - String name = pi.name.substr(pi.name.find_char('/') + 1); + String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length()); r_options->push_back(name.quote()); } } @@ -183,25 +181,6 @@ bool InputMap::has_action(const StringName &p_action) const { return input_map.has(p_action); } -String InputMap::get_action_description(const StringName &p_action) const { - ERR_FAIL_COND_V_MSG(!input_map.has(p_action), String(), suggest_actions(p_action)); - - String ret; - const List> &inputs = input_map[p_action].inputs; - for (Ref iek : inputs) { - if (iek.is_valid()) { - if (!ret.is_empty()) { - ret += RTR(" or "); - } - ret += iek->as_text(); - } - } - if (ret.is_empty()) { - ret = RTR("Action has no bound inputs"); - } - return ret; -} - float InputMap::action_get_deadzone(const StringName &p_action) { ERR_FAIL_COND_V_MSG(!input_map.has(p_action), 0.0f, suggest_actions(p_action)); @@ -325,7 +304,7 @@ void InputMap::load_from_project_settings() { continue; } - String name = pi.name.substr(pi.name.find_char('/') + 1); + String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length()); Dictionary action = GLOBAL_GET(pi.name); float deadzone = action.has("deadzone") ? (float)action["deadzone"] : DEFAULT_DEADZONE; @@ -365,7 +344,6 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_cut", TTRC("Cut") }, { "ui_copy", TTRC("Copy") }, { "ui_paste", TTRC("Paste") }, - { "ui_focus_mode", TTRC("Toggle Tab Focus Mode") }, { "ui_undo", TTRC("Undo") }, { "ui_redo", TTRC("Redo") }, { "ui_text_completion_query", TTRC("Completion Query") }, @@ -419,21 +397,17 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_text_submit", TTRC("Submit Text") }, { "ui_graph_duplicate", TTRC("Duplicate Nodes") }, { "ui_graph_delete", TTRC("Delete Nodes") }, - { "ui_graph_follow_left", TTRC("Follow Input Port Connection") }, - { "ui_graph_follow_right", TTRC("Follow Output Port Connection") }, { "ui_filedialog_up_one_level", TTRC("Go Up One Level") }, { "ui_filedialog_refresh", TTRC("Refresh") }, { "ui_filedialog_show_hidden", TTRC("Show Hidden") }, { "ui_swap_input_direction ", TTRC("Swap Input Direction") }, { "ui_unicode_start", TTRC("Start Unicode Character Input") }, - { "ui_colorpicker_delete_preset", TTRC("Toggle License Notices") }, - { "ui_accessibility_drag_and_drop", TTRC("Accessibility: Keyboard Drag and Drop") }, { "", ""} /* clang-format on */ }; String InputMap::get_builtin_display_name(const String &p_name) const { - constexpr int len = std::size(_builtin_action_display_names); + int len = sizeof(_builtin_action_display_names) / sizeof(_BuiltinActionDisplayName); for (int i = 0; i < len; i++) { if (_builtin_action_display_names[i].name == p_name) { @@ -513,9 +487,6 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::END)); default_builtin_cache.insert("ui_end", inputs); - inputs = List>(); - default_builtin_cache.insert("ui_accessibility_drag_and_drop", inputs); - // ///// UI basic Shortcuts ///// inputs = List>(); @@ -528,10 +499,6 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::CMD_OR_CTRL)); default_builtin_cache.insert("ui_copy", inputs); - inputs = List>(); - inputs.push_back(InputEventKey::create_reference(Key::M | KeyModifierMask::CTRL)); - default_builtin_cache.insert("ui_focus_mode", inputs); - inputs = List>(); inputs.push_back(InputEventKey::create_reference(Key::V | KeyModifierMask::CMD_OR_CTRL)); inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::SHIFT)); @@ -805,22 +772,6 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE)); default_builtin_cache.insert("ui_graph_delete", inputs); - inputs = List>(); - inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::CMD_OR_CTRL)); - default_builtin_cache.insert("ui_graph_follow_left", inputs); - - inputs = List>(); - inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::ALT)); - default_builtin_cache.insert("ui_graph_follow_left.macos", inputs); - - inputs = List>(); - inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::CMD_OR_CTRL)); - default_builtin_cache.insert("ui_graph_follow_right", inputs); - - inputs = List>(); - inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::ALT)); - default_builtin_cache.insert("ui_graph_follow_right.macos", inputs); - // ///// UI File Dialog Shortcuts ///// inputs = List>(); inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE)); @@ -838,12 +789,6 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::QUOTELEFT | KeyModifierMask::CMD_OR_CTRL)); default_builtin_cache.insert("ui_swap_input_direction", inputs); - // ///// UI ColorPicker Shortcuts ///// - inputs = List>(); - inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::X)); - inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE)); - default_builtin_cache.insert("ui_colorpicker_delete_preset", inputs); - return default_builtin_cache; } diff --git a/engine/core/input/input_map.h b/engine/core/input/input_map.h index 00bc1550..520c10c4 100644 --- a/engine/core/input/input_map.h +++ b/engine/core/input/input_map.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef INPUT_MAP_H +#define INPUT_MAP_H #include "core/input/input_event.h" #include "core/object/class_db.h" @@ -85,8 +86,6 @@ public: void add_action(const StringName &p_action, float p_deadzone = DEFAULT_DEADZONE); void erase_action(const StringName &p_action); - String get_action_description(const StringName &p_action) const; - float action_get_deadzone(const StringName &p_action); void action_set_deadzone(const StringName &p_action, float p_deadzone); void action_add_event(const StringName &p_action, const Ref &p_event); @@ -117,3 +116,5 @@ public: InputMap(); ~InputMap(); }; + +#endif // INPUT_MAP_H diff --git a/engine/core/input/shortcut.h b/engine/core/input/shortcut.h index 5c054827..4109e31f 100644 --- a/engine/core/input/shortcut.h +++ b/engine/core/input/shortcut.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef SHORTCUT_H +#define SHORTCUT_H #include "core/input/input_event.h" #include "core/io/resource.h" @@ -54,3 +55,5 @@ public: static bool is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2); }; + +#endif // SHORTCUT_H diff --git a/engine/core/io/compression.cpp b/engine/core/io/compression.cpp index 79f37db1..4e4627c4 100644 --- a/engine/core/io/compression.cpp +++ b/engine/core/io/compression.cpp @@ -42,12 +42,6 @@ #include #endif -// Caches for zstd. -static BinaryMutex mutex; -static ZSTD_DCtx *current_zstd_d_ctx = nullptr; -static bool current_zstd_long_distance_matching; -static int current_zstd_window_log_size; - int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) { switch (p_mode) { case MODE_BROTLI: { @@ -193,22 +187,12 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p return total; } break; case MODE_ZSTD: { - MutexLock lock(mutex); - - if (!current_zstd_d_ctx || current_zstd_long_distance_matching != zstd_long_distance_matching || current_zstd_window_log_size != zstd_window_log_size) { - if (current_zstd_d_ctx) { - ZSTD_freeDCtx(current_zstd_d_ctx); - } - - current_zstd_d_ctx = ZSTD_createDCtx(); - if (zstd_long_distance_matching) { - ZSTD_DCtx_setParameter(current_zstd_d_ctx, ZSTD_d_windowLogMax, zstd_window_log_size); - } - current_zstd_long_distance_matching = zstd_long_distance_matching; - current_zstd_window_log_size = zstd_window_log_size; + ZSTD_DCtx *dctx = ZSTD_createDCtx(); + if (zstd_long_distance_matching) { + ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size); } - - int ret = ZSTD_decompressDCtx(current_zstd_d_ctx, p_dst, p_dst_max_size, p_src, p_src_size); + int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size); + ZSTD_freeDCtx(dctx); return ret; } break; } diff --git a/engine/core/io/compression.h b/engine/core/io/compression.h index 08468de9..ea56ab8e 100644 --- a/engine/core/io/compression.h +++ b/engine/core/io/compression.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef COMPRESSION_H +#define COMPRESSION_H #include "core/templates/vector.h" #include "core/typedefs.h" @@ -55,3 +56,5 @@ public: static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); static int decompress_dynamic(Vector *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode); }; + +#endif // COMPRESSION_H diff --git a/engine/core/io/config_file.h b/engine/core/io/config_file.h index 01a860be..05b4ed89 100644 --- a/engine/core/io/config_file.h +++ b/engine/core/io/config_file.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CONFIG_FILE_H +#define CONFIG_FILE_H #include "core/io/file_access.h" #include "core/object/ref_counted.h" @@ -77,3 +78,5 @@ public: Error save_encrypted(const String &p_path, const Vector &p_key); Error save_encrypted_pass(const String &p_path, const String &p_pass); }; + +#endif // CONFIG_FILE_H diff --git a/engine/core/io/dir_access.cpp b/engine/core/io/dir_access.cpp index 02f270da..4bdfc5a5 100644 --- a/engine/core/io/dir_access.cpp +++ b/engine/core/io/dir_access.cpp @@ -146,7 +146,7 @@ Error DirAccess::make_dir_recursive(const String &p_dir) { full_dir = p_dir; } - full_dir = full_dir.replace_char('\\', '/'); + full_dir = full_dir.replace("\\", "/"); String base; @@ -336,7 +336,7 @@ Ref DirAccess::create_temp(const String &p_prefix, bool p_keep, Error uint32_t suffix_i = 0; String path; while (true) { - String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:"); + String datetime = Time::get_singleton()->get_datetime_string_from_system().replace("-", "").replace("T", "").replace(":", ""); datetime += itos(Time::get_singleton()->get_ticks_usec()); String suffix = datetime + (suffix_i > 0 ? itos(suffix_i) : ""); path = (p_prefix.is_empty() ? "" : p_prefix + "-") + suffix; @@ -626,10 +626,6 @@ bool DirAccess::is_case_sensitive(const String &p_path) const { return true; } -bool DirAccess::is_equivalent(const String &p_path_a, const String &p_path_b) const { - return p_path_a == p_path_b; -} - void DirAccess::_bind_methods() { ClassDB::bind_static_method("DirAccess", D_METHOD("open", "path"), &DirAccess::_open); ClassDB::bind_static_method("DirAccess", D_METHOD("get_open_error"), &DirAccess::get_open_error); @@ -675,7 +671,6 @@ void DirAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("get_include_hidden"), &DirAccess::get_include_hidden); ClassDB::bind_method(D_METHOD("is_case_sensitive", "path"), &DirAccess::is_case_sensitive); - ClassDB::bind_method(D_METHOD("is_equivalent", "path_a", "path_b"), &DirAccess::is_equivalent); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_navigational"), "set_include_navigational", "get_include_navigational"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_hidden"), "set_include_hidden", "get_include_hidden"); diff --git a/engine/core/io/dir_access.h b/engine/core/io/dir_access.h index 511a414f..588e0377 100644 --- a/engine/core/io/dir_access.h +++ b/engine/core/io/dir_access.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DIR_ACCESS_H +#define DIR_ACCESS_H #include "core/object/ref_counted.h" #include "core/string/ustring.h" @@ -168,9 +169,10 @@ public: virtual bool is_case_sensitive(const String &p_path) const; virtual bool is_bundle(const String &p_file) const { return false; } - virtual bool is_equivalent(const String &p_path_a, const String &p_path_b) const; public: DirAccess() {} virtual ~DirAccess(); }; + +#endif // DIR_ACCESS_H diff --git a/engine/core/io/dtls_server.h b/engine/core/io/dtls_server.h index e22a0eff..5ffed1ec 100644 --- a/engine/core/io/dtls_server.h +++ b/engine/core/io/dtls_server.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DTLS_SERVER_H +#define DTLS_SERVER_H #include "core/io/net_socket.h" #include "core/io/packet_peer_dtls.h" @@ -52,3 +53,5 @@ public: DTLSServer() {} }; + +#endif // DTLS_SERVER_H diff --git a/engine/core/io/file_access.cpp b/engine/core/io/file_access.cpp index 68b85cd1..7d422bf0 100644 --- a/engine/core/io/file_access.cpp +++ b/engine/core/io/file_access.cpp @@ -104,7 +104,7 @@ Ref FileAccess::create_temp(int p_mode_flags, const String &p_prefix uint32_t suffix_i = 0; String path; while (true) { - String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:"); + String datetime = Time::get_singleton()->get_datetime_string_from_system().replace("-", "").replace("T", "").replace(":", ""); datetime += itos(Time::get_singleton()->get_ticks_usec()); String suffix = datetime + (suffix_i > 0 ? itos(suffix_i) : ""); path = TEMP_DIR.path_join((p_prefix.is_empty() ? "" : p_prefix + "-") + suffix + (extension.is_empty() ? "" : "." + extension)); @@ -259,7 +259,7 @@ FileAccess::AccessType FileAccess::get_access_type() const { String FileAccess::fix_path(const String &p_path) const { // Helper used by file accesses that use a single filesystem. - String r_path = p_path.replace_char('\\', '/'); + String r_path = p_path.replace("\\", "/"); switch (_access_type) { case ACCESS_RESOURCES: { @@ -313,15 +313,9 @@ uint16_t FileAccess::get_16() const { uint16_t data = 0; get_buffer(reinterpret_cast(&data), sizeof(uint16_t)); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - data = BSWAP16(data); - } -#else if (big_endian) { data = BSWAP16(data); } -#endif return data; } @@ -330,15 +324,9 @@ uint32_t FileAccess::get_32() const { uint32_t data = 0; get_buffer(reinterpret_cast(&data), sizeof(uint32_t)); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - data = BSWAP32(data); - } -#else if (big_endian) { data = BSWAP32(data); } -#endif return data; } @@ -347,15 +335,9 @@ uint64_t FileAccess::get_64() const { uint64_t data = 0; get_buffer(reinterpret_cast(&data), sizeof(uint64_t)); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - data = BSWAP64(data); - } -#else if (big_endian) { data = BSWAP64(data); } -#endif return data; } @@ -447,7 +429,7 @@ class CharBuffer { public: _FORCE_INLINE_ CharBuffer() : buffer(stack_buffer), - capacity(std::size(stack_buffer)) { + capacity(sizeof(stack_buffer) / sizeof(char)) { } _FORCE_INLINE_ void push_back(char c) { @@ -583,7 +565,7 @@ String FileAccess::get_as_utf8_string(bool p_skip_cr) const { w[len] = 0; String s; - s.append_utf8((const char *)w, len, p_skip_cr); + s.parse_utf8((const char *)w, len, p_skip_cr); return s; } @@ -592,43 +574,25 @@ bool FileAccess::store_8(uint8_t p_dest) { } bool FileAccess::store_16(uint16_t p_dest) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_dest = BSWAP16(p_dest); - } -#else if (big_endian) { p_dest = BSWAP16(p_dest); } -#endif return store_buffer(reinterpret_cast(&p_dest), sizeof(uint16_t)); } bool FileAccess::store_32(uint32_t p_dest) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_dest = BSWAP32(p_dest); - } -#else if (big_endian) { p_dest = BSWAP32(p_dest); } -#endif return store_buffer(reinterpret_cast(&p_dest), sizeof(uint32_t)); } bool FileAccess::store_64(uint64_t p_dest) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_dest = BSWAP64(p_dest); - } -#else if (big_endian) { p_dest = BSWAP64(p_dest); } -#endif return store_buffer(reinterpret_cast(&p_dest), sizeof(uint64_t)); } @@ -665,29 +629,8 @@ uint64_t FileAccess::get_modified_time(const String &p_file) { Ref fa = create_for_path(p_file); ERR_FAIL_COND_V_MSG(fa.is_null(), 0, vformat("Cannot create FileAccess for path '%s'.", p_file)); - return fa->_get_modified_time(p_file); -} - -uint64_t FileAccess::get_access_time(const String &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; - } - - Ref fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'."); - - return fa->_get_access_time(p_file); -} - -int64_t FileAccess::get_size(const String &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 PackedData::get_singleton()->get_size(p_file); - } - - Ref fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), -1, "Cannot create FileAccess for path '" + p_file + "'."); - - return fa->_get_size(p_file); + uint64_t mt = fa->_get_modified_time(p_file); + return mt; } BitField FileAccess::get_unix_permissions(const String &p_file) { @@ -780,7 +723,9 @@ String FileAccess::get_pascal_string() { get_buffer((uint8_t *)cs.ptr(), sl); cs[sl] = 0; - return String::utf8(cs.ptr(), sl); + String ret; + ret.parse_utf8(cs.ptr(), sl); + return ret; } bool FileAccess::store_line(const String &p_line) { @@ -872,7 +817,7 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) { } String ret; - ret.append_utf8((const char *)array.ptr(), array.size()); + ret.parse_utf8((const char *)array.ptr(), array.size()); return ret; } @@ -986,7 +931,7 @@ void FileAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("get_float"), &FileAccess::get_float); ClassDB::bind_method(D_METHOD("get_double"), &FileAccess::get_double); ClassDB::bind_method(D_METHOD("get_real"), &FileAccess::get_real); - ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector (FileAccess::*)(int64_t) const) & FileAccess::get_buffer); + ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector(FileAccess::*)(int64_t) const) & FileAccess::get_buffer); ClassDB::bind_method(D_METHOD("get_line"), &FileAccess::get_line); ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &FileAccess::get_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("get_as_text", "skip_cr"), &FileAccess::get_as_text, DEFVAL(false)); @@ -1005,7 +950,7 @@ void FileAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("store_float", "value"), &FileAccess::store_float); ClassDB::bind_method(D_METHOD("store_double", "value"), &FileAccess::store_double); ClassDB::bind_method(D_METHOD("store_real", "value"), &FileAccess::store_real); - ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (bool (FileAccess::*)(const Vector &))&FileAccess::store_buffer); + ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (bool(FileAccess::*)(const Vector &)) & FileAccess::store_buffer); ClassDB::bind_method(D_METHOD("store_line", "line"), &FileAccess::store_line); ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &FileAccess::store_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("store_string", "string"), &FileAccess::store_string); @@ -1018,8 +963,6 @@ void FileAccess::_bind_methods() { ClassDB::bind_static_method("FileAccess", D_METHOD("file_exists", "path"), &FileAccess::exists); ClassDB::bind_static_method("FileAccess", D_METHOD("get_modified_time", "file"), &FileAccess::get_modified_time); - ClassDB::bind_static_method("FileAccess", D_METHOD("get_access_time", "file"), &FileAccess::get_access_time); - ClassDB::bind_static_method("FileAccess", D_METHOD("get_size", "file"), &FileAccess::get_size); ClassDB::bind_static_method("FileAccess", D_METHOD("get_unix_permissions", "file"), &FileAccess::get_unix_permissions); ClassDB::bind_static_method("FileAccess", D_METHOD("set_unix_permissions", "file", "permissions"), &FileAccess::set_unix_permissions); diff --git a/engine/core/io/file_access.h b/engine/core/io/file_access.h index 1947da85..f53f1f18 100644 --- a/engine/core/io/file_access.h +++ b/engine/core/io/file_access.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef FILE_ACCESS_H +#define FILE_ACCESS_H #include "core/io/compression.h" #include "core/math/math_defs.h" @@ -86,11 +87,7 @@ public: typedef void (*FileCloseFailNotify)(const String &); typedef Ref (*CreateFunc)(); -#ifdef BIG_ENDIAN_ENABLED - bool big_endian = true; -#else bool big_endian = false; -#endif bool real_is_double = false; virtual BitField _get_unix_permissions(const String &p_file) = 0; @@ -108,8 +105,6 @@ protected: virtual String fix_path(const String &p_path) const; virtual Error open_internal(const String &p_path, int p_mode_flags) = 0; ///< open a file virtual uint64_t _get_modified_time(const String &p_file) = 0; - virtual uint64_t _get_access_time(const String &p_file) = 0; - virtual int64_t _get_size(const String &p_file) = 0; virtual void _set_access_type(AccessType p_access); static FileCloseFailNotify close_fail_notify; @@ -244,8 +239,6 @@ public: static CreateFunc get_create_func(AccessType p_access); static bool exists(const String &p_name); ///< return true if a file exists static uint64_t get_modified_time(const String &p_file); - static uint64_t get_access_time(const String &p_file); - static int64_t get_size(const String &p_file); static BitField get_unix_permissions(const String &p_file); static Error set_unix_permissions(const String &p_file, BitField p_permissions); @@ -280,3 +273,5 @@ public: VARIANT_ENUM_CAST(FileAccess::CompressionMode); VARIANT_ENUM_CAST(FileAccess::ModeFlags); VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags); + +#endif // FILE_ACCESS_H diff --git a/engine/core/io/file_access_compressed.cpp b/engine/core/io/file_access_compressed.cpp index da313492..b7300ded 100644 --- a/engine/core/io/file_access_compressed.cpp +++ b/engine/core/io/file_access_compressed.cpp @@ -247,11 +247,7 @@ bool FileAccessCompressed::eof_reached() const { } uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const { - if (p_length == 0) { - return 0; - } - - ERR_FAIL_NULL_V(p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V_MSG(f.is_null(), -1, "File must be opened before use."); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); @@ -260,38 +256,29 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con return 0; } - uint64_t dst_idx = 0; - while (true) { - // Copy over as much of our current block as possible. - const uint32_t copied_bytes_count = MIN(p_length - dst_idx, read_block_size - read_pos); - memcpy(p_dst + dst_idx, read_ptr + read_pos, copied_bytes_count); - dst_idx += copied_bytes_count; - read_pos += copied_bytes_count; + for (uint64_t i = 0; i < p_length; i++) { + p_dst[i] = read_ptr[read_pos]; + read_pos++; + if (read_pos >= read_block_size) { + read_block++; - if (dst_idx == p_length) { - // We're done! We read back all that was requested. - return p_length; - } + if (read_block < read_block_count) { + //read another block of compressed data + f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize); + int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); + ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt."); + read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size; + read_pos = 0; - // We're not done yet; try reading the next block. - read_block++; - - if (read_block >= read_block_count) { - // We're done! We read back the whole file. - read_block--; - at_end = true; - if (dst_idx + 1 < p_length) { - read_eof = true; + } else { + read_block--; + at_end = true; + if (i + 1 < p_length) { + read_eof = true; + } + return i + 1; } - return dst_idx; } - - // Read the next block of compressed data. - f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize); - int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); - ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt."); - read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size; - read_pos = 0; } return p_length; @@ -345,22 +332,6 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) { } } -uint64_t FileAccessCompressed::_get_access_time(const String &p_file) { - if (f.is_valid()) { - return f->get_access_time(p_file); - } else { - return 0; - } -} - -int64_t FileAccessCompressed::_get_size(const String &p_file) { - if (f.is_valid()) { - return f->get_size(p_file); - } else { - return -1; - } -} - BitField FileAccessCompressed::_get_unix_permissions(const String &p_file) { if (f.is_valid()) { return f->_get_unix_permissions(p_file); diff --git a/engine/core/io/file_access_compressed.h b/engine/core/io/file_access_compressed.h index 7c5e6a5f..607a45fc 100644 --- a/engine/core/io/file_access_compressed.h +++ b/engine/core/io/file_access_compressed.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef FILE_ACCESS_COMPRESSED_H +#define FILE_ACCESS_COMPRESSED_H #include "core/io/compression.h" #include "core/io/file_access.h" class FileAccessCompressed : public FileAccess { - GDSOFTCLASS(FileAccessCompressed, FileAccess); Compression::Mode cmode = Compression::MODE_ZSTD; bool writing = false; uint64_t write_pos = 0; @@ -94,8 +94,6 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override; - virtual uint64_t _get_access_time(const String &p_file) override; - virtual int64_t _get_size(const String &p_file) override; virtual BitField _get_unix_permissions(const String &p_file) override; virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; @@ -109,3 +107,5 @@ public: FileAccessCompressed() {} virtual ~FileAccessCompressed(); }; + +#endif // FILE_ACCESS_COMPRESSED_H diff --git a/engine/core/io/file_access_encrypted.cpp b/engine/core/io/file_access_encrypted.cpp index 7af7737c..f2749157 100644 --- a/engine/core/io/file_access_encrypted.cpp +++ b/engine/core/io/file_access_encrypted.cpp @@ -30,17 +30,9 @@ #include "file_access_encrypted.h" +#include "core/crypto/crypto_core.h" #include "core/variant/variant.h" -CryptoCore::RandomGenerator *FileAccessEncrypted::_fae_static_rng = nullptr; - -void FileAccessEncrypted::deinitialize() { - if (_fae_static_rng) { - memdelete(_fae_static_rng); - _fae_static_rng = nullptr; - } -} - Error FileAccessEncrypted::open_and_parse(Ref p_base, const Vector &p_key, Mode p_mode, bool p_with_magic, const Vector &p_iv) { ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute())); ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER); @@ -56,15 +48,9 @@ Error FileAccessEncrypted::open_and_parse(Ref p_base, const Vectorinit() != OK) { - memdelete(_fae_static_rng); - _fae_static_rng = nullptr; - ERR_FAIL_V_MSG(FAILED, "Failed to initialize random number generator."); - } - } - Error err = _fae_static_rng->get_random_bytes(iv.ptrw(), 16); + CryptoCore::RandomGenerator rng; + ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator."); + Error err = rng.get_random_bytes(iv.ptrw(), 16); ERR_FAIL_COND_V(err != OK, err); } else { ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER); @@ -279,27 +265,7 @@ bool FileAccessEncrypted::file_exists(const String &p_name) { } uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) { - if (file.is_valid()) { - return file->get_modified_time(p_file); - } else { - return 0; - } -} - -uint64_t FileAccessEncrypted::_get_access_time(const String &p_file) { - if (file.is_valid()) { - return file->get_access_time(p_file); - } else { - return 0; - } -} - -int64_t FileAccessEncrypted::_get_size(const String &p_file) { - if (file.is_valid()) { - return file->get_size(p_file); - } else { - return -1; - } + return 0; } BitField FileAccessEncrypted::_get_unix_permissions(const String &p_file) { diff --git a/engine/core/io/file_access_encrypted.h b/engine/core/io/file_access_encrypted.h index 15cad3a1..570955b7 100644 --- a/engine/core/io/file_access_encrypted.h +++ b/engine/core/io/file_access_encrypted.h @@ -28,16 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef FILE_ACCESS_ENCRYPTED_H +#define FILE_ACCESS_ENCRYPTED_H -#include "core/crypto/crypto_core.h" #include "core/io/file_access.h" #define ENCRYPTED_HEADER_MAGIC 0x43454447 class FileAccessEncrypted : public FileAccess { - GDSOFTCLASS(FileAccessEncrypted, FileAccess); - public: enum Mode : int32_t { MODE_READ, @@ -59,8 +57,6 @@ private: void _close(); - static CryptoCore::RandomGenerator *_fae_static_rng; - public: Error open_and_parse(Ref p_base, const Vector &p_key, Mode p_mode, bool p_with_magic = true, const Vector &p_iv = Vector()); Error open_and_parse_password(Ref p_base, const String &p_key, Mode p_mode); @@ -91,8 +87,6 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override; - virtual uint64_t _get_access_time(const String &p_file) override; - virtual int64_t _get_size(const String &p_file) override; virtual BitField _get_unix_permissions(const String &p_file) override; virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; @@ -103,8 +97,8 @@ public: virtual void close() override; - static void deinitialize(); - FileAccessEncrypted() {} ~FileAccessEncrypted(); }; + +#endif // FILE_ACCESS_ENCRYPTED_H diff --git a/engine/core/io/file_access_memory.h b/engine/core/io/file_access_memory.h index 2ff638e9..6845cf71 100644 --- a/engine/core/io/file_access_memory.h +++ b/engine/core/io/file_access_memory.h @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef FILE_ACCESS_MEMORY_H +#define FILE_ACCESS_MEMORY_H #include "core/io/file_access.h" class FileAccessMemory : public FileAccess { - GDSOFTCLASS(FileAccessMemory, FileAccess); uint8_t *data = nullptr; uint64_t length = 0; mutable uint64_t pos = 0; @@ -66,9 +66,6 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } - virtual uint64_t _get_access_time(const String &p_file) override { return 0; } - virtual int64_t _get_size(const String &p_file) override { return -1; } - virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } @@ -81,3 +78,5 @@ public: FileAccessMemory() {} }; + +#endif // FILE_ACCESS_MEMORY_H diff --git a/engine/core/io/file_access_pack.cpp b/engine/core/io/file_access_pack.cpp index 788825f3..3fba2c70 100644 --- a/engine/core/io/file_access_pack.cpp +++ b/engine/core/io/file_access_pack.cpp @@ -264,7 +264,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, f->get_32(); // patch number, not used for validation. ERR_FAIL_COND_V_MSG(version != PACK_FORMAT_VERSION, false, vformat("Pack version unsupported: %d.", version)); - ERR_FAIL_COND_V_MSG(ver_major > GODOT_VERSION_MAJOR || (ver_major == GODOT_VERSION_MAJOR && ver_minor > GODOT_VERSION_MINOR), false, vformat("Pack created with a newer version of the engine: %d.%d.", ver_major, ver_minor)); + ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, vformat("Pack created with a newer version of the engine: %d.%d.", ver_major, ver_minor)); uint32_t pack_flags = f->get_32(); uint64_t file_base = f->get_64(); @@ -306,7 +306,9 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, f->get_buffer((uint8_t *)cs.ptr(), sl); cs[sl] = 0; - String path = String::utf8(cs.ptr(), sl); + String path; + path.parse_utf8(cs.ptr(), sl); + uint64_t ofs = f->get_64(); uint64_t size = f->get_64(); uint8_t md5[16]; @@ -548,7 +550,7 @@ String DirAccessPack::get_drive(int p_drive) { } PackedData::PackedDir *DirAccessPack::_find_dir(const String &p_dir) { - String nd = p_dir.replace_char('\\', '/'); + String nd = p_dir.replace("\\", "/"); // Special handling since simplify_path() will forbid it if (p_dir == "..") { diff --git a/engine/core/io/file_access_pack.h b/engine/core/io/file_access_pack.h index 9a482db7..0e4e7cd2 100644 --- a/engine/core/io/file_access_pack.h +++ b/engine/core/io/file_access_pack.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef FILE_ACCESS_PACK_H +#define FILE_ACCESS_PACK_H #include "core/io/dir_access.h" #include "core/io/file_access.h" @@ -126,8 +127,6 @@ public: _FORCE_INLINE_ Ref try_open_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path); - _FORCE_INLINE_ int64_t get_size(const String &p_path); - _FORCE_INLINE_ Ref try_open_directory(const String &p_path); _FORCE_INLINE_ bool has_directory(const String &p_path); @@ -157,7 +156,6 @@ public: }; class FileAccessPack : public FileAccess { - GDSOFTCLASS(FileAccessPack, FileAccess); PackedData::PackedFile pf; mutable uint64_t pos; @@ -167,8 +165,6 @@ class FileAccessPack : public FileAccess { Ref f; virtual Error open_internal(const String &p_path, int p_mode_flags) override; virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } - virtual uint64_t _get_access_time(const String &p_file) override { return 0; } - virtual int64_t _get_size(const String &p_file) override { return -1; } virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } @@ -204,19 +200,6 @@ public: FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file); }; -int64_t PackedData::get_size(const String &p_path) { - String simplified_path = p_path.simplify_path(); - PathMD5 pmd5(simplified_path.md5_buffer()); - HashMap::Iterator E = files.find(pmd5); - if (!E) { - return -1; // File not found. - } - if (E->value.offset == 0) { - return -1; // File was erased. - } - return E->value.size; -} - Ref PackedData::try_open_path(const String &p_path) { String simplified_path = p_path.simplify_path().trim_prefix("res://"); PathMD5 pmd5(simplified_path.md5_buffer()); @@ -242,7 +225,6 @@ bool PackedData::has_directory(const String &p_path) { } class DirAccessPack : public DirAccess { - GDSOFTCLASS(DirAccessPack, DirAccess); PackedData::PackedDir *current; List list_dirs; @@ -290,3 +272,5 @@ Ref PackedData::try_open_directory(const String &p_path) { } return da; } + +#endif // FILE_ACCESS_PACK_H diff --git a/engine/core/io/file_access_zip.h b/engine/core/io/file_access_zip.h index e1f4439d..a1544fee 100644 --- a/engine/core/io/file_access_zip.h +++ b/engine/core/io/file_access_zip.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef FILE_ACCESS_ZIP_H +#define FILE_ACCESS_ZIP_H #ifdef MINIZIP_ENABLED @@ -73,7 +74,6 @@ public: }; class FileAccessZip : public FileAccess { - GDSOFTCLASS(FileAccessZip, FileAccess); unzFile zfile = nullptr; unz_file_info64 file_info; @@ -102,9 +102,7 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } - virtual uint64_t _get_access_time(const String &p_file) override { return 0; } - virtual int64_t _get_size(const String &p_file) override { return -1; } + virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } @@ -120,3 +118,5 @@ public: }; #endif // MINIZIP_ENABLED + +#endif // FILE_ACCESS_ZIP_H diff --git a/engine/core/io/http_client.cpp b/engine/core/io/http_client.cpp index c452faf1..b7a324e7 100644 --- a/engine/core/io/http_client.cpp +++ b/engine/core/io/http_client.cpp @@ -70,9 +70,10 @@ Error HTTPClient::_request(Method p_method, const String &p_url, const Vector &kv : p_dict) { - String encoded_key = String(kv.key).uri_encode(); - const Variant &value = kv.value; + Array keys = p_dict.keys(); + for (int i = 0; i < keys.size(); ++i) { + String encoded_key = String(keys[i]).uri_encode(); + const Variant &value = p_dict[keys[i]]; switch (value.get_type()) { case Variant::ARRAY: { // Repeat the key with every values @@ -117,7 +118,7 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() { continue; } String key = s.substr(0, sp).strip_edges(); - String value = s.substr(sp + 1).strip_edges(); + String value = s.substr(sp + 1, s.length()).strip_edges(); ret[key] = value; } diff --git a/engine/core/io/http_client.h b/engine/core/io/http_client.h index fe2f2df2..59452911 100644 --- a/engine/core/io/http_client.h +++ b/engine/core/io/http_client.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef HTTP_CLIENT_H +#define HTTP_CLIENT_H #include "core/crypto/crypto.h" #include "core/io/ip.h" @@ -204,3 +205,5 @@ public: VARIANT_ENUM_CAST(HTTPClient::ResponseCode) VARIANT_ENUM_CAST(HTTPClient::Method); VARIANT_ENUM_CAST(HTTPClient::Status); + +#endif // HTTP_CLIENT_H diff --git a/engine/core/io/http_client_tcp.cpp b/engine/core/io/http_client_tcp.cpp index f6495585..3147b59c 100644 --- a/engine/core/io/http_client_tcp.cpp +++ b/engine/core/io/http_client_tcp.cpp @@ -50,13 +50,13 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, Refis_server(), ERR_INVALID_PARAMETER); @@ -196,7 +196,7 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector< // Should it add utf8 encoding? } if (add_uagent) { - request += "User-Agent: GodotEngine/" + String(GODOT_VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n"; + request += "User-Agent: GodotEngine/" + String(VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n"; } if (add_accept) { request += "Accept: */*\r\n"; @@ -483,7 +483,8 @@ Error HTTPClientTCP::poll() { (rs >= 4 && response_str[rs - 4] == '\r' && response_str[rs - 3] == '\n' && response_str[rs - 2] == '\r' && response_str[rs - 1] == '\n')) { // End of response, parse. response_str.push_back(0); - String response = String::utf8((const char *)response_str.ptr(), response_str.size()); + String response; + response.parse_utf8((const char *)response_str.ptr(), response_str.size()); Vector responses = response.split("\n"); body_size = -1; chunked = false; @@ -507,11 +508,11 @@ Error HTTPClientTCP::poll() { continue; } if (s.begins_with("content-length:")) { - body_size = s.substr(s.find_char(':') + 1).strip_edges().to_int(); + body_size = s.substr(s.find_char(':') + 1, s.length()).strip_edges().to_int(); body_left = body_size; } else if (s.begins_with("transfer-encoding:")) { - String encoding = header.substr(header.find_char(':') + 1).strip_edges(); + String encoding = header.substr(header.find_char(':') + 1, header.length()).strip_edges(); if (encoding == "chunked") { chunked = true; } diff --git a/engine/core/io/http_client_tcp.h b/engine/core/io/http_client_tcp.h index 4e4db3ac..dd6cc6b8 100644 --- a/engine/core/io/http_client_tcp.h +++ b/engine/core/io/http_client_tcp.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef HTTP_CLIENT_TCP_H +#define HTTP_CLIENT_TCP_H #include "http_client.h" @@ -99,3 +100,5 @@ public: void set_https_proxy(const String &p_host, int p_port) override; HTTPClientTCP(); }; + +#endif // HTTP_CLIENT_TCP_H diff --git a/engine/core/io/image.cpp b/engine/core/io/image.cpp index 857a9ec6..45f9599c 100644 --- a/engine/core/io/image.cpp +++ b/engine/core/io/image.cpp @@ -31,6 +31,7 @@ #include "image.h" #include "core/config/project_settings.h" +#include "core/error/error_list.h" #include "core/error/error_macros.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" @@ -88,13 +89,11 @@ SavePNGFunc Image::save_png_func = nullptr; SaveJPGFunc Image::save_jpg_func = nullptr; SaveEXRFunc Image::save_exr_func = nullptr; SaveWebPFunc Image::save_webp_func = nullptr; -SaveDDSFunc Image::save_dds_func = nullptr; SavePNGBufferFunc Image::save_png_buffer_func = nullptr; SaveJPGBufferFunc Image::save_jpg_buffer_func = nullptr; SaveEXRBufferFunc Image::save_exr_buffer_func = nullptr; SaveWebPBufferFunc Image::save_webp_buffer_func = nullptr; -SaveDDSBufferFunc Image::save_dds_buffer_func = nullptr; // External loader function pointers. @@ -106,7 +105,6 @@ ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr; ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; ScalableImageMemLoadFunc Image::_svg_scalable_mem_loader_func = nullptr; ImageMemLoadFunc Image::_ktx_mem_loader_func = nullptr; -ImageMemLoadFunc Image::_dds_mem_loader_func = nullptr; // External VRAM compression function pointers. @@ -573,7 +571,7 @@ static bool _are_formats_compatible(Image::Format p_format0, Image::Format p_for void Image::convert(Format p_new_format) { ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, vformat("The Image format specified (%d) is out of range. See Image's Format enum.", p_new_format)); - if (data.is_empty() || p_new_format == format) { + if (data.size() == 0 || p_new_format == format) { return; } @@ -798,7 +796,7 @@ Image::Format Image::get_format() const { } static double _bicubic_interp_kernel(double x) { - x = Math::abs(x); + x = ABS(x); double bc = 0; @@ -1141,7 +1139,7 @@ bool Image::is_size_po2() const { } void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) { - ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats."); int w = next_power_of_2(width); int h = next_power_of_2(height); @@ -1160,7 +1158,7 @@ void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) { void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { ERR_FAIL_COND_MSG(data.is_empty(), "Cannot resize image before creating it, use set_data() first."); - ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats."); bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */; @@ -1463,7 +1461,8 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) { - ERR_FAIL_COND_MSG(is_compressed(), "Cannot crop in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot crop in compressed or custom image formats."); + ERR_FAIL_COND_MSG(p_x < 0, "Start x position cannot be smaller than 0."); ERR_FAIL_COND_MSG(p_y < 0, "Start y position cannot be smaller than 0."); ERR_FAIL_COND_MSG(p_width <= 0, "Width of image must be greater than 0."); @@ -1516,7 +1515,7 @@ void Image::crop(int p_width, int p_height) { } void Image::rotate_90(ClockDirection p_direction) { - ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats."); ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width)); ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height)); @@ -1634,7 +1633,7 @@ void Image::rotate_90(ClockDirection p_direction) { } void Image::rotate_180() { - ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats."); ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width)); ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height)); @@ -1668,7 +1667,7 @@ void Image::rotate_180() { } void Image::flip_y() { - ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_y in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats."); bool used_mipmaps = has_mipmaps(); if (used_mipmaps) { @@ -1698,7 +1697,7 @@ void Image::flip_y() { } void Image::flip_x() { - ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_x in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_x in compressed or custom image formats."); bool used_mipmaps = has_mipmaps(); if (used_mipmaps) { @@ -1790,6 +1789,10 @@ int64_t Image::_get_dst_image_size(int p_width, int p_height, Format p_format, i return size; } +bool Image::_can_modify(Format p_format) const { + return !Image::is_format_compressed(p_format); +} + template @@ -1923,7 +1926,7 @@ void Image::shrink_x2() { memcpy(new_data.ptrw(), data.ptr() + ofs, new_size); } else { // Generate a mipmap and replace the original. - ERR_FAIL_COND(is_compressed()); + ERR_FAIL_COND(!_can_modify(format)); new_data.resize((width / 2) * (height / 2) * get_format_pixel_size(format)); ERR_FAIL_COND(data.is_empty() || new_data.is_empty()); @@ -1960,7 +1963,7 @@ void Image::normalize() { } Error Image::generate_mipmaps(bool p_renormalize) { - ERR_FAIL_COND_V_MSG(is_compressed(), ERR_UNAVAILABLE, "Cannot generate mipmaps from compressed image formats."); + ERR_FAIL_COND_V_MSG(!_can_modify(format), ERR_UNAVAILABLE, "Cannot generate mipmaps in compressed or custom image formats."); ERR_FAIL_COND_V_MSG(format == FORMAT_RGBA4444, ERR_UNAVAILABLE, "Cannot generate mipmaps from RGBA4444 format."); ERR_FAIL_COND_V_MSG(width == 0 || height == 0, ERR_UNCONFIGURED, "Cannot generate mipmaps with width or height equal to 0."); @@ -2177,7 +2180,7 @@ void Image::clear_mipmaps() { } bool Image::is_empty() const { - return (data.is_empty()); + return (data.size() == 0); } Vector Image::get_data() const { @@ -2294,7 +2297,7 @@ void Image::initialize_data(const char **p_xpm) { switch (status) { case READING_HEADER: { String line_str = line_ptr; - line_str.replace_char('\t', ' '); + line_str.replace("\t", " "); size_width = line_str.get_slicec(' ', 0).to_int(); size_height = line_str.get_slicec(' ', 1).to_int(); @@ -2438,75 +2441,47 @@ void Image::initialize_data(const char **p_xpm) { } bool Image::is_invisible() const { - int w, h; - int64_t len; - _get_mipmap_offset_and_size(1, len, w, h); + if (format == FORMAT_L8 || format == FORMAT_RGB8 || format == FORMAT_RG8) { + return false; + } + + int64_t len = data.size(); if (len == 0) { return true; } + int w, h; + _get_mipmap_offset_and_size(1, len, w, h); + + const uint8_t *r = data.ptr(); + const unsigned char *data_ptr = r; + + bool detected = false; + switch (format) { case FORMAT_LA8: { - const int pixel_count = len / 2; - const uint16_t *pixeldata = reinterpret_cast(data.ptr()); - - for (int i = 0; i < pixel_count; i++) { - if ((pixeldata[i] & 0xFF00) != 0) { - return false; - } + for (int i = 0; i < (len >> 1); i++) { + DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]); } + } break; case FORMAT_RGBA8: { - const int pixel_count = len / 4; - const uint32_t *pixeldata = reinterpret_cast(data.ptr()); - - for (int i = 0; i < pixel_count; i++) { - if ((pixeldata[i] & 0xFF000000) != 0) { - return false; - } + for (int i = 0; i < (len >> 2); i++) { + DETECT_NON_ALPHA(data_ptr[(i << 2) + 3]) } + } break; - case FORMAT_RGBA4444: { - const int pixel_count = len / 2; - const uint16_t *pixeldata = reinterpret_cast(data.ptr()); - for (int i = 0; i < pixel_count; i++) { - if ((pixeldata[i] & 0x000F) != 0) { - return false; - } - } - } break; - case FORMAT_RGBAH: { - // The alpha mask accounts for the sign bit. - const int pixel_count = len / 4; - const uint16_t *pixeldata = reinterpret_cast(data.ptr()); - - for (int i = 0; i < pixel_count; i += 4) { - if ((pixeldata[i + 3] & 0x7FFF) != 0) { - return false; - } - } - } break; - case FORMAT_RGBAF: { - // The alpha mask accounts for the sign bit. - const int pixel_count = len / 4; - const uint32_t *pixeldata = reinterpret_cast(data.ptr()); - - for (int i = 0; i < pixel_count; i += 4) { - if ((pixeldata[i + 3] & 0x7FFFFFFF) != 0) { - return false; - } - } + case FORMAT_DXT3: + case FORMAT_DXT5: { + detected = true; } break; default: { - // Formats that are compressed or don't support alpha channels are presumed to be visible. - return false; } } - // Every pixel has been checked, the image is invisible. - return true; + return !detected; } Image::AlphaMode Image::detect_alpha() const { @@ -2628,21 +2603,6 @@ Vector Image::save_exr_to_buffer(bool p_grayscale) const { return save_exr_buffer_func(Ref((Image *)this), p_grayscale); } -Error Image::save_dds(const String &p_path) const { - if (save_dds_func == nullptr) { - return ERR_UNAVAILABLE; - } - - return save_dds_func(p_path, Ref((Image *)this)); -} - -Vector Image::save_dds_to_buffer() const { - if (save_dds_buffer_func == nullptr) { - return Vector(); - } - return save_dds_buffer_func(Ref((Image *)this)); -} - Error Image::save_webp(const String &p_path, const bool p_lossy, const float p_quality) const { if (save_webp_func == nullptr) { return ERR_UNAVAILABLE; @@ -2722,19 +2682,6 @@ Error Image::decompress() { return OK; } -bool Image::can_decompress(const String &p_format_tag) { - if (p_format_tag == "astc") { - return _image_decompress_astc != nullptr; - } else if (p_format_tag == "bptc") { - return _image_decompress_bptc != nullptr; - } else if (p_format_tag == "etc2") { - return _image_decompress_etc2 != nullptr; - } else if (p_format_tag == "s3tc") { - return _image_decompress_bc != nullptr; - } - return false; -} - Error Image::compress(CompressMode p_mode, CompressSource p_source, ASTCFormat p_astc_format) { ERR_FAIL_INDEX_V_MSG(p_mode, COMPRESS_MAX, ERR_INVALID_PARAMETER, "Invalid compress mode."); ERR_FAIL_INDEX_V_MSG(p_source, COMPRESS_SOURCE_MAX, ERR_INVALID_PARAMETER, "Invalid compress source."); @@ -2916,7 +2863,7 @@ void Image::blit_rect(const Ref &p_src, const Rect2i &p_src_rect, const P ERR_FAIL_COND(dsize == 0); ERR_FAIL_COND(srcdsize == 0); ERR_FAIL_COND(format != p_src->format); - ERR_FAIL_COND_MSG(is_compressed(), "Cannot blit_rect in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot blit_rect in compressed or custom image formats."); Rect2i src_rect; Rect2i dest_rect; @@ -3096,10 +3043,10 @@ void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_s } void Image::fill(const Color &p_color) { - if (data.is_empty()) { + if (data.size() == 0) { return; } - ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats."); uint8_t *dst_data_ptr = data.ptrw(); @@ -3112,10 +3059,10 @@ void Image::fill(const Color &p_color) { } void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) { - if (data.is_empty()) { + if (data.size() == 0) { return; } - ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill rect in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats."); Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect.abs()); if (!r.has_area()) { @@ -3331,7 +3278,7 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color) uint16_t rgba = 0; rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)); - rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 63)) << 5; + rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 33)) << 5; rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 11; ((uint16_t *)ptr)[ofs] = rgba; @@ -3419,7 +3366,7 @@ int64_t Image::get_data_size() const { } void Image::adjust_bcs(float p_brightness, float p_contrast, float p_saturation) { - ERR_FAIL_COND_MSG(is_compressed(), "Cannot adjust_bcs in compressed image formats."); + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot adjust_bcs in compressed or custom image formats."); uint8_t *w = data.ptrw(); uint32_t pixel_size = get_format_pixel_size(format); @@ -3577,9 +3524,6 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("save_jpg_to_buffer", "quality"), &Image::save_jpg_to_buffer, DEFVAL(0.75)); ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false)); ClassDB::bind_method(D_METHOD("save_exr_to_buffer", "grayscale"), &Image::save_exr_to_buffer, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("save_dds", "path"), &Image::save_dds); - ClassDB::bind_method(D_METHOD("save_dds_to_buffer"), &Image::save_dds_to_buffer); - ClassDB::bind_method(D_METHOD("save_webp", "path", "lossy", "quality"), &Image::save_webp, DEFVAL(false), DEFVAL(0.75f)); ClassDB::bind_method(D_METHOD("save_webp_to_buffer", "lossy", "quality"), &Image::save_webp_to_buffer, DEFVAL(false), DEFVAL(0.75f)); @@ -3633,7 +3577,6 @@ void Image::_bind_methods() { 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); ClassDB::bind_method(D_METHOD("load_ktx_from_buffer", "buffer"), &Image::load_ktx_from_buffer); - ClassDB::bind_method(D_METHOD("load_dds_from_buffer", "buffer"), &Image::load_dds_from_buffer); ClassDB::bind_method(D_METHOD("load_svg_from_buffer", "buffer", "scale"), &Image::load_svg_from_buffer, DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("load_svg_from_string", "svg_str", "scale"), &Image::load_svg_from_string, DEFVAL(1.0)); @@ -3734,7 +3677,7 @@ void Image::normal_map_to_xy() { } Ref Image::rgbe_to_srgb() { - if (data.is_empty()) { + if (data.size() == 0) { return Ref(); } @@ -3781,7 +3724,7 @@ Ref Image::get_image_from_mipmap(int p_mipmap) const { } void Image::bump_map_to_normal_map(float bump_scale) { - ERR_FAIL_COND(is_compressed()); + ERR_FAIL_COND(!_can_modify(format)); clear_mipmaps(); convert(Image::FORMAT_RF); @@ -3856,7 +3799,7 @@ bool Image::detect_signed(bool p_include_mips) const { } void Image::srgb_to_linear() { - if (data.is_empty()) { + if (data.size() == 0) { return; } @@ -3887,7 +3830,7 @@ void Image::srgb_to_linear() { } void Image::linear_to_srgb() { - if (data.is_empty()) { + if (data.size() == 0) { return; } @@ -3918,7 +3861,7 @@ void Image::linear_to_srgb() { } void Image::premultiply_alpha() { - if (data.is_empty()) { + if (data.size() == 0) { return; } @@ -3940,7 +3883,7 @@ void Image::premultiply_alpha() { } void Image::fix_alpha_edges() { - if (data.is_empty()) { + if (data.size() == 0) { return; } @@ -4129,14 +4072,6 @@ Error Image::load_bmp_from_buffer(const Vector &p_array) { return _load_from_buffer(p_array, _bmp_mem_loader_func); } -Error Image::load_dds_from_buffer(const Vector &p_array) { - ERR_FAIL_NULL_V_MSG( - _dds_mem_loader_func, - ERR_UNAVAILABLE, - "The DDS module isn't enabled. Recompile the Godot editor or export template binary with the `module_dds_enabled=yes` SCons option."); - return _load_from_buffer(p_array, _dds_mem_loader_func); -} - Error Image::load_svg_from_buffer(const Vector &p_array, float scale) { ERR_FAIL_NULL_V_MSG( _svg_scalable_mem_loader_func, @@ -4331,10 +4266,10 @@ Dictionary Image::compute_image_metrics(const Ref p_compared_image, bool // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Dictionary result; - result["max"] = Math::INF; - result["mean"] = Math::INF; - result["mean_squared"] = Math::INF; - result["root_mean_squared"] = Math::INF; + result["max"] = INFINITY; + result["mean"] = INFINITY; + result["mean_squared"] = INFINITY; + result["root_mean_squared"] = INFINITY; result["peak_snr"] = 0.0f; ERR_FAIL_COND_V(p_compared_image.is_null(), result); diff --git a/engine/core/io/image.h b/engine/core/io/image.h index 3cb57a3a..992c4359 100644 --- a/engine/core/io/image.h +++ b/engine/core/io/image.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef IMAGE_H +#define IMAGE_H #include "core/io/resource.h" #include "core/math/color.h" @@ -58,9 +59,6 @@ typedef Vector (*SaveWebPBufferFunc)(const Ref &p_img, const boo typedef Error (*SaveEXRFunc)(const String &p_path, const Ref &p_img, bool p_grayscale); typedef Vector (*SaveEXRBufferFunc)(const Ref &p_img, bool p_grayscale); -typedef Error (*SaveDDSFunc)(const String &p_path, const Ref &p_img); -typedef Vector (*SaveDDSBufferFunc)(const Ref &p_img); - class Image : public Resource { GDCLASS(Image, Resource); @@ -188,12 +186,10 @@ public: static SaveJPGFunc save_jpg_func; static SaveEXRFunc save_exr_func; static SaveWebPFunc save_webp_func; - static SaveDDSFunc save_dds_func; static SavePNGBufferFunc save_png_buffer_func; static SaveEXRBufferFunc save_exr_buffer_func; static SaveJPGBufferFunc save_jpg_buffer_func; static SaveWebPBufferFunc save_webp_buffer_func; - static SaveDDSBufferFunc save_dds_buffer_func; // External loader function pointers. @@ -205,7 +201,6 @@ public: static ImageMemLoadFunc _bmp_mem_loader_func; static ScalableImageMemLoadFunc _svg_scalable_mem_loader_func; static ImageMemLoadFunc _ktx_mem_loader_func; - static ImageMemLoadFunc _dds_mem_loader_func; // External VRAM compression function pointers. @@ -256,6 +251,7 @@ private: _FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int64_t &r_offset, int &r_width, int &r_height) const; // Get where the mipmap begins in data. static int64_t _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr); + bool _can_modify(Format p_format) const; _FORCE_INLINE_ void _get_clipped_src_and_dest_rects(const Ref &p_src, const Rect2i &p_src_rect, const Point2i &p_dest, Rect2i &r_clipped_src_rect, Rect2i &r_clipped_dest_rect) const; @@ -338,11 +334,9 @@ public: static Ref load_from_file(const String &p_path); Error save_png(const String &p_path) const; Error save_jpg(const String &p_path, float p_quality = 0.75) const; - Error save_dds(const String &p_path) const; Vector save_png_to_buffer() const; Vector save_jpg_to_buffer(float p_quality = 0.75) const; Vector save_exr_to_buffer(bool p_grayscale = false) const; - Vector save_dds_to_buffer() const; Error save_exr(const String &p_path, bool p_grayscale = false) const; Error save_webp(const String &p_path, const bool p_lossy = false, const float p_quality = 0.75f) const; Vector save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const; @@ -379,8 +373,6 @@ public: bool is_compressed() const; static bool is_format_compressed(Format p_format); - static bool can_decompress(const String &p_format_tag); - void fix_alpha_edges(); void premultiply_alpha(); void srgb_to_linear(); @@ -411,7 +403,6 @@ public: Error load_tga_from_buffer(const Vector &p_array); Error load_bmp_from_buffer(const Vector &p_array); Error load_ktx_from_buffer(const Vector &p_array); - Error load_dds_from_buffer(const Vector &p_array); Error load_svg_from_buffer(const Vector &p_array, float scale = 1.0); Error load_svg_from_string(const String &p_svg_str, float scale = 1.0); @@ -451,3 +442,5 @@ VARIANT_ENUM_CAST(Image::UsedChannels) VARIANT_ENUM_CAST(Image::AlphaMode) VARIANT_ENUM_CAST(Image::RoughnessChannel) VARIANT_ENUM_CAST(Image::ASTCFormat) + +#endif // IMAGE_H diff --git a/engine/core/io/image_loader.h b/engine/core/io/image_loader.h index 00642da0..26af6503 100644 --- a/engine/core/io/image_loader.h +++ b/engine/core/io/image_loader.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef IMAGE_LOADER_H +#define IMAGE_LOADER_H #include "core/core_bind.h" #include "core/io/file_access.h" @@ -107,3 +108,5 @@ public: virtual bool handles_type(const String &p_type) const override; virtual String get_resource_type(const String &p_path) const override; }; + +#endif // IMAGE_LOADER_H diff --git a/engine/core/io/ip.h b/engine/core/io/ip.h index 9d23a465..4816d59a 100644 --- a/engine/core/io/ip.h +++ b/engine/core/io/ip.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef IP_H +#define IP_H #include "core/io/ip_address.h" #include "core/os/os.h" @@ -109,3 +110,5 @@ public: VARIANT_ENUM_CAST(IP::Type); VARIANT_ENUM_CAST(IP::ResolverStatus); + +#endif // IP_H diff --git a/engine/core/io/ip_address.cpp b/engine/core/io/ip_address.cpp index 78b8a19f..f12c896d 100644 --- a/engine/core/io/ip_address.cpp +++ b/engine/core/io/ip_address.cpp @@ -148,7 +148,7 @@ void IPAddress::_parse_ipv6(const String &p_string) { void IPAddress::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) { String ip; if (p_start != 0) { - ip = p_string.substr(p_start); + ip = p_string.substr(p_start, p_string.length() - p_start); } else { ip = p_string; } diff --git a/engine/core/io/ip_address.h b/engine/core/io/ip_address.h index 114038d9..da7b0f77 100644 --- a/engine/core/io/ip_address.h +++ b/engine/core/io/ip_address.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef IP_ADDRESS_H +#define IP_ADDRESS_H #include "core/string/ustring.h" @@ -95,6 +96,4 @@ public: IPAddress() { clear(); } }; -// Zero-constructing IPAddress initializes field, valid, and wildcard to 0 (and thus empty). -template <> -struct is_zero_constructible : std::true_type {}; +#endif // IP_ADDRESS_H diff --git a/engine/core/io/json.cpp b/engine/core/io/json.cpp index fcb6182f..131a7e80 100644 --- a/engine/core/io/json.cpp +++ b/engine/core/io/json.cpp @@ -122,7 +122,8 @@ String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_ ERR_FAIL_COND_V_MSG(p_markers.has(d.id()), "\"{...}\"", "Converting circular structure to JSON."); p_markers.insert(d.id()); - LocalVector keys = d.get_key_list(); + List keys; + d.get_key_list(&keys); if (p_sort_keys) { keys.sort_custom(); @@ -663,96 +664,201 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_ case Variant::VECTOR2: { const Vector2 v = p_variant; - Array args = { v.x, v.y }; + + Array args; + args.push_back(v.x); + args.push_back(v.y); + RETURN_ARGS; } break; case Variant::VECTOR2I: { const Vector2i v = p_variant; - Array args = { v.x, v.y }; + + Array args; + args.push_back(v.x); + args.push_back(v.y); + RETURN_ARGS; } break; case Variant::RECT2: { const Rect2 r = p_variant; - Array args = { r.position.x, r.position.y, r.size.width, r.size.height }; + + Array args; + args.push_back(r.position.x); + args.push_back(r.position.y); + args.push_back(r.size.width); + args.push_back(r.size.height); + RETURN_ARGS; } break; case Variant::RECT2I: { const Rect2i r = p_variant; - Array args = { r.position.x, r.position.y, r.size.width, r.size.height }; + + Array args; + args.push_back(r.position.x); + args.push_back(r.position.y); + args.push_back(r.size.width); + args.push_back(r.size.height); + RETURN_ARGS; } break; case Variant::VECTOR3: { const Vector3 v = p_variant; - Array args = { v.x, v.y, v.z }; + + Array args; + args.push_back(v.x); + args.push_back(v.y); + args.push_back(v.z); + RETURN_ARGS; } break; case Variant::VECTOR3I: { const Vector3i v = p_variant; - Array args = { v.x, v.y, v.z }; + + Array args; + args.push_back(v.x); + args.push_back(v.y); + args.push_back(v.z); + RETURN_ARGS; } break; case Variant::TRANSFORM2D: { const Transform2D t = p_variant; - Array args = { t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y }; + + Array args; + args.push_back(t[0].x); + args.push_back(t[0].y); + args.push_back(t[1].x); + args.push_back(t[1].y); + args.push_back(t[2].x); + args.push_back(t[2].y); + RETURN_ARGS; } break; case Variant::VECTOR4: { const Vector4 v = p_variant; - Array args = { v.x, v.y, v.z, v.w }; + + Array args; + args.push_back(v.x); + args.push_back(v.y); + args.push_back(v.z); + args.push_back(v.w); + RETURN_ARGS; } break; case Variant::VECTOR4I: { const Vector4i v = p_variant; - Array args = { v.x, v.y, v.z, v.w }; + + Array args; + args.push_back(v.x); + args.push_back(v.y); + args.push_back(v.z); + args.push_back(v.w); + RETURN_ARGS; } break; case Variant::PLANE: { const Plane p = p_variant; - Array args = { p.normal.x, p.normal.y, p.normal.z, p.d }; + + Array args; + args.push_back(p.normal.x); + args.push_back(p.normal.y); + args.push_back(p.normal.z); + args.push_back(p.d); + RETURN_ARGS; } break; case Variant::QUATERNION: { const Quaternion q = p_variant; - Array args = { q.x, q.y, q.z, q.w }; + + Array args; + args.push_back(q.x); + args.push_back(q.y); + args.push_back(q.z); + args.push_back(q.w); + RETURN_ARGS; } break; case Variant::AABB: { const AABB aabb = p_variant; - Array args = { aabb.position.x, aabb.position.y, aabb.position.z, aabb.size.x, aabb.size.y, aabb.size.z }; + + Array args; + args.push_back(aabb.position.x); + args.push_back(aabb.position.y); + args.push_back(aabb.position.z); + args.push_back(aabb.size.x); + args.push_back(aabb.size.y); + args.push_back(aabb.size.z); + RETURN_ARGS; } break; case Variant::BASIS: { const Basis b = p_variant; - Array args = { b.get_column(0).x, b.get_column(0).y, b.get_column(0).z, - b.get_column(1).x, b.get_column(1).y, b.get_column(1).z, - b.get_column(2).x, b.get_column(2).y, b.get_column(2).z }; + Array args; + args.push_back(b.get_column(0).x); + args.push_back(b.get_column(0).y); + args.push_back(b.get_column(0).z); + args.push_back(b.get_column(1).x); + args.push_back(b.get_column(1).y); + args.push_back(b.get_column(1).z); + args.push_back(b.get_column(2).x); + args.push_back(b.get_column(2).y); + args.push_back(b.get_column(2).z); RETURN_ARGS; } break; case Variant::TRANSFORM3D: { const Transform3D t = p_variant; - Array args = { t.basis.get_column(0).x, t.basis.get_column(0).y, t.basis.get_column(0).z, - t.basis.get_column(1).x, t.basis.get_column(1).y, t.basis.get_column(1).z, - t.basis.get_column(2).x, t.basis.get_column(2).y, t.basis.get_column(2).z, - t.origin.x, t.origin.y, t.origin.z }; + Array args; + args.push_back(t.basis.get_column(0).x); + args.push_back(t.basis.get_column(0).y); + args.push_back(t.basis.get_column(0).z); + args.push_back(t.basis.get_column(1).x); + args.push_back(t.basis.get_column(1).y); + args.push_back(t.basis.get_column(1).z); + args.push_back(t.basis.get_column(2).x); + args.push_back(t.basis.get_column(2).y); + args.push_back(t.basis.get_column(2).z); + args.push_back(t.origin.x); + args.push_back(t.origin.y); + args.push_back(t.origin.z); RETURN_ARGS; } break; case Variant::PROJECTION: { const Projection p = p_variant; - Array args = { p[0].x, p[0].y, p[0].z, p[0].w, - p[1].x, p[1].y, p[1].z, p[1].w, - p[2].x, p[2].y, p[2].z, p[2].w, - p[3].x, p[3].y, p[3].z, p[3].w }; + Array args; + args.push_back(p[0].x); + args.push_back(p[0].y); + args.push_back(p[0].z); + args.push_back(p[0].w); + args.push_back(p[1].x); + args.push_back(p[1].y); + args.push_back(p[1].z); + args.push_back(p[1].w); + args.push_back(p[2].x); + args.push_back(p[2].y); + args.push_back(p[2].z); + args.push_back(p[2].w); + args.push_back(p[3].x); + args.push_back(p[3].y); + args.push_back(p[3].z); + args.push_back(p[3].w); RETURN_ARGS; } break; case Variant::COLOR: { const Color c = p_variant; - Array args = { c.r, c.g, c.b, c.a }; + + Array args; + args.push_back(c.r); + args.push_back(c.g); + args.push_back(c.b); + args.push_back(c.a); + RETURN_ARGS; } break; @@ -816,9 +922,12 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_ ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ret, "Variant is too deep. Bailing."); - for (const KeyValue &kv : dict) { - args.push_back(_from_native(kv.key, p_full_objects, p_depth + 1)); - args.push_back(_from_native(kv.value, p_full_objects, p_depth + 1)); + List keys; + dict.get_key_list(&keys); + + for (const Variant &key : keys) { + args.push_back(_from_native(key, p_full_objects, p_depth + 1)); + args.push_back(_from_native(dict[key], p_full_objects, p_depth + 1)); } return ret; diff --git a/engine/core/io/json.h b/engine/core/io/json.h index 9169e578..70baf289 100644 --- a/engine/core/io/json.h +++ b/engine/core/io/json.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef JSON_H +#define JSON_H #include "core/io/resource.h" #include "core/io/resource_loader.h" @@ -124,3 +125,5 @@ public: virtual void get_recognized_extensions(const Ref &p_resource, List *p_extensions) const override; virtual bool recognize(const Ref &p_resource) const override; }; + +#endif // JSON_H diff --git a/engine/core/io/logger.cpp b/engine/core/io/logger.cpp index 26fb06eb..2965a1ea 100644 --- a/engine/core/io/logger.cpp +++ b/engine/core/io/logger.cpp @@ -36,9 +36,10 @@ #include "core/templates/rb_set.h" #include "modules/modules_enabled.gen.h" // For regex. - #ifdef MODULE_REGEX_ENABLED #include "modules/regex/regex.h" +#else +class RegEx : public RefCounted {}; #endif // MODULE_REGEX_ENABLED #if defined(MINGW_ENABLED) || defined(_MSC_VER) @@ -155,7 +156,7 @@ void RotatedFileLogger::rotate_file() { if (FileAccess::exists(base_path)) { if (max_files > 1) { - String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace_char(':', '.'); + String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace(":", "."); String backup_name = base_path.get_basename() + timestamp; if (!base_path.get_extension().is_empty()) { backup_name += "." + base_path.get_extension(); diff --git a/engine/core/io/logger.h b/engine/core/io/logger.h index f3d8acad..e55f73f6 100644 --- a/engine/core/io/logger.h +++ b/engine/core/io/logger.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef LOGGER_H +#define LOGGER_H #include "core/io/file_access.h" #include "core/string/ustring.h" @@ -108,3 +109,5 @@ public: virtual ~CompositeLogger(); }; + +#endif // LOGGER_H diff --git a/engine/core/io/marshalls.cpp b/engine/core/io/marshalls.cpp index c81aaecc..19efe289 100644 --- a/engine/core/io/marshalls.cpp +++ b/engine/core/io/marshalls.cpp @@ -107,7 +107,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF); String str; - ERR_FAIL_COND_V(str.append_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA); + ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA); r_string = str; // Add padding. @@ -1345,7 +1345,7 @@ static Error _encode_container_type(const ContainerType &p_type, uint8_t *&buf, _encode_string(EncodedObjectAsID::get_class_static(), buf, r_len); } } else if (p_type.class_name != StringName()) { - _encode_string(p_full_objects ? p_type.class_name : EncodedObjectAsID::get_class_static(), buf, r_len); + _encode_string(p_full_objects ? p_type.class_name.operator String() : EncodedObjectAsID::get_class_static(), buf, r_len); } else { // No need to check `p_full_objects` since `class_name` should be non-empty for `builtin_type == Variant::OBJECT`. if (buf) { @@ -1849,16 +1849,19 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } r_len += 4; - for (const KeyValue &kv : dict) { + List keys; + dict.get_key_list(&keys); + + for (const Variant &key : keys) { int len; - Error err = encode_variant(kv.key, buf, len, p_full_objects, p_depth + 1); + Error err = encode_variant(key, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { buf += len; } - const Variant *value = dict.getptr(kv.key); + const Variant *value = dict.getptr(key); ERR_FAIL_NULL_V(value, ERR_BUG); err = encode_variant(*value, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); diff --git a/engine/core/io/marshalls.h b/engine/core/io/marshalls.h index 1d057d4d..82c760c2 100644 --- a/engine/core/io/marshalls.h +++ b/engine/core/io/marshalls.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef MARSHALLS_H +#define MARSHALLS_H #include "core/math/math_defs.h" #include "core/object/ref_counted.h" @@ -225,3 +226,5 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false, int p_depth = 0); Vector vector3_to_float32_array(const Vector3 *vecs, size_t count); + +#endif // MARSHALLS_H diff --git a/engine/core/io/missing_resource.h b/engine/core/io/missing_resource.h index 702cd3b3..4cded5ca 100644 --- a/engine/core/io/missing_resource.h +++ b/engine/core/io/missing_resource.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef MISSING_RESOURCE_H +#define MISSING_RESOURCE_H #include "core/io/resource.h" @@ -60,3 +61,5 @@ public: MissingResource(); }; + +#endif // MISSING_RESOURCE_H diff --git a/engine/core/io/net_socket.h b/engine/core/io/net_socket.h index 49671ece..49b23575 100644 --- a/engine/core/io/net_socket.h +++ b/engine/core/io/net_socket.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef NET_SOCKET_H +#define NET_SOCKET_H #include "core/io/ip.h" #include "core/object/ref_counted.h" @@ -78,3 +79,5 @@ public: virtual ~NetSocket() {} }; + +#endif // NET_SOCKET_H diff --git a/engine/core/io/packed_data_container.cpp b/engine/core/io/packed_data_container.cpp index 222e1679..ca236ce0 100644 --- a/engine/core/io/packed_data_container.cpp +++ b/engine/core/io/packed_data_container.cpp @@ -268,12 +268,14 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector &tmpd encode_uint32(TYPE_DICT, &tmpdata.write[pos + 0]); encode_uint32(len, &tmpdata.write[pos + 4]); + List keys; + d.get_key_list(&keys); List sortk; - for (const KeyValue &kv : d) { + for (const Variant &key : keys) { DictKey dk; - dk.hash = kv.key.hash(); - dk.key = kv.key; + dk.hash = key.hash(); + dk.key = key; sortk.push_back(dk); } diff --git a/engine/core/io/packed_data_container.h b/engine/core/io/packed_data_container.h index 8d25d5c9..f4ffa090 100644 --- a/engine/core/io/packed_data_container.h +++ b/engine/core/io/packed_data_container.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PACKED_DATA_CONTAINER_H +#define PACKED_DATA_CONTAINER_H #include "core/io/resource.h" @@ -99,3 +100,5 @@ public: PackedDataContainerRef() {} }; + +#endif // PACKED_DATA_CONTAINER_H diff --git a/engine/core/io/packet_peer.h b/engine/core/io/packet_peer.h index 91d3bc44..86ebe32c 100644 --- a/engine/core/io/packet_peer.h +++ b/engine/core/io/packet_peer.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PACKET_PEER_H +#define PACKET_PEER_H #include "core/io/stream_peer.h" #include "core/object/class_db.h" @@ -123,3 +124,5 @@ public: int get_output_buffer_max_size() const; PacketPeerStream(); }; + +#endif // PACKET_PEER_H diff --git a/engine/core/io/packet_peer_dtls.h b/engine/core/io/packet_peer_dtls.h index 5de9640d..03d97a59 100644 --- a/engine/core/io/packet_peer_dtls.h +++ b/engine/core/io/packet_peer_dtls.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PACKET_PEER_DTLS_H +#define PACKET_PEER_DTLS_H #include "core/crypto/crypto.h" #include "core/io/packet_peer_udp.h" @@ -63,3 +64,5 @@ public: }; VARIANT_ENUM_CAST(PacketPeerDTLS::Status); + +#endif // PACKET_PEER_DTLS_H diff --git a/engine/core/io/packet_peer_udp.cpp b/engine/core/io/packet_peer_udp.cpp index 91e9934f..3463c41a 100644 --- a/engine/core/io/packet_peer_udp.cpp +++ b/engine/core/io/packet_peer_udp.cpp @@ -105,16 +105,18 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { return ERR_UNAVAILABLE; } - /* Bogus GCC warning here: - * In member function 'int RingBuffer::read(T*, int, bool) [with T = unsigned char]', - * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9, - * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7: - * Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] - * 68 | p_buf[dst++] = read[pos + i]; - * | ~~~~~~~~~~~~~^~~~~~~ - */ - GODOT_GCC_WARNING_PUSH - GODOT_GCC_PRAGMA(GCC diagnostic warning "-Wstringop-overflow=0") // Can't "ignore" this for some reason. +/* Bogus GCC warning here: + * In member function 'int RingBuffer::read(T*, int, bool) [with T = unsigned char]', + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9, + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7: + * Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] + * 68 | p_buf[dst++] = read[pos + i]; + * | ~~~~~~~~~~~~~^~~~~~~ + */ +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic warning "-Wstringop-overflow=0" +#endif uint32_t size = 0; uint8_t ipv6[16] = {}; @@ -127,7 +129,9 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { *r_buffer = packet_buffer; r_buffer_size = size; - GODOT_GCC_WARNING_POP +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif return OK; } diff --git a/engine/core/io/packet_peer_udp.h b/engine/core/io/packet_peer_udp.h index 1c909860..c69a138c 100644 --- a/engine/core/io/packet_peer_udp.h +++ b/engine/core/io/packet_peer_udp.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PACKET_PEER_UDP_H +#define PACKET_PEER_UDP_H #include "core/io/ip.h" #include "core/io/net_socket.h" @@ -96,3 +97,5 @@ public: PacketPeerUDP(); ~PacketPeerUDP(); }; + +#endif // PACKET_PEER_UDP_H diff --git a/engine/core/io/pck_packer.cpp b/engine/core/io/pck_packer.cpp index 75870f09..c7cfca19 100644 --- a/engine/core/io/pck_packer.cpp +++ b/engine/core/io/pck_packer.cpp @@ -91,9 +91,9 @@ Error PCKPacker::pck_start(const String &p_pck_path, int p_alignment, const Stri file->store_32(PACK_HEADER_MAGIC); file->store_32(PACK_FORMAT_VERSION); - file->store_32(GODOT_VERSION_MAJOR); - file->store_32(GODOT_VERSION_MINOR); - file->store_32(GODOT_VERSION_PATCH); + file->store_32(VERSION_MAJOR); + file->store_32(VERSION_MINOR); + file->store_32(VERSION_PATCH); uint32_t pack_flags = 0; if (enc_dir) { @@ -118,7 +118,8 @@ Error PCKPacker::add_file_removal(const String &p_target_path) { pf.size = 0; pf.removal = true; - pf.md5.resize_zeroed(16); + pf.md5.resize(16); + pf.md5.fill(0); files.push_back(pf); diff --git a/engine/core/io/pck_packer.h b/engine/core/io/pck_packer.h index 4c386b36..043a1dbd 100644 --- a/engine/core/io/pck_packer.h +++ b/engine/core/io/pck_packer.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PCK_PACKER_H +#define PCK_PACKER_H #include "core/object/ref_counted.h" @@ -65,3 +66,5 @@ public: PCKPacker() {} }; + +#endif // PCK_PACKER_H diff --git a/engine/core/io/plist.cpp b/engine/core/io/plist.cpp index b02ca8a7..30c786ae 100644 --- a/engine/core/io/plist.cpp +++ b/engine/core/io/plist.cpp @@ -383,16 +383,14 @@ void PListNode::store_text(String &p_stream, uint8_t p_indent) const { p_stream += String("\t").repeat(p_indent); p_stream += "\n"; p_stream += String("\t").repeat(p_indent); - // Data should be Base64 (i.e. ASCII only). - p_stream += String::ascii(data_string) + "\n"; + p_stream += data_string + "\n"; p_stream += String("\t").repeat(p_indent); p_stream += "\n"; } break; case PList::PLNodeType::PL_NODE_TYPE_DATE: { p_stream += String("\t").repeat(p_indent); p_stream += ""; - // Data should be ISO 8601 (i.e. ASCII only). - p_stream += String::ascii(data_string); + p_stream += data_string; p_stream += "\n"; } break; case PList::PLNodeType::PL_NODE_TYPE_STRING: { @@ -631,7 +629,7 @@ bool PList::load_file(const String &p_filename) { unsigned char magic[8]; fb->get_buffer(magic, 8); - if (String::ascii(Span((const char *)magic, 8)) == "bplist00") { + if (String((const char *)magic, 8) == "bplist00") { fb->seek_end(-26); trailer.offset_size = fb->get_8(); trailer.ref_size = fb->get_8(); @@ -647,8 +645,10 @@ bool PList::load_file(const String &p_filename) { Vector array = FileAccess::get_file_as_bytes(p_filename, &err); ERR_FAIL_COND_V(err != OK, false); + String ret; + ret.parse_utf8((const char *)array.ptr(), array.size()); String err_str; - bool ok = load_string(String::utf8((const char *)array.ptr(), array.size()), err_str); + bool ok = load_string(ret, err_str); ERR_FAIL_COND_V_MSG(!ok, false, "PList: " + err_str); return true; diff --git a/engine/core/io/plist.h b/engine/core/io/plist.h index 6d2dcef3..7b319906 100644 --- a/engine/core/io/plist.h +++ b/engine/core/io/plist.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PLIST_H +#define PLIST_H // Property list file format (application/x-plist) parser, property list ASN-1 serialization. @@ -83,8 +84,6 @@ public: /*************************************************************************/ class PListNode : public RefCounted { - GDSOFTCLASS(PListNode, RefCounted); - static int _asn1_size_len(uint8_t p_len_octets); public: @@ -123,3 +122,5 @@ public: PListNode() {} ~PListNode() {} }; + +#endif // PLIST_H diff --git a/engine/core/io/remote_filesystem_client.h b/engine/core/io/remote_filesystem_client.h index 6b4db9b5..f96c263c 100644 --- a/engine/core/io/remote_filesystem_client.h +++ b/engine/core/io/remote_filesystem_client.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef REMOTE_FILESYSTEM_CLIENT_H +#define REMOTE_FILESYSTEM_CLIENT_H #include "core/string/ustring.h" #include "core/templates/hash_set.h" @@ -59,3 +60,5 @@ public: Error synchronize_with_server(const String &p_host, int p_port, const String &p_password, String &r_cache_path); virtual ~RemoteFilesystemClient() {} }; + +#endif // REMOTE_FILESYSTEM_CLIENT_H diff --git a/engine/core/io/resource.cpp b/engine/core/io/resource.cpp index fac829d9..886ec6f5 100644 --- a/engine/core/io/resource.cpp +++ b/engine/core/io/resource.cpp @@ -32,15 +32,10 @@ #include "core/io/resource_loader.h" #include "core/math/math_funcs.h" -#include "core/math/random_pcg.h" #include "core/os/os.h" #include "scene/main/node.h" //only so casting works void Resource::emit_changed() { - if (emit_changed_state != EMIT_CHANGED_UNBLOCKED) { - emit_changed_state = EMIT_CHANGED_BLOCKED_PENDING_EMIT; - return; - } if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) { ResourceLoader::resource_changed_emit(this); return; @@ -49,20 +44,6 @@ void Resource::emit_changed() { emit_signal(CoreStringName(changed)); } -void Resource::_block_emit_changed() { - if (emit_changed_state == EMIT_CHANGED_UNBLOCKED) { - emit_changed_state = EMIT_CHANGED_BLOCKED; - } -} - -void Resource::_unblock_emit_changed() { - bool emit = (emit_changed_state == EMIT_CHANGED_BLOCKED_PENDING_EMIT); - emit_changed_state = EMIT_CHANGED_UNBLOCKED; - if (emit) { - emit_changed(); - } -} - void Resource::_resource_path_changed() { } @@ -114,7 +95,7 @@ void Resource::set_path_cache(const String &p_path) { GDVIRTUAL_CALL(_set_path_cache, p_path); } -static thread_local RandomPCG unique_id_gen = RandomPCG(0); +static thread_local RandomPCG unique_id_gen(0, RandomPCG::DEFAULT_INC); void Resource::seed_scene_unique_id(uint32_t p_seed) { unique_id_gen.seed(p_seed); @@ -224,8 +205,6 @@ Error Resource::copy_from(const Ref &p_resource) { return ERR_INVALID_PARAMETER; } - _block_emit_changed(); - reset_state(); // May want to reset state. List pi; @@ -241,9 +220,6 @@ Error Resource::copy_from(const Ref &p_resource) { set(E.name, p_resource->get(E.name)); } - - _unblock_emit_changed(); - return OK; } @@ -272,7 +248,9 @@ void Resource::_dupe_sub_resources(Variant &r_variant, Node *p_for_scene, HashMa } break; case Variant::DICTIONARY: { Dictionary d = r_variant; - for (Variant &k : d.get_key_list()) { + List keys; + d.get_key_list(&keys); + for (Variant &k : keys) { if (k.get_type() == Variant::OBJECT) { // Replace in dictionary key. Ref sr = k; @@ -344,9 +322,11 @@ void Resource::_find_sub_resources(const Variant &p_variant, HashSet &kv : d) { - _find_sub_resources(kv.key, p_resources_found); - _find_sub_resources(kv.value, p_resources_found); + List keys; + d.get_key_list(&keys); + for (const Variant &k : keys) { + _find_sub_resources(k, p_resources_found); + _find_sub_resources(d[k], p_resources_found); } } break; case Variant::OBJECT: { diff --git a/engine/core/io/resource.h b/engine/core/io/resource.h index 14c08629..ebc82cee 100644 --- a/engine/core/io/resource.h +++ b/engine/core/io/resource.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RESOURCE_H +#define RESOURCE_H #include "core/io/resource_uid.h" #include "core/object/class_db.h" @@ -71,12 +72,6 @@ private: String import_path; #endif - enum EmitChangedState { - EMIT_CHANGED_UNBLOCKED, - EMIT_CHANGED_BLOCKED, - EMIT_CHANGED_BLOCKED_PENDING_EMIT, - }; - EmitChangedState emit_changed_state = EMIT_CHANGED_UNBLOCKED; bool local_to_scene = false; friend class SceneState; Node *local_scene = nullptr; @@ -90,9 +85,6 @@ protected: virtual void _resource_path_changed(); static void _bind_methods(); - void _block_emit_changed(); - void _unblock_emit_changed(); - void _set_path(const String &p_path); void _take_over_path(const String &p_path); @@ -187,3 +179,5 @@ public: static void get_cached_resources(List> *p_resources); static int get_cached_resource_count(); }; + +#endif // RESOURCE_H diff --git a/engine/core/io/resource_format_binary.cpp b/engine/core/io/resource_format_binary.cpp index 98511f02..891510e3 100644 --- a/engine/core/io/resource_format_binary.cpp +++ b/engine/core/io/resource_format_binary.cpp @@ -162,7 +162,9 @@ StringName ResourceLoaderBinary::_get_string() { return StringName(); } f->get_buffer((uint8_t *)&str_buf[0], len); - return String::utf8(&str_buf[0], len); + String s; + s.parse_utf8(&str_buf[0], len); + return s; } return string_map[id]; @@ -916,7 +918,9 @@ static String get_ustring(Ref f) { Vector str_buf; str_buf.resize(len); f->get_buffer((uint8_t *)&str_buf[0], len); - return String::utf8(&str_buf[0], len); + String s; + s.parse_utf8(&str_buf[0], len); + return s; } String ResourceLoaderBinary::get_unicode_string() { @@ -928,7 +932,9 @@ String ResourceLoaderBinary::get_unicode_string() { return String(); } f->get_buffer((uint8_t *)&str_buf[0], len); - return String::utf8(&str_buf[0], len); + String s; + s.parse_utf8(&str_buf[0], len); + return s; } void ResourceLoaderBinary::get_classes_used(Ref p_f, HashSet *p_classes) { @@ -1022,10 +1028,10 @@ void ResourceLoaderBinary::open(Ref p_f, bool p_no_resources, bool p print_bl("minor: " + itos(ver_minor)); print_bl("format: " + itos(ver_format)); - if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { + if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { f.unref(); ERR_FAIL_MSG(vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", - local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH)); + local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); } type = get_unicode_string(); @@ -1149,7 +1155,7 @@ String ResourceLoaderBinary::recognize(Ref p_f) { f->get_32(); // ver_minor uint32_t ver_fmt = f->get_32(); - if (ver_fmt > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { + if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) { f.unref(); return ""; } @@ -1190,7 +1196,7 @@ String ResourceLoaderBinary::recognize_script_class(Ref p_f) { f->get_32(); // ver_minor uint32_t ver_fmt = f->get_32(); - if (ver_fmt > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { + if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) { f.unref(); return ""; } @@ -1342,10 +1348,13 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons bool use_real64 = f->get_32(); f->set_big_endian(big_endian != 0); //read big endian if saved as big endian - +#ifdef BIG_ENDIAN_ENABLED + fw->store_32(!big_endian); +#else fw->store_32(big_endian); - fw->store_32(use_real64); //use real64 +#endif fw->set_big_endian(big_endian != 0); + fw->store_32(use_real64); //use real64 uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); @@ -1383,10 +1392,10 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons return ResourceFormatSaverBinary::singleton->save(res, p_path); } - if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { + if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", - local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH)); + local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); } // Since we're not actually converting the file contents, leave the version @@ -1867,9 +1876,12 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref f, const V Dictionary d = p_property; f->store_32(uint32_t(d.size())); - for (const KeyValue &kv : d) { - write_variant(f, kv.key, resource_map, external_resources, string_map); - write_variant(f, kv.value, resource_map, external_resources, string_map); + List keys; + d.get_key_list(&keys); + + for (const Variant &E : keys) { + write_variant(f, E, resource_map, external_resources, string_map); + write_variant(f, d[E], resource_map, external_resources, string_map); } } break; @@ -2074,9 +2086,12 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant Dictionary d = p_variant; _find_resources(d.get_typed_key_script()); _find_resources(d.get_typed_value_script()); - for (const KeyValue &kv : d) { - _find_resources(kv.key); - _find_resources(kv.value); + List keys; + d.get_key_list(&keys); + for (const Variant &E : keys) { + _find_resources(E); + Variant v = d[E]; + _find_resources(v); } } break; case Variant::NODE_PATH: { @@ -2165,14 +2180,14 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Refstore_32(1); + f->set_big_endian(true); } else { f->store_32(0); } - f->store_32(0); //64 bits file, false for now - f->set_big_endian(big_endian); - f->store_32(GODOT_VERSION_MAJOR); - f->store_32(GODOT_VERSION_MINOR); + f->store_32(0); //64 bits file, false for now + f->store_32(VERSION_MAJOR); + f->store_32(VERSION_MINOR); f->store_32(FORMAT_VERSION); if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) { @@ -2409,10 +2424,13 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU big_endian = f->get_32(); bool use_real64 = f->get_32(); f->set_big_endian(big_endian != 0); //read big endian if saved as big endian - +#ifdef BIG_ENDIAN_ENABLED + fw->store_32(!big_endian); +#else fw->store_32(big_endian); - fw->store_32(use_real64); //use real64 +#endif fw->set_big_endian(big_endian != 0); + fw->store_32(use_real64); //use real64 uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); @@ -2432,10 +2450,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU return ERR_UNAVAILABLE; } - if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { + if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", - local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH)); + local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); } // Since we're not actually converting the file contents, leave the version diff --git a/engine/core/io/resource_format_binary.h b/engine/core/io/resource_format_binary.h index dfd2cd6f..ec8d7ead 100644 --- a/engine/core/io/resource_format_binary.h +++ b/engine/core/io/resource_format_binary.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RESOURCE_FORMAT_BINARY_H +#define RESOURCE_FORMAT_BINARY_H #include "core/io/file_access.h" #include "core/io/resource_loader.h" @@ -188,3 +189,5 @@ public: ResourceFormatSaverBinary(); }; + +#endif // RESOURCE_FORMAT_BINARY_H diff --git a/engine/core/io/resource_importer.cpp b/engine/core/io/resource_importer.cpp index 81c3deb9..b7a14f2b 100644 --- a/engine/core/io/resource_importer.cpp +++ b/engine/core/io/resource_importer.cpp @@ -32,7 +32,6 @@ #include "core/config/project_settings.h" #include "core/io/config_file.h" -#include "core/io/image.h" #include "core/os/os.h" #include "core/variant/variant_parser.h" @@ -42,7 +41,7 @@ bool ResourceFormatImporter::SortImporterByName::operator()(const Refget_importer_name() < p_b->get_importer_name(); } -Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid) const { +Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { Error err; Ref f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); @@ -66,10 +65,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy int lines = 0; String error_text; - bool path_found = false; // First match must have priority. - - String decomp_path; - bool decomp_path_found = false; + bool path_found = false; //first match must have priority while (true) { assign = Variant(); next_tag.fields.clear(); @@ -77,11 +73,6 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true); if (err == ERR_FILE_EOF) { - if (p_load && !path_found && decomp_path_found) { - print_verbose(vformat("No natively supported texture format found for %s, using decompressable format %s.", p_path, decomp_path)); - r_path_and_type.path = decomp_path; - } - return OK; } else if (err != OK) { ERR_PRINT(vformat("ResourceFormatImporter::load - %s.import:%d error: %s.", p_path, lines, error_text)); @@ -93,15 +84,12 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy String feature = assign.get_slicec('.', 1); if (OS::get_singleton()->has_feature(feature)) { r_path_and_type.path = value; - path_found = true; // First match must have priority. - } else if (p_load && Image::can_decompress(feature) && !decomp_path_found) { // When loading, check for decompressable formats and use first one found if nothing else is supported. - decomp_path = value; - decomp_path_found = true; // First match must have priority. + path_found = true; //first match must have priority } } else if (!path_found && assign == "path") { r_path_and_type.path = value; - path_found = true; // First match must have priority. + path_found = true; //first match must have priority } else if (assign == "type") { r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value); } else if (assign == "importer") { @@ -166,7 +154,7 @@ Ref ResourceFormatImporter::load(const String &p_path, const String &p Ref ResourceFormatImporter::load_internal(const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode, bool p_silence_errors) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, true); + Error err = _get_path_and_type(p_path, pat); if (err != OK) { if (r_error) { @@ -256,13 +244,13 @@ Error ResourceFormatImporter::get_import_order_threads_and_importer(const String if (FileAccess::exists(p_path + ".import")) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err == OK) { importer = get_importer_by_name(pat.importer); } } else { - importer = get_importer_by_file(p_path); + importer = get_importer_by_extension(p_path.get_extension().to_lower()); } if (importer.is_valid()) { @@ -280,13 +268,13 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const { if (FileAccess::exists(p_path + ".import")) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err == OK) { importer = get_importer_by_name(pat.importer); } } else { - importer = get_importer_by_file(p_path); + importer = get_importer_by_extension(p_path.get_extension().to_lower()); } if (importer.is_valid()) { @@ -312,7 +300,7 @@ bool ResourceFormatImporter::handles_type(const String &p_type) const { String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err != OK) { return String(); @@ -366,20 +354,20 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat String ResourceFormatImporter::get_import_group_file(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, false, &valid); + _get_path_and_type(p_path, pat, &valid); return valid ? pat.group_file : String(); } bool ResourceFormatImporter::is_import_valid(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, false, &valid); + _get_path_and_type(p_path, pat, &valid); return valid; } String ResourceFormatImporter::get_resource_type(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err != OK) { return ""; @@ -390,7 +378,7 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const { ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err != OK) { return ResourceUID::INVALID_ID; @@ -405,7 +393,7 @@ bool ResourceFormatImporter::has_custom_uid_support() const { Error ResourceFormatImporter::get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err == OK) { r_type = pat.type; @@ -422,7 +410,7 @@ Error ResourceFormatImporter::get_resource_import_info(const String &p_path, Str Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err != OK) { return Variant(); @@ -432,7 +420,7 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons } void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet *r_classes) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err != OK) { return; @@ -443,7 +431,7 @@ void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet *p_dependencies, bool p_add_types) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat, false); + Error err = _get_path_and_type(p_path, pat); if (err != OK) { return; @@ -471,12 +459,12 @@ void ResourceFormatImporter::add_importer(const Ref &p_importe } } -void ResourceFormatImporter::get_importers_for_file(const String &p_file, List> *r_importers) { +void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List> *r_importers) { for (int i = 0; i < importers.size(); i++) { List local_exts; importers[i]->get_recognized_extensions(&local_exts); for (const String &F : local_exts) { - if (p_file.right(F.length()).nocasecmp_to(F) == 0) { + if (p_extension.to_lower() == F) { r_importers->push_back(importers[i]); break; } @@ -490,7 +478,7 @@ void ResourceFormatImporter::get_importers(List> *r_import } } -Ref ResourceFormatImporter::get_importer_by_file(const String &p_file) const { +Ref ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const { Ref importer; float priority = 0; @@ -498,10 +486,9 @@ Ref ResourceFormatImporter::get_importer_by_file(const String List local_exts; importers[i]->get_recognized_extensions(&local_exts); for (const String &F : local_exts) { - if (p_file.right(F.length()).nocasecmp_to(F) == 0 && importers[i]->get_priority() > priority) { + if (p_extension.to_lower() == F && importers[i]->get_priority() > priority) { importer = importers[i]; priority = importers[i]->get_priority(); - break; } } } @@ -516,7 +503,7 @@ String ResourceFormatImporter::get_import_base_path(const String &p_for_file) co bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, false, &valid); + _get_path_and_type(p_path, pat, &valid); if (!valid) { return false; diff --git a/engine/core/io/resource_importer.h b/engine/core/io/resource_importer.h index ff1baad9..1d00ef3b 100644 --- a/engine/core/io/resource_importer.h +++ b/engine/core/io/resource_importer.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RESOURCE_IMPORTER_H +#define RESOURCE_IMPORTER_H #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -48,7 +49,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { ResourceUID::ID uid = ResourceUID::INVALID_ID; }; - Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid = nullptr) const; + Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = nullptr) const; static ResourceFormatImporter *singleton; @@ -89,8 +90,8 @@ public: void remove_importer(const Ref &p_importer) { importers.erase(p_importer); } Ref get_importer_by_name(const String &p_name) const; - Ref get_importer_by_file(const String &p_file) const; - void get_importers_for_file(const String &p_file, List> *r_importers); + Ref get_importer_by_extension(const String &p_extension) const; + void get_importers_for_extension(const String &p_extension, List> *r_importers); void get_importers(List> *r_importers); bool are_import_settings_valid(const String &p_path) const; @@ -165,3 +166,5 @@ class ResourceFormatImporterSaver : public ResourceFormatSaver { public: virtual Error set_uid(const String &p_path, ResourceUID::ID p_uid) override; }; + +#endif // RESOURCE_IMPORTER_H diff --git a/engine/core/io/resource_loader.cpp b/engine/core/io/resource_loader.cpp index 869faa98..04fd641f 100644 --- a/engine/core/io/resource_loader.cpp +++ b/engine/core/io/resource_loader.cpp @@ -61,6 +61,8 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_ return ret; } + String extension = p_path.get_extension(); + List extensions; if (p_for_type.is_empty()) { get_recognized_extensions(&extensions); @@ -69,8 +71,7 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_ } for (const String &E : extensions) { - const String ext = !E.begins_with(".") ? "." + E : E; - if (p_path.right(ext.length()).nocasecmp_to(ext) == 0) { + if (E.nocasecmp_to(extension) == 0) { return true; } } @@ -263,14 +264,6 @@ void ResourceLoader::LoadToken::clear() { thread_load_tasks.erase(local_path); } local_path.clear(); // Mark as already cleared. - if (task_to_await) { - for (KeyValue &E : thread_load_tasks) { - if (E.value.task_id == task_to_await) { - task_to_await = 0; - break; // Same task is reused by nested loads, do not wait for completion here. - } - } - } } } @@ -329,7 +322,7 @@ Ref ResourceLoader::_load(const String &p_path, const String &p_origin #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - if (ResourceFormatImporter::get_singleton()->get_importer_by_file(p_path).is_valid()) { + if (ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_path.get_extension()).is_valid()) { // The format is known to the editor, but the file hasn't been imported // (otherwise, ResourceFormatImporter would have been found as a suitable loader). found = true; @@ -779,10 +772,6 @@ Ref ResourceLoader::_load_complete(LoadToken &p_load_token, Error *r_e return _load_complete_inner(p_load_token, r_error, thread_load_lock); } -void ResourceLoader::set_is_import_thread(bool p_import_thread) { - import_thread = p_import_thread; -} - Ref ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Error *r_error, MutexLock> &p_thread_load_lock) { if (r_error) { *r_error = OK; @@ -836,12 +825,6 @@ Ref ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro p_thread_load_lock.temp_relock(); load_task.awaited = true; - // Mark nested loads with the same task id as awaited. - for (KeyValue &E : thread_load_tasks) { - if (E.value.task_id == load_task.task_id) { - E.value.awaited = true; - } - } DEV_ASSERT(load_task.status == THREAD_LOAD_FAILED || load_task.status == THREAD_LOAD_LOADED); } else if (load_task.need_wait) { @@ -903,11 +886,9 @@ Ref ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro MessageQueue::get_main_singleton()->push_callable(callable_mp(rcc.source, &Resource::connect_changed).bind(rcc.callable, rcc.flags)); } } - if (!import_thread) { // Main thread is blocked by initial resource reimport, do not wait. - CoreBind::Semaphore done; - MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &CoreBind::Semaphore::post).bind(1)); - done.wait(); - } + core_bind::Semaphore done; + MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &core_bind::Semaphore::post).bind(1)); + done.wait(); } } } @@ -1358,8 +1339,10 @@ void ResourceLoader::load_translation_remaps() { } Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); - for (const KeyValue &kv : remaps) { - Array langs = kv.value; + List keys; + remaps.get_key_list(&keys); + for (const Variant &E : keys) { + Array langs = remaps[E]; Vector lang_remaps; lang_remaps.resize(langs.size()); String *lang_remaps_ptrw = lang_remaps.ptrw(); @@ -1367,7 +1350,7 @@ void ResourceLoader::load_translation_remaps() { *lang_remaps_ptrw++ = lang; } - translation_remaps[String(kv.key)] = lang_remaps; + translation_remaps[String(E)] = lang_remaps; } } @@ -1582,7 +1565,6 @@ bool ResourceLoader::create_missing_resources_if_class_unavailable = false; bool ResourceLoader::abort_on_missing_resource = true; bool ResourceLoader::timestamp_on_load = false; -thread_local bool ResourceLoader::import_thread = false; thread_local int ResourceLoader::load_nesting = 0; thread_local Vector ResourceLoader::load_paths_stack; thread_local HashMap>> ResourceLoader::res_ref_overrides; diff --git a/engine/core/io/resource_loader.h b/engine/core/io/resource_loader.h index 189f000e..10a82e81 100644 --- a/engine/core/io/resource_loader.h +++ b/engine/core/io/resource_loader.h @@ -28,14 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RESOURCE_LOADER_H +#define RESOURCE_LOADER_H #include "core/io/resource.h" #include "core/object/gdvirtual.gen.inc" #include "core/object/worker_thread_pool.h" #include "core/os/thread.h" -namespace CoreBind { +namespace core_bind { class ResourceLoader; } @@ -104,7 +105,7 @@ typedef void (*ResourceLoadedCallback)(Ref p_resource, const String &p class ResourceLoader { friend class LoadToken; - friend class CoreBind::ResourceLoader; + friend class core_bind::ResourceLoader; enum { MAX_LOADERS = 64 @@ -204,7 +205,6 @@ private: static void _run_load_task(void *p_userdata); - static thread_local bool import_thread; static thread_local int load_nesting; static thread_local HashMap>> res_ref_overrides; // Outermost key is nesting level. static thread_local Vector load_paths_stack; @@ -254,8 +254,6 @@ public: static bool is_imported(const String &p_path); static int get_import_order(const String &p_path); - static void set_is_import_thread(bool p_import_thread); - static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; } static bool get_timestamp_on_load() { return timestamp_on_load; } @@ -318,3 +316,5 @@ public: static void initialize(); static void finalize(); }; + +#endif // RESOURCE_LOADER_H diff --git a/engine/core/io/resource_saver.h b/engine/core/io/resource_saver.h index 5602a3a4..3e082192 100644 --- a/engine/core/io/resource_saver.h +++ b/engine/core/io/resource_saver.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RESOURCE_SAVER_H +#define RESOURCE_SAVER_H #include "core/io/resource.h" #include "core/object/gdvirtual.gen.inc" @@ -102,3 +103,5 @@ public: static void add_custom_savers(); static void remove_custom_savers(); }; + +#endif // RESOURCE_SAVER_H diff --git a/engine/core/io/resource_uid.cpp b/engine/core/io/resource_uid.cpp index ef997f74..a73adf9d 100644 --- a/engine/core/io/resource_uid.cpp +++ b/engine/core/io/resource_uid.cpp @@ -35,7 +35,6 @@ #include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/io/resource_loader.h" -#include "core/math/random_pcg.h" // These constants are off by 1, causing the 'z' and '9' characters never to be used. // This cannot be fixed without breaking compatibility; see GH-83843. @@ -47,7 +46,7 @@ String ResourceUID::get_cache_file() { } static constexpr uint8_t uuid_characters[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', '0', '1', '2', '3', '4', '5', '6', '7', '8' }; -static constexpr uint32_t uuid_characters_element_count = std::size(uuid_characters); +static constexpr uint32_t uuid_characters_element_count = (sizeof(uuid_characters) / sizeof(*uuid_characters)); static constexpr uint8_t max_uuid_number_length = 13; // Max 0x7FFFFFFFFFFFFFFF (uid://d4n4ub6itg400) size is 13 characters. String ResourceUID::id_to_text(ID p_id) const { @@ -122,31 +121,10 @@ ResourceUID::ID ResourceUID::create_id() { } } -ResourceUID::ID ResourceUID::create_id_for_path(const String &p_path) { - ID id = INVALID_ID; - RandomPCG rng; - - const String project_name = GLOBAL_GET("application/config/name"); - rng.seed(project_name.hash64() * p_path.hash64() * FileAccess::get_md5(p_path).hash64()); - - while (true) { - int64_t num1 = rng.rand(); - int64_t num2 = ((int64_t)rng.rand()) << 32; - id = (num1 | num2) & 0x7FFFFFFFFFFFFFFF; - - MutexLock lock(mutex); - if (!unique_ids.has(id)) { - break; - } - } - return id; -} - bool ResourceUID::has_id(ID p_id) const { MutexLock l(mutex); return unique_ids.has(p_id); } - void ResourceUID::add_id(ID p_id, const String &p_path) { MutexLock l(mutex); ERR_FAIL_COND(unique_ids.has(p_id)); @@ -333,7 +311,7 @@ String ResourceUID::get_path_from_cache(Ref &p_cache_file, const Str ERR_FAIL_COND_V(rl != len, String()); if (singleton->id_to_text(id) == p_uid_string) { - return String::utf8(cs.get_data()); + return String(cs); } } return String(); @@ -349,7 +327,6 @@ void ResourceUID::_bind_methods() { ClassDB::bind_method(D_METHOD("text_to_id", "text_id"), &ResourceUID::text_to_id); ClassDB::bind_method(D_METHOD("create_id"), &ResourceUID::create_id); - ClassDB::bind_method(D_METHOD("create_id_for_path", "path"), &ResourceUID::create_id_for_path); ClassDB::bind_method(D_METHOD("has_id", "id"), &ResourceUID::has_id); ClassDB::bind_method(D_METHOD("add_id", "id", "path"), &ResourceUID::add_id); diff --git a/engine/core/io/resource_uid.h b/engine/core/io/resource_uid.h index 6ac4c9c9..2912168d 100644 --- a/engine/core/io/resource_uid.h +++ b/engine/core/io/resource_uid.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RESOURCE_UID_H +#define RESOURCE_UID_H #include "core/object/ref_counted.h" #include "core/string/string_name.h" @@ -70,7 +71,6 @@ public: ID text_to_id(const String &p_text) const; ID create_id(); - ID create_id_for_path(const String &p_path); bool has_id(ID p_id) const; void add_id(ID p_id, const String &p_path); void set_id(ID p_id, const String &p_path); @@ -93,3 +93,5 @@ public: ResourceUID(); ~ResourceUID(); }; + +#endif // RESOURCE_UID_H diff --git a/engine/core/io/stream_peer.cpp b/engine/core/io/stream_peer.cpp index 2f2c1d30..bc7ea8a0 100644 --- a/engine/core/io/stream_peer.cpp +++ b/engine/core/io/stream_peer.cpp @@ -125,90 +125,54 @@ void StreamPeer::put_8(int8_t p_val) { } void StreamPeer::put_u16(uint16_t p_val) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_val = BSWAP16(p_val); - } -#else if (big_endian) { p_val = BSWAP16(p_val); } -#endif uint8_t buf[2]; encode_uint16(p_val, buf); put_data(buf, 2); } void StreamPeer::put_16(int16_t p_val) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_val = BSWAP16(p_val); - } -#else if (big_endian) { p_val = BSWAP16(p_val); } -#endif uint8_t buf[2]; encode_uint16(p_val, buf); put_data(buf, 2); } void StreamPeer::put_u32(uint32_t p_val) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_val = BSWAP32(p_val); - } -#else if (big_endian) { p_val = BSWAP32(p_val); } -#endif uint8_t buf[4]; encode_uint32(p_val, buf); put_data(buf, 4); } void StreamPeer::put_32(int32_t p_val) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_val = BSWAP32(p_val); - } -#else if (big_endian) { p_val = BSWAP32(p_val); } -#endif uint8_t buf[4]; encode_uint32(p_val, buf); put_data(buf, 4); } void StreamPeer::put_u64(uint64_t p_val) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_val = BSWAP64(p_val); - } -#else if (big_endian) { p_val = BSWAP64(p_val); } -#endif uint8_t buf[8]; encode_uint64(p_val, buf); put_data(buf, 8); } void StreamPeer::put_64(int64_t p_val) { -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - p_val = BSWAP64(p_val); - } -#else if (big_endian) { p_val = BSWAP64(p_val); } -#endif uint8_t buf[8]; encode_uint64(p_val, buf); put_data(buf, 8); @@ -219,15 +183,9 @@ void StreamPeer::put_half(float p_val) { encode_half(p_val, buf); uint16_t *p16 = (uint16_t *)buf; -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - *p16 = BSWAP16(*p16); - } -#else if (big_endian) { *p16 = BSWAP16(*p16); } -#endif put_data(buf, 2); } @@ -236,17 +194,10 @@ void StreamPeer::put_float(float p_val) { uint8_t buf[4]; encode_float(p_val, buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - uint32_t *p32 = (uint32_t *)buf; - *p32 = BSWAP32(*p32); - } -#else if (big_endian) { uint32_t *p32 = (uint32_t *)buf; *p32 = BSWAP32(*p32); } -#endif put_data(buf, 4); } @@ -255,17 +206,10 @@ void StreamPeer::put_double(double p_val) { uint8_t buf[8]; encode_double(p_val, buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - uint64_t *p64 = (uint64_t *)buf; - *p64 = BSWAP64(*p64); - } -#else if (big_endian) { uint64_t *p64 = (uint64_t *)buf; *p64 = BSWAP64(*p64); } -#endif put_data(buf, 8); } @@ -309,15 +253,9 @@ uint16_t StreamPeer::get_u16() { get_data(buf, 2); uint16_t r = decode_uint16(buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - r = BSWAP16(r); - } -#else if (big_endian) { r = BSWAP16(r); } -#endif return r; } @@ -327,15 +265,9 @@ int16_t StreamPeer::get_16() { get_data(buf, 2); uint16_t r = decode_uint16(buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - r = BSWAP16(r); - } -#else if (big_endian) { r = BSWAP16(r); } -#endif return int16_t(r); } @@ -345,15 +277,9 @@ uint32_t StreamPeer::get_u32() { get_data(buf, 4); uint32_t r = decode_uint32(buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - r = BSWAP32(r); - } -#else if (big_endian) { r = BSWAP32(r); } -#endif return r; } @@ -363,15 +289,9 @@ int32_t StreamPeer::get_32() { get_data(buf, 4); uint32_t r = decode_uint32(buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - r = BSWAP32(r); - } -#else if (big_endian) { r = BSWAP32(r); } -#endif return int32_t(r); } @@ -381,15 +301,9 @@ uint64_t StreamPeer::get_u64() { get_data(buf, 8); uint64_t r = decode_uint64(buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - r = BSWAP64(r); - } -#else if (big_endian) { r = BSWAP64(r); } -#endif return r; } @@ -399,15 +313,9 @@ int64_t StreamPeer::get_64() { get_data(buf, 8); uint64_t r = decode_uint64(buf); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - r = BSWAP64(r); - } -#else if (big_endian) { r = BSWAP64(r); } -#endif return int64_t(r); } @@ -416,17 +324,10 @@ float StreamPeer::get_half() { uint8_t buf[2]; get_data(buf, 2); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - uint16_t *p16 = (uint16_t *)buf; - *p16 = BSWAP16(*p16); - } -#else if (big_endian) { uint16_t *p16 = (uint16_t *)buf; *p16 = BSWAP16(*p16); } -#endif return decode_half(buf); } @@ -435,17 +336,10 @@ float StreamPeer::get_float() { uint8_t buf[4]; get_data(buf, 4); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - uint32_t *p32 = (uint32_t *)buf; - *p32 = BSWAP32(*p32); - } -#else if (big_endian) { uint32_t *p32 = (uint32_t *)buf; *p32 = BSWAP32(*p32); } -#endif return decode_float(buf); } @@ -454,17 +348,10 @@ double StreamPeer::get_double() { uint8_t buf[8]; get_data(buf, 8); -#ifdef BIG_ENDIAN_ENABLED - if (!big_endian) { - uint64_t *p64 = (uint64_t *)buf; - *p64 = BSWAP64(*p64); - } -#else if (big_endian) { uint64_t *p64 = (uint64_t *)buf; *p64 = BSWAP64(*p64); } -#endif return decode_double(buf); } @@ -496,7 +383,9 @@ String StreamPeer::get_utf8_string(int p_bytes) { err = get_data(buf.ptrw(), p_bytes); ERR_FAIL_COND_V(err != OK, String()); - return String::utf8((const char *)buf.ptr(), buf.size()); + String ret; + ret.parse_utf8((const char *)buf.ptr(), buf.size()); + return ret; } Variant StreamPeer::get_var(bool p_allow_objects) { diff --git a/engine/core/io/stream_peer.h b/engine/core/io/stream_peer.h index a73e92d2..44bbfbf1 100644 --- a/engine/core/io/stream_peer.h +++ b/engine/core/io/stream_peer.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef STREAM_PEER_H +#define STREAM_PEER_H #include "core/object/ref_counted.h" @@ -49,11 +50,7 @@ protected: Array _get_data(int p_bytes); Array _get_partial_data(int p_bytes); -#ifdef BIG_ENDIAN_ENABLED - bool big_endian = true; -#else bool big_endian = false; -#endif public: virtual Error put_data(const uint8_t *p_data, int p_bytes) = 0; ///< put a whole chunk of data, blocking until it sent @@ -155,3 +152,5 @@ public: StreamPeerBuffer() {} }; + +#endif // STREAM_PEER_H diff --git a/engine/core/io/stream_peer_gzip.cpp b/engine/core/io/stream_peer_gzip.cpp index ed247eaf..514bcf59 100644 --- a/engine/core/io/stream_peer_gzip.cpp +++ b/engine/core/io/stream_peer_gzip.cpp @@ -195,12 +195,12 @@ int StreamPeerGZIP::get_available_bytes() const { Error StreamPeerGZIP::finish() { ERR_FAIL_COND_V(!ctx || !compressing, ERR_UNAVAILABLE); // Ensure we have enough space in temporary buffer. - if (buffer.size() < get_available_bytes()) { - buffer.resize(get_available_bytes()); // get_available_bytes() is what we can store in RingBuffer. + if (buffer.size() < 1024) { + buffer.resize(1024); // 1024 should be more than enough. } int consumed = 0; int to_write = 0; - Error err = _process(buffer.ptrw(), buffer.size(), nullptr, 0, consumed, to_write, true); // compress + Error err = _process(buffer.ptrw(), 1024, nullptr, 0, consumed, to_write, true); // compress if (err != OK) { return err; } diff --git a/engine/core/io/stream_peer_gzip.h b/engine/core/io/stream_peer_gzip.h index 394fd613..a2e25ea4 100644 --- a/engine/core/io/stream_peer_gzip.h +++ b/engine/core/io/stream_peer_gzip.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef STREAM_PEER_GZIP_H +#define STREAM_PEER_GZIP_H #include "core/io/stream_peer.h" @@ -71,3 +72,5 @@ public: StreamPeerGZIP(); ~StreamPeerGZIP(); }; + +#endif // STREAM_PEER_GZIP_H diff --git a/engine/core/io/stream_peer_tcp.h b/engine/core/io/stream_peer_tcp.h index 80097a66..d7da7503 100644 --- a/engine/core/io/stream_peer_tcp.h +++ b/engine/core/io/stream_peer_tcp.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef STREAM_PEER_TCP_H +#define STREAM_PEER_TCP_H #include "core/io/ip.h" #include "core/io/ip_address.h" @@ -91,3 +92,5 @@ public: }; VARIANT_ENUM_CAST(StreamPeerTCP::Status); + +#endif // STREAM_PEER_TCP_H diff --git a/engine/core/io/stream_peer_tls.h b/engine/core/io/stream_peer_tls.h index 80a48115..3e03e25a 100644 --- a/engine/core/io/stream_peer_tls.h +++ b/engine/core/io/stream_peer_tls.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef STREAM_PEER_TLS_H +#define STREAM_PEER_TLS_H #include "core/crypto/crypto.h" #include "core/io/stream_peer.h" @@ -65,3 +66,5 @@ public: }; VARIANT_ENUM_CAST(StreamPeerTLS::Status); + +#endif // STREAM_PEER_TLS_H diff --git a/engine/core/io/tcp_server.h b/engine/core/io/tcp_server.h index 943d4c6f..472d86f3 100644 --- a/engine/core/io/tcp_server.h +++ b/engine/core/io/tcp_server.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef TCP_SERVER_H +#define TCP_SERVER_H #include "core/io/ip.h" #include "core/io/net_socket.h" @@ -58,3 +59,5 @@ public: TCPServer(); ~TCPServer(); }; + +#endif // TCP_SERVER_H diff --git a/engine/core/io/translation_loader_po.cpp b/engine/core/io/translation_loader_po.cpp index 35773109..1761d6fa 100644 --- a/engine/core/io/translation_loader_po.cpp +++ b/engine/core/io/translation_loader_po.cpp @@ -76,17 +76,14 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ bool is_plural = false; for (uint32_t j = 0; j < str_len + 1; j++) { if (data[j] == 0x04) { - msg_context.clear(); - msg_context.append_utf8((const char *)data.ptr(), j); + msg_context.parse_utf8((const char *)data.ptr(), j); str_start = j + 1; } if (data[j] == 0x00) { if (is_plural) { - msg_id_plural.clear(); - msg_id_plural.append_utf8((const char *)(data.ptr() + str_start), j - str_start); + msg_id_plural.parse_utf8((const char *)(data.ptr() + str_start), j - str_start); } else { - msg_id.clear(); - msg_id.append_utf8((const char *)(data.ptr() + str_start), j - str_start); + msg_id.parse_utf8((const char *)(data.ptr() + str_start), j - str_start); is_plural = true; } str_start = j + 1; @@ -192,7 +189,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ } } msg_context = ""; - l = l.substr(7).strip_edges(); + l = l.substr(7, l.length()).strip_edges(); status = STATUS_READING_CONTEXT; entered_context = true; } @@ -205,7 +202,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ } // We don't record the message in "msgid_plural" itself as tr_n(), TTRN(), RTRN() interfaces provide the plural string already. // We just have to reset variables related to plurals for "msgstr[]" later on. - l = l.substr(12).strip_edges(); + l = l.substr(12, l.length()).strip_edges(); plural_index = -1; msgs_plural.clear(); msgs_plural.resize(plural_forms); @@ -233,7 +230,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ } } - l = l.substr(5).strip_edges(); + l = l.substr(5, l.length()).strip_edges(); status = STATUS_READING_ID; // If we did not encounter msgctxt, we reset context to empty to reset it. if (!entered_context) { @@ -249,10 +246,10 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ if (l.begins_with("msgstr[")) { ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Ref(), vformat("Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: %s:%d.", path, line)); plural_index++; // Increment to add to the next slot in vector msgs_plural. - l = l.substr(9).strip_edges(); + l = l.substr(9, l.length()).strip_edges(); } else if (l.begins_with("msgstr")) { ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Ref(), vformat("Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: %s:%d.", path, line)); - l = l.substr(6).strip_edges(); + l = l.substr(6, l.length()).strip_edges(); status = STATUS_READING_STRING; } @@ -266,7 +263,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Ref(), vformat("Invalid line '%s' while parsing: %s:%d.", l, path, line)); - l = l.substr(1); + l = l.substr(1, l.length()); // Find final quote, ignoring escaped ones (\"). // The escape_next logic is necessary to properly parse things like \\" // where the backslash is the one being escaped, not the quote. @@ -332,7 +329,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ continue; } String prop = c.substr(0, p).strip_edges(); - String value = c.substr(p + 1).strip_edges(); + String value = c.substr(p + 1, c.length()).strip_edges(); if (prop == "X-Language" || prop == "Language") { translation->set_locale(value); diff --git a/engine/core/io/translation_loader_po.h b/engine/core/io/translation_loader_po.h index 5ed0e1f5..1f9782c4 100644 --- a/engine/core/io/translation_loader_po.h +++ b/engine/core/io/translation_loader_po.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef TRANSLATION_LOADER_PO_H +#define TRANSLATION_LOADER_PO_H #include "core/io/file_access.h" #include "core/io/resource_loader.h" @@ -48,3 +49,5 @@ public: TranslationLoaderPO() {} }; + +#endif // TRANSLATION_LOADER_PO_H diff --git a/engine/core/io/udp_server.h b/engine/core/io/udp_server.h index 9edf4318..39b7fd98 100644 --- a/engine/core/io/udp_server.h +++ b/engine/core/io/udp_server.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef UDP_SERVER_H +#define UDP_SERVER_H #include "core/io/net_socket.h" #include "core/io/packet_peer_udp.h" @@ -75,3 +76,5 @@ public: UDPServer(); ~UDPServer(); }; + +#endif // UDP_SERVER_H diff --git a/engine/core/io/xml_parser.cpp b/engine/core/io/xml_parser.cpp index a50a1723..ed1f6f4e 100644 --- a/engine/core/io/xml_parser.cpp +++ b/engine/core/io/xml_parser.cpp @@ -95,8 +95,7 @@ void XMLParser::_ignore_definition() { while (*P && *P != '>') { next_char(); } - node_name.clear(); - node_name.append_utf8(F, P - F); + node_name.parse_utf8(F, P - F); if (*P) { next_char(); diff --git a/engine/core/io/xml_parser.h b/engine/core/io/xml_parser.h index 911d2b11..a14bdee5 100644 --- a/engine/core/io/xml_parser.h +++ b/engine/core/io/xml_parser.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef XML_PARSER_H +#define XML_PARSER_H #include "core/object/ref_counted.h" #include "core/string/ustring.h" @@ -125,3 +126,5 @@ public: }; VARIANT_ENUM_CAST(XMLParser::NodeType); + +#endif // XML_PARSER_H diff --git a/engine/core/io/zip_io.cpp b/engine/core/io/zip_io.cpp index e01c181a..972656e2 100644 --- a/engine/core/io/zip_io.cpp +++ b/engine/core/io/zip_io.cpp @@ -76,7 +76,8 @@ void *zipio_open(voidpf opaque, const char *p_fname, int mode) { Ref *fa = reinterpret_cast *>(opaque); ERR_FAIL_NULL_V(fa, nullptr); - String fname = String::utf8(p_fname); + String fname; + fname.parse_utf8(p_fname); int file_access_mode = 0; if (mode & ZLIB_FILEFUNC_MODE_READ) { diff --git a/engine/core/io/zip_io.h b/engine/core/io/zip_io.h index 82004d9c..cd5c873c 100644 --- a/engine/core/io/zip_io.h +++ b/engine/core/io/zip_io.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef ZIP_IO_H +#define ZIP_IO_H #include "core/io/file_access.h" @@ -60,3 +61,5 @@ voidpf zipio_alloc(voidpf opaque, uInt items, uInt size); void zipio_free(voidpf opaque, voidpf address); zlib_filefunc_def zipio_create_io(Ref *p_data); + +#endif // ZIP_IO_H diff --git a/engine/core/math/a_star.cpp b/engine/core/math/a_star.cpp index 9b6717c6..060b1bb1 100644 --- a/engine/core/math/a_star.cpp +++ b/engine/core/math/a_star.cpp @@ -302,7 +302,12 @@ Vector3 AStar3D::get_closest_position_in_segment(const Vector3 &p_point) const { continue; } - Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, from_point->pos, to_point->pos); + Vector3 segment[2] = { + from_point->pos, + to_point->pos, + }; + + Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment); real_t d = p_point.distance_squared_to(p); if (d < closest_dist) { closest_point = p; diff --git a/engine/core/math/a_star.h b/engine/core/math/a_star.h index d7e0f3fd..e510923b 100644 --- a/engine/core/math/a_star.h +++ b/engine/core/math/a_star.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef A_STAR_H +#define A_STAR_H #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" @@ -221,3 +222,5 @@ public: AStar2D() {} ~AStar2D() {} }; + +#endif // A_STAR_H diff --git a/engine/core/math/a_star_grid_2d.cpp b/engine/core/math/a_star_grid_2d.cpp index 8bde50ad..7e0e982c 100644 --- a/engine/core/math/a_star_grid_2d.cpp +++ b/engine/core/math/a_star_grid_2d.cpp @@ -34,27 +34,27 @@ #include "core/variant/typed_array.h" static real_t heuristic_euclidean(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)Math::abs(p_to.x - p_from.x); - real_t dy = (real_t)Math::abs(p_to.y - p_from.y); + real_t dx = (real_t)ABS(p_to.x - p_from.x); + real_t dy = (real_t)ABS(p_to.y - p_from.y); return (real_t)Math::sqrt(dx * dx + dy * dy); } static real_t heuristic_manhattan(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)Math::abs(p_to.x - p_from.x); - real_t dy = (real_t)Math::abs(p_to.y - p_from.y); + real_t dx = (real_t)ABS(p_to.x - p_from.x); + real_t dy = (real_t)ABS(p_to.y - p_from.y); return dx + dy; } static real_t heuristic_octile(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)Math::abs(p_to.x - p_from.x); - real_t dy = (real_t)Math::abs(p_to.y - p_from.y); - real_t F = Math::SQRT2 - 1; + real_t dx = (real_t)ABS(p_to.x - p_from.x); + real_t dy = (real_t)ABS(p_to.y - p_from.y); + real_t F = Math_SQRT2 - 1; return (dx < dy) ? F * dx + dy : F * dy + dx; } static real_t heuristic_chebyshev(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)Math::abs(p_to.x - p_from.x); - real_t dy = (real_t)Math::abs(p_to.y - p_from.y); + real_t dx = (real_t)ABS(p_to.x - p_from.x); + real_t dy = (real_t)ABS(p_to.y - p_from.y); return MAX(dx, dy); } @@ -503,7 +503,6 @@ bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point, bool p_allow_ LocalVector open_list; SortArray sorter; - LocalVector nbors; p_begin_point->g_score = 0; p_begin_point->f_score = _estimate_cost(p_begin_point->id, p_end_point->id); @@ -529,7 +528,7 @@ bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point, bool p_allow_ open_list.remove_at(open_list.size() - 1); p->closed_pass = pass; // Mark the point as closed. - nbors.clear(); + LocalVector nbors; _get_nbors(p, nbors); for (Point *e : nbors) { diff --git a/engine/core/math/a_star_grid_2d.h b/engine/core/math/a_star_grid_2d.h index 4883c092..ae6f3a1f 100644 --- a/engine/core/math/a_star_grid_2d.h +++ b/engine/core/math/a_star_grid_2d.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef A_STAR_GRID_2D_H +#define A_STAR_GRID_2D_H #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" @@ -229,3 +230,5 @@ public: VARIANT_ENUM_CAST(AStarGrid2D::DiagonalMode); VARIANT_ENUM_CAST(AStarGrid2D::Heuristic); VARIANT_ENUM_CAST(AStarGrid2D::CellShape) + +#endif // A_STAR_GRID_2D_H diff --git a/engine/core/math/aabb.cpp b/engine/core/math/aabb.cpp index 0e01771a..7d1d7c56 100644 --- a/engine/core/math/aabb.cpp +++ b/engine/core/math/aabb.cpp @@ -37,6 +37,14 @@ real_t AABB::get_volume() const { return size.x * size.y * size.z; } +bool AABB::operator==(const AABB &p_rval) const { + return ((position == p_rval.position) && (size == p_rval.size)); +} + +bool AABB::operator!=(const AABB &p_rval) const { + return ((position != p_rval.position) || (size != p_rval.size)); +} + void AABB::merge_with(const AABB &p_aabb) { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { @@ -68,10 +76,6 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const { return position.is_equal_approx(p_aabb.position) && size.is_equal_approx(p_aabb.size); } -bool AABB::is_same(const AABB &p_aabb) const { - return position.is_same(p_aabb.position) && size.is_same(p_aabb.size); -} - bool AABB::is_finite() const { return position.is_finite() && size.is_finite(); } diff --git a/engine/core/math/aabb.h b/engine/core/math/aabb.h index 4d78fed8..7a5581b5 100644 --- a/engine/core/math/aabb.h +++ b/engine/core/math/aabb.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef AABB_H +#define AABB_H #include "core/math/plane.h" #include "core/math/vector3.h" @@ -58,15 +59,10 @@ struct [[nodiscard]] AABB { const Vector3 &get_size() const { return size; } void set_size(const Vector3 &p_size) { size = p_size; } - constexpr bool operator==(const AABB &p_rval) const { - return position == p_rval.position && size == p_rval.size; - } - constexpr bool operator!=(const AABB &p_rval) const { - return position != p_rval.position || size != p_rval.size; - } + bool operator==(const AABB &p_rval) const; + bool operator!=(const AABB &p_rval) const; bool is_equal_approx(const AABB &p_aabb) const; - bool is_same(const AABB &p_aabb) const; bool is_finite() const; _FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap _FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap @@ -133,8 +129,8 @@ struct [[nodiscard]] AABB { operator String() const; - AABB() = default; - constexpr AABB(const Vector3 &p_pos, const Vector3 &p_size) : + _FORCE_INLINE_ AABB() {} + inline AABB(const Vector3 &p_pos, const Vector3 &p_size) : position(p_pos), size(p_size) { } @@ -500,5 +496,4 @@ AABB AABB::quantized(real_t p_unit) const { return ret; } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // AABB_H diff --git a/engine/core/math/audio_frame.h b/engine/core/math/audio_frame.h index ff0f9a5b..e205126c 100644 --- a/engine/core/math/audio_frame.h +++ b/engine/core/math/audio_frame.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef AUDIO_FRAME_H +#define AUDIO_FRAME_H #include "core/math/vector2.h" #include "core/typedefs.h" @@ -52,7 +53,6 @@ static const float AUDIO_MIN_PEAK_DB = -200.0f; // linear_to_db(AUDIO_PEAK_OFFSE struct AudioFrame { // Left and right samples. union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { float left; float right; @@ -64,7 +64,6 @@ struct AudioFrame { }; #endif float levels[2] = { 0.0 }; - // NOLINTEND(modernize-use-default-member-init) }; _ALWAYS_INLINE_ const float &operator[](int p_idx) const { @@ -76,46 +75,46 @@ struct AudioFrame { return levels[p_idx]; } - constexpr AudioFrame operator+(const AudioFrame &p_frame) const { return AudioFrame(left + p_frame.left, right + p_frame.right); } - constexpr AudioFrame operator-(const AudioFrame &p_frame) const { return AudioFrame(left - p_frame.left, right - p_frame.right); } - constexpr AudioFrame operator*(const AudioFrame &p_frame) const { return AudioFrame(left * p_frame.left, right * p_frame.right); } - constexpr AudioFrame operator/(const AudioFrame &p_frame) const { return AudioFrame(left / p_frame.left, right / p_frame.right); } + _ALWAYS_INLINE_ AudioFrame operator+(const AudioFrame &p_frame) const { return AudioFrame(left + p_frame.left, right + p_frame.right); } + _ALWAYS_INLINE_ AudioFrame operator-(const AudioFrame &p_frame) const { return AudioFrame(left - p_frame.left, right - p_frame.right); } + _ALWAYS_INLINE_ AudioFrame operator*(const AudioFrame &p_frame) const { return AudioFrame(left * p_frame.left, right * p_frame.right); } + _ALWAYS_INLINE_ AudioFrame operator/(const AudioFrame &p_frame) const { return AudioFrame(left / p_frame.left, right / p_frame.right); } - constexpr AudioFrame operator+(float p_sample) const { return AudioFrame(left + p_sample, right + p_sample); } - constexpr AudioFrame operator-(float p_sample) const { return AudioFrame(left - p_sample, right - p_sample); } - constexpr AudioFrame operator*(float p_sample) const { return AudioFrame(left * p_sample, right * p_sample); } - constexpr AudioFrame operator/(float p_sample) const { return AudioFrame(left / p_sample, right / p_sample); } + _ALWAYS_INLINE_ AudioFrame operator+(float p_sample) const { return AudioFrame(left + p_sample, right + p_sample); } + _ALWAYS_INLINE_ AudioFrame operator-(float p_sample) const { return AudioFrame(left - p_sample, right - p_sample); } + _ALWAYS_INLINE_ AudioFrame operator*(float p_sample) const { return AudioFrame(left * p_sample, right * p_sample); } + _ALWAYS_INLINE_ AudioFrame operator/(float p_sample) const { return AudioFrame(left / p_sample, right / p_sample); } - constexpr void operator+=(const AudioFrame &p_frame) { + _ALWAYS_INLINE_ void operator+=(const AudioFrame &p_frame) { left += p_frame.left; right += p_frame.right; } - constexpr void operator-=(const AudioFrame &p_frame) { + _ALWAYS_INLINE_ void operator-=(const AudioFrame &p_frame) { left -= p_frame.left; right -= p_frame.right; } - constexpr void operator*=(const AudioFrame &p_frame) { + _ALWAYS_INLINE_ void operator*=(const AudioFrame &p_frame) { left *= p_frame.left; right *= p_frame.right; } - constexpr void operator/=(const AudioFrame &p_frame) { + _ALWAYS_INLINE_ void operator/=(const AudioFrame &p_frame) { left /= p_frame.left; right /= p_frame.right; } - constexpr void operator+=(float p_sample) { + _ALWAYS_INLINE_ void operator+=(float p_sample) { left += p_sample; right += p_sample; } - constexpr void operator-=(float p_sample) { + _ALWAYS_INLINE_ void operator-=(float p_sample) { left -= p_sample; right -= p_sample; } - constexpr void operator*=(float p_sample) { + _ALWAYS_INLINE_ void operator*=(float p_sample) { left *= p_sample; right *= p_sample; } - constexpr void operator/=(float p_sample) { + _ALWAYS_INLINE_ void operator/=(float p_sample) { left /= p_sample; right /= p_sample; } @@ -134,41 +133,41 @@ struct AudioFrame { return res; } - // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) - constexpr AudioFrame(float p_left, float p_right) : - left(p_left), right(p_right) {} - constexpr AudioFrame(const AudioFrame &p_frame) : - left(p_frame.left), right(p_frame.right) {} - // NOLINTEND(cppcoreguidelines-pro-type-member-init) - - constexpr void operator=(const AudioFrame &p_frame) { + _ALWAYS_INLINE_ AudioFrame(float p_left, float p_right) { + left = p_left; + right = p_right; + } + _ALWAYS_INLINE_ AudioFrame(const AudioFrame &p_frame) { left = p_frame.left; right = p_frame.right; } - constexpr operator Vector2() const { + _ALWAYS_INLINE_ void operator=(const AudioFrame &p_frame) { + left = p_frame.left; + right = p_frame.right; + } + + _ALWAYS_INLINE_ operator Vector2() const { return Vector2(left, right); } - // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) - constexpr AudioFrame(const Vector2 &p_v2) : - left(p_v2.x), right(p_v2.y) {} - constexpr AudioFrame() : - left(0), right(0) {} - // NOLINTEND(cppcoreguidelines-pro-type-member-init) + _ALWAYS_INLINE_ AudioFrame(const Vector2 &p_v2) { + left = p_v2.x; + right = p_v2.y; + } + _ALWAYS_INLINE_ AudioFrame() {} }; -constexpr AudioFrame operator*(float p_scalar, const AudioFrame &p_frame) { +_ALWAYS_INLINE_ AudioFrame operator*(float p_scalar, const AudioFrame &p_frame) { return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar); } -constexpr AudioFrame operator*(int32_t p_scalar, const AudioFrame &p_frame) { +_ALWAYS_INLINE_ AudioFrame operator*(int32_t p_scalar, const AudioFrame &p_frame) { return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar); } -constexpr AudioFrame operator*(int64_t p_scalar, const AudioFrame &p_frame) { +_ALWAYS_INLINE_ AudioFrame operator*(int64_t p_scalar, const AudioFrame &p_frame) { return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar); } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // AUDIO_FRAME_H diff --git a/engine/core/math/basis.cpp b/engine/core/math/basis.cpp index 191f8a6a..18959f3c 100644 --- a/engine/core/math/basis.cpp +++ b/engine/core/math/basis.cpp @@ -186,7 +186,7 @@ Basis Basis::diagonalize() { // Compute the rotation angle real_t angle; if (Math::is_equal_approx(rows[j][j], rows[i][i])) { - angle = Math::PI / 4; + angle = Math_PI / 4; } else { angle = 0.5f * Math::atan(2 * rows[i][j] / (rows[j][j] - rows[i][i])); } @@ -486,12 +486,12 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } } else { euler.x = Math::atan2(rows[2][1], rows[1][1]); - euler.y = -Math::PI / 2.0f; + euler.y = -Math_PI / 2.0f; euler.z = 0.0f; } } else { euler.x = Math::atan2(rows[2][1], rows[1][1]); - euler.y = Math::PI / 2.0f; + euler.y = Math_PI / 2.0f; euler.z = 0.0f; } return euler; @@ -515,13 +515,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { // It's -1 euler.x = -Math::atan2(rows[1][2], rows[2][2]); euler.y = 0.0f; - euler.z = Math::PI / 2.0f; + euler.z = Math_PI / 2.0f; } } else { // It's 1 euler.x = -Math::atan2(rows[1][2], rows[2][2]); euler.y = 0.0f; - euler.z = -Math::PI / 2.0f; + euler.z = -Math_PI / 2.0f; } return euler; } @@ -551,12 +551,12 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = atan2(rows[1][0], rows[1][1]); } } else { // m12 == -1 - euler.x = Math::PI * 0.5f; + euler.x = Math_PI * 0.5f; euler.y = atan2(rows[0][1], rows[0][0]); euler.z = 0; } } else { // m12 == 1 - euler.x = -Math::PI * 0.5f; + euler.x = -Math_PI * 0.5f; euler.y = -atan2(rows[0][1], rows[0][0]); euler.z = 0; } @@ -582,13 +582,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { // It's -1 euler.x = Math::atan2(rows[2][1], rows[2][2]); euler.y = 0.0f; - euler.z = -Math::PI / 2.0f; + euler.z = -Math_PI / 2.0f; } } else { // It's 1 euler.x = Math::atan2(rows[2][1], rows[2][2]); euler.y = 0.0f; - euler.z = Math::PI / 2.0f; + euler.z = Math_PI / 2.0f; } return euler; } break; @@ -608,13 +608,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = Math::atan2(-rows[0][1], rows[1][1]); } else { // It's -1 - euler.x = -Math::PI / 2.0f; + euler.x = -Math_PI / 2.0f; euler.y = Math::atan2(rows[0][2], rows[0][0]); euler.z = 0; } } else { // It's 1 - euler.x = Math::PI / 2.0f; + euler.x = Math_PI / 2.0f; euler.y = Math::atan2(rows[0][2], rows[0][0]); euler.z = 0; } @@ -637,13 +637,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } else { // It's -1 euler.x = 0; - euler.y = Math::PI / 2.0f; + euler.y = Math_PI / 2.0f; euler.z = -Math::atan2(rows[0][1], rows[1][1]); } } else { // It's 1 euler.x = 0; - euler.y = -Math::PI / 2.0f; + euler.y = -Math_PI / 2.0f; euler.z = -Math::atan2(rows[0][1], rows[1][1]); } return euler; @@ -699,14 +699,26 @@ bool Basis::is_equal_approx(const Basis &p_basis) const { return rows[0].is_equal_approx(p_basis.rows[0]) && rows[1].is_equal_approx(p_basis.rows[1]) && rows[2].is_equal_approx(p_basis.rows[2]); } -bool Basis::is_same(const Basis &p_basis) const { - return rows[0].is_same(p_basis.rows[0]) && rows[1].is_same(p_basis.rows[1]) && rows[2].is_same(p_basis.rows[2]); -} - bool Basis::is_finite() const { return rows[0].is_finite() && rows[1].is_finite() && rows[2].is_finite(); } +bool Basis::operator==(const Basis &p_matrix) const { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (rows[i][j] != p_matrix.rows[i][j]) { + return false; + } + } + } + + return true; +} + +bool Basis::operator!=(const Basis &p_matrix) const { + return (!(*this == p_matrix)); +} + Basis::operator String() const { return "[X: " + get_column(0).operator String() + ", Y: " + get_column(1).operator String() + @@ -778,8 +790,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { if ((xx > yy) && (xx > zz)) { // rows[0][0] is the largest diagonal term. if (xx < CMP_EPSILON) { x = 0; - y = Math::SQRT12; - z = Math::SQRT12; + y = Math_SQRT12; + z = Math_SQRT12; } else { x = Math::sqrt(xx); y = xy / x; @@ -787,9 +799,9 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { } } else if (yy > zz) { // rows[1][1] is the largest diagonal term. if (yy < CMP_EPSILON) { - x = Math::SQRT12; + x = Math_SQRT12; y = 0; - z = Math::SQRT12; + z = Math_SQRT12; } else { y = Math::sqrt(yy); x = xy / y; @@ -797,8 +809,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { } } else { // rows[2][2] is the largest diagonal term so base result on this. if (zz < CMP_EPSILON) { - x = Math::SQRT12; - y = Math::SQRT12; + x = Math_SQRT12; + y = Math_SQRT12; z = 0; } else { z = Math::sqrt(zz); @@ -807,7 +819,7 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { } } r_axis = Vector3(x, y, z); - r_angle = Math::PI; + r_angle = Math_PI; return; } // As we have reached here there are no singularities so we can handle normally. diff --git a/engine/core/math/basis.h b/engine/core/math/basis.h index e85437e7..2d4994de 100644 --- a/engine/core/math/basis.h +++ b/engine/core/math/basis.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef BASIS_H +#define BASIS_H #include "core/math/quaternion.h" #include "core/math/vector3.h" @@ -40,10 +41,10 @@ struct [[nodiscard]] Basis { Vector3(0, 0, 1) }; - constexpr const Vector3 &operator[](int p_row) const { + _FORCE_INLINE_ const Vector3 &operator[](int p_row) const { return rows[p_row]; } - constexpr Vector3 &operator[](int p_row) { + _FORCE_INLINE_ Vector3 &operator[](int p_row) { return rows[p_row]; } @@ -120,24 +121,23 @@ struct [[nodiscard]] Basis { } bool is_equal_approx(const Basis &p_basis) const; - bool is_same(const Basis &p_basis) const; bool is_finite() const; - constexpr bool operator==(const Basis &p_matrix) const; - constexpr bool operator!=(const Basis &p_matrix) const; + bool operator==(const Basis &p_matrix) const; + bool operator!=(const Basis &p_matrix) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const; _FORCE_INLINE_ void operator*=(const Basis &p_matrix); _FORCE_INLINE_ Basis operator*(const Basis &p_matrix) const; - constexpr void operator+=(const Basis &p_matrix); - constexpr Basis operator+(const Basis &p_matrix) const; - constexpr void operator-=(const Basis &p_matrix); - constexpr Basis operator-(const Basis &p_matrix) const; - constexpr void operator*=(real_t p_val); - constexpr Basis operator*(real_t p_val) const; - constexpr void operator/=(real_t p_val); - constexpr Basis operator/(real_t p_val) const; + _FORCE_INLINE_ void operator+=(const Basis &p_matrix); + _FORCE_INLINE_ Basis operator+(const Basis &p_matrix) const; + _FORCE_INLINE_ void operator-=(const Basis &p_matrix); + _FORCE_INLINE_ Basis operator-(const Basis &p_matrix) const; + _FORCE_INLINE_ void operator*=(real_t p_val); + _FORCE_INLINE_ Basis operator*(real_t p_val) const; + _FORCE_INLINE_ void operator/=(real_t p_val); + _FORCE_INLINE_ Basis operator/(real_t p_val) const; bool is_orthogonal() const; bool is_orthonormal() const; @@ -204,12 +204,9 @@ struct [[nodiscard]] Basis { rows[0].z * p_m[0].y + rows[1].z * p_m[1].y + rows[2].z * p_m[2].y, rows[0].z * p_m[0].z + rows[1].z * p_m[1].z + rows[2].z * p_m[2].z); } - constexpr Basis(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) : - rows{ - { p_xx, p_xy, p_xz }, - { p_yx, p_yy, p_yz }, - { p_zx, p_zy, p_zz }, - } {} + Basis(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) { + set(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz); + } void orthonormalize(); Basis orthonormalized() const; @@ -233,36 +230,17 @@ struct [[nodiscard]] Basis { Basis(const Vector3 &p_axis, real_t p_angle, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_angle, p_scale); } static Basis from_scale(const Vector3 &p_scale); - constexpr Basis(const Vector3 &p_x_axis, const Vector3 &p_y_axis, const Vector3 &p_z_axis) : - rows{ - { p_x_axis.x, p_y_axis.x, p_z_axis.x }, - { p_x_axis.y, p_y_axis.y, p_z_axis.y }, - { p_x_axis.z, p_y_axis.z, p_z_axis.z }, - } {} + _FORCE_INLINE_ Basis(const Vector3 &p_x_axis, const Vector3 &p_y_axis, const Vector3 &p_z_axis) { + set_columns(p_x_axis, p_y_axis, p_z_axis); + } - Basis() = default; + _FORCE_INLINE_ Basis() {} private: // Helper method. void _set_diagonal(const Vector3 &p_diag); }; -constexpr bool Basis::operator==(const Basis &p_matrix) const { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (rows[i][j] != p_matrix.rows[i][j]) { - return false; - } - } - } - - return true; -} - -constexpr bool Basis::operator!=(const Basis &p_matrix) const { - return (!(*this == p_matrix)); -} - _FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) { set( p_matrix.tdotx(rows[0]), p_matrix.tdoty(rows[0]), p_matrix.tdotz(rows[0]), @@ -277,49 +255,49 @@ _FORCE_INLINE_ Basis Basis::operator*(const Basis &p_matrix) const { p_matrix.tdotx(rows[2]), p_matrix.tdoty(rows[2]), p_matrix.tdotz(rows[2])); } -constexpr void Basis::operator+=(const Basis &p_matrix) { +_FORCE_INLINE_ void Basis::operator+=(const Basis &p_matrix) { rows[0] += p_matrix.rows[0]; rows[1] += p_matrix.rows[1]; rows[2] += p_matrix.rows[2]; } -constexpr Basis Basis::operator+(const Basis &p_matrix) const { +_FORCE_INLINE_ Basis Basis::operator+(const Basis &p_matrix) const { Basis ret(*this); ret += p_matrix; return ret; } -constexpr void Basis::operator-=(const Basis &p_matrix) { +_FORCE_INLINE_ void Basis::operator-=(const Basis &p_matrix) { rows[0] -= p_matrix.rows[0]; rows[1] -= p_matrix.rows[1]; rows[2] -= p_matrix.rows[2]; } -constexpr Basis Basis::operator-(const Basis &p_matrix) const { +_FORCE_INLINE_ Basis Basis::operator-(const Basis &p_matrix) const { Basis ret(*this); ret -= p_matrix; return ret; } -constexpr void Basis::operator*=(real_t p_val) { +_FORCE_INLINE_ void Basis::operator*=(real_t p_val) { rows[0] *= p_val; rows[1] *= p_val; rows[2] *= p_val; } -constexpr Basis Basis::operator*(real_t p_val) const { +_FORCE_INLINE_ Basis Basis::operator*(real_t p_val) const { Basis ret(*this); ret *= p_val; return ret; } -constexpr void Basis::operator/=(real_t p_val) { +_FORCE_INLINE_ void Basis::operator/=(real_t p_val) { rows[0] /= p_val; rows[1] /= p_val; rows[2] /= p_val; } -constexpr Basis Basis::operator/(real_t p_val) const { +_FORCE_INLINE_ Basis Basis::operator/(real_t p_val) const { Basis ret(*this); ret /= p_val; return ret; @@ -344,3 +322,5 @@ real_t Basis::determinant() const { rows[1][0] * (rows[0][1] * rows[2][2] - rows[2][1] * rows[0][2]) + rows[2][0] * (rows[0][1] * rows[1][2] - rows[1][1] * rows[0][2]); } + +#endif // BASIS_H diff --git a/engine/core/math/bvh.h b/engine/core/math/bvh.h index 9a9dde17..4815466e 100644 --- a/engine/core/math/bvh.h +++ b/engine/core/math/bvh.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef BVH_H +#define BVH_H // BVH // This class provides a wrapper around BVH tree, which contains most of the functionality @@ -51,8 +52,6 @@ // and pairable_mask is either 0 if static, or set to all if non static #include "bvh_tree.h" - -#include "core/math/geometry_3d.h" #include "core/os/mutex.h" #define BVHTREE_CLASS BVH_Tree @@ -406,7 +405,7 @@ public: } Vector convex_points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size()); - if (convex_points.is_empty()) { + if (convex_points.size() == 0) { return 0; } @@ -436,6 +435,8 @@ private: return; } + BOUNDS bb; + typename BVHTREE_CLASS::CullParams params; params.result_count_overall = 0; @@ -805,3 +806,5 @@ public: }; #undef BVHTREE_CLASS + +#endif // BVH_H diff --git a/engine/core/math/bvh_abb.h b/engine/core/math/bvh_abb.h index b96ea085..3d32c250 100644 --- a/engine/core/math/bvh_abb.h +++ b/engine/core/math/bvh_abb.h @@ -28,9 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once - -#include "core/math/aabb.h" +#ifndef BVH_ABB_H +#define BVH_ABB_H // special optimized version of axis aligned bounding box template @@ -289,3 +288,5 @@ struct BVH_ABB { return false; } }; + +#endif // BVH_ABB_H diff --git a/engine/core/math/bvh_tree.h b/engine/core/math/bvh_tree.h index 76e5c999..2a2a6d67 100644 --- a/engine/core/math/bvh_tree.h +++ b/engine/core/math/bvh_tree.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef BVH_TREE_H +#define BVH_TREE_H // BVH Tree // This is an implementation of a dynamic BVH with templated leaf size. @@ -40,6 +41,7 @@ #include "core/math/aabb.h" #include "core/math/bvh_abb.h" +#include "core/math/geometry_3d.h" #include "core/math/vector3.h" #include "core/templates/local_vector.h" #include "core/templates/pooled_list.h" @@ -452,3 +454,5 @@ private: }; #undef VERBOSE_PRINT + +#endif // BVH_TREE_H diff --git a/engine/core/math/color.cpp b/engine/core/math/color.cpp index d032a3fe..4c31d814 100644 --- a/engine/core/math/color.cpp +++ b/engine/core/math/color.cpp @@ -109,27 +109,36 @@ uint64_t Color::to_rgba64() const { return c; } -void _append_hex(float p_val, char32_t *string) { +String _to_hex(float p_val) { int v = Math::round(p_val * 255.0f); v = CLAMP(v, 0, 255); + String ret; - string[0] = hex_char_table_lower[(v >> 4) & 0xF]; - string[1] = hex_char_table_lower[v & 0xF]; + for (int i = 0; i < 2; i++) { + char32_t c[2] = { 0, 0 }; + int lv = v & 0xF; + if (lv < 10) { + c[0] = '0' + lv; + } else { + c[0] = 'a' + lv - 10; + } + + v >>= 4; + String cs = (const char32_t *)c; + ret = cs + ret; + } + + return ret; } String Color::to_html(bool p_alpha) const { String txt; - txt.resize(p_alpha ? 9 : 7); - char32_t *ptr = txt.ptrw(); - - _append_hex(r, ptr + 0); - _append_hex(g, ptr + 2); - _append_hex(b, ptr + 4); + txt += _to_hex(r); + txt += _to_hex(g); + txt += _to_hex(b); if (p_alpha) { - _append_hex(a, ptr + 6); + txt += _to_hex(a); } - ptr[txt.size() - 1] = '\0'; - return txt; } @@ -250,10 +259,6 @@ bool Color::is_equal_approx(const Color &p_color) const { return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a); } -bool Color::is_same(const Color &p_color) const { - return Math::is_same(r, p_color.r) && Math::is_same(g, p_color.g) && Math::is_same(b, p_color.b) && Math::is_same(a, p_color.a); -} - Color Color::clamp(const Color &p_min, const Color &p_max) const { return Color( CLAMP(r, p_min.r, p_max.r), @@ -316,38 +321,47 @@ Color Color::inverted() const { } Color Color::html(const String &p_rgba) { - if (p_rgba.is_empty()) { + String color = p_rgba; + if (color.length() == 0) { return Color(); } + if (color[0] == '#') { + color = color.substr(1); + } - const int current_pos = (p_rgba[0] == '#') ? 1 : 0; - const int num_of_digits = p_rgba.length() - current_pos; + // If enabled, use 1 hex digit per channel instead of 2. + // Other sizes aren't in the HTML/CSS spec but we could add them if desired. + bool is_shorthand = color.length() < 5; + bool alpha = false; - float r, g, b, a = 1.0f; - - if (num_of_digits == 3) { - // #rgb - r = _parse_col4(p_rgba, current_pos) / 15.0f; - g = _parse_col4(p_rgba, current_pos + 1) / 15.0f; - b = _parse_col4(p_rgba, current_pos + 2) / 15.0f; - } else if (num_of_digits == 4) { - r = _parse_col4(p_rgba, current_pos) / 15.0f; - g = _parse_col4(p_rgba, current_pos + 1) / 15.0f; - b = _parse_col4(p_rgba, current_pos + 2) / 15.0f; - a = _parse_col4(p_rgba, current_pos + 3) / 15.0f; - } else if (num_of_digits == 6) { - r = _parse_col8(p_rgba, current_pos) / 255.0f; - g = _parse_col8(p_rgba, current_pos + 2) / 255.0f; - b = _parse_col8(p_rgba, current_pos + 4) / 255.0f; - } else if (num_of_digits == 8) { - r = _parse_col8(p_rgba, current_pos) / 255.0f; - g = _parse_col8(p_rgba, current_pos + 2) / 255.0f; - b = _parse_col8(p_rgba, current_pos + 4) / 255.0f; - a = _parse_col8(p_rgba, current_pos + 6) / 255.0f; + if (color.length() == 8) { + alpha = true; + } else if (color.length() == 6) { + alpha = false; + } else if (color.length() == 4) { + alpha = true; + } else if (color.length() == 3) { + alpha = false; } else { ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_rgba + "."); } + float r, g, b, a = 1.0f; + if (is_shorthand) { + r = _parse_col4(color, 0) / 15.0f; + g = _parse_col4(color, 1) / 15.0f; + b = _parse_col4(color, 2) / 15.0f; + if (alpha) { + a = _parse_col4(color, 3) / 15.0f; + } + } else { + r = _parse_col8(color, 0) / 255.0f; + g = _parse_col8(color, 2) / 255.0f; + b = _parse_col8(color, 4) / 255.0f; + if (alpha) { + a = _parse_col8(color, 6) / 255.0f; + } + } ERR_FAIL_COND_V_MSG(r < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); ERR_FAIL_COND_V_MSG(g < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); ERR_FAIL_COND_V_MSG(b < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); @@ -359,20 +373,22 @@ Color Color::html(const String &p_rgba) { bool Color::html_is_valid(const String &p_color) { String color = p_color; - if (color.is_empty()) { + if (color.length() == 0) { return false; } + if (color[0] == '#') { + color = color.substr(1); + } - const int current_pos = (color[0] == '#') ? 1 : 0; - const int len = color.length(); - const int num_of_digits = len - current_pos; - if (!(num_of_digits == 3 || num_of_digits == 4 || num_of_digits == 6 || num_of_digits == 8)) { + // Check if the amount of hex digits is valid. + int len = color.length(); + if (!(len == 3 || len == 4 || len == 6 || len == 8)) { return false; } // Check if each hex digit is valid. - for (int i = current_pos; i < len; i++) { - if (!is_hex_digit(p_color[i])) { + for (int i = 0; i < len; i++) { + if (_parse_col4(color, i) == -1) { return false; } } @@ -399,14 +415,18 @@ Color Color::named(const String &p_name, const Color &p_default) { int Color::find_named_color(const String &p_name) { String name = p_name; // Normalize name. - name = name.remove_chars(" -_'."); + name = name.replace(" ", ""); + name = name.replace("-", ""); + name = name.replace("_", ""); + name = name.replace("'", ""); + name = name.replace(".", ""); name = name.to_upper(); static HashMap named_colors_hashmap; if (unlikely(named_colors_hashmap.is_empty())) { const int named_color_count = get_named_color_count(); for (int i = 0; i < named_color_count; i++) { - named_colors_hashmap[String(named_colors[i].name).remove_char('_')] = i; + named_colors_hashmap[String(named_colors[i].name).replace("_", "")] = i; } } @@ -419,7 +439,7 @@ int Color::find_named_color(const String &p_name) { } int Color::get_named_color_count() { - return std::size(named_colors); + return sizeof(named_colors) / sizeof(NamedColor); } String Color::get_named_color_name(int p_idx) { @@ -470,6 +490,104 @@ Color::operator String() const { return "(" + String::num(r, 4) + ", " + String::num(g, 4) + ", " + String::num(b, 4) + ", " + String::num(a, 4) + ")"; } +Color Color::operator+(const Color &p_color) const { + return Color( + r + p_color.r, + g + p_color.g, + b + p_color.b, + 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, + g - p_color.g, + b - p_color.b, + 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, + g * p_color.g, + b * p_color.b, + a * p_color.a); +} + +Color Color::operator*(float p_scalar) const { + return Color( + r * p_scalar, + g * p_scalar, + b * p_scalar, + a * p_scalar); +} + +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; +} + +void Color::operator*=(float p_scalar) { + r = r * p_scalar; + g = g * p_scalar; + b = b * p_scalar; + a = a * p_scalar; +} + +Color Color::operator/(const Color &p_color) const { + return Color( + r / p_color.r, + g / p_color.g, + b / p_color.b, + a / p_color.a); +} + +Color Color::operator/(float p_scalar) const { + return Color( + r / p_scalar, + g / p_scalar, + b / p_scalar, + a / p_scalar); +} + +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; +} + +void Color::operator/=(float p_scalar) { + r = r / p_scalar; + g = g / p_scalar; + b = b / p_scalar; + a = a / p_scalar; +} + +Color Color::operator-() const { + return Color( + 1.0f - r, + 1.0f - g, + 1.0f - b, + 1.0f - a); +} + Color Color::from_ok_hsl(float p_h, float p_s, float p_l, float p_alpha) { Color c; c.set_ok_hsl(p_h, p_s, p_l, p_alpha); diff --git a/engine/core/math/color.h b/engine/core/math/color.h index ae91677d..c2ffde18 100644 --- a/engine/core/math/color.h +++ b/engine/core/math/color.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef COLOR_H +#define COLOR_H #include "core/math/math_funcs.h" @@ -36,7 +37,6 @@ class String; struct [[nodiscard]] Color { union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { float r; float g; @@ -44,7 +44,6 @@ struct [[nodiscard]] Color { float a; }; float components[4] = { 0, 0, 0, 1.0 }; - // NOLINTEND(modernize-use-default-member-init) }; uint32_t to_rgba32() const; @@ -70,32 +69,31 @@ struct [[nodiscard]] Color { return components[p_idx]; } - constexpr bool operator==(const Color &p_color) const { + bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); } - constexpr bool operator!=(const Color &p_color) const { + bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); } - constexpr Color operator+(const Color &p_color) const; - constexpr void operator+=(const Color &p_color); + Color operator+(const Color &p_color) const; + void operator+=(const Color &p_color); - constexpr Color operator-() const; - constexpr Color operator-(const Color &p_color) const; - constexpr void operator-=(const Color &p_color); + Color operator-() const; + Color operator-(const Color &p_color) const; + void operator-=(const Color &p_color); - constexpr Color operator*(const Color &p_color) const; - constexpr Color operator*(float p_scalar) const; - constexpr void operator*=(const Color &p_color); - constexpr void operator*=(float p_scalar); + Color operator*(const Color &p_color) const; + Color operator*(float p_scalar) const; + void operator*=(const Color &p_color); + void operator*=(float p_scalar); - constexpr Color operator/(const Color &p_color) const; - constexpr Color operator/(float p_scalar) const; - constexpr void operator/=(const Color &p_color); - constexpr void operator/=(float p_scalar); + Color operator/(const Color &p_color) const; + Color operator/(float p_scalar) const; + void operator/=(const Color &p_color); + void operator/=(float p_scalar); bool is_equal_approx(const Color &p_color) const; - bool is_same(const Color &p_color) const; Color clamp(const Color &p_min = Color(0, 0, 0, 0), const Color &p_max = Color(1, 1, 1, 1)) const; void invert(); @@ -217,7 +215,7 @@ struct [[nodiscard]] Color { static Color from_rgbe9995(uint32_t p_rgbe); static Color from_rgba8(int64_t p_r8, int64_t p_g8, int64_t p_b8, int64_t p_a8 = 255); - constexpr bool operator<(const Color &p_color) const; // Used in set keys. + _FORCE_INLINE_ bool operator<(const Color &p_color) const; // Used in set keys. operator String() const; // For the binder. @@ -237,29 +235,39 @@ struct [[nodiscard]] Color { _FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l(), a); } _FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l, a); } - constexpr Color() : - r(0), g(0), b(0), a(1) {} + _FORCE_INLINE_ Color() {} /** * RGBA construct parameters. * Alpha is not optional as otherwise we can't bind the RGB version for scripting. */ - constexpr Color(float p_r, float p_g, float p_b, float p_a) : - r(p_r), g(p_g), b(p_b), a(p_a) {} + _FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a) { + r = p_r; + g = p_g; + b = p_b; + a = p_a; + } /** * RGB construct parameters. */ - constexpr Color(float p_r, float p_g, float p_b) : - r(p_r), g(p_g), b(p_b), a(1) {} + _FORCE_INLINE_ Color(float p_r, float p_g, float p_b) { + r = p_r; + g = p_g; + b = p_b; + a = 1.0f; + } /** * Construct a Color from another Color, but with the specified alpha value. */ - constexpr Color(const Color &p_c, float p_a) : - r(p_c.r), g(p_c.g), b(p_c.b), a(p_a) {} + _FORCE_INLINE_ Color(const Color &p_c, float p_a) { + r = p_c.r; + g = p_c.g; + b = p_c.b; + a = p_a; + } - // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) Color(const String &p_code) { if (html_is_valid(p_code)) { *this = html(p_code); @@ -272,108 +280,9 @@ struct [[nodiscard]] Color { *this = Color(p_code); a = p_a; } - // NOLINTEND(cppcoreguidelines-pro-type-member-init) }; -constexpr Color Color::operator+(const Color &p_color) const { - return Color( - r + p_color.r, - g + p_color.g, - b + p_color.b, - a + p_color.a); -} - -constexpr 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; -} - -constexpr Color Color::operator-(const Color &p_color) const { - return Color( - r - p_color.r, - g - p_color.g, - b - p_color.b, - a - p_color.a); -} - -constexpr 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; -} - -constexpr Color Color::operator*(const Color &p_color) const { - return Color( - r * p_color.r, - g * p_color.g, - b * p_color.b, - a * p_color.a); -} - -constexpr Color Color::operator*(float p_scalar) const { - return Color( - r * p_scalar, - g * p_scalar, - b * p_scalar, - a * p_scalar); -} - -constexpr 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; -} - -constexpr void Color::operator*=(float p_scalar) { - r = r * p_scalar; - g = g * p_scalar; - b = b * p_scalar; - a = a * p_scalar; -} - -constexpr Color Color::operator/(const Color &p_color) const { - return Color( - r / p_color.r, - g / p_color.g, - b / p_color.b, - a / p_color.a); -} - -constexpr Color Color::operator/(float p_scalar) const { - return Color( - r / p_scalar, - g / p_scalar, - b / p_scalar, - a / p_scalar); -} - -constexpr 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; -} - -constexpr void Color::operator/=(float p_scalar) { - r = r / p_scalar; - g = g / p_scalar; - b = b / p_scalar; - a = a / p_scalar; -} - -constexpr Color Color::operator-() const { - return Color( - 1.0f - r, - 1.0f - g, - 1.0f - b, - 1.0f - a); -} - -constexpr bool Color::operator<(const Color &p_color) const { +bool Color::operator<(const Color &p_color) const { if (r == p_color.r) { if (g == p_color.g) { if (b == p_color.b) { @@ -389,6 +298,8 @@ constexpr bool Color::operator<(const Color &p_color) const { } } -constexpr Color operator*(float p_scalar, const Color &p_color) { +_FORCE_INLINE_ Color operator*(float p_scalar, const Color &p_color) { return p_color * p_scalar; } + +#endif // COLOR_H diff --git a/engine/core/math/color_names.inc b/engine/core/math/color_names.inc index 969acc68..6c0d2a4b 100644 --- a/engine/core/math/color_names.inc +++ b/engine/core/math/color_names.inc @@ -28,16 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once - // 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 -#include "core/math/color.h" - struct NamedColor { const char *name; Color color; diff --git a/engine/core/math/convex_hull.cpp b/engine/core/math/convex_hull.cpp index fbd367b9..4052234f 100644 --- a/engine/core/math/convex_hull.cpp +++ b/engine/core/math/convex_hull.cpp @@ -2237,7 +2237,7 @@ real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, rea Error ConvexHullComputer::convex_hull(const Vector &p_points, Geometry3D::MeshData &r_mesh) { r_mesh = Geometry3D::MeshData(); // clear - if (p_points.is_empty()) { + if (p_points.size() == 0) { return FAILED; // matches QuickHull } diff --git a/engine/core/math/convex_hull.h b/engine/core/math/convex_hull.h index 9af39790..75787f7b 100644 --- a/engine/core/math/convex_hull.h +++ b/engine/core/math/convex_hull.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CONVEX_HULL_H +#define CONVEX_HULL_H /* Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net @@ -111,3 +112,5 @@ public: static Error convex_hull(const Vector &p_points, Geometry3D::MeshData &r_mesh); }; + +#endif // CONVEX_HULL_H diff --git a/engine/core/math/delaunay_2d.h b/engine/core/math/delaunay_2d.h index cb0eca2b..0bc67a92 100644 --- a/engine/core/math/delaunay_2d.h +++ b/engine/core/math/delaunay_2d.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DELAUNAY_2D_H +#define DELAUNAY_2D_H #include "core/math/rect2.h" #include "core/templates/vector.h" @@ -155,3 +156,5 @@ public: return triangles; } }; + +#endif // DELAUNAY_2D_H diff --git a/engine/core/math/delaunay_3d.h b/engine/core/math/delaunay_3d.h index 122ff945..5bbdcc09 100644 --- a/engine/core/math/delaunay_3d.h +++ b/engine/core/math/delaunay_3d.h @@ -28,15 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DELAUNAY_3D_H +#define DELAUNAY_3D_H +#include "core/io/file_access.h" #include "core/math/aabb.h" #include "core/math/projection.h" #include "core/math/vector3.h" -#include "core/templates/list.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" @@ -185,7 +187,7 @@ class Delaunay3D { Plane p(p_points[p_simplex.points[i]], p_points[p_simplex.points[(i + 1) % 4]], p_points[p_simplex.points[(i + 2) % 4]]); // This tolerance should not be smaller than the one used with // Plane::has_point() when creating the LightmapGI probe BSP tree. - if (Math::abs(p.distance_to(p_points[p_simplex.points[(i + 3) % 4]])) < 0.001) { + if (ABS(p.distance_to(p_points[p_simplex.points[(i + 3) % 4]])) < 0.001) { return true; } } @@ -387,3 +389,5 @@ public: return ret_simplices; } }; + +#endif // DELAUNAY_3D_H diff --git a/engine/core/math/disjoint_set.h b/engine/core/math/disjoint_set.h index 9345375f..4348da99 100644 --- a/engine/core/math/disjoint_set.h +++ b/engine/core/math/disjoint_set.h @@ -28,9 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DISJOINT_SET_H +#define DISJOINT_SET_H -#include "core/templates/hash_map.h" +#include "core/templates/rb_map.h" #include "core/templates/vector.h" /* This DisjointSet class uses Find with path compression and Union by rank */ @@ -145,3 +146,5 @@ void DisjointSet::get_members(Vector &out_members, T representat } } } + +#endif // DISJOINT_SET_H diff --git a/engine/core/math/dynamic_bvh.cpp b/engine/core/math/dynamic_bvh.cpp index 1195072a..e1315d1c 100644 --- a/engine/core/math/dynamic_bvh.cpp +++ b/engine/core/math/dynamic_bvh.cpp @@ -181,7 +181,7 @@ DynamicBVH::Volume DynamicBVH::_bounds(Node **leaves, int p_count) { void DynamicBVH::_bottom_up(Node **leaves, int p_count) { while (p_count > 1) { - real_t minsize = Math::INF; + real_t minsize = INFINITY; int minidx[2] = { -1, -1 }; for (int i = 0; i < p_count; ++i) { for (int j = i + 1; j < p_count; ++j) { diff --git a/engine/core/math/dynamic_bvh.h b/engine/core/math/dynamic_bvh.h index 10e4e063..26fc517f 100644 --- a/engine/core/math/dynamic_bvh.h +++ b/engine/core/math/dynamic_bvh.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef DYNAMIC_BVH_H +#define DYNAMIC_BVH_H #include "core/math/aabb.h" #include "core/templates/list.h" @@ -473,3 +474,5 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu } } while (depth > 0); } + +#endif // DYNAMIC_BVH_H diff --git a/engine/core/math/expression.cpp b/engine/core/math/expression.cpp index 0bfc8def..26b773a2 100644 --- a/engine/core/math/expression.cpp +++ b/engine/core/math/expression.cpp @@ -454,16 +454,16 @@ Error Expression::_get_token(Token &r_token) { r_token.value = false; } else if (id == "PI") { r_token.type = TK_CONSTANT; - r_token.value = Math::PI; + r_token.value = Math_PI; } else if (id == "TAU") { r_token.type = TK_CONSTANT; - r_token.value = Math::TAU; + r_token.value = Math_TAU; } else if (id == "INF") { r_token.type = TK_CONSTANT; - r_token.value = Math::INF; + r_token.value = INFINITY; } else if (id == "NAN") { r_token.type = TK_CONSTANT; - r_token.value = Math::NaN; + r_token.value = NAN; } else if (id == "not") { r_token.type = TK_OP_NOT; } else if (id == "or") { diff --git a/engine/core/math/expression.h b/engine/core/math/expression.h index aea714cf..46bc3618 100644 --- a/engine/core/math/expression.h +++ b/engine/core/math/expression.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef EXPRESSION_H +#define EXPRESSION_H #include "core/object/ref_counted.h" @@ -270,3 +271,5 @@ public: Expression() {} ~Expression(); }; + +#endif // EXPRESSION_H diff --git a/engine/core/math/face3.cpp b/engine/core/math/face3.cpp index b9ab85e4..1dff0ee4 100644 --- a/engine/core/math/face3.cpp +++ b/engine/core/math/face3.cpp @@ -263,7 +263,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform3D &p_transform, // check if edge is valid as a support real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n); - dot = Math::abs(dot); + dot = ABS(dot); if (dot < edge_support_threshold) { *p_count = MIN(2, p_max); diff --git a/engine/core/math/face3.h b/engine/core/math/face3.h index b7472f9d..519dcb64 100644 --- a/engine/core/math/face3.h +++ b/engine/core/math/face3.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef FACE3_H +#define FACE3_H #include "core/math/aabb.h" #include "core/math/plane.h" @@ -78,9 +79,12 @@ struct [[nodiscard]] Face3 { _FORCE_INLINE_ bool intersects_aabb2(const AABB &p_aabb) const; operator String() const; - Face3() = default; - constexpr Face3(const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) : - vertex{ p_v1, p_v2, p_v3 } {} + inline Face3() {} + inline Face3(const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) { + vertex[0] = p_v1; + vertex[1] = p_v2; + vertex[2] = p_v3; + } }; bool Face3::intersects_aabb2(const AABB &p_aabb) const { @@ -234,5 +238,4 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const { return true; } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // FACE3_H diff --git a/engine/core/math/geometry_2d.cpp b/engine/core/math/geometry_2d.cpp index 30ea79a0..376d5d0b 100644 --- a/engine/core/math/geometry_2d.cpp +++ b/engine/core/math/geometry_2d.cpp @@ -38,63 +38,17 @@ const int clipper_precision = 5; // Based on CMP_EPSILON. const double clipper_scale = Math::pow(10.0, clipper_precision); -void Geometry2D::merge_many_polygons(const Vector> &p_polygons, Vector> &r_out_polygons, Vector> &r_out_holes) { - using namespace Clipper2Lib; - - PathsD subjects; - for (const Vector &polygon : p_polygons) { - PathD path(polygon.size()); - for (int i = 0; i < polygon.size(); i++) { - const Vector2 &point = polygon[i]; - path[i] = PointD(point.x, point.y); - } - subjects.push_back(path); - } - - PathsD solution = Union(subjects, FillRule::NonZero); - solution = SimplifyPaths(solution, 0.01); - - r_out_polygons.clear(); - r_out_holes.clear(); - for (PathsD::size_type i = 0; i < solution.size(); ++i) { - PathD &path = solution[i]; - - Vector output_polygon; - output_polygon.resize(path.size()); - for (PathsD::size_type j = 0; j < path.size(); ++j) { - output_polygon.set(j, Vector2(static_cast(path[j].x), static_cast(path[j].y))); - } - if (IsPositive(path)) { - r_out_polygons.push_back(output_polygon); - } else { - r_out_holes.push_back(output_polygon); - } - } -} - -Vector> Geometry2D::decompose_many_polygons_in_convex(const Vector> &p_polygons, const Vector> &p_holes) { +Vector> Geometry2D::decompose_polygon_in_convex(const Vector &polygon) { Vector> decomp; List in_poly, out_poly; - for (const Vector &polygon : p_polygons) { - TPPLPoly inp; - inp.Init(polygon.size()); - for (int i = 0; i < polygon.size(); i++) { - inp.GetPoint(i) = polygon[i]; - } - inp.SetOrientation(TPPL_ORIENTATION_CCW); - in_poly.push_back(inp); - } - for (const Vector &polygon : p_holes) { - TPPLPoly inp; - inp.Init(polygon.size()); - for (int i = 0; i < polygon.size(); i++) { - inp.GetPoint(i) = polygon[i]; - } - inp.SetOrientation(TPPL_ORIENTATION_CW); - inp.SetHole(true); - in_poly.push_back(inp); + TPPLPoly inp; + inp.Init(polygon.size()); + for (int i = 0; i < polygon.size(); i++) { + inp.GetPoint(i) = polygon[i]; } + inp.SetOrientation(TPPL_ORIENTATION_CCW); + in_poly.push_back(inp); TPPLPartition tpart; if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed. ERR_PRINT("Convex decomposing failed!"); @@ -103,7 +57,9 @@ Vector> Geometry2D::decompose_many_polygons_in_convex(const Vect decomp.resize(out_poly.size()); int idx = 0; - for (TPPLPoly &tp : out_poly) { + for (List::Element *I = out_poly.front(); I; I = I->next()) { + TPPLPoly &tp = I->get(); + decomp.write[idx].resize(tp.GetNumPoints()); for (int64_t i = 0; i < tp.GetNumPoints(); i++) { @@ -116,10 +72,6 @@ Vector> Geometry2D::decompose_many_polygons_in_convex(const Vect return decomp; } -Vector> Geometry2D::decompose_polygon_in_convex(const Vector &p_polygon) { - return Geometry2D::decompose_many_polygons_in_convex({ p_polygon }, {}); -} - struct _AtlasWorkRect { Size2i s; Point2i p; diff --git a/engine/core/math/geometry_2d.h b/engine/core/math/geometry_2d.h index fa5b0f06..abd395d8 100644 --- a/engine/core/math/geometry_2d.h +++ b/engine/core/math/geometry_2d.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GEOMETRY_2D_H +#define GEOMETRY_2D_H #include "core/math/delaunay_2d.h" #include "core/math/math_funcs.h" @@ -99,39 +100,27 @@ public: return Math::sqrt((c1 - c2).dot(c1 - c2)); } -#ifndef DISABLE_DEPRECATED static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 *p_segment) { - return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]); - } -#endif // DISABLE_DEPRECATED - - static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { - Vector2 p = p_point - p_segment_a; - Vector2 n = p_segment_b - p_segment_a; + Vector2 p = p_point - p_segment[0]; + Vector2 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment_a; // Both points are the same, just give any. + return p_segment[0]; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; if (d <= 0.0f) { - return p_segment_a; // Before first point. + return p_segment[0]; // Before first point. } else if (d >= 1.0f) { - return p_segment_b; // After first point. + return p_segment[1]; // After first point. } else { - return p_segment_a + n * d; // Inside. + return p_segment[0] + n * d; // Inside. } } -#ifndef DISABLE_DEPRECATED static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 *p_segment) { - return get_distance_to_segment(p_point, p_segment[0], p_segment[1]); - } -#endif // DISABLE_DEPRECATED - - static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { - return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment_a, p_segment_b)); + return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment)); } static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) { @@ -148,26 +137,24 @@ public: return (cn.cross(an) > 0) == orientation; } -#ifndef DISABLE_DEPRECATED static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 *p_segment) { - return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]); - } -#endif // DISABLE_DEPRECATED - - static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { - Vector2 p = p_point - p_segment_a; - Vector2 n = p_segment_b - p_segment_a; + Vector2 p = p_point - p_segment[0]; + Vector2 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment_a; // Both points are the same, just give any. + return p_segment[0]; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - return p_segment_a + n * d; // Inside. + return p_segment[0] + n * d; // Inside. } - GODOT_MSVC_WARNING_PUSH_AND_IGNORE(4723) // Potential divide by 0. False positive (see: GH-44274). +// Disable False Positives in MSVC compiler; we correctly check for 0 here to prevent a division by 0. +// See: https://github.com/godotengine/godot/pull/44274 +#ifdef _MSC_VER +#pragma warning(disable : 4723) +#endif static bool line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b, Vector2 &r_result) { // See http://paulbourke.net/geometry/pointlineplane/ @@ -183,7 +170,10 @@ public: return true; } - GODOT_MSVC_WARNING_POP +// Re-enable division by 0 warning +#ifdef _MSC_VER +#pragma warning(default : 4723) +#endif static bool segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b, Vector2 *r_result) { Vector2 B = p_to_a - p_from_a; @@ -499,10 +489,7 @@ public: return points; } - static void merge_many_polygons(const Vector> &p_polygons, Vector> &r_out_polygons, Vector> &r_out_holes); - static Vector> decompose_many_polygons_in_convex(const Vector> &p_polygons, const Vector> &p_holes); - - static Vector> decompose_polygon_in_convex(const Vector &p_polygon); + static Vector> decompose_polygon_in_convex(const Vector &polygon); static void make_atlas(const Vector &p_rects, Vector &r_result, Size2i &r_size); static Vector partial_pack_rects(const Vector &p_sizes, const Size2i &p_atlas_size); @@ -511,3 +498,5 @@ private: static Vector> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector &p_polypath_a, const Vector &p_polypath_b, bool is_a_open = false); static Vector> _polypath_offset(const Vector &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type); }; + +#endif // GEOMETRY_2D_H diff --git a/engine/core/math/geometry_3d.cpp b/engine/core/math/geometry_3d.cpp index 71559ead..361a0607 100644 --- a/engine/core/math/geometry_3d.cpp +++ b/engine/core/math/geometry_3d.cpp @@ -30,8 +30,6 @@ #include "geometry_3d.h" -#include "core/templates/hash_map.h" - void Geometry3D::get_closest_points_between_segments(const Vector3 &p_p0, const Vector3 &p_p1, const Vector3 &p_q0, const Vector3 &p_q1, Vector3 &r_ps, Vector3 &r_qt) { // Based on David Eberly's Computation of Distance Between Line Segments algorithm. @@ -595,7 +593,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector &p_planes Vector3 ref = Vector3(0.0, 1.0, 0.0); - if (Math::abs(p.normal.dot(ref)) > 0.95f) { + if (ABS(p.normal.dot(ref)) > 0.95f) { ref = Vector3(0.0, 0.0, 1.0); // Change axis. } @@ -744,7 +742,7 @@ Vector Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height Vector planes; - const double sides_step = Math::TAU / p_sides; + const double sides_step = Math_TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); @@ -775,7 +773,7 @@ Vector Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; - const double lon_step = Math::TAU / p_lons; + const double lon_step = Math_TAU / p_lons; for (int i = 0; i < p_lons; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * lon_step); @@ -806,7 +804,7 @@ Vector Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height, axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; - const double sides_step = Math::TAU / p_sides; + const double sides_step = Math_TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); @@ -862,6 +860,7 @@ Vector Geometry3D::compute_convex_mesh_points(const Plane *p_planes, in } #define square(m_s) ((m_s) * (m_s)) +#define INF 1e20 /* dt of 1d function using squared distance */ static void edt(float *f, int stride, int n) { @@ -871,8 +870,8 @@ static void edt(float *f, int stride, int n) { int k = 0; v[0] = 0; - z[0] = -Math::INF; - z[1] = +Math::INF; + z[0] = -INF; + z[1] = +INF; for (int q = 1; q <= n - 1; q++) { float s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]); while (s <= z[k]) { @@ -883,7 +882,7 @@ static void edt(float *f, int stride, int n) { v[k] = q; z[k] = s; - z[k + 1] = +Math::INF; + z[k + 1] = +INF; } k = 0; @@ -908,7 +907,7 @@ Vector Geometry3D::generate_edf(const Vector &p_voxels, const Ve float *work_memory = memnew_arr(float, float_count); for (uint32_t i = 0; i < float_count; i++) { - work_memory[i] = Math::INF; + work_memory[i] = INF; } uint32_t y_mult = p_size.x; diff --git a/engine/core/math/geometry_3d.h b/engine/core/math/geometry_3d.h index bd8dbe43..ff39d825 100644 --- a/engine/core/math/geometry_3d.h +++ b/engine/core/math/geometry_3d.h @@ -28,10 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef GEOMETRY_3D_H +#define GEOMETRY_3D_H #include "core/math/delaunay_3d.h" #include "core/math/face3.h" +#include "core/object/object.h" #include "core/templates/local_vector.h" #include "core/templates/vector.h" @@ -272,7 +274,7 @@ public: return true; } - static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *r_res, Vector3 *r_norm) { + static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *p_res, Vector3 *p_norm) { real_t min = -1e20, max = 1e20; Vector3 rel = p_to - p_from; @@ -315,58 +317,46 @@ public: return false; // No intersection. } - if (r_res) { - *r_res = p_from + dir * min; + if (p_res) { + *p_res = p_from + dir * min; } - if (r_norm) { - *r_norm = p_planes[min_index].normal; + if (p_norm) { + *p_norm = p_planes[min_index].normal; } return true; } -#ifndef DISABLE_DEPRECATED static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 *p_segment) { - return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]); - } -#endif // DISABLE_DEPRECATED - - static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) { - Vector3 p = p_point - p_segment_a; - Vector3 n = p_segment_b - p_segment_a; + Vector3 p = p_point - p_segment[0]; + Vector3 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment_a; // Both points are the same, just give any. + return p_segment[0]; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; if (d <= 0.0f) { - return p_segment_a; // Before first point. + return p_segment[0]; // Before first point. } else if (d >= 1.0f) { - return p_segment_b; // After first point. + return p_segment[1]; // After first point. } else { - return p_segment_a + n * d; // Inside. + return p_segment[0] + n * d; // Inside. } } -#ifndef DISABLE_DEPRECATED static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 *p_segment) { - return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]); - } -#endif // DISABLE_DEPRECATED - - static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) { - Vector3 p = p_point - p_segment_a; - Vector3 n = p_segment_b - p_segment_a; + Vector3 p = p_point - p_segment[0]; + Vector3 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment_a; // Both points are the same, just give any. + return p_segment[0]; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - return p_segment_a + n * d; // Inside. + return p_segment[0] + n * d; // Inside. } static inline bool point_in_projected_triangle(const Vector3 &p_point, const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) { @@ -393,14 +383,8 @@ public: return true; } -#ifndef DISABLE_DEPRECATED static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) { - return triangle_sphere_intersection_test(p_triangle[0], p_triangle[1], p_triangle[2], p_normal, p_sphere_pos, p_sphere_radius, r_triangle_contact, r_sphere_contact); - } -#endif // DISABLE_DEPRECATED - - static inline bool triangle_sphere_intersection_test(const Vector3 &p_triangle_a, const Vector3 &p_triangle_b, const Vector3 &p_triangle_c, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) { - real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle_a); + real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle[0]); if (d > p_sphere_radius || d < -p_sphere_radius) { // Not touching the plane of the face, return. @@ -411,7 +395,7 @@ public: /** 2nd) TEST INSIDE TRIANGLE **/ - if (Geometry3D::point_in_projected_triangle(contact, p_triangle_a, p_triangle_b, p_triangle_c)) { + if (Geometry3D::point_in_projected_triangle(contact, p_triangle[0], p_triangle[1], p_triangle[2])) { r_triangle_contact = contact; r_sphere_contact = p_sphere_pos - p_normal * p_sphere_radius; //printf("solved inside triangle\n"); @@ -420,7 +404,7 @@ public: /** 3rd TEST INSIDE EDGE CYLINDERS **/ - const Vector3 verts[4] = { p_triangle_a, p_triangle_b, p_triangle_c, p_triangle_a }; // for() friendly + const Vector3 verts[4] = { p_triangle[0], p_triangle[1], p_triangle[2], p_triangle[0] }; // for() friendly for (int i = 0; i < 3; i++) { // Check edge cylinder. @@ -436,7 +420,7 @@ public: real_t ad = axis.dot(n2); - if (Math::abs(ad) > p_sphere_radius) { + if (ABS(ad) > p_sphere_radius) { // No chance with this edge, too far away. continue; } @@ -484,7 +468,7 @@ public: LOC_OUTSIDE = -1 }; - if (polygon.is_empty()) { + if (polygon.size() == 0) { return polygon; } @@ -856,3 +840,5 @@ public: return n.normalized(); } }; + +#endif // GEOMETRY_3D_H diff --git a/engine/core/math/math_defs.h b/engine/core/math/math_defs.h index 5a9be58c..fe53121a 100644 --- a/engine/core/math/math_defs.h +++ b/engine/core/math/math_defs.h @@ -28,24 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once - -#include "core/typedefs.h" - -#include - -namespace Math { -inline constexpr double SQRT2 = 1.4142135623730950488016887242; -inline constexpr double SQRT3 = 1.7320508075688772935274463415059; -inline constexpr double SQRT12 = 0.7071067811865475244008443621048490; -inline constexpr double SQRT13 = 0.57735026918962576450914878050196; -inline constexpr double LN2 = 0.6931471805599453094172321215; -inline constexpr double TAU = 6.2831853071795864769252867666; -inline constexpr double PI = 3.1415926535897932384626433833; -inline constexpr double E = 2.7182818284590452353602874714; -inline constexpr double INF = std::numeric_limits::infinity(); -inline constexpr double NaN = std::numeric_limits::quiet_NaN(); -} // namespace Math +#ifndef MATH_DEFS_H +#define MATH_DEFS_H #define CMP_EPSILON 0.00001 #define CMP_EPSILON2 (CMP_EPSILON * CMP_EPSILON) @@ -53,6 +37,13 @@ inline constexpr double NaN = std::numeric_limits::quiet_NaN(); #define CMP_NORMALIZE_TOLERANCE 0.000001 #define CMP_POINT_IN_PLANE_EPSILON 0.00001 +#define Math_SQRT12 0.7071067811865475244008443621048490 +#define Math_SQRT2 1.4142135623730950488016887242 +#define Math_LN2 0.6931471805599453094172321215 +#define Math_TAU 6.2831853071795864769252867666 +#define Math_PI 3.1415926535897932384626433833 +#define Math_E 2.7182818284590452353602874714 + #ifdef DEBUG_ENABLED #define MATH_CHECKS #endif @@ -145,3 +136,5 @@ typedef double real_t; #else typedef float real_t; #endif + +#endif // MATH_DEFS_H diff --git a/engine/core/math/math_fieldwise.cpp b/engine/core/math/math_fieldwise.cpp index 8e81e4cc..4064e6aa 100644 --- a/engine/core/math/math_fieldwise.cpp +++ b/engine/core/math/math_fieldwise.cpp @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifdef DEBUG_ENABLED +#ifdef TOOLS_ENABLED #include "math_fieldwise.h" @@ -242,4 +242,4 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const /* clang-format on */ } -#endif // DEBUG_ENABLED +#endif // TOOLS_ENABLED diff --git a/engine/core/math/math_fieldwise.h b/engine/core/math/math_fieldwise.h index 2628beb4..6d222c15 100644 --- a/engine/core/math/math_fieldwise.h +++ b/engine/core/math/math_fieldwise.h @@ -28,12 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef MATH_FIELDWISE_H +#define MATH_FIELDWISE_H -#ifdef DEBUG_ENABLED +#ifdef TOOLS_ENABLED #include "core/variant/variant.h" Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field); -#endif // DEBUG_ENABLED +#endif // TOOLS_ENABLED + +#endif // MATH_FIELDWISE_H diff --git a/engine/core/math/math_funcs.cpp b/engine/core/math/math_funcs.cpp index 76d9cd25..0d5b0faa 100644 --- a/engine/core/math/math_funcs.cpp +++ b/engine/core/math/math_funcs.cpp @@ -31,19 +31,18 @@ #include "math_funcs.h" #include "core/error/error_macros.h" -#include "core/math/random_pcg.h" -static RandomPCG default_rand; +RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC); -uint32_t Math::rand_from_seed(uint64_t *p_seed) { - RandomPCG rng = RandomPCG(*p_seed); +uint32_t Math::rand_from_seed(uint64_t *seed) { + RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC); uint32_t r = rng.rand(); - *p_seed = rng.get_seed(); + *seed = rng.get_seed(); return r; } -void Math::seed(uint64_t p_value) { - default_rand.seed(p_value); +void Math::seed(uint64_t x) { + default_rand.seed(x); } void Math::randomize() { @@ -54,8 +53,8 @@ uint32_t Math::rand() { return default_rand.rand(); } -double Math::randfn(double p_mean, double p_deviation) { - return default_rand.randfn(p_mean, p_deviation); +double Math::randfn(double mean, double deviation) { + return default_rand.randfn(mean, deviation); } int Math::step_decimals(double p_step) { @@ -169,14 +168,14 @@ uint32_t Math::larger_prime(uint32_t p_val) { } } -double Math::random(double p_from, double p_to) { - return default_rand.random(p_from, p_to); +double Math::random(double from, double to) { + return default_rand.random(from, to); } -float Math::random(float p_from, float p_to) { - return default_rand.random(p_from, p_to); +float Math::random(float from, float to) { + return default_rand.random(from, to); } -int Math::random(int p_from, int p_to) { - return default_rand.random(p_from, p_to); +int Math::random(int from, int to) { + return default_rand.random(from, to); } diff --git a/engine/core/math/math_funcs.h b/engine/core/math/math_funcs.h index 56027765..1afc5f4b 100644 --- a/engine/core/math/math_funcs.h +++ b/engine/core/math/math_funcs.h @@ -28,851 +28,735 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef MATH_FUNCS_H +#define MATH_FUNCS_H #include "core/error/error_macros.h" #include "core/math/math_defs.h" +#include "core/math/random_pcg.h" #include "core/typedefs.h" +#include "thirdparty/misc/pcg.h" + #include #include -namespace Math { +class Math { + static RandomPCG default_rand; -_ALWAYS_INLINE_ double sin(double p_x) { - return ::sin(p_x); -} -_ALWAYS_INLINE_ float sin(float p_x) { - return ::sinf(p_x); -} +public: + Math() {} // useless to instance -_ALWAYS_INLINE_ double cos(double p_x) { - return ::cos(p_x); -} -_ALWAYS_INLINE_ float cos(float p_x) { - return ::cosf(p_x); -} + // Not using 'RANDOM_MAX' to avoid conflict with system headers on some OSes (at least NetBSD). + static const uint64_t RANDOM_32BIT_MAX = 0xFFFFFFFF; -_ALWAYS_INLINE_ double tan(double p_x) { - return ::tan(p_x); -} -_ALWAYS_INLINE_ float tan(float p_x) { - return ::tanf(p_x); -} + static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); } + static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); } -_ALWAYS_INLINE_ double sinh(double p_x) { - return ::sinh(p_x); -} -_ALWAYS_INLINE_ float sinh(float p_x) { - return ::sinhf(p_x); -} + static _ALWAYS_INLINE_ double cos(double p_x) { return ::cos(p_x); } + static _ALWAYS_INLINE_ float cos(float p_x) { return ::cosf(p_x); } -_ALWAYS_INLINE_ double sinc(double p_x) { - return p_x == 0 ? 1 : sin(p_x) / p_x; -} -_ALWAYS_INLINE_ float sinc(float p_x) { - return p_x == 0 ? 1 : sin(p_x) / p_x; -} + static _ALWAYS_INLINE_ double tan(double p_x) { return ::tan(p_x); } + static _ALWAYS_INLINE_ float tan(float p_x) { return ::tanf(p_x); } -_ALWAYS_INLINE_ double sincn(double p_x) { - return sinc(PI * p_x); -} -_ALWAYS_INLINE_ float sincn(float p_x) { - return sinc((float)PI * p_x); -} + static _ALWAYS_INLINE_ double sinh(double p_x) { return ::sinh(p_x); } + static _ALWAYS_INLINE_ float sinh(float p_x) { return ::sinhf(p_x); } -_ALWAYS_INLINE_ double cosh(double p_x) { - return ::cosh(p_x); -} -_ALWAYS_INLINE_ float cosh(float p_x) { - return ::coshf(p_x); -} + static _ALWAYS_INLINE_ float sinc(float p_x) { return p_x == 0 ? 1 : ::sin(p_x) / p_x; } + static _ALWAYS_INLINE_ double sinc(double p_x) { return p_x == 0 ? 1 : ::sin(p_x) / p_x; } -_ALWAYS_INLINE_ double tanh(double p_x) { - return ::tanh(p_x); -} -_ALWAYS_INLINE_ float tanh(float p_x) { - return ::tanhf(p_x); -} + static _ALWAYS_INLINE_ float sincn(float p_x) { return sinc((float)Math_PI * p_x); } + static _ALWAYS_INLINE_ double sincn(double p_x) { return sinc(Math_PI * p_x); } -// Always does clamping so always safe to use. -_ALWAYS_INLINE_ double asin(double p_x) { - return p_x < -1 ? (-PI / 2) : (p_x > 1 ? (PI / 2) : ::asin(p_x)); -} -_ALWAYS_INLINE_ float asin(float p_x) { - return p_x < -1 ? (-(float)PI / 2) : (p_x > 1 ? ((float)PI / 2) : ::asinf(p_x)); -} + static _ALWAYS_INLINE_ double cosh(double p_x) { return ::cosh(p_x); } + static _ALWAYS_INLINE_ float cosh(float p_x) { return ::coshf(p_x); } -// Always does clamping so always safe to use. -_ALWAYS_INLINE_ double acos(double p_x) { - return p_x < -1 ? PI : (p_x > 1 ? 0 : ::acos(p_x)); -} -_ALWAYS_INLINE_ float acos(float p_x) { - return p_x < -1 ? (float)PI : (p_x > 1 ? 0 : ::acosf(p_x)); -} + static _ALWAYS_INLINE_ double tanh(double p_x) { return ::tanh(p_x); } + static _ALWAYS_INLINE_ float tanh(float p_x) { return ::tanhf(p_x); } -_ALWAYS_INLINE_ double atan(double p_x) { - return ::atan(p_x); -} -_ALWAYS_INLINE_ float atan(float p_x) { - return ::atanf(p_x); -} + // Always does clamping so always safe to use. + static _ALWAYS_INLINE_ double asin(double p_x) { return p_x < -1 ? (-Math_PI / 2) : (p_x > 1 ? (Math_PI / 2) : ::asin(p_x)); } + static _ALWAYS_INLINE_ float asin(float p_x) { return p_x < -1 ? (-Math_PI / 2) : (p_x > 1 ? (Math_PI / 2) : ::asinf(p_x)); } -_ALWAYS_INLINE_ double atan2(double p_y, double p_x) { - return ::atan2(p_y, p_x); -} -_ALWAYS_INLINE_ float atan2(float p_y, float p_x) { - return ::atan2f(p_y, p_x); -} + // Always does clamping so always safe to use. + static _ALWAYS_INLINE_ double acos(double p_x) { return p_x < -1 ? Math_PI : (p_x > 1 ? 0 : ::acos(p_x)); } + static _ALWAYS_INLINE_ float acos(float p_x) { return p_x < -1 ? Math_PI : (p_x > 1 ? 0 : ::acosf(p_x)); } -_ALWAYS_INLINE_ double asinh(double p_x) { - return ::asinh(p_x); -} -_ALWAYS_INLINE_ float asinh(float p_x) { - return ::asinhf(p_x); -} + static _ALWAYS_INLINE_ double atan(double p_x) { return ::atan(p_x); } + static _ALWAYS_INLINE_ float atan(float p_x) { return ::atanf(p_x); } -// Always does clamping so always safe to use. -_ALWAYS_INLINE_ double acosh(double p_x) { - return p_x < 1 ? 0 : ::acosh(p_x); -} -_ALWAYS_INLINE_ float acosh(float p_x) { - return p_x < 1 ? 0 : ::acoshf(p_x); -} + static _ALWAYS_INLINE_ double atan2(double p_y, double p_x) { return ::atan2(p_y, p_x); } + static _ALWAYS_INLINE_ float atan2(float p_y, float p_x) { return ::atan2f(p_y, p_x); } -// Always does clamping so always safe to use. -_ALWAYS_INLINE_ double atanh(double p_x) { - return p_x <= -1 ? -INF : (p_x >= 1 ? INF : ::atanh(p_x)); -} -_ALWAYS_INLINE_ float atanh(float p_x) { - return p_x <= -1 ? (float)-INF : (p_x >= 1 ? (float)INF : ::atanhf(p_x)); -} + static _ALWAYS_INLINE_ double asinh(double p_x) { return ::asinh(p_x); } + static _ALWAYS_INLINE_ float asinh(float p_x) { return ::asinhf(p_x); } -_ALWAYS_INLINE_ double sqrt(double p_x) { - return ::sqrt(p_x); -} -_ALWAYS_INLINE_ float sqrt(float p_x) { - return ::sqrtf(p_x); -} + // Always does clamping so always safe to use. + static _ALWAYS_INLINE_ double acosh(double p_x) { return p_x < 1 ? 0 : ::acosh(p_x); } + static _ALWAYS_INLINE_ float acosh(float p_x) { return p_x < 1 ? 0 : ::acoshf(p_x); } -_ALWAYS_INLINE_ double fmod(double p_x, double p_y) { - return ::fmod(p_x, p_y); -} -_ALWAYS_INLINE_ float fmod(float p_x, float p_y) { - return ::fmodf(p_x, p_y); -} + // Always does clamping so always safe to use. + static _ALWAYS_INLINE_ double atanh(double p_x) { return p_x <= -1 ? -INFINITY : (p_x >= 1 ? INFINITY : ::atanh(p_x)); } + static _ALWAYS_INLINE_ float atanh(float p_x) { return p_x <= -1 ? -INFINITY : (p_x >= 1 ? INFINITY : ::atanhf(p_x)); } -_ALWAYS_INLINE_ double modf(double p_x, double *r_y) { - return ::modf(p_x, r_y); -} -_ALWAYS_INLINE_ float modf(float p_x, float *r_y) { - return ::modff(p_x, r_y); -} + static _ALWAYS_INLINE_ double sqrt(double p_x) { return ::sqrt(p_x); } + static _ALWAYS_INLINE_ float sqrt(float p_x) { return ::sqrtf(p_x); } -_ALWAYS_INLINE_ double floor(double p_x) { - return ::floor(p_x); -} -_ALWAYS_INLINE_ float floor(float p_x) { - return ::floorf(p_x); -} + static _ALWAYS_INLINE_ double fmod(double p_x, double p_y) { return ::fmod(p_x, p_y); } + static _ALWAYS_INLINE_ float fmod(float p_x, float p_y) { return ::fmodf(p_x, p_y); } -_ALWAYS_INLINE_ double ceil(double p_x) { - return ::ceil(p_x); -} -_ALWAYS_INLINE_ float ceil(float p_x) { - return ::ceilf(p_x); -} + static _ALWAYS_INLINE_ double modf(double p_x, double *r_y) { return ::modf(p_x, r_y); } + static _ALWAYS_INLINE_ float modf(float p_x, float *r_y) { return ::modff(p_x, r_y); } -_ALWAYS_INLINE_ double pow(double p_x, double p_y) { - return ::pow(p_x, p_y); -} -_ALWAYS_INLINE_ float pow(float p_x, float p_y) { - return ::powf(p_x, p_y); -} + static _ALWAYS_INLINE_ double floor(double p_x) { return ::floor(p_x); } + static _ALWAYS_INLINE_ float floor(float p_x) { return ::floorf(p_x); } -_ALWAYS_INLINE_ double log(double p_x) { - return ::log(p_x); -} -_ALWAYS_INLINE_ float log(float p_x) { - return ::logf(p_x); -} + static _ALWAYS_INLINE_ double ceil(double p_x) { return ::ceil(p_x); } + static _ALWAYS_INLINE_ float ceil(float p_x) { return ::ceilf(p_x); } -_ALWAYS_INLINE_ double log1p(double p_x) { - return ::log1p(p_x); -} -_ALWAYS_INLINE_ float log1p(float p_x) { - return ::log1pf(p_x); -} + static _ALWAYS_INLINE_ double pow(double p_x, double p_y) { return ::pow(p_x, p_y); } + static _ALWAYS_INLINE_ float pow(float p_x, float p_y) { return ::powf(p_x, p_y); } -_ALWAYS_INLINE_ double log2(double p_x) { - return ::log2(p_x); -} -_ALWAYS_INLINE_ float log2(float p_x) { - return ::log2f(p_x); -} + static _ALWAYS_INLINE_ double log(double p_x) { return ::log(p_x); } + static _ALWAYS_INLINE_ float log(float p_x) { return ::logf(p_x); } -_ALWAYS_INLINE_ double exp(double p_x) { - return ::exp(p_x); -} -_ALWAYS_INLINE_ float exp(float p_x) { - return ::expf(p_x); -} + static _ALWAYS_INLINE_ double log1p(double p_x) { return ::log1p(p_x); } + static _ALWAYS_INLINE_ float log1p(float p_x) { return ::log1pf(p_x); } -_ALWAYS_INLINE_ bool is_nan(double p_val) { + static _ALWAYS_INLINE_ double log2(double p_x) { return ::log2(p_x); } + static _ALWAYS_INLINE_ float log2(float p_x) { return ::log2f(p_x); } + + static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); } + static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); } + + static _ALWAYS_INLINE_ bool is_nan(double p_val) { #ifdef _MSC_VER - return _isnan(p_val); + return _isnan(p_val); #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint64_t u; - double f; - } ieee754; - ieee754.f = p_val; - // (unsigned)(0x7ff0000000000001 >> 32) : 0x7ff00000 - return ((((unsigned)(ieee754.u >> 32) & 0x7fffffff) + ((unsigned)ieee754.u != 0)) > 0x7ff00000); + union { + uint64_t u; + double f; + } ieee754; + ieee754.f = p_val; + // (unsigned)(0x7ff0000000000001 >> 32) : 0x7ff00000 + return ((((unsigned)(ieee754.u >> 32) & 0x7fffffff) + ((unsigned)ieee754.u != 0)) > 0x7ff00000); #else - return isnan(p_val); + return isnan(p_val); #endif -} + } -_ALWAYS_INLINE_ bool is_nan(float p_val) { + static _ALWAYS_INLINE_ bool is_nan(float p_val) { #ifdef _MSC_VER - return _isnan(p_val); + return _isnan(p_val); #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint32_t u; - float f; - } ieee754; - ieee754.f = p_val; - // ----------------------------------- - // (single-precision floating-point) - // NaN : s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx - // : (> 0x7f800000) - // where, - // s : sign - // x : non-zero number - // ----------------------------------- - return ((ieee754.u & 0x7fffffff) > 0x7f800000); + union { + uint32_t u; + float f; + } ieee754; + ieee754.f = p_val; + // ----------------------------------- + // (single-precision floating-point) + // NaN : s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx + // : (> 0x7f800000) + // where, + // s : sign + // x : non-zero number + // ----------------------------------- + return ((ieee754.u & 0x7fffffff) > 0x7f800000); #else - return isnan(p_val); + return isnan(p_val); #endif -} + } -_ALWAYS_INLINE_ bool is_inf(double p_val) { + static _ALWAYS_INLINE_ bool is_inf(double p_val) { #ifdef _MSC_VER - return !_finite(p_val); + return !_finite(p_val); // use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint64_t u; - double f; - } ieee754; - ieee754.f = p_val; - return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && - ((unsigned)ieee754.u == 0); + union { + uint64_t u; + double f; + } ieee754; + ieee754.f = p_val; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && + ((unsigned)ieee754.u == 0); #else - return isinf(p_val); + return isinf(p_val); #endif -} + } -_ALWAYS_INLINE_ bool is_inf(float p_val) { + static _ALWAYS_INLINE_ bool is_inf(float p_val) { #ifdef _MSC_VER - return !_finite(p_val); + return !_finite(p_val); // use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint32_t u; - float f; - } ieee754; - ieee754.f = p_val; - return (ieee754.u & 0x7fffffff) == 0x7f800000; + union { + uint32_t u; + float f; + } ieee754; + ieee754.f = p_val; + return (ieee754.u & 0x7fffffff) == 0x7f800000; #else - return isinf(p_val); + return isinf(p_val); #endif -} - -// These methods assume (p_num + p_den) doesn't overflow. -_ALWAYS_INLINE_ int32_t division_round_up(int32_t p_num, int32_t p_den) { - int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; - return (p_num + p_den + offset) / p_den; -} -_ALWAYS_INLINE_ uint32_t division_round_up(uint32_t p_num, uint32_t p_den) { - return (p_num + p_den - 1) / p_den; -} -_ALWAYS_INLINE_ int64_t division_round_up(int64_t p_num, int64_t p_den) { - int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; - return (p_num + p_den + offset) / p_den; -} -_ALWAYS_INLINE_ uint64_t division_round_up(uint64_t p_num, uint64_t p_den) { - return (p_num + p_den - 1) / p_den; -} - -_ALWAYS_INLINE_ bool is_finite(double p_val) { - return isfinite(p_val); -} -_ALWAYS_INLINE_ bool is_finite(float p_val) { - return isfinite(p_val); -} - -_ALWAYS_INLINE_ double absd(double p_value) { - return ::fabs(p_value); -} -_ALWAYS_INLINE_ float absf(float p_value) { - return ::fabsf(p_value); -} - -_ALWAYS_INLINE_ double abs(double p_value) { - return absd(p_value); -} -_ALWAYS_INLINE_ float abs(float p_value) { - return absf(p_value); -} -_ALWAYS_INLINE_ int8_t abs(int8_t p_value) { - return p_value > 0 ? p_value : -p_value; -} -_ALWAYS_INLINE_ int16_t abs(int16_t p_value) { - return p_value > 0 ? p_value : -p_value; -} -_ALWAYS_INLINE_ int32_t abs(int32_t p_value) { - return ::abs(p_value); -} -_ALWAYS_INLINE_ int64_t abs(int64_t p_value) { - return ::llabs(p_value); -} - -_ALWAYS_INLINE_ double fposmod(double p_x, double p_y) { - double value = fmod(p_x, p_y); - if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { - value += p_y; } - value += 0.0; - return value; -} -_ALWAYS_INLINE_ float fposmod(float p_x, float p_y) { - float value = fmod(p_x, p_y); - if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { - value += p_y; + + // These methods assume (p_num + p_den) doesn't overflow. + static _ALWAYS_INLINE_ int32_t division_round_up(int32_t p_num, int32_t p_den) { + int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; + return (p_num + p_den + offset) / p_den; } - value += 0.0f; - return value; -} - -_ALWAYS_INLINE_ double fposmodp(double p_x, double p_y) { - double value = fmod(p_x, p_y); - if (value < 0) { - value += p_y; + static _ALWAYS_INLINE_ uint32_t division_round_up(uint32_t p_num, uint32_t p_den) { + return (p_num + p_den - 1) / p_den; } - value += 0.0; - return value; -} -_ALWAYS_INLINE_ float fposmodp(float p_x, float p_y) { - float value = fmod(p_x, p_y); - if (value < 0) { - value += p_y; + static _ALWAYS_INLINE_ int64_t division_round_up(int64_t p_num, int64_t p_den) { + int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; + return (p_num + p_den + offset) / p_den; } - value += 0.0f; - return value; -} - -_ALWAYS_INLINE_ int64_t posmod(int64_t p_x, int64_t p_y) { - ERR_FAIL_COND_V_MSG(p_y == 0, 0, "Division by zero in posmod is undefined. Returning 0 as fallback."); - int64_t value = p_x % p_y; - if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { - value += p_y; + static _ALWAYS_INLINE_ uint64_t division_round_up(uint64_t p_num, uint64_t p_den) { + return (p_num + p_den - 1) / p_den; } - return value; -} -_ALWAYS_INLINE_ double deg_to_rad(double p_y) { - return p_y * (PI / 180.0); -} -_ALWAYS_INLINE_ float deg_to_rad(float p_y) { - return p_y * ((float)PI / 180.0f); -} + static _ALWAYS_INLINE_ bool is_finite(double p_val) { return isfinite(p_val); } + static _ALWAYS_INLINE_ bool is_finite(float p_val) { return isfinite(p_val); } -_ALWAYS_INLINE_ double rad_to_deg(double p_y) { - return p_y * (180.0 / PI); -} -_ALWAYS_INLINE_ float rad_to_deg(float p_y) { - return p_y * (180.0f / (float)PI); -} + static _ALWAYS_INLINE_ double abs(double g) { return absd(g); } + static _ALWAYS_INLINE_ float abs(float g) { return absf(g); } + static _ALWAYS_INLINE_ int abs(int g) { return g > 0 ? g : -g; } -_ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { - return p_from + (p_to - p_from) * p_weight; -} -_ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { - return p_from + (p_to - p_from) * p_weight; -} - -_ALWAYS_INLINE_ double cubic_interpolate(double p_from, double p_to, double p_pre, double p_post, double p_weight) { - return 0.5 * - ((p_from * 2.0) + - (-p_pre + p_to) * p_weight + - (2.0 * p_pre - 5.0 * p_from + 4.0 * p_to - p_post) * (p_weight * p_weight) + - (-p_pre + 3.0 * p_from - 3.0 * p_to + p_post) * (p_weight * p_weight * p_weight)); -} -_ALWAYS_INLINE_ float cubic_interpolate(float p_from, float p_to, float p_pre, float p_post, float p_weight) { - return 0.5f * - ((p_from * 2.0f) + - (-p_pre + p_to) * p_weight + - (2.0f * p_pre - 5.0f * p_from + 4.0f * p_to - p_post) * (p_weight * p_weight) + - (-p_pre + 3.0f * p_from - 3.0f * p_to + p_post) * (p_weight * p_weight * p_weight)); -} - -_ALWAYS_INLINE_ double cubic_interpolate_angle(double p_from, double p_to, double p_pre, double p_post, double p_weight) { - double from_rot = fmod(p_from, TAU); - - double pre_diff = fmod(p_pre - from_rot, TAU); - double pre_rot = from_rot + fmod(2.0 * pre_diff, TAU) - pre_diff; - - double to_diff = fmod(p_to - from_rot, TAU); - double to_rot = from_rot + fmod(2.0 * to_diff, TAU) - to_diff; - - double post_diff = fmod(p_post - to_rot, TAU); - double post_rot = to_rot + fmod(2.0 * post_diff, TAU) - post_diff; - - return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); -} - -_ALWAYS_INLINE_ float cubic_interpolate_angle(float p_from, float p_to, float p_pre, float p_post, float p_weight) { - float from_rot = fmod(p_from, (float)TAU); - - float pre_diff = fmod(p_pre - from_rot, (float)TAU); - float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)TAU) - pre_diff; - - float to_diff = fmod(p_to - from_rot, (float)TAU); - float to_rot = from_rot + fmod(2.0f * to_diff, (float)TAU) - to_diff; - - float post_diff = fmod(p_post - to_rot, (float)TAU); - float post_rot = to_rot + fmod(2.0f * post_diff, (float)TAU) - post_diff; - - return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); -} - -_ALWAYS_INLINE_ double cubic_interpolate_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, - double p_to_t, double p_pre_t, double p_post_t) { - /* Barry-Goldman method */ - double t = lerp(0.0, p_to_t, p_weight); - double a1 = lerp(p_pre, p_from, p_pre_t == 0 ? 0.0 : (t - p_pre_t) / -p_pre_t); - double a2 = lerp(p_from, p_to, p_to_t == 0 ? 0.5 : t / p_to_t); - double a3 = lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0 : (t - p_to_t) / (p_post_t - p_to_t)); - double b1 = lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0 : (t - p_pre_t) / (p_to_t - p_pre_t)); - double b2 = lerp(a2, a3, p_post_t == 0 ? 1.0 : t / p_post_t); - return lerp(b1, b2, p_to_t == 0 ? 0.5 : t / p_to_t); -} -_ALWAYS_INLINE_ float cubic_interpolate_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, - float p_to_t, float p_pre_t, float p_post_t) { - /* Barry-Goldman method */ - float t = lerp(0.0f, p_to_t, p_weight); - float a1 = lerp(p_pre, p_from, p_pre_t == 0 ? 0.0f : (t - p_pre_t) / -p_pre_t); - float a2 = lerp(p_from, p_to, p_to_t == 0 ? 0.5f : t / p_to_t); - float a3 = lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0f : (t - p_to_t) / (p_post_t - p_to_t)); - float b1 = lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0f : (t - p_pre_t) / (p_to_t - p_pre_t)); - float b2 = lerp(a2, a3, p_post_t == 0 ? 1.0f : t / p_post_t); - return lerp(b1, b2, p_to_t == 0 ? 0.5f : t / p_to_t); -} - -_ALWAYS_INLINE_ double cubic_interpolate_angle_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, - double p_to_t, double p_pre_t, double p_post_t) { - double from_rot = fmod(p_from, TAU); - - double pre_diff = fmod(p_pre - from_rot, TAU); - double pre_rot = from_rot + fmod(2.0 * pre_diff, TAU) - pre_diff; - - double to_diff = fmod(p_to - from_rot, TAU); - double to_rot = from_rot + fmod(2.0 * to_diff, TAU) - to_diff; - - double post_diff = fmod(p_post - to_rot, TAU); - double post_rot = to_rot + fmod(2.0 * post_diff, TAU) - post_diff; - - return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); -} -_ALWAYS_INLINE_ float cubic_interpolate_angle_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, - float p_to_t, float p_pre_t, float p_post_t) { - float from_rot = fmod(p_from, (float)TAU); - - float pre_diff = fmod(p_pre - from_rot, (float)TAU); - float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)TAU) - pre_diff; - - float to_diff = fmod(p_to - from_rot, (float)TAU); - float to_rot = from_rot + fmod(2.0f * to_diff, (float)TAU) - to_diff; - - float post_diff = fmod(p_post - to_rot, (float)TAU); - float post_rot = to_rot + fmod(2.0f * post_diff, (float)TAU) - post_diff; - - return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); -} - -_ALWAYS_INLINE_ double bezier_interpolate(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - double omt = (1.0 - p_t); - double omt2 = omt * omt; - double omt3 = omt2 * omt; - double t2 = p_t * p_t; - double t3 = t2 * p_t; - - return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; -} -_ALWAYS_INLINE_ float bezier_interpolate(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - float omt = (1.0f - p_t); - float omt2 = omt * omt; - float omt3 = omt2 * omt; - float t2 = p_t * p_t; - float t3 = t2 * p_t; - - return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0f + p_control_2 * omt * t2 * 3.0f + p_end * t3; -} - -_ALWAYS_INLINE_ double bezier_derivative(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - double omt = (1.0 - p_t); - double omt2 = omt * omt; - double t2 = p_t * p_t; - - double d = (p_control_1 - p_start) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2; - return d; -} -_ALWAYS_INLINE_ float bezier_derivative(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - float omt = (1.0f - p_t); - float omt2 = omt * omt; - float t2 = p_t * p_t; - - float d = (p_control_1 - p_start) * 3.0f * omt2 + (p_control_2 - p_control_1) * 6.0f * omt * p_t + (p_end - p_control_2) * 3.0f * t2; - return d; -} - -_ALWAYS_INLINE_ double angle_difference(double p_from, double p_to) { - double difference = fmod(p_to - p_from, TAU); - return fmod(2.0 * difference, TAU) - difference; -} -_ALWAYS_INLINE_ float angle_difference(float p_from, float p_to) { - float difference = fmod(p_to - p_from, (float)TAU); - return fmod(2.0f * difference, (float)TAU) - difference; -} - -_ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) { - return p_from + angle_difference(p_from, p_to) * p_weight; -} -_ALWAYS_INLINE_ float lerp_angle(float p_from, float p_to, float p_weight) { - return p_from + angle_difference(p_from, p_to) * p_weight; -} - -_ALWAYS_INLINE_ double inverse_lerp(double p_from, double p_to, double p_value) { - return (p_value - p_from) / (p_to - p_from); -} -_ALWAYS_INLINE_ float inverse_lerp(float p_from, float p_to, float p_value) { - return (p_value - p_from) / (p_to - p_from); -} - -_ALWAYS_INLINE_ double remap(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { - return lerp(p_ostart, p_ostop, inverse_lerp(p_istart, p_istop, p_value)); -} -_ALWAYS_INLINE_ float remap(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { - return lerp(p_ostart, p_ostop, inverse_lerp(p_istart, p_istop, p_value)); -} - -_ALWAYS_INLINE_ bool is_equal_approx(double p_left, double p_right, double p_tolerance) { - // Check for exact equality first, required to handle "infinity" values. - if (p_left == p_right) { - return true; - } - // Then check for approximate equality. - return abs(p_left - p_right) < p_tolerance; -} -_ALWAYS_INLINE_ bool is_equal_approx(float p_left, float p_right, float p_tolerance) { - // Check for exact equality first, required to handle "infinity" values. - if (p_left == p_right) { - return true; - } - // Then check for approximate equality. - return abs(p_left - p_right) < p_tolerance; -} - -_ALWAYS_INLINE_ bool is_equal_approx(double p_left, double p_right) { - // Check for exact equality first, required to handle "infinity" values. - if (p_left == p_right) { - return true; - } - // Then check for approximate equality. - double tolerance = CMP_EPSILON * abs(p_left); - if (tolerance < CMP_EPSILON) { - tolerance = CMP_EPSILON; - } - return abs(p_left - p_right) < tolerance; -} -_ALWAYS_INLINE_ bool is_equal_approx(float p_left, float p_right) { - // Check for exact equality first, required to handle "infinity" values. - if (p_left == p_right) { - return true; - } - // Then check for approximate equality. - float tolerance = (float)CMP_EPSILON * abs(p_left); - if (tolerance < (float)CMP_EPSILON) { - tolerance = (float)CMP_EPSILON; - } - return abs(p_left - p_right) < tolerance; -} - -_ALWAYS_INLINE_ bool is_zero_approx(double p_value) { - return abs(p_value) < CMP_EPSILON; -} -_ALWAYS_INLINE_ bool is_zero_approx(float p_value) { - return abs(p_value) < (float)CMP_EPSILON; -} - -_ALWAYS_INLINE_ bool is_same(double p_left, double p_right) { - return (p_left == p_right) || (is_nan(p_left) && is_nan(p_right)); -} -_ALWAYS_INLINE_ bool is_same(float p_left, float p_right) { - return (p_left == p_right) || (is_nan(p_left) && is_nan(p_right)); -} - -_ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) { - if (is_equal_approx(p_from, p_to)) { - if (likely(p_from <= p_to)) { - return p_s <= p_from ? 0.0 : 1.0; - } else { - return p_s <= p_to ? 1.0 : 0.0; + static _ALWAYS_INLINE_ double fposmod(double p_x, double p_y) { + double value = Math::fmod(p_x, p_y); + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { + value += p_y; } + value += 0.0; + return value; } - double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0); - return s * s * (3.0 - 2.0 * s); -} -_ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) { - if (is_equal_approx(p_from, p_to)) { - if (likely(p_from <= p_to)) { - return p_s <= p_from ? 0.0f : 1.0f; - } else { - return p_s <= p_to ? 1.0f : 0.0f; + static _ALWAYS_INLINE_ float fposmod(float p_x, float p_y) { + float value = Math::fmod(p_x, p_y); + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { + value += p_y; } + value += 0.0f; + return value; } - float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); - return s * s * (3.0f - 2.0f * s); -} - -_ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { - return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; -} -_ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { - return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; -} - -_ALWAYS_INLINE_ double rotate_toward(double p_from, double p_to, double p_delta) { - double difference = angle_difference(p_from, p_to); - double abs_difference = abs(difference); - // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). - return p_from + CLAMP(p_delta, abs_difference - PI, abs_difference) * (difference >= 0.0 ? 1.0 : -1.0); -} -_ALWAYS_INLINE_ float rotate_toward(float p_from, float p_to, float p_delta) { - float difference = angle_difference(p_from, p_to); - float abs_difference = abs(difference); - // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). - return p_from + CLAMP(p_delta, abs_difference - (float)PI, abs_difference) * (difference >= 0.0f ? 1.0f : -1.0f); -} - -_ALWAYS_INLINE_ double linear_to_db(double p_linear) { - return log(p_linear) * 8.6858896380650365530225783783321; -} -_ALWAYS_INLINE_ float linear_to_db(float p_linear) { - return log(p_linear) * (float)8.6858896380650365530225783783321; -} - -_ALWAYS_INLINE_ double db_to_linear(double p_db) { - return exp(p_db * 0.11512925464970228420089957273422); -} -_ALWAYS_INLINE_ float db_to_linear(float p_db) { - return exp(p_db * (float)0.11512925464970228420089957273422); -} - -_ALWAYS_INLINE_ double round(double p_val) { - return ::round(p_val); -} -_ALWAYS_INLINE_ float round(float p_val) { - return ::roundf(p_val); -} - -_ALWAYS_INLINE_ double wrapf(double p_value, double p_min, double p_max) { - double range = p_max - p_min; - if (is_zero_approx(range)) { - return p_min; + static _ALWAYS_INLINE_ float fposmodp(float p_x, float p_y) { + float value = Math::fmod(p_x, p_y); + if (value < 0) { + value += p_y; + } + value += 0.0f; + return value; } - double result = p_value - (range * floor((p_value - p_min) / range)); - if (is_equal_approx(result, p_max)) { - return p_min; + static _ALWAYS_INLINE_ double fposmodp(double p_x, double p_y) { + double value = Math::fmod(p_x, p_y); + if (value < 0) { + value += p_y; + } + value += 0.0; + return value; } - return result; -} -_ALWAYS_INLINE_ float wrapf(float p_value, float p_min, float p_max) { - float range = p_max - p_min; - if (is_zero_approx(range)) { - return p_min; + + static _ALWAYS_INLINE_ int64_t posmod(int64_t p_x, int64_t p_y) { + ERR_FAIL_COND_V_MSG(p_y == 0, 0, "Division by zero in posmod is undefined. Returning 0 as fallback."); + int64_t value = p_x % p_y; + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { + value += p_y; + } + return value; } - float result = p_value - (range * floor((p_value - p_min) / range)); - if (is_equal_approx(result, p_max)) { - return p_min; + + static _ALWAYS_INLINE_ double deg_to_rad(double p_y) { return p_y * (Math_PI / 180.0); } + static _ALWAYS_INLINE_ float deg_to_rad(float p_y) { return p_y * (float)(Math_PI / 180.0); } + + static _ALWAYS_INLINE_ double rad_to_deg(double p_y) { return p_y * (180.0 / Math_PI); } + static _ALWAYS_INLINE_ float rad_to_deg(float p_y) { return p_y * (float)(180.0 / Math_PI); } + + static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; } + static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; } + + static _ALWAYS_INLINE_ double cubic_interpolate(double p_from, double p_to, double p_pre, double p_post, double p_weight) { + return 0.5 * + ((p_from * 2.0) + + (-p_pre + p_to) * p_weight + + (2.0 * p_pre - 5.0 * p_from + 4.0 * p_to - p_post) * (p_weight * p_weight) + + (-p_pre + 3.0 * p_from - 3.0 * p_to + p_post) * (p_weight * p_weight * p_weight)); + } + static _ALWAYS_INLINE_ float cubic_interpolate(float p_from, float p_to, float p_pre, float p_post, float p_weight) { + return 0.5f * + ((p_from * 2.0f) + + (-p_pre + p_to) * p_weight + + (2.0f * p_pre - 5.0f * p_from + 4.0f * p_to - p_post) * (p_weight * p_weight) + + (-p_pre + 3.0f * p_from - 3.0f * p_to + p_post) * (p_weight * p_weight * p_weight)); } - return result; -} -_ALWAYS_INLINE_ int64_t wrapi(int64_t p_value, int64_t p_min, int64_t p_max) { - int64_t range = p_max - p_min; - return range == 0 ? p_min : p_min + ((((p_value - p_min) % range) + range) % range); -} + static _ALWAYS_INLINE_ double cubic_interpolate_angle(double p_from, double p_to, double p_pre, double p_post, double p_weight) { + double from_rot = fmod(p_from, Math_TAU); -_ALWAYS_INLINE_ double fract(double p_value) { - return p_value - floor(p_value); -} -_ALWAYS_INLINE_ float fract(float p_value) { - return p_value - floor(p_value); -} + double pre_diff = fmod(p_pre - from_rot, Math_TAU); + double pre_rot = from_rot + fmod(2.0 * pre_diff, Math_TAU) - pre_diff; -_ALWAYS_INLINE_ double pingpong(double p_value, double p_length) { - return (p_length != 0.0) ? abs(fract((p_value - p_length) / (p_length * 2.0)) * p_length * 2.0 - p_length) : 0.0; -} -_ALWAYS_INLINE_ float pingpong(float p_value, float p_length) { - return (p_length != 0.0f) ? abs(fract((p_value - p_length) / (p_length * 2.0f)) * p_length * 2.0f - p_length) : 0.0f; -} + double to_diff = fmod(p_to - from_rot, Math_TAU); + double to_rot = from_rot + fmod(2.0 * to_diff, Math_TAU) - to_diff; -// double only, as these functions are mainly used by the editor and not performance-critical, -double ease(double p_x, double p_c); -int step_decimals(double p_step); -int range_step_decimals(double p_step); // For editor use only. -double snapped(double p_value, double p_step); + double post_diff = fmod(p_post - to_rot, Math_TAU); + double post_rot = to_rot + fmod(2.0 * post_diff, Math_TAU) - post_diff; -uint32_t larger_prime(uint32_t p_val); + return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); + } -void seed(uint64_t p_seed); -void randomize(); -uint32_t rand_from_seed(uint64_t *p_seed); -uint32_t rand(); -_ALWAYS_INLINE_ double randd() { - return (double)rand() / (double)UINT32_MAX; -} -_ALWAYS_INLINE_ float randf() { - return (float)rand() / (float)UINT32_MAX; -} -double randfn(double p_mean, double p_deviation); + static _ALWAYS_INLINE_ float cubic_interpolate_angle(float p_from, float p_to, float p_pre, float p_post, float p_weight) { + float from_rot = fmod(p_from, (float)Math_TAU); -double random(double p_from, double p_to); -float random(float p_from, float p_to); -int random(int p_from, int p_to); + float pre_diff = fmod(p_pre - from_rot, (float)Math_TAU); + float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)Math_TAU) - pre_diff; -// This function should be as fast as possible and rounding mode should not matter. -_ALWAYS_INLINE_ int fast_ftoi(float p_value) { - // Assuming every supported compiler has `lrint()`. - return lrintf(p_value); -} + float to_diff = fmod(p_to - from_rot, (float)Math_TAU); + float to_rot = from_rot + fmod(2.0f * to_diff, (float)Math_TAU) - to_diff; -_ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t p_half) { - uint16_t h_exp, h_sig; - uint32_t f_sgn, f_exp, f_sig; + float post_diff = fmod(p_post - to_rot, (float)Math_TAU); + float post_rot = to_rot + fmod(2.0f * post_diff, (float)Math_TAU) - post_diff; - h_exp = (p_half & 0x7c00u); - f_sgn = ((uint32_t)p_half & 0x8000u) << 16; - switch (h_exp) { - case 0x0000u: /* 0 or subnormal */ - h_sig = (p_half & 0x03ffu); - /* Signed zero */ - if (h_sig == 0) { - return f_sgn; + return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); + } + + static _ALWAYS_INLINE_ double cubic_interpolate_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, + double p_to_t, double p_pre_t, double p_post_t) { + /* Barry-Goldman method */ + double t = Math::lerp(0.0, p_to_t, p_weight); + double a1 = Math::lerp(p_pre, p_from, p_pre_t == 0 ? 0.0 : (t - p_pre_t) / -p_pre_t); + double a2 = Math::lerp(p_from, p_to, p_to_t == 0 ? 0.5 : t / p_to_t); + double a3 = Math::lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0 : (t - p_to_t) / (p_post_t - p_to_t)); + double b1 = Math::lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0 : (t - p_pre_t) / (p_to_t - p_pre_t)); + double b2 = Math::lerp(a2, a3, p_post_t == 0 ? 1.0 : t / p_post_t); + return Math::lerp(b1, b2, p_to_t == 0 ? 0.5 : t / p_to_t); + } + + static _ALWAYS_INLINE_ float cubic_interpolate_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, + float p_to_t, float p_pre_t, float p_post_t) { + /* Barry-Goldman method */ + float t = Math::lerp(0.0f, p_to_t, p_weight); + float a1 = Math::lerp(p_pre, p_from, p_pre_t == 0 ? 0.0f : (t - p_pre_t) / -p_pre_t); + float a2 = Math::lerp(p_from, p_to, p_to_t == 0 ? 0.5f : t / p_to_t); + float a3 = Math::lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0f : (t - p_to_t) / (p_post_t - p_to_t)); + float b1 = Math::lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0f : (t - p_pre_t) / (p_to_t - p_pre_t)); + float b2 = Math::lerp(a2, a3, p_post_t == 0 ? 1.0f : t / p_post_t); + return Math::lerp(b1, b2, p_to_t == 0 ? 0.5f : t / p_to_t); + } + + static _ALWAYS_INLINE_ double cubic_interpolate_angle_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, + double p_to_t, double p_pre_t, double p_post_t) { + double from_rot = fmod(p_from, Math_TAU); + + double pre_diff = fmod(p_pre - from_rot, Math_TAU); + double pre_rot = from_rot + fmod(2.0 * pre_diff, Math_TAU) - pre_diff; + + double to_diff = fmod(p_to - from_rot, Math_TAU); + double to_rot = from_rot + fmod(2.0 * to_diff, Math_TAU) - to_diff; + + double post_diff = fmod(p_post - to_rot, Math_TAU); + double post_rot = to_rot + fmod(2.0 * post_diff, Math_TAU) - post_diff; + + return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); + } + + static _ALWAYS_INLINE_ float cubic_interpolate_angle_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, + float p_to_t, float p_pre_t, float p_post_t) { + float from_rot = fmod(p_from, (float)Math_TAU); + + float pre_diff = fmod(p_pre - from_rot, (float)Math_TAU); + float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)Math_TAU) - pre_diff; + + float to_diff = fmod(p_to - from_rot, (float)Math_TAU); + float to_rot = from_rot + fmod(2.0f * to_diff, (float)Math_TAU) - to_diff; + + float post_diff = fmod(p_post - to_rot, (float)Math_TAU); + float post_rot = to_rot + fmod(2.0f * post_diff, (float)Math_TAU) - post_diff; + + return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); + } + + static _ALWAYS_INLINE_ double bezier_interpolate(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + double omt = (1.0 - p_t); + double omt2 = omt * omt; + double omt3 = omt2 * omt; + double t2 = p_t * p_t; + double t3 = t2 * p_t; + + return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; + } + + static _ALWAYS_INLINE_ float bezier_interpolate(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + float omt = (1.0f - p_t); + float omt2 = omt * omt; + float omt3 = omt2 * omt; + float t2 = p_t * p_t; + float t3 = t2 * p_t; + + return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0f + p_control_2 * omt * t2 * 3.0f + p_end * t3; + } + + static _ALWAYS_INLINE_ double bezier_derivative(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + double omt = (1.0 - p_t); + double omt2 = omt * omt; + double t2 = p_t * p_t; + + double d = (p_control_1 - p_start) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2; + return d; + } + + static _ALWAYS_INLINE_ float bezier_derivative(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + float omt = (1.0f - p_t); + float omt2 = omt * omt; + float t2 = p_t * p_t; + + float d = (p_control_1 - p_start) * 3.0f * omt2 + (p_control_2 - p_control_1) * 6.0f * omt * p_t + (p_end - p_control_2) * 3.0f * t2; + return d; + } + + static _ALWAYS_INLINE_ double angle_difference(double p_from, double p_to) { + double difference = fmod(p_to - p_from, Math_TAU); + return fmod(2.0 * difference, Math_TAU) - difference; + } + static _ALWAYS_INLINE_ float angle_difference(float p_from, float p_to) { + float difference = fmod(p_to - p_from, (float)Math_TAU); + return fmod(2.0f * difference, (float)Math_TAU) - difference; + } + + static _ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) { + return p_from + Math::angle_difference(p_from, p_to) * p_weight; + } + static _ALWAYS_INLINE_ float lerp_angle(float p_from, float p_to, float p_weight) { + return p_from + Math::angle_difference(p_from, p_to) * p_weight; + } + + static _ALWAYS_INLINE_ double inverse_lerp(double p_from, double p_to, double p_value) { + return (p_value - p_from) / (p_to - p_from); + } + static _ALWAYS_INLINE_ float inverse_lerp(float p_from, float p_to, float p_value) { + return (p_value - p_from) / (p_to - p_from); + } + + static _ALWAYS_INLINE_ double remap(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { + return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); + } + static _ALWAYS_INLINE_ float remap(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { + return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); + } + + static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) { + if (is_equal_approx(p_from, p_to)) { + if (likely(p_from <= p_to)) { + return p_s <= p_from ? 0.0 : 1.0; + } else { + return p_s <= p_to ? 1.0 : 0.0; } - /* Subnormal */ - h_sig <<= 1; - while ((h_sig & 0x0400u) == 0) { + } + double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0); + return s * s * (3.0 - 2.0 * s); + } + static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) { + if (is_equal_approx(p_from, p_to)) { + if (likely(p_from <= p_to)) { + return p_s <= p_from ? 0.0f : 1.0f; + } else { + return p_s <= p_to ? 1.0f : 0.0f; + } + } + float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); + return s * s * (3.0f - 2.0f * s); + } + + static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { + return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; + } + static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { + return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; + } + + static _ALWAYS_INLINE_ double rotate_toward(double p_from, double p_to, double p_delta) { + double difference = Math::angle_difference(p_from, p_to); + double abs_difference = Math::abs(difference); + // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). + return p_from + CLAMP(p_delta, abs_difference - Math_PI, abs_difference) * (difference >= 0.0 ? 1.0 : -1.0); + } + static _ALWAYS_INLINE_ float rotate_toward(float p_from, float p_to, float p_delta) { + float difference = Math::angle_difference(p_from, p_to); + float abs_difference = Math::abs(difference); + // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). + return p_from + CLAMP(p_delta, abs_difference - (float)Math_PI, abs_difference) * (difference >= 0.0f ? 1.0f : -1.0f); + } + + static _ALWAYS_INLINE_ double linear_to_db(double p_linear) { + return Math::log(p_linear) * 8.6858896380650365530225783783321; + } + static _ALWAYS_INLINE_ float linear_to_db(float p_linear) { + return Math::log(p_linear) * (float)8.6858896380650365530225783783321; + } + + static _ALWAYS_INLINE_ double db_to_linear(double p_db) { + return Math::exp(p_db * 0.11512925464970228420089957273422); + } + static _ALWAYS_INLINE_ float db_to_linear(float p_db) { + return Math::exp(p_db * (float)0.11512925464970228420089957273422); + } + + static _ALWAYS_INLINE_ double round(double p_val) { return ::round(p_val); } + static _ALWAYS_INLINE_ float round(float p_val) { return ::roundf(p_val); } + + static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) { + int64_t range = max - min; + return range == 0 ? min : min + ((((value - min) % range) + range) % range); + } + static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) { + double range = max - min; + if (is_zero_approx(range)) { + return min; + } + double result = value - (range * Math::floor((value - min) / range)); + if (is_equal_approx(result, max)) { + return min; + } + return result; + } + static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) { + float range = max - min; + if (is_zero_approx(range)) { + return min; + } + float result = value - (range * Math::floor((value - min) / range)); + if (is_equal_approx(result, max)) { + return min; + } + return result; + } + + static _ALWAYS_INLINE_ float fract(float value) { + return value - floor(value); + } + static _ALWAYS_INLINE_ double fract(double value) { + return value - floor(value); + } + static _ALWAYS_INLINE_ float pingpong(float value, float length) { + return (length != 0.0f) ? abs(fract((value - length) / (length * 2.0f)) * length * 2.0f - length) : 0.0f; + } + static _ALWAYS_INLINE_ double pingpong(double value, double length) { + return (length != 0.0) ? abs(fract((value - length) / (length * 2.0)) * length * 2.0 - length) : 0.0; + } + + // double only, as these functions are mainly used by the editor and not performance-critical, + static double ease(double p_x, double p_c); + static int step_decimals(double p_step); + static int range_step_decimals(double p_step); // For editor use only. + static double snapped(double p_value, double p_step); + + static uint32_t larger_prime(uint32_t p_val); + + static void seed(uint64_t x); + static void randomize(); + static uint32_t rand_from_seed(uint64_t *seed); + static uint32_t rand(); + static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; } + static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; } + static double randfn(double mean, double deviation); + + static double random(double from, double to); + static float random(float from, float to); + static int random(int from, int to); + + static _ALWAYS_INLINE_ bool is_equal_approx(float a, float b) { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) { + return true; + } + // Then check for approximate equality. + float tolerance = (float)CMP_EPSILON * abs(a); + if (tolerance < (float)CMP_EPSILON) { + tolerance = (float)CMP_EPSILON; + } + return abs(a - b) < tolerance; + } + + static _ALWAYS_INLINE_ bool is_equal_approx(float a, float b, float tolerance) { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) { + return true; + } + // Then check for approximate equality. + return abs(a - b) < tolerance; + } + + static _ALWAYS_INLINE_ bool is_zero_approx(float s) { + return abs(s) < (float)CMP_EPSILON; + } + + static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b) { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) { + return true; + } + // Then check for approximate equality. + double tolerance = CMP_EPSILON * abs(a); + if (tolerance < CMP_EPSILON) { + tolerance = CMP_EPSILON; + } + return abs(a - b) < tolerance; + } + + static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b, double tolerance) { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) { + return true; + } + // Then check for approximate equality. + return abs(a - b) < tolerance; + } + + static _ALWAYS_INLINE_ bool is_zero_approx(double s) { + return abs(s) < CMP_EPSILON; + } + + static _ALWAYS_INLINE_ float absf(float g) { + union { + float f; + uint32_t i; + } u; + + u.f = g; + u.i &= 2147483647u; + return u.f; + } + + static _ALWAYS_INLINE_ double absd(double g) { + union { + double d; + uint64_t i; + } u; + u.d = g; + u.i &= (uint64_t)9223372036854775807ll; + return u.d; + } + + // This function should be as fast as possible and rounding mode should not matter. + static _ALWAYS_INLINE_ int fast_ftoi(float a) { + // Assuming every supported compiler has `lrint()`. + return lrintf(a); + } + + static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) { + uint16_t h_exp, h_sig; + uint32_t f_sgn, f_exp, f_sig; + + h_exp = (h & 0x7c00u); + f_sgn = ((uint32_t)h & 0x8000u) << 16; + switch (h_exp) { + case 0x0000u: /* 0 or subnormal */ + h_sig = (h & 0x03ffu); + /* Signed zero */ + if (h_sig == 0) { + return f_sgn; + } + /* Subnormal */ h_sig <<= 1; - h_exp++; + while ((h_sig & 0x0400u) == 0) { + h_sig <<= 1; + h_exp++; + } + f_exp = ((uint32_t)(127 - 15 - h_exp)) << 23; + f_sig = ((uint32_t)(h_sig & 0x03ffu)) << 13; + return f_sgn + f_exp + f_sig; + case 0x7c00u: /* inf or NaN */ + /* All-ones exponent and a copy of the significand */ + return f_sgn + 0x7f800000u + (((uint32_t)(h & 0x03ffu)) << 13); + default: /* normalized */ + /* Just need to adjust the exponent and shift */ + return f_sgn + (((uint32_t)(h & 0x7fffu) + 0x1c000u) << 13); + } + } + + static _ALWAYS_INLINE_ float halfptr_to_float(const uint16_t *h) { + union { + uint32_t u32; + float f32; + } u; + + u.u32 = halfbits_to_floatbits(*h); + return u.f32; + } + + static _ALWAYS_INLINE_ float half_to_float(const uint16_t h) { + return halfptr_to_float(&h); + } + + static _ALWAYS_INLINE_ uint16_t make_half_float(float f) { + union { + float fv; + uint32_t ui; + } ci; + ci.fv = f; + + uint32_t x = ci.ui; + uint32_t sign = (unsigned short)(x >> 31); + uint32_t mantissa; + uint32_t exponent; + uint16_t hf; + + // get mantissa + mantissa = x & ((1 << 23) - 1); + // get exponent bits + exponent = x & (0xFF << 23); + if (exponent >= 0x47800000) { + // check if the original single precision float number is a NaN + if (mantissa && (exponent == (0xFF << 23))) { + // we have a single precision NaN + mantissa = (1 << 23) - 1; + } else { + // 16-bit half-float representation stores number as Inf + mantissa = 0; } - f_exp = ((uint32_t)(127 - 15 - h_exp)) << 23; - f_sig = ((uint32_t)(h_sig & 0x03ffu)) << 13; - return f_sgn + f_exp + f_sig; - case 0x7c00u: /* inf or NaN */ - /* All-ones exponent and a copy of the significand */ - return f_sgn + 0x7f800000u + (((uint32_t)(p_half & 0x03ffu)) << 13); - default: /* normalized */ - /* Just need to adjust the exponent and shift */ - return f_sgn + (((uint32_t)(p_half & 0x7fffu) + 0x1c000u) << 13); - } -} - -_ALWAYS_INLINE_ float halfptr_to_float(const uint16_t *p_half) { - union { - uint32_t u32; - float f32; - } u; - - u.u32 = halfbits_to_floatbits(*p_half); - return u.f32; -} - -_ALWAYS_INLINE_ float half_to_float(const uint16_t p_half) { - return halfptr_to_float(&p_half); -} - -_ALWAYS_INLINE_ uint16_t make_half_float(float p_value) { - union { - float fv; - uint32_t ui; - } ci; - ci.fv = p_value; - - uint32_t x = ci.ui; - uint32_t sign = (unsigned short)(x >> 31); - uint32_t mantissa; - uint32_t exponent; - uint16_t hf; - - // get mantissa - mantissa = x & ((1 << 23) - 1); - // get exponent bits - exponent = x & (0xFF << 23); - if (exponent >= 0x47800000) { - // check if the original single precision float number is a NaN - if (mantissa && (exponent == (0xFF << 23))) { - // we have a single precision NaN - mantissa = (1 << 23) - 1; - } else { - // 16-bit half-float representation stores number as Inf - mantissa = 0; + hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) | + (uint16_t)(mantissa >> 13); } - hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) | - (uint16_t)(mantissa >> 13); - } - // check if exponent is <= -15 - else if (exponent <= 0x38000000) { - /* - // store a denorm half-float value or zero - exponent = (0x38000000 - exponent) >> 23; - mantissa >>= (14 + exponent); + // check if exponent is <= -15 + else if (exponent <= 0x38000000) { + /* + // store a denorm half-float value or zero + exponent = (0x38000000 - exponent) >> 23; + mantissa >>= (14 + exponent); - hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa); - */ - hf = 0; //denormals do not work for 3D, convert to zero - } else { - hf = (((uint16_t)sign) << 15) | - (uint16_t)((exponent - 0x38000000) >> 13) | - (uint16_t)(mantissa >> 13); - } - - return hf; -} - -_ALWAYS_INLINE_ float snap_scalar(float p_offset, float p_step, float p_target) { - return p_step != 0 ? snapped(p_target - p_offset, p_step) + p_offset : p_target; -} - -_ALWAYS_INLINE_ float snap_scalar_separation(float p_offset, float p_step, float p_target, float p_separation) { - if (p_step != 0) { - float a = snapped(p_target - p_offset, p_step + p_separation) + p_offset; - float b = a; - if (p_target >= 0) { - b -= p_separation; + hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa); + */ + hf = 0; //denormals do not work for 3D, convert to zero } else { - b += p_step; + hf = (((uint16_t)sign) << 15) | + (uint16_t)((exponent - 0x38000000) >> 13) | + (uint16_t)(mantissa >> 13); } - return (abs(p_target - a) < abs(p_target - b)) ? a : b; - } - return p_target; -} -}; // namespace Math + return hf; + } + + static _ALWAYS_INLINE_ float snap_scalar(float p_offset, float p_step, float p_target) { + return p_step != 0 ? Math::snapped(p_target - p_offset, p_step) + p_offset : p_target; + } + + static _ALWAYS_INLINE_ float snap_scalar_separation(float p_offset, float p_step, float p_target, float p_separation) { + if (p_step != 0) { + float a = Math::snapped(p_target - p_offset, p_step + p_separation) + p_offset; + float b = a; + if (p_target >= 0) { + b -= p_separation; + } else { + b += p_step; + } + return (Math::abs(p_target - a) < Math::abs(p_target - b)) ? a : b; + } + return p_target; + } +}; + +#endif // MATH_FUNCS_H diff --git a/engine/core/math/plane.cpp b/engine/core/math/plane.cpp index 74783b2a..6b9bcea0 100644 --- a/engine/core/math/plane.cpp +++ b/engine/core/math/plane.cpp @@ -58,7 +58,7 @@ Vector3 Plane::get_any_perpendicular_normal() const { static const Vector3 p2 = Vector3(0, 1, 0); Vector3 p; - if (Math::abs(normal.dot(p1)) > 0.99f) { // if too similar to p1 + if (ABS(normal.dot(p1)) > 0.99f) { // if too similar to p1 p = p2; // use p2 } else { p = p1; // use p1 @@ -172,10 +172,6 @@ bool Plane::is_equal_approx(const Plane &p_plane) const { return normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d); } -bool Plane::is_same(const Plane &p_plane) const { - return normal.is_same(p_plane.normal) && Math::is_same(d, p_plane.d); -} - bool Plane::is_finite() const { return normal.is_finite() && Math::is_finite(d); } diff --git a/engine/core/math/plane.h b/engine/core/math/plane.h index 77a53e57..65783ff4 100644 --- a/engine/core/math/plane.h +++ b/engine/core/math/plane.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PLANE_H +#define PLANE_H #include "core/math/vector3.h" @@ -70,22 +71,21 @@ struct [[nodiscard]] Plane { /* misc */ - constexpr Plane operator-() const { return Plane(-normal, -d); } + Plane operator-() const { return Plane(-normal, -d); } bool is_equal_approx(const Plane &p_plane) const; - bool is_same(const Plane &p_plane) const; bool is_equal_approx_any_side(const Plane &p_plane) const; bool is_finite() const; - constexpr bool operator==(const Plane &p_plane) const; - constexpr bool operator!=(const Plane &p_plane) const; + _FORCE_INLINE_ bool operator==(const Plane &p_plane) const; + _FORCE_INLINE_ bool operator!=(const Plane &p_plane) const; operator String() const; - Plane() = default; - constexpr Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) : + _FORCE_INLINE_ Plane() {} + _FORCE_INLINE_ Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) : normal(p_a, p_b, p_c), d(p_d) {} - constexpr Plane(const Vector3 &p_normal, real_t p_d = 0.0); + _FORCE_INLINE_ Plane(const Vector3 &p_normal, real_t p_d = 0.0); _FORCE_INLINE_ Plane(const Vector3 &p_normal, const Vector3 &p_point); _FORCE_INLINE_ Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir = CLOCKWISE); }; @@ -100,11 +100,11 @@ real_t Plane::distance_to(const Vector3 &p_point) const { bool Plane::has_point(const Vector3 &p_point, real_t p_tolerance) const { real_t dist = normal.dot(p_point) - d; - dist = Math::abs(dist); + dist = ABS(dist); return (dist <= p_tolerance); } -constexpr Plane::Plane(const Vector3 &p_normal, real_t p_d) : +Plane::Plane(const Vector3 &p_normal, real_t p_d) : normal(p_normal), d(p_d) { } @@ -125,13 +125,12 @@ Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_ d = normal.dot(p_point1); } -constexpr bool Plane::operator==(const Plane &p_plane) const { +bool Plane::operator==(const Plane &p_plane) const { return normal == p_plane.normal && d == p_plane.d; } -constexpr bool Plane::operator!=(const Plane &p_plane) const { +bool Plane::operator!=(const Plane &p_plane) const { return normal != p_plane.normal || d != p_plane.d; } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // PLANE_H diff --git a/engine/core/math/projection.cpp b/engine/core/math/projection.cpp index a71e44d9..20638826 100644 --- a/engine/core/math/projection.cpp +++ b/engine/core/math/projection.cpp @@ -402,35 +402,82 @@ void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, r } real_t Projection::get_z_far() const { - // NOTE: This assumes z-facing near and far planes, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0) - return (columns[3][3] - columns[3][2]) / (columns[2][3] - columns[2][2]); + const real_t *matrix = (const real_t *)columns; + Plane new_plane = Plane(matrix[3] - matrix[2], + matrix[7] - matrix[6], + matrix[11] - matrix[10], + matrix[15] - matrix[14]); + + new_plane.normalize(); + + return new_plane.d; } real_t Projection::get_z_near() const { - // NOTE: This assumes z-facing near and far planes, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0) - return (columns[3][3] + columns[3][2]) / (columns[2][3] + columns[2][2]); + const real_t *matrix = (const real_t *)columns; + Plane new_plane = Plane(matrix[3] + matrix[2], + matrix[7] + matrix[6], + matrix[11] + matrix[10], + -matrix[15] - matrix[14]); + + new_plane.normalize(); + return new_plane.d; } Vector2 Projection::get_viewport_half_extents() const { - // NOTE: This assumes a symmetrical frustum, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) - // - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0) - real_t w = -get_z_near() * columns[2][3] + columns[3][3]; - return Vector2(w / columns[0][0], w / columns[1][1]); + const real_t *matrix = (const real_t *)columns; + ///////--- Near Plane ---/////// + Plane near_plane = Plane(matrix[3] + matrix[2], + matrix[7] + matrix[6], + matrix[11] + matrix[10], + -matrix[15] - matrix[14]); + near_plane.normalize(); + + ///////--- Right Plane ---/////// + Plane right_plane = Plane(matrix[3] - matrix[0], + matrix[7] - matrix[4], + matrix[11] - matrix[8], + -matrix[15] + matrix[12]); + right_plane.normalize(); + + Plane top_plane = Plane(matrix[3] - matrix[1], + matrix[7] - matrix[5], + matrix[11] - matrix[9], + -matrix[15] + matrix[13]); + top_plane.normalize(); + + Vector3 res; + near_plane.intersect_3(right_plane, top_plane, &res); + + return Vector2(res.x, res.y); } Vector2 Projection::get_far_plane_half_extents() const { - // NOTE: This assumes a symmetrical frustum, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) - // - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0) - real_t w = -get_z_far() * columns[2][3] + columns[3][3]; - return Vector2(w / columns[0][0], w / columns[1][1]); + const real_t *matrix = (const real_t *)columns; + ///////--- Far Plane ---/////// + Plane far_plane = Plane(matrix[3] - matrix[2], + matrix[7] - matrix[6], + matrix[11] - matrix[10], + -matrix[15] + matrix[14]); + far_plane.normalize(); + + ///////--- Right Plane ---/////// + Plane right_plane = Plane(matrix[3] - matrix[0], + matrix[7] - matrix[4], + matrix[11] - matrix[8], + -matrix[15] + matrix[12]); + right_plane.normalize(); + + Plane top_plane = Plane(matrix[3] - matrix[1], + matrix[7] - matrix[5], + matrix[11] - matrix[9], + -matrix[15] + matrix[13]); + top_plane.normalize(); + + Vector3 res; + far_plane.intersect_3(right_plane, top_plane, &res); + + return Vector2(res.x, res.y); } bool Projection::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const { @@ -780,8 +827,24 @@ void Projection::flip_y() { } } -bool Projection::is_same(const Projection &p_cam) const { - return columns[0].is_same(p_cam.columns[0]) && columns[1].is_same(p_cam.columns[1]) && columns[2].is_same(p_cam.columns[2]) && columns[3].is_same(p_cam.columns[3]); +Projection::Projection() { + set_identity(); +} + +Projection Projection::operator*(const Projection &p_matrix) const { + Projection new_matrix; + + for (int j = 0; j < 4; j++) { + for (int i = 0; i < 4; i++) { + real_t ab = 0; + for (int k = 0; k < 4; k++) { + ab += columns[k][i] * p_matrix.columns[j][k]; + } + new_matrix.columns[j][i] = ab; + } + } + + return new_matrix; } void Projection::set_depth_correction(bool p_flip_y, bool p_reverse_z, bool p_remap_z) { @@ -856,45 +919,53 @@ Projection::operator String() const { } real_t Projection::get_aspect() const { - // NOTE: This assumes a rectangular projection plane, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) - return columns[1][1] / columns[0][0]; + Vector2 vp_he = get_viewport_half_extents(); + return vp_he.x / vp_he.y; } int Projection::get_pixels_per_meter(int p_for_pixel_width) const { - // NOTE: This assumes a rectangular projection plane, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) - real_t width = 2 * (-get_z_near() * columns[2][3] + columns[3][3]) / columns[0][0]; - return p_for_pixel_width / width; // Note : return type should be real_t (kept as int for compatibility for now). + Vector3 result = xform(Vector3(1, 0, -1)); + + return int((result.x * 0.5 + 0.5) * p_for_pixel_width); } bool Projection::is_orthogonal() const { - // NOTE: This assumes that the matrix is a projection across z-axis - // i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0 - return columns[2][3] == 0.0; + return columns[3][3] == 1.0; } real_t Projection::get_fov() const { - // NOTE: This assumes a rectangular projection plane, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) - if (columns[2][0] == 0) { - return Math::rad_to_deg(2 * Math::atan2(1, columns[0][0])); + const real_t *matrix = (const real_t *)columns; + + Plane right_plane = Plane(matrix[3] - matrix[0], + matrix[7] - matrix[4], + matrix[11] - matrix[8], + -matrix[15] + matrix[12]); + right_plane.normalize(); + + if ((matrix[8] == 0) && (matrix[9] == 0)) { + return Math::rad_to_deg(Math::acos(Math::abs(right_plane.normal.x))) * 2.0; } else { - // The frustum is asymmetrical so we need to calculate the left and right angles separately. - real_t right = Math::atan2(columns[2][0] + 1, columns[0][0]); - real_t left = Math::atan2(columns[2][0] - 1, columns[0][0]); - return Math::rad_to_deg(right - left); + // our frustum is asymmetrical need to calculate the left planes angle separately.. + Plane left_plane = Plane(matrix[3] + matrix[0], + matrix[7] + matrix[4], + matrix[11] + matrix[8], + matrix[15] + matrix[12]); + left_plane.normalize(); + + return Math::rad_to_deg(Math::acos(Math::abs(left_plane.normal.x))) + Math::rad_to_deg(Math::acos(Math::abs(right_plane.normal.x))); } } real_t Projection::get_lod_multiplier() const { - // NOTE: This assumes a rectangular projection plane, i.e. that : - // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) - // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) - return 2 / columns[0][0]; + if (is_orthogonal()) { + return get_viewport_half_extents().x; + } else { + const real_t zn = get_z_near(); + const real_t width = get_viewport_half_extents().x * 2.0f; + return 1.0f / (zn / width); + } + + // Usage is lod_size / (lod_distance * multiplier) < threshold } void Projection::make_scale(const Vector3 &p_scale) { @@ -957,6 +1028,13 @@ Projection::operator Transform3D() const { return tr; } +Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) { + columns[0] = p_x; + columns[1] = p_y; + columns[2] = p_z; + columns[3] = p_w; +} + Projection::Projection(const Transform3D &p_transform) { const Transform3D &tr = p_transform; real_t *m = &columns[0][0]; @@ -978,3 +1056,6 @@ Projection::Projection(const Transform3D &p_transform) { m[14] = tr.origin.z; m[15] = 1.0; } + +Projection::~Projection() { +} diff --git a/engine/core/math/projection.h b/engine/core/math/projection.h index 6d5f585c..5af43561 100644 --- a/engine/core/math/projection.h +++ b/engine/core/math/projection.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef PROJECTION_H +#define PROJECTION_H #include "core/math/vector3.h" #include "core/math/vector4.h" @@ -52,19 +53,14 @@ struct [[nodiscard]] Projection { PLANE_BOTTOM }; - Vector4 columns[4] = { - { 1, 0, 0, 0 }, - { 0, 1, 0, 0 }, - { 0, 0, 1, 0 }, - { 0, 0, 0, 1 }, - }; + Vector4 columns[4]; - constexpr const Vector4 &operator[](int p_axis) const { + _FORCE_INLINE_ const Vector4 &operator[](int p_axis) const { DEV_ASSERT((unsigned int)p_axis < 4); return columns[p_axis]; } - constexpr Vector4 &operator[](int p_axis) { + _FORCE_INLINE_ Vector4 &operator[](int p_axis) { DEV_ASSERT((unsigned int)p_axis < 4); return columns[p_axis]; } @@ -119,7 +115,7 @@ struct [[nodiscard]] Projection { void invert(); Projection inverse() const; - constexpr Projection operator*(const Projection &p_matrix) const; + Projection operator*(const Projection &p_matrix) const; Plane xform4(const Plane &p_vec4) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec3) const; @@ -137,9 +133,7 @@ struct [[nodiscard]] Projection { void flip_y(); - bool is_same(const Projection &p_cam) const; - - constexpr bool operator==(const Projection &p_cam) const { + bool operator==(const Projection &p_cam) const { for (uint32_t i = 0; i < 4; i++) { for (uint32_t j = 0; j < 4; j++) { if (columns[i][j] != p_cam.columns[i][j]) { @@ -150,41 +144,18 @@ struct [[nodiscard]] Projection { return true; } - constexpr bool operator!=(const Projection &p_cam) const { + bool operator!=(const Projection &p_cam) const { return !(*this == p_cam); } real_t get_lod_multiplier() const; - Projection() = default; - constexpr Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) : - columns{ p_x, p_y, p_z, p_w } {} - constexpr Projection(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_xw, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_yw, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_zw, real_t p_wx, real_t p_wy, real_t p_wz, real_t p_ww) : - columns{ - { p_xx, p_xy, p_xz, p_xw }, - { p_yx, p_yy, p_yz, p_yw }, - { p_zx, p_zy, p_zz, p_zw }, - { p_wx, p_wy, p_wz, p_ww }, - } {} + Projection(); + Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w); Projection(const Transform3D &p_transform); + ~Projection(); }; -constexpr Projection Projection::operator*(const Projection &p_matrix) const { - Projection new_matrix; - - for (int j = 0; j < 4; j++) { - for (int i = 0; i < 4; i++) { - real_t ab = 0; - for (int k = 0; k < 4; k++) { - ab += columns[k][i] * p_matrix.columns[j][k]; - } - new_matrix.columns[j][i] = ab; - } - } - - return new_matrix; -} - Vector3 Projection::xform(const Vector3 &p_vec3) const { Vector3 ret; ret.x = columns[0][0] * p_vec3.x + columns[1][0] * p_vec3.y + columns[2][0] * p_vec3.z + columns[3][0]; @@ -193,3 +164,5 @@ Vector3 Projection::xform(const Vector3 &p_vec3) const { real_t w = columns[0][3] * p_vec3.x + columns[1][3] * p_vec3.y + columns[2][3] * p_vec3.z + columns[3][3]; return ret / w; } + +#endif // PROJECTION_H diff --git a/engine/core/math/quaternion.cpp b/engine/core/math/quaternion.cpp index 6c0b491a..08eac14b 100644 --- a/engine/core/math/quaternion.cpp +++ b/engine/core/math/quaternion.cpp @@ -46,12 +46,24 @@ Vector3 Quaternion::get_euler(EulerOrder p_order) const { return Basis(*this).get_euler(p_order); } -bool Quaternion::is_equal_approx(const Quaternion &p_quaternion) const { - return Math::is_equal_approx(x, p_quaternion.x) && Math::is_equal_approx(y, p_quaternion.y) && Math::is_equal_approx(z, p_quaternion.z) && Math::is_equal_approx(w, p_quaternion.w); +void Quaternion::operator*=(const Quaternion &p_q) { + real_t xx = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y; + real_t yy = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z; + real_t zz = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x; + w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z; + x = xx; + y = yy; + z = zz; } -bool Quaternion::is_same(const Quaternion &p_quaternion) const { - return Math::is_same(x, p_quaternion.x) && Math::is_same(y, p_quaternion.y) && Math::is_same(z, p_quaternion.z) && Math::is_same(w, p_quaternion.w); +Quaternion Quaternion::operator*(const Quaternion &p_q) const { + Quaternion r = *this; + r *= p_q; + return r; +} + +bool Quaternion::is_equal_approx(const Quaternion &p_quaternion) const { + return Math::is_equal_approx(x, p_quaternion.x) && Math::is_equal_approx(y, p_quaternion.y) && Math::is_equal_approx(z, p_quaternion.z) && Math::is_equal_approx(w, p_quaternion.w); } bool Quaternion::is_finite() const { diff --git a/engine/core/math/quaternion.h b/engine/core/math/quaternion.h index 6dae7a79..58a4ec5b 100644 --- a/engine/core/math/quaternion.h +++ b/engine/core/math/quaternion.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef QUATERNION_H +#define QUATERNION_H #include "core/math/math_funcs.h" #include "core/math/vector3.h" @@ -36,7 +37,6 @@ struct [[nodiscard]] Quaternion { union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { real_t x; real_t y; @@ -44,7 +44,6 @@ struct [[nodiscard]] Quaternion { real_t w; }; real_t components[4] = { 0, 0, 0, 1.0 }; - // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ real_t &operator[](int p_idx) { @@ -55,7 +54,6 @@ struct [[nodiscard]] Quaternion { } _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Quaternion &p_quaternion) const; - bool is_same(const Quaternion &p_quaternion) const; bool is_finite() const; real_t length() const; void normalize(); @@ -86,8 +84,8 @@ struct [[nodiscard]] Quaternion { r_axis.z = z * r; } - constexpr void operator*=(const Quaternion &p_q); - constexpr Quaternion operator*(const Quaternion &p_q) const; + void operator*=(const Quaternion &p_q); + Quaternion operator*(const Quaternion &p_q) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_v) const { #ifdef MATH_CHECKS @@ -102,33 +100,40 @@ struct [[nodiscard]] Quaternion { return inverse().xform(p_v); } - constexpr void operator+=(const Quaternion &p_q); - constexpr void operator-=(const Quaternion &p_q); - constexpr void operator*=(real_t p_s); - constexpr void operator/=(real_t p_s); - constexpr Quaternion operator+(const Quaternion &p_q2) const; - constexpr Quaternion operator-(const Quaternion &p_q2) const; - constexpr Quaternion operator-() const; - constexpr Quaternion operator*(real_t p_s) const; - constexpr Quaternion operator/(real_t p_s) const; + _FORCE_INLINE_ void operator+=(const Quaternion &p_q); + _FORCE_INLINE_ void operator-=(const Quaternion &p_q); + _FORCE_INLINE_ void operator*=(real_t p_s); + _FORCE_INLINE_ void operator/=(real_t p_s); + _FORCE_INLINE_ Quaternion operator+(const Quaternion &p_q2) const; + _FORCE_INLINE_ Quaternion operator-(const Quaternion &p_q2) const; + _FORCE_INLINE_ Quaternion operator-() const; + _FORCE_INLINE_ Quaternion operator*(real_t p_s) const; + _FORCE_INLINE_ Quaternion operator/(real_t p_s) const; - constexpr bool operator==(const Quaternion &p_quaternion) const; - constexpr bool operator!=(const Quaternion &p_quaternion) const; + _FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const; + _FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const; operator String() const; - constexpr Quaternion() : - x(0), y(0), z(0), w(1) {} + _FORCE_INLINE_ Quaternion() {} - constexpr Quaternion(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : - x(p_x), y(p_y), z(p_z), w(p_w) {} + _FORCE_INLINE_ Quaternion(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : + x(p_x), + y(p_y), + z(p_z), + w(p_w) { + } Quaternion(const Vector3 &p_axis, real_t p_angle); - constexpr Quaternion(const Quaternion &p_q) : - x(p_q.x), y(p_q.y), z(p_q.z), w(p_q.w) {} + Quaternion(const Quaternion &p_q) : + x(p_q.x), + y(p_q.y), + z(p_q.z), + w(p_q.w) { + } - constexpr void operator=(const Quaternion &p_q) { + void operator=(const Quaternion &p_q) { x = p_q.x; y = p_q.y; z = p_q.z; @@ -173,78 +178,64 @@ real_t Quaternion::length_squared() const { return dot(*this); } -constexpr void Quaternion::operator+=(const Quaternion &p_q) { +void Quaternion::operator+=(const Quaternion &p_q) { x += p_q.x; y += p_q.y; z += p_q.z; w += p_q.w; } -constexpr void Quaternion::operator-=(const Quaternion &p_q) { +void Quaternion::operator-=(const Quaternion &p_q) { x -= p_q.x; y -= p_q.y; z -= p_q.z; w -= p_q.w; } -constexpr void Quaternion::operator*=(real_t p_s) { +void Quaternion::operator*=(real_t p_s) { x *= p_s; y *= p_s; z *= p_s; w *= p_s; } -constexpr void Quaternion::operator/=(real_t p_s) { - *this *= (1 / p_s); +void Quaternion::operator/=(real_t p_s) { + *this *= 1.0f / p_s; } -constexpr Quaternion Quaternion::operator+(const Quaternion &p_q2) const { +Quaternion Quaternion::operator+(const Quaternion &p_q2) const { const Quaternion &q1 = *this; return Quaternion(q1.x + p_q2.x, q1.y + p_q2.y, q1.z + p_q2.z, q1.w + p_q2.w); } -constexpr Quaternion Quaternion::operator-(const Quaternion &p_q2) const { +Quaternion Quaternion::operator-(const Quaternion &p_q2) const { const Quaternion &q1 = *this; return Quaternion(q1.x - p_q2.x, q1.y - p_q2.y, q1.z - p_q2.z, q1.w - p_q2.w); } -constexpr Quaternion Quaternion::operator-() const { +Quaternion Quaternion::operator-() const { const Quaternion &q2 = *this; return Quaternion(-q2.x, -q2.y, -q2.z, -q2.w); } -constexpr Quaternion Quaternion::operator*(real_t p_s) const { +Quaternion Quaternion::operator*(real_t p_s) const { return Quaternion(x * p_s, y * p_s, z * p_s, w * p_s); } -constexpr Quaternion Quaternion::operator/(real_t p_s) const { - return *this * (1 / p_s); +Quaternion Quaternion::operator/(real_t p_s) const { + return *this * (1.0f / p_s); } -constexpr bool Quaternion::operator==(const Quaternion &p_quaternion) const { +bool Quaternion::operator==(const Quaternion &p_quaternion) const { return x == p_quaternion.x && y == p_quaternion.y && z == p_quaternion.z && w == p_quaternion.w; } -constexpr bool Quaternion::operator!=(const Quaternion &p_quaternion) const { +bool Quaternion::operator!=(const Quaternion &p_quaternion) const { return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w; } -constexpr void Quaternion::operator*=(const Quaternion &p_q) { - real_t xx = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y; - real_t yy = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z; - real_t zz = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x; - w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z; - x = xx; - y = yy; - z = zz; -} - -constexpr Quaternion Quaternion::operator*(const Quaternion &p_q) const { - Quaternion r = *this; - r *= p_q; - return r; -} - -constexpr Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) { +_FORCE_INLINE_ Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) { return p_quaternion * p_real; } + +#endif // QUATERNION_H diff --git a/engine/core/math/quick_hull.cpp b/engine/core/math/quick_hull.cpp index 360b272e..34a0c021 100644 --- a/engine/core/math/quick_hull.cpp +++ b/engine/core/math/quick_hull.cpp @@ -30,9 +30,6 @@ #include "quick_hull.h" -#include "core/templates/hash_map.h" -#include "core/templates/hash_set.h" - uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF; Error QuickHull::build(const Vector &p_points, Geometry3D::MeshData &r_mesh) { @@ -323,7 +320,7 @@ Error QuickHull::build(const Vector &p_points, Geometry3D::MeshData &r_ for (List::Element *&E : new_faces) { Face &f2 = E->get(); - if (f2.points_over.is_empty()) { + if (f2.points_over.size() == 0) { faces.move_to_front(E); } } diff --git a/engine/core/math/quick_hull.h b/engine/core/math/quick_hull.h index e374211d..f4891a7c 100644 --- a/engine/core/math/quick_hull.h +++ b/engine/core/math/quick_hull.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef QUICK_HULL_H +#define QUICK_HULL_H #include "core/math/geometry_3d.h" #include "core/templates/list.h" @@ -88,3 +89,5 @@ public: static uint32_t debug_stop_after; static Error build(const Vector &p_points, Geometry3D::MeshData &r_mesh); }; + +#endif // QUICK_HULL_H diff --git a/engine/core/math/random_number_generator.h b/engine/core/math/random_number_generator.h index aa21b41a..7ec4cdff 100644 --- a/engine/core/math/random_number_generator.h +++ b/engine/core/math/random_number_generator.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RANDOM_NUMBER_GENERATOR_H +#define RANDOM_NUMBER_GENERATOR_H #include "core/math/random_pcg.h" #include "core/object/ref_counted.h" @@ -60,3 +61,5 @@ public: RandomNumberGenerator() { randbase.randomize(); } }; + +#endif // RANDOM_NUMBER_GENERATOR_H diff --git a/engine/core/math/random_pcg.h b/engine/core/math/random_pcg.h index f39cd7ab..6bad7005 100644 --- a/engine/core/math/random_pcg.h +++ b/engine/core/math/random_pcg.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RANDOM_PCG_H +#define RANDOM_PCG_H #include "core/math/math_defs.h" @@ -134,17 +135,19 @@ public: if (temp < CMP_EPSILON) { temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function. } - return p_mean + p_deviation * (cos(Math::TAU * randd()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. + return p_mean + p_deviation * (cos(Math_TAU * randd()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. } _FORCE_INLINE_ float randfn(float p_mean, float p_deviation) { float temp = randf(); if (temp < CMP_EPSILON) { temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function. } - return p_mean + p_deviation * (cos((float)Math::TAU * randf()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. + return p_mean + p_deviation * (cos((float)Math_TAU * randf()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. } double random(double p_from, double p_to); float random(float p_from, float p_to); int random(int p_from, int p_to); }; + +#endif // RANDOM_PCG_H diff --git a/engine/core/math/rect2.cpp b/engine/core/math/rect2.cpp index 102a9e4b..7f77b078 100644 --- a/engine/core/math/rect2.cpp +++ b/engine/core/math/rect2.cpp @@ -38,10 +38,6 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const { return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size); } -bool Rect2::is_same(const Rect2 &p_rect) const { - return position.is_same(p_rect.position) && size.is_same(p_rect.size); -} - bool Rect2::is_finite() const { return position.is_finite() && size.is_finite(); } diff --git a/engine/core/math/rect2.h b/engine/core/math/rect2.h index 27a701e9..817923c1 100644 --- a/engine/core/math/rect2.h +++ b/engine/core/math/rect2.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RECT2_H +#define RECT2_H #include "core/error/error_macros.h" #include "core/math/vector2.h" @@ -202,11 +203,10 @@ struct [[nodiscard]] Rect2 { } bool is_equal_approx(const Rect2 &p_rect) const; - bool is_same(const Rect2 &p_rect) const; bool is_finite() const; - constexpr bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } - constexpr bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } + bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } + bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } inline Rect2 grow(real_t p_amount) const { Rect2 g = *this; @@ -361,16 +361,15 @@ struct [[nodiscard]] Rect2 { operator String() const; operator Rect2i() const; - Rect2() = default; - constexpr Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) : + Rect2() {} + Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) : position(Point2(p_x, p_y)), size(Size2(p_width, p_height)) { } - constexpr Rect2(const Point2 &p_pos, const Size2 &p_size) : + Rect2(const Point2 &p_pos, const Size2 &p_size) : position(p_pos), size(p_size) { } }; -template <> -struct is_zero_constructible : std::true_type {}; +#endif // RECT2_H diff --git a/engine/core/math/rect2i.h b/engine/core/math/rect2i.h index d0b8b5e7..5f3a3d54 100644 --- a/engine/core/math/rect2i.h +++ b/engine/core/math/rect2i.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef RECT2I_H +#define RECT2I_H #include "core/error/error_macros.h" #include "core/math/vector2i.h" @@ -143,8 +144,8 @@ struct [[nodiscard]] Rect2i { return true; } - constexpr bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } - constexpr bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } + bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } + bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } Rect2i grow(int p_amount) const { Rect2i g = *this; @@ -226,16 +227,15 @@ struct [[nodiscard]] Rect2i { operator String() const; operator Rect2() const; - Rect2i() = default; - constexpr Rect2i(int p_x, int p_y, int p_width, int p_height) : + Rect2i() {} + Rect2i(int p_x, int p_y, int p_width, int p_height) : position(Point2i(p_x, p_y)), size(Size2i(p_width, p_height)) { } - constexpr Rect2i(const Point2i &p_pos, const Size2i &p_size) : + Rect2i(const Point2i &p_pos, const Size2i &p_size) : position(p_pos), size(p_size) { } }; -template <> -struct is_zero_constructible : std::true_type {}; +#endif // RECT2I_H diff --git a/engine/core/math/static_raycaster.h b/engine/core/math/static_raycaster.h index fbb5194c..74e4b751 100644 --- a/engine/core/math/static_raycaster.h +++ b/engine/core/math/static_raycaster.h @@ -28,10 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef STATIC_RAYCASTER_H +#define STATIC_RAYCASTER_H #include "core/object/ref_counted.h" +#if !defined(__aligned) + +#if defined(_WIN32) && defined(_MSC_VER) +#define __aligned(...) __declspec(align(__VA_ARGS__)) +#else +#define __aligned(...) __attribute__((aligned(__VA_ARGS__))) +#endif + +#endif + class StaticRaycaster : public RefCounted { GDCLASS(StaticRaycaster, RefCounted) protected: @@ -39,7 +50,7 @@ protected: public: // Compatible with embree4 rays. - struct alignas(16) Ray { + struct __aligned(16) Ray { const static unsigned int INVALID_GEOMETRY_ID = ((unsigned int)-1); // from rtcore_common.h /*! Default construction does nothing. */ @@ -51,7 +62,7 @@ public: _FORCE_INLINE_ Ray(const Vector3 &p_org, const Vector3 &p_dir, float p_tnear = 0.0f, - float p_tfar = Math::INF) : + float p_tfar = INFINITY) : org(p_org), tnear(p_tnear), dir(p_dir), @@ -96,3 +107,5 @@ public: static Ref create(); }; + +#endif // STATIC_RAYCASTER_H diff --git a/engine/core/math/transform_2d.cpp b/engine/core/math/transform_2d.cpp index b5a971e7..f6525fe5 100644 --- a/engine/core/math/transform_2d.cpp +++ b/engine/core/math/transform_2d.cpp @@ -71,12 +71,12 @@ void Transform2D::rotate(real_t p_angle) { real_t Transform2D::get_skew() const { real_t det = determinant(); - return Math::acos(columns[0].normalized().dot(SIGN(det) * columns[1].normalized())) - (real_t)Math::PI * 0.5f; + return Math::acos(columns[0].normalized().dot(SIGN(det) * columns[1].normalized())) - (real_t)Math_PI * 0.5f; } void Transform2D::set_skew(real_t p_angle) { real_t det = determinant(); - columns[1] = SIGN(det) * columns[0].rotated(((real_t)Math::PI * 0.5f + p_angle)).normalized() * columns[1].length(); + columns[1] = SIGN(det) * columns[0].rotated(((real_t)Math_PI * 0.5f + p_angle)).normalized() * columns[1].length(); } real_t Transform2D::get_rotation() const { @@ -180,10 +180,6 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const { return columns[0].is_equal_approx(p_transform.columns[0]) && columns[1].is_equal_approx(p_transform.columns[1]) && columns[2].is_equal_approx(p_transform.columns[2]); } -bool Transform2D::is_same(const Transform2D &p_transform) const { - return columns[0].is_same(p_transform.columns[0]) && columns[1].is_same(p_transform.columns[1]) && columns[2].is_same(p_transform.columns[2]); -} - bool Transform2D::is_finite() const { return columns[0].is_finite() && columns[1].is_finite() && columns[2].is_finite(); } @@ -195,6 +191,26 @@ Transform2D Transform2D::looking_at(const Vector2 &p_target) const { return return_trans; } +bool Transform2D::operator==(const Transform2D &p_transform) const { + for (int i = 0; i < 3; i++) { + if (columns[i] != p_transform.columns[i]) { + return false; + } + } + + return true; +} + +bool Transform2D::operator!=(const Transform2D &p_transform) const { + for (int i = 0; i < 3; i++) { + if (columns[i] != p_transform.columns[i]) { + return true; + } + } + + return false; +} + void Transform2D::operator*=(const Transform2D &p_transform) { columns[2] = xform(p_transform.columns[2]); @@ -267,6 +283,30 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t get_origin().lerp(p_transform.get_origin(), p_weight)); } +void Transform2D::operator*=(real_t p_val) { + columns[0] *= p_val; + columns[1] *= p_val; + columns[2] *= p_val; +} + +Transform2D Transform2D::operator*(real_t p_val) const { + Transform2D ret(*this); + ret *= p_val; + return ret; +} + +void Transform2D::operator/=(real_t p_val) { + columns[0] /= p_val; + columns[1] /= p_val; + columns[2] /= p_val; +} + +Transform2D Transform2D::operator/(real_t p_val) const { + Transform2D ret(*this); + ret /= p_val; + return ret; +} + Transform2D::operator String() const { return "[X: " + columns[0].operator String() + ", Y: " + columns[1].operator String() + diff --git a/engine/core/math/transform_2d.h b/engine/core/math/transform_2d.h index 27eebe1a..1ee7d3d8 100644 --- a/engine/core/math/transform_2d.h +++ b/engine/core/math/transform_2d.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef TRANSFORM_2D_H +#define TRANSFORM_2D_H #include "core/math/math_funcs.h" #include "core/math/rect2.h" @@ -52,17 +53,13 @@ struct [[nodiscard]] Transform2D { // WARNING: Be aware that unlike 3D code, 2D code uses a left-handed coordinate system: // Y-axis points down, and angle is measure from +X to +Y in a clockwise-fashion. - Vector2 columns[3] = { - { 1, 0 }, - { 0, 1 }, - { 0, 0 }, - }; + Vector2 columns[3]; _FORCE_INLINE_ real_t tdotx(const Vector2 &p_v) const { return columns[0][0] * p_v.x + columns[1][0] * p_v.y; } _FORCE_INLINE_ real_t tdoty(const Vector2 &p_v) const { return columns[0][1] * p_v.x + columns[1][1] * p_v.y; } - constexpr const Vector2 &operator[](int p_idx) const { return columns[p_idx]; } - constexpr Vector2 &operator[](int p_idx) { return columns[p_idx]; } + const Vector2 &operator[](int p_idx) const { return columns[p_idx]; } + Vector2 &operator[](int p_idx) { return columns[p_idx]; } void invert(); Transform2D inverse() const; @@ -104,20 +101,19 @@ struct [[nodiscard]] Transform2D { Transform2D orthonormalized() const; bool is_conformal() const; bool is_equal_approx(const Transform2D &p_transform) const; - bool is_same(const Transform2D &p_transform) const; bool is_finite() const; Transform2D looking_at(const Vector2 &p_target) const; - constexpr bool operator==(const Transform2D &p_transform) const; - constexpr bool operator!=(const Transform2D &p_transform) const; + bool operator==(const Transform2D &p_transform) const; + bool operator!=(const Transform2D &p_transform) const; void operator*=(const Transform2D &p_transform); Transform2D operator*(const Transform2D &p_transform) const; - constexpr void operator*=(real_t p_val); - constexpr Transform2D operator*(real_t p_val) const; - constexpr void operator/=(real_t p_val); - constexpr Transform2D operator/(real_t p_val) const; + void operator*=(real_t p_val); + Transform2D operator*(real_t p_val) const; + void operator/=(real_t p_val); + Transform2D operator/(real_t p_val) const; Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const; @@ -132,67 +128,31 @@ struct [[nodiscard]] Transform2D { operator String() const; - constexpr Transform2D(real_t p_xx, real_t p_xy, real_t p_yx, real_t p_yy, real_t p_ox, real_t p_oy) : - columns{ - { p_xx, p_xy }, - { p_yx, p_yy }, - { p_ox, p_oy }, - } {} + Transform2D(real_t p_xx, real_t p_xy, real_t p_yx, real_t p_yy, real_t p_ox, real_t p_oy) { + columns[0][0] = p_xx; + columns[0][1] = p_xy; + columns[1][0] = p_yx; + columns[1][1] = p_yy; + columns[2][0] = p_ox; + columns[2][1] = p_oy; + } - constexpr Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) : - columns{ p_x, p_y, p_origin } {} + Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) { + columns[0] = p_x; + columns[1] = p_y; + columns[2] = p_origin; + } Transform2D(real_t p_rot, const Vector2 &p_pos); Transform2D(real_t p_rot, const Size2 &p_scale, real_t p_skew, const Vector2 &p_pos); - Transform2D() = default; + Transform2D() { + columns[0][0] = 1.0; + columns[1][1] = 1.0; + } }; -constexpr bool Transform2D::operator==(const Transform2D &p_transform) const { - for (int i = 0; i < 3; i++) { - if (columns[i] != p_transform.columns[i]) { - return false; - } - } - - return true; -} - -constexpr bool Transform2D::operator!=(const Transform2D &p_transform) const { - for (int i = 0; i < 3; i++) { - if (columns[i] != p_transform.columns[i]) { - return true; - } - } - - return false; -} - -constexpr void Transform2D::operator*=(real_t p_val) { - columns[0] *= p_val; - columns[1] *= p_val; - columns[2] *= p_val; -} - -constexpr Transform2D Transform2D::operator*(real_t p_val) const { - Transform2D ret(*this); - ret *= p_val; - return ret; -} - -constexpr void Transform2D::operator/=(real_t p_val) { - columns[0] /= p_val; - columns[1] /= p_val; - columns[2] /= p_val; -} - -constexpr Transform2D Transform2D::operator/(real_t p_val) const { - Transform2D ret(*this); - ret /= p_val; - return ret; -} - Vector2 Transform2D::basis_xform(const Vector2 &p_vec) const { return Vector2( tdotx(p_vec), @@ -289,3 +249,5 @@ Vector Transform2D::xform_inv(const Vector &p_array) const { } return array; } + +#endif // TRANSFORM_2D_H diff --git a/engine/core/math/transform_3d.cpp b/engine/core/math/transform_3d.cpp index b4d02408..d4673851 100644 --- a/engine/core/math/transform_3d.cpp +++ b/engine/core/math/transform_3d.cpp @@ -173,14 +173,18 @@ bool Transform3D::is_equal_approx(const Transform3D &p_transform) const { return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin); } -bool Transform3D::is_same(const Transform3D &p_transform) const { - return basis.is_same(p_transform.basis) && origin.is_same(p_transform.origin); -} - bool Transform3D::is_finite() const { return basis.is_finite() && origin.is_finite(); } +bool Transform3D::operator==(const Transform3D &p_transform) const { + return (basis == p_transform.basis && origin == p_transform.origin); +} + +bool Transform3D::operator!=(const Transform3D &p_transform) const { + return (basis != p_transform.basis || origin != p_transform.origin); +} + void Transform3D::operator*=(const Transform3D &p_transform) { origin = xform(p_transform.origin); basis *= p_transform.basis; @@ -192,9 +196,48 @@ Transform3D Transform3D::operator*(const Transform3D &p_transform) const { return t; } +void Transform3D::operator*=(real_t p_val) { + origin *= p_val; + basis *= p_val; +} + +Transform3D Transform3D::operator*(real_t p_val) const { + Transform3D ret(*this); + ret *= p_val; + return ret; +} + +void Transform3D::operator/=(real_t p_val) { + basis /= p_val; + origin /= p_val; +} + +Transform3D Transform3D::operator/(real_t p_val) const { + Transform3D ret(*this); + ret /= p_val; + return ret; +} + Transform3D::operator String() const { return "[X: " + basis.get_column(0).operator String() + ", Y: " + basis.get_column(1).operator String() + ", Z: " + basis.get_column(2).operator String() + ", O: " + origin.operator String() + "]"; } + +Transform3D::Transform3D(const Basis &p_basis, const Vector3 &p_origin) : + basis(p_basis), + origin(p_origin) { +} + +Transform3D::Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) : + origin(p_origin) { + basis.set_column(0, p_x); + basis.set_column(1, p_y); + basis.set_column(2, p_z); +} + +Transform3D::Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz) { + basis = Basis(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz); + origin = Vector3(p_ox, p_oy, p_oz); +} diff --git a/engine/core/math/transform_3d.h b/engine/core/math/transform_3d.h index 0d5cbb0f..b1de2334 100644 --- a/engine/core/math/transform_3d.h +++ b/engine/core/math/transform_3d.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef TRANSFORM_3D_H +#define TRANSFORM_3D_H #include "core/math/aabb.h" #include "core/math/basis.h" @@ -74,11 +75,10 @@ struct [[nodiscard]] Transform3D { void orthogonalize(); Transform3D orthogonalized() const; bool is_equal_approx(const Transform3D &p_transform) const; - bool is_same(const Transform3D &p_transform) const; bool is_finite() const; - constexpr bool operator==(const Transform3D &p_transform) const; - constexpr bool operator!=(const Transform3D &p_transform) const; + bool operator==(const Transform3D &p_transform) const; + bool operator!=(const Transform3D &p_transform) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const; @@ -102,10 +102,10 @@ struct [[nodiscard]] Transform3D { void operator*=(const Transform3D &p_transform); Transform3D operator*(const Transform3D &p_transform) const; - constexpr void operator*=(real_t p_val); - constexpr Transform3D operator*(real_t p_val) const; - constexpr void operator/=(real_t p_val); - constexpr Transform3D operator/(real_t p_val) const; + void operator*=(real_t p_val); + Transform3D operator*(real_t p_val) const; + void operator/=(real_t p_val); + Transform3D operator/(real_t p_val) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; @@ -124,48 +124,12 @@ struct [[nodiscard]] Transform3D { operator String() const; - Transform3D() = default; - constexpr Transform3D(const Basis &p_basis, const Vector3 &p_origin = Vector3()) : - basis(p_basis), - origin(p_origin) {} - constexpr Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) : - basis(p_x, p_y, p_z), - origin(p_origin) {} - constexpr Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz) : - basis(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz), - origin(p_ox, p_oy, p_oz) {} + Transform3D() {} + Transform3D(const Basis &p_basis, const Vector3 &p_origin = Vector3()); + Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin); + Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz); }; -constexpr bool Transform3D::operator==(const Transform3D &p_transform) const { - return (basis == p_transform.basis && origin == p_transform.origin); -} - -constexpr bool Transform3D::operator!=(const Transform3D &p_transform) const { - return (basis != p_transform.basis || origin != p_transform.origin); -} - -constexpr void Transform3D::operator*=(real_t p_val) { - origin *= p_val; - basis *= p_val; -} - -constexpr Transform3D Transform3D::operator*(real_t p_val) const { - Transform3D ret(*this); - ret *= p_val; - return ret; -} - -constexpr void Transform3D::operator/=(real_t p_val) { - basis /= p_val; - origin /= p_val; -} - -constexpr Transform3D Transform3D::operator/(real_t p_val) const { - Transform3D ret(*this); - ret /= p_val; - return ret; -} - _FORCE_INLINE_ Vector3 Transform3D::xform(const Vector3 &p_vector) const { return Vector3( basis[0].dot(p_vector) + origin.x, @@ -305,3 +269,5 @@ _FORCE_INLINE_ Plane Transform3D::xform_inv_fast(const Plane &p_plane, const Tra real_t d = normal.dot(point); return Plane(normal, d); } + +#endif // TRANSFORM_3D_H diff --git a/engine/core/math/transform_interpolator.h b/engine/core/math/transform_interpolator.h index d80876d9..cc556707 100644 --- a/engine/core/math/transform_interpolator.h +++ b/engine/core/math/transform_interpolator.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef TRANSFORM_INTERPOLATOR_H +#define TRANSFORM_INTERPOLATOR_H #include "core/math/math_defs.h" #include "core/math/vector3.h" @@ -90,3 +91,5 @@ public: static Method find_method(const Basis &p_a, const Basis &p_b); }; + +#endif // TRANSFORM_INTERPOLATOR_H diff --git a/engine/core/math/triangle_mesh.cpp b/engine/core/math/triangle_mesh.cpp index 3b24b351..01b73318 100644 --- a/engine/core/math/triangle_mesh.cpp +++ b/engine/core/math/triangle_mesh.cpp @@ -182,11 +182,7 @@ void TriangleMesh::create(const Vector &p_faces, const Vector valid = true; } -bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const { - if (!valid) { - return false; - } - +bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -238,9 +234,6 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en if (r_surf_index) { *r_surf_index = s.surface_index; } - if (r_face_index) { - *r_face_index = b.face_index; - } inters = true; } } @@ -290,11 +283,7 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en return inters; } -bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const { - if (!valid) { - return false; - } - +bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -346,9 +335,6 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V if (r_surf_index) { *r_surf_index = s.surface_index; } - if (r_face_index) { - *r_face_index = b.face_index; - } inters = true; } } @@ -399,10 +385,6 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V } bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale) const { - if (!valid) { - return false; - } - uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -521,85 +503,6 @@ Vector TriangleMesh::get_faces() const { return faces; } -bool TriangleMesh::create_from_faces(const Vector &p_faces) { - create(p_faces); - return is_valid(); -} - -Dictionary TriangleMesh::intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const { - if (!valid) { - return Dictionary(); - } - - Vector3 r_point; - Vector3 r_normal; - int32_t r_face_index = -1; - - bool intersected = intersect_segment(p_begin, p_end, r_point, r_normal, nullptr, &r_face_index); - if (!intersected) { - return Dictionary(); - } - - Dictionary result; - result["position"] = r_point; - result["normal"] = r_normal; - result["face_index"] = r_face_index; - - return result; -} - -Dictionary TriangleMesh::intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const { - if (!valid) { - return Dictionary(); - } - - Vector3 r_point; - Vector3 r_normal; - int32_t r_face_index = -1; - - bool intersected = intersect_ray(p_begin, p_dir, r_point, r_normal, nullptr, &r_face_index); - if (!intersected) { - return Dictionary(); - } - - Dictionary result; - result["position"] = r_point; - result["normal"] = r_normal; - result["face_index"] = r_face_index; - - return result; -} - -Vector TriangleMesh::get_faces_scriptwrap() const { - if (!valid) { - return Vector(); - } - - Vector faces; - int ts = triangles.size(); - faces.resize(triangles.size() * 3); - - Vector3 *w = faces.ptrw(); - const Triangle *r = triangles.ptr(); - const Vector3 *rv = vertices.ptr(); - - for (int i = 0; i < ts; i++) { - for (int j = 0; j < 3; j++) { - w[i * 3 + j] = rv[r[i].indices[j]]; - } - } - - return faces; -} - -void TriangleMesh::_bind_methods() { - ClassDB::bind_method(D_METHOD("create_from_faces", "faces"), &TriangleMesh::create_from_faces); - ClassDB::bind_method(D_METHOD("get_faces"), &TriangleMesh::get_faces_scriptwrap); - - ClassDB::bind_method(D_METHOD("intersect_segment", "begin", "end"), &TriangleMesh::intersect_segment_scriptwrap); - ClassDB::bind_method(D_METHOD("intersect_ray", "begin", "dir"), &TriangleMesh::intersect_ray_scriptwrap); -} - TriangleMesh::TriangleMesh() { valid = false; max_depth = 0; diff --git a/engine/core/math/triangle_mesh.h b/engine/core/math/triangle_mesh.h index 65fd0ff9..24fc12dd 100644 --- a/engine/core/math/triangle_mesh.h +++ b/engine/core/math/triangle_mesh.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef TRIANGLE_MESH_H +#define TRIANGLE_MESH_H #include "core/math/face3.h" #include "core/object/ref_counted.h" @@ -40,12 +41,9 @@ public: struct Triangle { Vector3 normal; int indices[3]; - int32_t surface_index = 0; + int32_t surface_index; }; -protected: - static void _bind_methods(); - private: Vector triangles; Vector vertices; @@ -53,10 +51,10 @@ private: struct BVH { AABB aabb; Vector3 center; //used for sorting - int left = -1; - int right = -1; + int left; + int right; - int32_t face_index = -1; + int face_index; }; struct BVHCmpX { @@ -79,13 +77,13 @@ private: int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc); Vector bvh; - int max_depth = 0; - bool valid = false; + int max_depth; + bool valid; public: bool is_valid() const; - bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const; - bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const; + bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; + bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const; Vector get_faces() const; @@ -94,13 +92,7 @@ public: void get_indices(Vector *r_triangles_indices) const; void create(const Vector &p_faces, const Vector &p_surface_indices = Vector()); - - // Wrapped functions for compatibility with method bindings - // and user exposed script api that can't use more native types. - bool create_from_faces(const Vector &p_faces); - Dictionary intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const; - Dictionary intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const; - Vector get_faces_scriptwrap() const; - TriangleMesh(); }; + +#endif // TRIANGLE_MESH_H diff --git a/engine/core/math/triangulate.h b/engine/core/math/triangulate.h index 87cdbd4f..0b88f7ec 100644 --- a/engine/core/math/triangulate.h +++ b/engine/core/math/triangulate.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef TRIANGULATE_H +#define TRIANGULATE_H #include "core/math/vector2.h" #include "core/templates/vector.h" @@ -57,3 +58,5 @@ public: private: static bool snip(const Vector &p_contour, int u, int v, int w, int n, const Vector &V, bool relaxed); }; + +#endif // TRIANGULATE_H diff --git a/engine/core/math/vector2.cpp b/engine/core/math/vector2.cpp index 7a51c139..0590ee8a 100644 --- a/engine/core/math/vector2.cpp +++ b/engine/core/math/vector2.cpp @@ -194,10 +194,6 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y); } -bool Vector2::is_same(const Vector2 &p_v) const { - return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y); -} - bool Vector2::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y); } diff --git a/engine/core/math/vector2.h b/engine/core/math/vector2.h index 3f6dbefc..edb47db6 100644 --- a/engine/core/math/vector2.h +++ b/engine/core/math/vector2.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef VECTOR2_H +#define VECTOR2_H #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -45,19 +46,18 @@ struct [[nodiscard]] Vector2 { }; union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { - real_t x; - real_t y; - }; - - struct { - real_t width; - real_t height; + union { + real_t x; + real_t width; + }; + union { + real_t y; + real_t height; + }; }; real_t coord[2] = { 0 }; - // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ real_t &operator[](int p_axis) { @@ -129,36 +129,35 @@ struct [[nodiscard]] Vector2 { Vector2 reflect(const Vector2 &p_normal) const; bool is_equal_approx(const Vector2 &p_v) const; - bool is_same(const Vector2 &p_v) const; bool is_zero_approx() const; bool is_finite() const; - constexpr Vector2 operator+(const Vector2 &p_v) const; - constexpr void operator+=(const Vector2 &p_v); - constexpr Vector2 operator-(const Vector2 &p_v) const; - constexpr void operator-=(const Vector2 &p_v); - constexpr Vector2 operator*(const Vector2 &p_v1) const; + Vector2 operator+(const Vector2 &p_v) const; + void operator+=(const Vector2 &p_v); + Vector2 operator-(const Vector2 &p_v) const; + void operator-=(const Vector2 &p_v); + Vector2 operator*(const Vector2 &p_v1) const; - constexpr Vector2 operator*(real_t p_rvalue) const; - constexpr void operator*=(real_t p_rvalue); - constexpr void operator*=(const Vector2 &p_rvalue) { *this = *this * p_rvalue; } + Vector2 operator*(real_t p_rvalue) const; + void operator*=(real_t p_rvalue); + void operator*=(const Vector2 &p_rvalue) { *this = *this * p_rvalue; } - constexpr Vector2 operator/(const Vector2 &p_v1) const; + Vector2 operator/(const Vector2 &p_v1) const; - constexpr Vector2 operator/(real_t p_rvalue) const; + Vector2 operator/(real_t p_rvalue) const; - constexpr void operator/=(real_t p_rvalue); - constexpr void operator/=(const Vector2 &p_rvalue) { *this = *this / p_rvalue; } + void operator/=(real_t p_rvalue); + void operator/=(const Vector2 &p_rvalue) { *this = *this / p_rvalue; } - constexpr Vector2 operator-() const; + Vector2 operator-() const; - constexpr bool operator==(const Vector2 &p_vec2) const; - constexpr bool operator!=(const Vector2 &p_vec2) const; + bool operator==(const Vector2 &p_vec2) const; + bool operator!=(const Vector2 &p_vec2) const; - constexpr bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); } - constexpr bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); } - constexpr bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } - constexpr bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } + bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); } + bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); } + bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } + bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } real_t angle() const; static Vector2 from_angle(real_t p_angle); @@ -185,71 +184,70 @@ struct [[nodiscard]] Vector2 { operator String() const; operator Vector2i() const; - // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) - constexpr Vector2() : - x(0), y(0) {} - constexpr Vector2(real_t p_x, real_t p_y) : - x(p_x), y(p_y) {} - // NOLINTEND(cppcoreguidelines-pro-type-member-init) + _FORCE_INLINE_ Vector2() {} + _FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) { + x = p_x; + y = p_y; + } }; _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const { return p_vec - *this * (dot(p_vec) - p_d); } -constexpr Vector2 Vector2::operator+(const Vector2 &p_v) const { +_FORCE_INLINE_ Vector2 Vector2::operator+(const Vector2 &p_v) const { return Vector2(x + p_v.x, y + p_v.y); } -constexpr void Vector2::operator+=(const Vector2 &p_v) { +_FORCE_INLINE_ void Vector2::operator+=(const Vector2 &p_v) { x += p_v.x; y += p_v.y; } -constexpr Vector2 Vector2::operator-(const Vector2 &p_v) const { +_FORCE_INLINE_ Vector2 Vector2::operator-(const Vector2 &p_v) const { return Vector2(x - p_v.x, y - p_v.y); } -constexpr void Vector2::operator-=(const Vector2 &p_v) { +_FORCE_INLINE_ void Vector2::operator-=(const Vector2 &p_v) { x -= p_v.x; y -= p_v.y; } -constexpr Vector2 Vector2::operator*(const Vector2 &p_v1) const { +_FORCE_INLINE_ Vector2 Vector2::operator*(const Vector2 &p_v1) const { return Vector2(x * p_v1.x, y * p_v1.y); } -constexpr Vector2 Vector2::operator*(real_t p_rvalue) const { +_FORCE_INLINE_ Vector2 Vector2::operator*(real_t p_rvalue) const { return Vector2(x * p_rvalue, y * p_rvalue); } -constexpr void Vector2::operator*=(real_t p_rvalue) { +_FORCE_INLINE_ void Vector2::operator*=(real_t p_rvalue) { x *= p_rvalue; y *= p_rvalue; } -constexpr Vector2 Vector2::operator/(const Vector2 &p_v1) const { +_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const { return Vector2(x / p_v1.x, y / p_v1.y); } -constexpr Vector2 Vector2::operator/(real_t p_rvalue) const { +_FORCE_INLINE_ Vector2 Vector2::operator/(real_t p_rvalue) const { return Vector2(x / p_rvalue, y / p_rvalue); } -constexpr void Vector2::operator/=(real_t p_rvalue) { +_FORCE_INLINE_ void Vector2::operator/=(real_t p_rvalue) { x /= p_rvalue; y /= p_rvalue; } -constexpr Vector2 Vector2::operator-() const { +_FORCE_INLINE_ Vector2 Vector2::operator-() const { return Vector2(-x, -y); } -constexpr bool Vector2::operator==(const Vector2 &p_vec2) const { +_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const { return x == p_vec2.x && y == p_vec2.y; } -constexpr bool Vector2::operator!=(const Vector2 &p_vec2) const { +_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { return x != p_vec2.x || y != p_vec2.y; } @@ -310,24 +308,23 @@ Vector2 Vector2::direction_to(const Vector2 &p_to) const { // Multiplication operators required to workaround issues with LLVM using implicit conversion // to Vector2i instead for integers where it should not. -constexpr Vector2 operator*(float p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -constexpr Vector2 operator*(double p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -constexpr Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -constexpr Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } typedef Vector2 Size2; typedef Vector2 Point2; -template <> -struct is_zero_constructible : std::true_type {}; +#endif // VECTOR2_H diff --git a/engine/core/math/vector2i.cpp b/engine/core/math/vector2i.cpp index cef55185..790f5647 100644 --- a/engine/core/math/vector2i.cpp +++ b/engine/core/math/vector2i.cpp @@ -65,6 +65,75 @@ double Vector2i::length() const { return Math::sqrt((double)length_squared()); } +Vector2i Vector2i::operator+(const Vector2i &p_v) const { + return Vector2i(x + p_v.x, y + p_v.y); +} + +void Vector2i::operator+=(const Vector2i &p_v) { + x += p_v.x; + y += p_v.y; +} + +Vector2i Vector2i::operator-(const Vector2i &p_v) const { + return Vector2i(x - p_v.x, y - p_v.y); +} + +void Vector2i::operator-=(const Vector2i &p_v) { + x -= p_v.x; + y -= p_v.y; +} + +Vector2i Vector2i::operator*(const Vector2i &p_v1) const { + return Vector2i(x * p_v1.x, y * p_v1.y); +} + +Vector2i Vector2i::operator*(int32_t p_rvalue) const { + return Vector2i(x * p_rvalue, y * p_rvalue); +} + +void Vector2i::operator*=(int32_t p_rvalue) { + x *= p_rvalue; + y *= p_rvalue; +} + +Vector2i Vector2i::operator/(const Vector2i &p_v1) const { + return Vector2i(x / p_v1.x, y / p_v1.y); +} + +Vector2i Vector2i::operator/(int32_t p_rvalue) const { + return Vector2i(x / p_rvalue, y / p_rvalue); +} + +void Vector2i::operator/=(int32_t p_rvalue) { + x /= p_rvalue; + y /= p_rvalue; +} + +Vector2i Vector2i::operator%(const Vector2i &p_v1) const { + return Vector2i(x % p_v1.x, y % p_v1.y); +} + +Vector2i Vector2i::operator%(int32_t p_rvalue) const { + return Vector2i(x % p_rvalue, y % p_rvalue); +} + +void Vector2i::operator%=(int32_t p_rvalue) { + x %= p_rvalue; + y %= p_rvalue; +} + +Vector2i Vector2i::operator-() const { + return Vector2i(-x, -y); +} + +bool Vector2i::operator==(const Vector2i &p_vec2) const { + return x == p_vec2.x && y == p_vec2.y; +} + +bool Vector2i::operator!=(const Vector2i &p_vec2) const { + return x != p_vec2.x || y != p_vec2.y; +} + Vector2i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ")"; } diff --git a/engine/core/math/vector2i.h b/engine/core/math/vector2i.h index 5ce0b93b..fff9b0a6 100644 --- a/engine/core/math/vector2i.h +++ b/engine/core/math/vector2i.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef VECTOR2I_H +#define VECTOR2I_H #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -45,19 +46,18 @@ struct [[nodiscard]] Vector2i { }; union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { - int32_t x; - int32_t y; - }; - - struct { - int32_t width; - int32_t height; + union { + int32_t x; + int32_t width; + }; + union { + int32_t y; + int32_t height; + }; }; int32_t coord[2] = { 0 }; - // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ int32_t &operator[](int p_axis) { @@ -101,32 +101,32 @@ struct [[nodiscard]] Vector2i { return (p_to - *this).length_squared(); } - constexpr Vector2i operator+(const Vector2i &p_v) const; - constexpr void operator+=(const Vector2i &p_v); - constexpr Vector2i operator-(const Vector2i &p_v) const; - constexpr void operator-=(const Vector2i &p_v); - constexpr Vector2i operator*(const Vector2i &p_v1) const; + Vector2i operator+(const Vector2i &p_v) const; + void operator+=(const Vector2i &p_v); + Vector2i operator-(const Vector2i &p_v) const; + void operator-=(const Vector2i &p_v); + Vector2i operator*(const Vector2i &p_v1) const; - constexpr Vector2i operator*(int32_t p_rvalue) const; - constexpr void operator*=(int32_t p_rvalue); + Vector2i operator*(int32_t p_rvalue) const; + void operator*=(int32_t p_rvalue); - constexpr Vector2i operator/(const Vector2i &p_v1) const; - constexpr Vector2i operator/(int32_t p_rvalue) const; - constexpr void operator/=(int32_t p_rvalue); + Vector2i operator/(const Vector2i &p_v1) const; + Vector2i operator/(int32_t p_rvalue) const; + void operator/=(int32_t p_rvalue); - constexpr Vector2i operator%(const Vector2i &p_v1) const; - constexpr Vector2i operator%(int32_t p_rvalue) const; - constexpr void operator%=(int32_t p_rvalue); + Vector2i operator%(const Vector2i &p_v1) const; + Vector2i operator%(int32_t p_rvalue) const; + void operator%=(int32_t p_rvalue); - constexpr Vector2i operator-() const; - constexpr bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - constexpr bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } + 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); } - constexpr bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } - constexpr 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); } + bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } - constexpr bool operator==(const Vector2i &p_vec2) const; - constexpr bool operator!=(const Vector2i &p_vec2) const; + bool operator==(const Vector2i &p_vec2) const; + bool operator!=(const Vector2i &p_vec2) const; int64_t length_squared() const; double length() const; @@ -142,103 +142,32 @@ struct [[nodiscard]] Vector2i { operator String() const; operator Vector2() const; - // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) - constexpr Vector2i() : - x(0), y(0) {} - constexpr Vector2i(int32_t p_x, int32_t p_y) : - x(p_x), y(p_y) {} - // NOLINTEND(cppcoreguidelines-pro-type-member-init) + inline Vector2i() {} + inline Vector2i(int32_t p_x, int32_t p_y) { + x = p_x; + y = p_y; + } }; -constexpr Vector2i Vector2i::operator+(const Vector2i &p_v) const { - return Vector2i(x + p_v.x, y + p_v.y); -} - -constexpr void Vector2i::operator+=(const Vector2i &p_v) { - x += p_v.x; - y += p_v.y; -} - -constexpr Vector2i Vector2i::operator-(const Vector2i &p_v) const { - return Vector2i(x - p_v.x, y - p_v.y); -} - -constexpr void Vector2i::operator-=(const Vector2i &p_v) { - x -= p_v.x; - y -= p_v.y; -} - -constexpr Vector2i Vector2i::operator*(const Vector2i &p_v1) const { - return Vector2i(x * p_v1.x, y * p_v1.y); -} - -constexpr Vector2i Vector2i::operator*(int32_t p_rvalue) const { - return Vector2i(x * p_rvalue, y * p_rvalue); -} - -constexpr void Vector2i::operator*=(int32_t p_rvalue) { - x *= p_rvalue; - y *= p_rvalue; -} - -constexpr Vector2i Vector2i::operator/(const Vector2i &p_v1) const { - return Vector2i(x / p_v1.x, y / p_v1.y); -} - -constexpr Vector2i Vector2i::operator/(int32_t p_rvalue) const { - return Vector2i(x / p_rvalue, y / p_rvalue); -} - -constexpr void Vector2i::operator/=(int32_t p_rvalue) { - x /= p_rvalue; - y /= p_rvalue; -} - -constexpr Vector2i Vector2i::operator%(const Vector2i &p_v1) const { - return Vector2i(x % p_v1.x, y % p_v1.y); -} - -constexpr Vector2i Vector2i::operator%(int32_t p_rvalue) const { - return Vector2i(x % p_rvalue, y % p_rvalue); -} - -constexpr void Vector2i::operator%=(int32_t p_rvalue) { - x %= p_rvalue; - y %= p_rvalue; -} - -constexpr Vector2i Vector2i::operator-() const { - return Vector2i(-x, -y); -} - -constexpr bool Vector2i::operator==(const Vector2i &p_vec2) const { - return x == p_vec2.x && y == p_vec2.y; -} - -constexpr bool Vector2i::operator!=(const Vector2i &p_vec2) const { - return x != p_vec2.x || y != p_vec2.y; -} - // Multiplication operators required to workaround issues with LLVM using implicit conversion. -constexpr Vector2i operator*(int32_t p_scalar, const Vector2i &p_vector) { +_FORCE_INLINE_ Vector2i operator*(int32_t p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } -constexpr Vector2i operator*(int64_t p_scalar, const Vector2i &p_vector) { +_FORCE_INLINE_ Vector2i operator*(int64_t p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } -constexpr Vector2i operator*(float p_scalar, const Vector2i &p_vector) { +_FORCE_INLINE_ Vector2i operator*(float p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } -constexpr Vector2i operator*(double p_scalar, const Vector2i &p_vector) { +_FORCE_INLINE_ Vector2i operator*(double p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } typedef Vector2i Size2i; typedef Vector2i Point2i; -template <> -struct is_zero_constructible : std::true_type {}; +#endif // VECTOR2I_H diff --git a/engine/core/math/vector3.cpp b/engine/core/math/vector3.cpp index 24422c57..e18ac3b0 100644 --- a/engine/core/math/vector3.cpp +++ b/engine/core/math/vector3.cpp @@ -156,10 +156,6 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y) && Math::is_equal_approx(z, p_v.z); } -bool Vector3::is_same(const Vector3 &p_v) const { - return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y) && Math::is_same(z, p_v.z); -} - bool Vector3::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z); } diff --git a/engine/core/math/vector3.h b/engine/core/math/vector3.h index 4ddfac64..fd0dec35 100644 --- a/engine/core/math/vector3.h +++ b/engine/core/math/vector3.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef VECTOR3_H +#define VECTOR3_H #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -48,7 +49,6 @@ struct [[nodiscard]] Vector3 { }; union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { real_t x; real_t y; @@ -56,7 +56,6 @@ struct [[nodiscard]] Vector3 { }; real_t coord[3] = { 0 }; - // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ const real_t &operator[](int p_axis) const { @@ -157,42 +156,43 @@ struct [[nodiscard]] Vector3 { _FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const; bool is_equal_approx(const Vector3 &p_v) const; - bool is_same(const Vector3 &p_v) const; bool is_zero_approx() const; bool is_finite() const; /* Operators */ - constexpr Vector3 &operator+=(const Vector3 &p_v); - constexpr Vector3 operator+(const Vector3 &p_v) const; - constexpr Vector3 &operator-=(const Vector3 &p_v); - constexpr Vector3 operator-(const Vector3 &p_v) const; - constexpr Vector3 &operator*=(const Vector3 &p_v); - constexpr Vector3 operator*(const Vector3 &p_v) const; - constexpr Vector3 &operator/=(const Vector3 &p_v); - constexpr Vector3 operator/(const Vector3 &p_v) const; + _FORCE_INLINE_ Vector3 &operator+=(const Vector3 &p_v); + _FORCE_INLINE_ Vector3 operator+(const Vector3 &p_v) const; + _FORCE_INLINE_ Vector3 &operator-=(const Vector3 &p_v); + _FORCE_INLINE_ Vector3 operator-(const Vector3 &p_v) const; + _FORCE_INLINE_ Vector3 &operator*=(const Vector3 &p_v); + _FORCE_INLINE_ Vector3 operator*(const Vector3 &p_v) const; + _FORCE_INLINE_ Vector3 &operator/=(const Vector3 &p_v); + _FORCE_INLINE_ Vector3 operator/(const Vector3 &p_v) const; - constexpr Vector3 &operator*=(real_t p_scalar); - constexpr Vector3 operator*(real_t p_scalar) const; - constexpr Vector3 &operator/=(real_t p_scalar); - constexpr Vector3 operator/(real_t p_scalar) const; + _FORCE_INLINE_ Vector3 &operator*=(real_t p_scalar); + _FORCE_INLINE_ Vector3 operator*(real_t p_scalar) const; + _FORCE_INLINE_ Vector3 &operator/=(real_t p_scalar); + _FORCE_INLINE_ Vector3 operator/(real_t p_scalar) const; - constexpr Vector3 operator-() const; + _FORCE_INLINE_ Vector3 operator-() const; - constexpr bool operator==(const Vector3 &p_v) const; - constexpr bool operator!=(const Vector3 &p_v) const; - constexpr bool operator<(const Vector3 &p_v) const; - constexpr bool operator<=(const Vector3 &p_v) const; - constexpr bool operator>(const Vector3 &p_v) const; - constexpr bool operator>=(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator==(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator<(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator>(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const; operator String() const; operator Vector3i() const; - constexpr Vector3() : - x(0), y(0), z(0) {} - constexpr Vector3(real_t p_x, real_t p_y, real_t p_z) : - x(p_x), y(p_y), z(p_z) {} + _FORCE_INLINE_ Vector3() {} + _FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) { + x = p_x; + y = p_y; + z = p_z; + } }; Vector3 Vector3::cross(const Vector3 &p_with) const { @@ -339,51 +339,51 @@ Vector3 Vector3::get_any_perpendicular() const { /* Operators */ -constexpr Vector3 &Vector3::operator+=(const Vector3 &p_v) { +Vector3 &Vector3::operator+=(const Vector3 &p_v) { x += p_v.x; y += p_v.y; z += p_v.z; return *this; } -constexpr Vector3 Vector3::operator+(const Vector3 &p_v) const { +Vector3 Vector3::operator+(const Vector3 &p_v) const { return Vector3(x + p_v.x, y + p_v.y, z + p_v.z); } -constexpr Vector3 &Vector3::operator-=(const Vector3 &p_v) { +Vector3 &Vector3::operator-=(const Vector3 &p_v) { x -= p_v.x; y -= p_v.y; z -= p_v.z; return *this; } -constexpr Vector3 Vector3::operator-(const Vector3 &p_v) const { +Vector3 Vector3::operator-(const Vector3 &p_v) const { return Vector3(x - p_v.x, y - p_v.y, z - p_v.z); } -constexpr Vector3 &Vector3::operator*=(const Vector3 &p_v) { +Vector3 &Vector3::operator*=(const Vector3 &p_v) { x *= p_v.x; y *= p_v.y; z *= p_v.z; return *this; } -constexpr Vector3 Vector3::operator*(const Vector3 &p_v) const { +Vector3 Vector3::operator*(const Vector3 &p_v) const { return Vector3(x * p_v.x, y * p_v.y, z * p_v.z); } -constexpr Vector3 &Vector3::operator/=(const Vector3 &p_v) { +Vector3 &Vector3::operator/=(const Vector3 &p_v) { x /= p_v.x; y /= p_v.y; z /= p_v.z; return *this; } -constexpr Vector3 Vector3::operator/(const Vector3 &p_v) const { +Vector3 Vector3::operator/(const Vector3 &p_v) const { return Vector3(x / p_v.x, y / p_v.y, z / p_v.z); } -constexpr Vector3 &Vector3::operator*=(real_t p_scalar) { +Vector3 &Vector3::operator*=(real_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; @@ -393,50 +393,50 @@ constexpr Vector3 &Vector3::operator*=(real_t p_scalar) { // Multiplication operators required to workaround issues with LLVM using implicit conversion // to Vector3i instead for integers where it should not. -constexpr Vector3 operator*(float p_scalar, const Vector3 &p_vec) { +_FORCE_INLINE_ Vector3 operator*(float p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -constexpr Vector3 operator*(double p_scalar, const Vector3 &p_vec) { +_FORCE_INLINE_ Vector3 operator*(double p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -constexpr Vector3 operator*(int32_t p_scalar, const Vector3 &p_vec) { +_FORCE_INLINE_ Vector3 operator*(int32_t p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -constexpr Vector3 operator*(int64_t p_scalar, const Vector3 &p_vec) { +_FORCE_INLINE_ Vector3 operator*(int64_t p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -constexpr Vector3 Vector3::operator*(real_t p_scalar) const { +Vector3 Vector3::operator*(real_t p_scalar) const { return Vector3(x * p_scalar, y * p_scalar, z * p_scalar); } -constexpr Vector3 &Vector3::operator/=(real_t p_scalar) { +Vector3 &Vector3::operator/=(real_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; return *this; } -constexpr Vector3 Vector3::operator/(real_t p_scalar) const { +Vector3 Vector3::operator/(real_t p_scalar) const { return Vector3(x / p_scalar, y / p_scalar, z / p_scalar); } -constexpr Vector3 Vector3::operator-() const { +Vector3 Vector3::operator-() const { return Vector3(-x, -y, -z); } -constexpr bool Vector3::operator==(const Vector3 &p_v) const { +bool Vector3::operator==(const Vector3 &p_v) const { return x == p_v.x && y == p_v.y && z == p_v.z; } -constexpr bool Vector3::operator!=(const Vector3 &p_v) const { +bool Vector3::operator!=(const Vector3 &p_v) const { return x != p_v.x || y != p_v.y || z != p_v.z; } -constexpr bool Vector3::operator<(const Vector3 &p_v) const { +bool Vector3::operator<(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z < p_v.z; @@ -446,7 +446,7 @@ constexpr bool Vector3::operator<(const Vector3 &p_v) const { return x < p_v.x; } -constexpr bool Vector3::operator>(const Vector3 &p_v) const { +bool Vector3::operator>(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z > p_v.z; @@ -456,7 +456,7 @@ constexpr bool Vector3::operator>(const Vector3 &p_v) const { return x > p_v.x; } -constexpr bool Vector3::operator<=(const Vector3 &p_v) const { +bool Vector3::operator<=(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z <= p_v.z; @@ -466,7 +466,7 @@ constexpr bool Vector3::operator<=(const Vector3 &p_v) const { return x < p_v.x; } -constexpr bool Vector3::operator>=(const Vector3 &p_v) const { +bool Vector3::operator>=(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z >= p_v.z; @@ -550,5 +550,4 @@ Vector3 Vector3::reflect(const Vector3 &p_normal) const { return 2.0f * p_normal * dot(p_normal) - *this; } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // VECTOR3_H diff --git a/engine/core/math/vector3i.h b/engine/core/math/vector3i.h index d7d1455e..40d0700b 100644 --- a/engine/core/math/vector3i.h +++ b/engine/core/math/vector3i.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef VECTOR3I_H +#define VECTOR3I_H #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -46,7 +47,6 @@ struct [[nodiscard]] Vector3i { }; union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { int32_t x; int32_t y; @@ -54,7 +54,6 @@ struct [[nodiscard]] Vector3i { }; int32_t coord[3] = { 0 }; - // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ const int32_t &operator[](int p_axis) const { @@ -103,40 +102,42 @@ struct [[nodiscard]] Vector3i { /* Operators */ - constexpr Vector3i &operator+=(const Vector3i &p_v); - constexpr Vector3i operator+(const Vector3i &p_v) const; - constexpr Vector3i &operator-=(const Vector3i &p_v); - constexpr Vector3i operator-(const Vector3i &p_v) const; - constexpr Vector3i &operator*=(const Vector3i &p_v); - constexpr Vector3i operator*(const Vector3i &p_v) const; - constexpr Vector3i &operator/=(const Vector3i &p_v); - constexpr Vector3i operator/(const Vector3i &p_v) const; - constexpr Vector3i &operator%=(const Vector3i &p_v); - constexpr 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*=(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%=(const Vector3i &p_v); + _FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const; - constexpr Vector3i &operator*=(int32_t p_scalar); - constexpr Vector3i operator*(int32_t p_scalar) const; - constexpr Vector3i &operator/=(int32_t p_scalar); - constexpr Vector3i operator/(int32_t p_scalar) const; - constexpr Vector3i &operator%=(int32_t p_scalar); - constexpr 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%=(int32_t p_scalar); + _FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const; - constexpr Vector3i operator-() const; + _FORCE_INLINE_ Vector3i operator-() const; - constexpr bool operator==(const Vector3i &p_v) const; - constexpr bool operator!=(const Vector3i &p_v) const; - constexpr bool operator<(const Vector3i &p_v) const; - constexpr bool operator<=(const Vector3i &p_v) const; - constexpr bool operator>(const Vector3i &p_v) const; - constexpr bool operator>=(const Vector3i &p_v) const; + _FORCE_INLINE_ bool operator==(const Vector3i &p_v) const; + _FORCE_INLINE_ bool operator!=(const Vector3i &p_v) const; + _FORCE_INLINE_ bool operator<(const Vector3i &p_v) const; + _FORCE_INLINE_ bool operator<=(const Vector3i &p_v) const; + _FORCE_INLINE_ bool operator>(const Vector3i &p_v) const; + _FORCE_INLINE_ bool operator>=(const Vector3i &p_v) const; operator String() const; operator Vector3() const; - constexpr Vector3i() : - x(0), y(0), z(0) {} - constexpr Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) : - x(p_x), y(p_y), z(p_z) {} + _FORCE_INLINE_ Vector3i() {} + _FORCE_INLINE_ Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) { + x = p_x; + y = p_y; + z = p_z; + } }; int64_t Vector3i::length_squared() const { @@ -165,125 +166,125 @@ int64_t Vector3i::distance_squared_to(const Vector3i &p_to) const { /* Operators */ -constexpr Vector3i &Vector3i::operator+=(const Vector3i &p_v) { +Vector3i &Vector3i::operator+=(const Vector3i &p_v) { x += p_v.x; y += p_v.y; z += p_v.z; return *this; } -constexpr Vector3i Vector3i::operator+(const Vector3i &p_v) const { +Vector3i Vector3i::operator+(const Vector3i &p_v) const { return Vector3i(x + p_v.x, y + p_v.y, z + p_v.z); } -constexpr Vector3i &Vector3i::operator-=(const Vector3i &p_v) { +Vector3i &Vector3i::operator-=(const Vector3i &p_v) { x -= p_v.x; y -= p_v.y; z -= p_v.z; return *this; } -constexpr Vector3i Vector3i::operator-(const Vector3i &p_v) const { +Vector3i Vector3i::operator-(const Vector3i &p_v) const { return Vector3i(x - p_v.x, y - p_v.y, z - p_v.z); } -constexpr Vector3i &Vector3i::operator*=(const Vector3i &p_v) { +Vector3i &Vector3i::operator*=(const Vector3i &p_v) { x *= p_v.x; y *= p_v.y; z *= p_v.z; return *this; } -constexpr Vector3i Vector3i::operator*(const Vector3i &p_v) const { +Vector3i Vector3i::operator*(const Vector3i &p_v) const { return Vector3i(x * p_v.x, y * p_v.y, z * p_v.z); } -constexpr Vector3i &Vector3i::operator/=(const Vector3i &p_v) { +Vector3i &Vector3i::operator/=(const Vector3i &p_v) { x /= p_v.x; y /= p_v.y; z /= p_v.z; return *this; } -constexpr Vector3i Vector3i::operator/(const Vector3i &p_v) const { +Vector3i Vector3i::operator/(const Vector3i &p_v) const { return Vector3i(x / p_v.x, y / p_v.y, z / p_v.z); } -constexpr Vector3i &Vector3i::operator%=(const Vector3i &p_v) { +Vector3i &Vector3i::operator%=(const Vector3i &p_v) { x %= p_v.x; y %= p_v.y; z %= p_v.z; return *this; } -constexpr Vector3i Vector3i::operator%(const Vector3i &p_v) const { +Vector3i Vector3i::operator%(const Vector3i &p_v) const { return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z); } -constexpr Vector3i &Vector3i::operator*=(int32_t p_scalar) { +Vector3i &Vector3i::operator*=(int32_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; return *this; } -constexpr Vector3i Vector3i::operator*(int32_t p_scalar) const { +Vector3i Vector3i::operator*(int32_t p_scalar) const { return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar); } // Multiplication operators required to workaround issues with LLVM using implicit conversion. -constexpr Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) { +_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -constexpr Vector3i operator*(int64_t p_scalar, const Vector3i &p_vector) { +_FORCE_INLINE_ Vector3i operator*(int64_t p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -constexpr Vector3i operator*(float p_scalar, const Vector3i &p_vector) { +_FORCE_INLINE_ Vector3i operator*(float p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -constexpr Vector3i operator*(double p_scalar, const Vector3i &p_vector) { +_FORCE_INLINE_ Vector3i operator*(double p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -constexpr Vector3i &Vector3i::operator/=(int32_t p_scalar) { +Vector3i &Vector3i::operator/=(int32_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; return *this; } -constexpr Vector3i Vector3i::operator/(int32_t p_scalar) const { +Vector3i Vector3i::operator/(int32_t p_scalar) const { return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar); } -constexpr Vector3i &Vector3i::operator%=(int32_t p_scalar) { +Vector3i &Vector3i::operator%=(int32_t p_scalar) { x %= p_scalar; y %= p_scalar; z %= p_scalar; return *this; } -constexpr Vector3i Vector3i::operator%(int32_t p_scalar) const { +Vector3i Vector3i::operator%(int32_t p_scalar) const { return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar); } -constexpr Vector3i Vector3i::operator-() const { +Vector3i Vector3i::operator-() const { return Vector3i(-x, -y, -z); } -constexpr bool Vector3i::operator==(const Vector3i &p_v) const { +bool Vector3i::operator==(const Vector3i &p_v) const { return (x == p_v.x && y == p_v.y && z == p_v.z); } -constexpr bool Vector3i::operator!=(const Vector3i &p_v) const { +bool Vector3i::operator!=(const Vector3i &p_v) const { return (x != p_v.x || y != p_v.y || z != p_v.z); } -constexpr bool Vector3i::operator<(const Vector3i &p_v) const { +bool Vector3i::operator<(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z < p_v.z; @@ -295,7 +296,7 @@ constexpr bool Vector3i::operator<(const Vector3i &p_v) const { } } -constexpr bool Vector3i::operator>(const Vector3i &p_v) const { +bool Vector3i::operator>(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z > p_v.z; @@ -307,7 +308,7 @@ constexpr bool Vector3i::operator>(const Vector3i &p_v) const { } } -constexpr bool Vector3i::operator<=(const Vector3i &p_v) const { +bool Vector3i::operator<=(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z <= p_v.z; @@ -319,7 +320,7 @@ constexpr bool Vector3i::operator<=(const Vector3i &p_v) const { } } -constexpr bool Vector3i::operator>=(const Vector3i &p_v) const { +bool Vector3i::operator>=(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z >= p_v.z; @@ -335,5 +336,4 @@ void Vector3i::zero() { x = y = z = 0; } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // VECTOR3I_H diff --git a/engine/core/math/vector4.cpp b/engine/core/math/vector4.cpp index e4fa1769..8ac2c4bf 100644 --- a/engine/core/math/vector4.cpp +++ b/engine/core/math/vector4.cpp @@ -62,10 +62,6 @@ bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); } -bool Vector4::is_same(const Vector4 &p_vec4) const { - return Math::is_same(x, p_vec4.x) && Math::is_same(y, p_vec4.y) && Math::is_same(z, p_vec4.z) && Math::is_same(w, p_vec4.w); -} - bool Vector4::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w); } diff --git a/engine/core/math/vector4.h b/engine/core/math/vector4.h index c8356413..9197e358 100644 --- a/engine/core/math/vector4.h +++ b/engine/core/math/vector4.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef VECTOR4_H +#define VECTOR4_H #include "core/error/error_macros.h" #include "core/math/math_defs.h" @@ -48,7 +49,6 @@ struct [[nodiscard]] Vector4 { }; union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { real_t x; real_t y; @@ -56,7 +56,6 @@ struct [[nodiscard]] Vector4 { real_t w; }; real_t coord[4] = { 0, 0, 0, 0 }; - // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ real_t &operator[](int p_axis) { @@ -90,7 +89,6 @@ struct [[nodiscard]] Vector4 { _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; bool is_zero_approx() const; - bool is_same(const Vector4 &p_vec4) const; bool is_finite() const; real_t length() const; void normalize(); @@ -122,34 +120,37 @@ struct [[nodiscard]] Vector4 { Vector4 inverse() const; _FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const; - constexpr void operator+=(const Vector4 &p_vec4); - constexpr void operator-=(const Vector4 &p_vec4); - constexpr void operator*=(const Vector4 &p_vec4); - constexpr void operator/=(const Vector4 &p_vec4); - constexpr void operator*=(real_t p_s); - constexpr void operator/=(real_t p_s); - constexpr Vector4 operator+(const Vector4 &p_vec4) const; - constexpr Vector4 operator-(const Vector4 &p_vec4) const; - constexpr Vector4 operator*(const Vector4 &p_vec4) const; - constexpr Vector4 operator/(const Vector4 &p_vec4) const; - constexpr Vector4 operator-() const; - constexpr Vector4 operator*(real_t p_s) const; - constexpr Vector4 operator/(real_t p_s) const; + _FORCE_INLINE_ void operator+=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator-=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator*=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator/=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator*=(real_t p_s); + _FORCE_INLINE_ void operator/=(real_t p_s); + _FORCE_INLINE_ Vector4 operator+(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator-(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator*(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator/(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator-() const; + _FORCE_INLINE_ Vector4 operator*(real_t p_s) const; + _FORCE_INLINE_ Vector4 operator/(real_t p_s) const; - constexpr bool operator==(const Vector4 &p_vec4) const; - constexpr bool operator!=(const Vector4 &p_vec4) const; - constexpr bool operator>(const Vector4 &p_vec4) const; - constexpr bool operator<(const Vector4 &p_vec4) const; - constexpr bool operator>=(const Vector4 &p_vec4) const; - constexpr bool operator<=(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator==(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator!=(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator>(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator<(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator>=(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator<=(const Vector4 &p_vec4) const; operator String() const; operator Vector4i() const; - constexpr Vector4() : - x(0), y(0), z(0), w(0) {} - constexpr Vector4(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : - x(p_x), y(p_y), z(p_z), w(p_w) {} + _FORCE_INLINE_ Vector4() {} + _FORCE_INLINE_ Vector4(real_t p_x, real_t p_y, real_t p_z, real_t p_w) { + x = p_x; + y = p_y; + z = p_z; + w = p_w; + } }; real_t Vector4::dot(const Vector4 &p_vec4) const { @@ -160,81 +161,81 @@ real_t Vector4::length_squared() const { return dot(*this); } -constexpr void Vector4::operator+=(const Vector4 &p_vec4) { +void Vector4::operator+=(const Vector4 &p_vec4) { x += p_vec4.x; y += p_vec4.y; z += p_vec4.z; w += p_vec4.w; } -constexpr void Vector4::operator-=(const Vector4 &p_vec4) { +void Vector4::operator-=(const Vector4 &p_vec4) { x -= p_vec4.x; y -= p_vec4.y; z -= p_vec4.z; w -= p_vec4.w; } -constexpr void Vector4::operator*=(const Vector4 &p_vec4) { +void Vector4::operator*=(const Vector4 &p_vec4) { x *= p_vec4.x; y *= p_vec4.y; z *= p_vec4.z; w *= p_vec4.w; } -constexpr void Vector4::operator/=(const Vector4 &p_vec4) { +void Vector4::operator/=(const Vector4 &p_vec4) { x /= p_vec4.x; y /= p_vec4.y; z /= p_vec4.z; w /= p_vec4.w; } -constexpr void Vector4::operator*=(real_t p_s) { +void Vector4::operator*=(real_t p_s) { x *= p_s; y *= p_s; z *= p_s; w *= p_s; } -constexpr void Vector4::operator/=(real_t p_s) { - *this *= (1 / p_s); +void Vector4::operator/=(real_t p_s) { + *this *= 1.0f / p_s; } -constexpr Vector4 Vector4::operator+(const Vector4 &p_vec4) const { +Vector4 Vector4::operator+(const Vector4 &p_vec4) const { return Vector4(x + p_vec4.x, y + p_vec4.y, z + p_vec4.z, w + p_vec4.w); } -constexpr Vector4 Vector4::operator-(const Vector4 &p_vec4) const { +Vector4 Vector4::operator-(const Vector4 &p_vec4) const { return Vector4(x - p_vec4.x, y - p_vec4.y, z - p_vec4.z, w - p_vec4.w); } -constexpr Vector4 Vector4::operator*(const Vector4 &p_vec4) const { +Vector4 Vector4::operator*(const Vector4 &p_vec4) const { return Vector4(x * p_vec4.x, y * p_vec4.y, z * p_vec4.z, w * p_vec4.w); } -constexpr Vector4 Vector4::operator/(const Vector4 &p_vec4) const { +Vector4 Vector4::operator/(const Vector4 &p_vec4) const { return Vector4(x / p_vec4.x, y / p_vec4.y, z / p_vec4.z, w / p_vec4.w); } -constexpr Vector4 Vector4::operator-() const { +Vector4 Vector4::operator-() const { return Vector4(-x, -y, -z, -w); } -constexpr Vector4 Vector4::operator*(real_t p_s) const { +Vector4 Vector4::operator*(real_t p_s) const { return Vector4(x * p_s, y * p_s, z * p_s, w * p_s); } -constexpr Vector4 Vector4::operator/(real_t p_s) const { - return *this * (1 / p_s); +Vector4 Vector4::operator/(real_t p_s) const { + return *this * (1.0f / p_s); } -constexpr bool Vector4::operator==(const Vector4 &p_vec4) const { +bool Vector4::operator==(const Vector4 &p_vec4) const { return x == p_vec4.x && y == p_vec4.y && z == p_vec4.z && w == p_vec4.w; } -constexpr bool Vector4::operator!=(const Vector4 &p_vec4) const { +bool Vector4::operator!=(const Vector4 &p_vec4) const { return x != p_vec4.x || y != p_vec4.y || z != p_vec4.z || w != p_vec4.w; } -constexpr bool Vector4::operator<(const Vector4 &p_v) const { +bool Vector4::operator<(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -247,7 +248,7 @@ constexpr bool Vector4::operator<(const Vector4 &p_v) const { return x < p_v.x; } -constexpr bool Vector4::operator>(const Vector4 &p_v) const { +bool Vector4::operator>(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -260,7 +261,7 @@ constexpr bool Vector4::operator>(const Vector4 &p_v) const { return x > p_v.x; } -constexpr bool Vector4::operator<=(const Vector4 &p_v) const { +bool Vector4::operator<=(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -273,7 +274,7 @@ constexpr bool Vector4::operator<=(const Vector4 &p_v) const { return x < p_v.x; } -constexpr bool Vector4::operator>=(const Vector4 &p_v) const { +bool Vector4::operator>=(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -286,21 +287,20 @@ constexpr bool Vector4::operator>=(const Vector4 &p_v) const { return x > p_v.x; } -constexpr Vector4 operator*(float p_scalar, const Vector4 &p_vec) { +_FORCE_INLINE_ Vector4 operator*(float p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -constexpr Vector4 operator*(double p_scalar, const Vector4 &p_vec) { +_FORCE_INLINE_ Vector4 operator*(double p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -constexpr Vector4 operator*(int32_t p_scalar, const Vector4 &p_vec) { +_FORCE_INLINE_ Vector4 operator*(int32_t p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -constexpr Vector4 operator*(int64_t p_scalar, const Vector4 &p_vec) { +_FORCE_INLINE_ Vector4 operator*(int64_t p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // VECTOR4_H diff --git a/engine/core/math/vector4i.h b/engine/core/math/vector4i.h index 56ae3f22..a9036d68 100644 --- a/engine/core/math/vector4i.h +++ b/engine/core/math/vector4i.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef VECTOR4I_H +#define VECTOR4I_H #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -47,7 +48,6 @@ struct [[nodiscard]] Vector4i { }; union { - // NOLINTBEGIN(modernize-use-default-member-init) struct { int32_t x; int32_t y; @@ -56,7 +56,6 @@ struct [[nodiscard]] Vector4i { }; int32_t coord[4] = { 0 }; - // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ const int32_t &operator[](int p_axis) const { @@ -105,41 +104,44 @@ struct [[nodiscard]] Vector4i { /* Operators */ - constexpr Vector4i &operator+=(const Vector4i &p_v); - constexpr Vector4i operator+(const Vector4i &p_v) const; - constexpr Vector4i &operator-=(const Vector4i &p_v); - constexpr Vector4i operator-(const Vector4i &p_v) const; - constexpr Vector4i &operator*=(const Vector4i &p_v); - constexpr Vector4i operator*(const Vector4i &p_v) const; - constexpr Vector4i &operator/=(const Vector4i &p_v); - constexpr Vector4i operator/(const Vector4i &p_v) const; - constexpr Vector4i &operator%=(const Vector4i &p_v); - constexpr Vector4i operator%(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator+=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator+(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator-=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator-(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator*=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator*(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator/=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator/(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator%=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator%(const Vector4i &p_v) const; - constexpr Vector4i &operator*=(int32_t p_scalar); - constexpr Vector4i operator*(int32_t p_scalar) const; - constexpr Vector4i &operator/=(int32_t p_scalar); - constexpr Vector4i operator/(int32_t p_scalar) const; - constexpr Vector4i &operator%=(int32_t p_scalar); - constexpr Vector4i operator%(int32_t p_scalar) const; + _FORCE_INLINE_ Vector4i &operator*=(int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator*(int32_t p_scalar) const; + _FORCE_INLINE_ Vector4i &operator/=(int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator/(int32_t p_scalar) const; + _FORCE_INLINE_ Vector4i &operator%=(int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator%(int32_t p_scalar) const; - constexpr Vector4i operator-() const; + _FORCE_INLINE_ Vector4i operator-() const; - constexpr bool operator==(const Vector4i &p_v) const; - constexpr bool operator!=(const Vector4i &p_v) const; - constexpr bool operator<(const Vector4i &p_v) const; - constexpr bool operator<=(const Vector4i &p_v) const; - constexpr bool operator>(const Vector4i &p_v) const; - constexpr bool operator>=(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator==(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator!=(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator<(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator<=(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator>(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator>=(const Vector4i &p_v) const; operator String() const; operator Vector4() const; - constexpr Vector4i() : - x(0), y(0), z(0), w(0) {} + _FORCE_INLINE_ Vector4i() {} Vector4i(const Vector4 &p_vec4); - constexpr Vector4i(int32_t p_x, int32_t p_y, int32_t p_z, int32_t p_w) : - x(p_x), y(p_y), z(p_z), w(p_w) {} + _FORCE_INLINE_ Vector4i(int32_t p_x, int32_t p_y, int32_t p_z, int32_t p_w) { + x = p_x; + y = p_y; + z = p_z; + w = p_w; + } }; int64_t Vector4i::length_squared() const { @@ -168,7 +170,7 @@ Vector4i Vector4i::sign() const { /* Operators */ -constexpr Vector4i &Vector4i::operator+=(const Vector4i &p_v) { +Vector4i &Vector4i::operator+=(const Vector4i &p_v) { x += p_v.x; y += p_v.y; z += p_v.z; @@ -176,11 +178,11 @@ constexpr Vector4i &Vector4i::operator+=(const Vector4i &p_v) { return *this; } -constexpr Vector4i Vector4i::operator+(const Vector4i &p_v) const { +Vector4i Vector4i::operator+(const Vector4i &p_v) const { return Vector4i(x + p_v.x, y + p_v.y, z + p_v.z, w + p_v.w); } -constexpr Vector4i &Vector4i::operator-=(const Vector4i &p_v) { +Vector4i &Vector4i::operator-=(const Vector4i &p_v) { x -= p_v.x; y -= p_v.y; z -= p_v.z; @@ -188,11 +190,11 @@ constexpr Vector4i &Vector4i::operator-=(const Vector4i &p_v) { return *this; } -constexpr Vector4i Vector4i::operator-(const Vector4i &p_v) const { +Vector4i Vector4i::operator-(const Vector4i &p_v) const { return Vector4i(x - p_v.x, y - p_v.y, z - p_v.z, w - p_v.w); } -constexpr Vector4i &Vector4i::operator*=(const Vector4i &p_v) { +Vector4i &Vector4i::operator*=(const Vector4i &p_v) { x *= p_v.x; y *= p_v.y; z *= p_v.z; @@ -200,11 +202,11 @@ constexpr Vector4i &Vector4i::operator*=(const Vector4i &p_v) { return *this; } -constexpr Vector4i Vector4i::operator*(const Vector4i &p_v) const { +Vector4i Vector4i::operator*(const Vector4i &p_v) const { return Vector4i(x * p_v.x, y * p_v.y, z * p_v.z, w * p_v.w); } -constexpr Vector4i &Vector4i::operator/=(const Vector4i &p_v) { +Vector4i &Vector4i::operator/=(const Vector4i &p_v) { x /= p_v.x; y /= p_v.y; z /= p_v.z; @@ -212,11 +214,11 @@ constexpr Vector4i &Vector4i::operator/=(const Vector4i &p_v) { return *this; } -constexpr Vector4i Vector4i::operator/(const Vector4i &p_v) const { +Vector4i Vector4i::operator/(const Vector4i &p_v) const { return Vector4i(x / p_v.x, y / p_v.y, z / p_v.z, w / p_v.w); } -constexpr Vector4i &Vector4i::operator%=(const Vector4i &p_v) { +Vector4i &Vector4i::operator%=(const Vector4i &p_v) { x %= p_v.x; y %= p_v.y; z %= p_v.z; @@ -224,11 +226,11 @@ constexpr Vector4i &Vector4i::operator%=(const Vector4i &p_v) { return *this; } -constexpr Vector4i Vector4i::operator%(const Vector4i &p_v) const { +Vector4i Vector4i::operator%(const Vector4i &p_v) const { return Vector4i(x % p_v.x, y % p_v.y, z % p_v.z, w % p_v.w); } -constexpr Vector4i &Vector4i::operator*=(int32_t p_scalar) { +Vector4i &Vector4i::operator*=(int32_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; @@ -236,29 +238,29 @@ constexpr Vector4i &Vector4i::operator*=(int32_t p_scalar) { return *this; } -constexpr Vector4i Vector4i::operator*(int32_t p_scalar) const { +Vector4i Vector4i::operator*(int32_t p_scalar) const { return Vector4i(x * p_scalar, y * p_scalar, z * p_scalar, w * p_scalar); } // Multiplication operators required to workaround issues with LLVM using implicit conversion. -constexpr Vector4i operator*(int32_t p_scalar, const Vector4i &p_vector) { +_FORCE_INLINE_ Vector4i operator*(int32_t p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -constexpr Vector4i operator*(int64_t p_scalar, const Vector4i &p_vector) { +_FORCE_INLINE_ Vector4i operator*(int64_t p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -constexpr Vector4i operator*(float p_scalar, const Vector4i &p_vector) { +_FORCE_INLINE_ Vector4i operator*(float p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -constexpr Vector4i operator*(double p_scalar, const Vector4i &p_vector) { +_FORCE_INLINE_ Vector4i operator*(double p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -constexpr Vector4i &Vector4i::operator/=(int32_t p_scalar) { +Vector4i &Vector4i::operator/=(int32_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; @@ -266,11 +268,11 @@ constexpr Vector4i &Vector4i::operator/=(int32_t p_scalar) { return *this; } -constexpr Vector4i Vector4i::operator/(int32_t p_scalar) const { +Vector4i Vector4i::operator/(int32_t p_scalar) const { return Vector4i(x / p_scalar, y / p_scalar, z / p_scalar, w / p_scalar); } -constexpr Vector4i &Vector4i::operator%=(int32_t p_scalar) { +Vector4i &Vector4i::operator%=(int32_t p_scalar) { x %= p_scalar; y %= p_scalar; z %= p_scalar; @@ -278,23 +280,23 @@ constexpr Vector4i &Vector4i::operator%=(int32_t p_scalar) { return *this; } -constexpr Vector4i Vector4i::operator%(int32_t p_scalar) const { +Vector4i Vector4i::operator%(int32_t p_scalar) const { return Vector4i(x % p_scalar, y % p_scalar, z % p_scalar, w % p_scalar); } -constexpr Vector4i Vector4i::operator-() const { +Vector4i Vector4i::operator-() const { return Vector4i(-x, -y, -z, -w); } -constexpr bool Vector4i::operator==(const Vector4i &p_v) const { +bool Vector4i::operator==(const Vector4i &p_v) const { return (x == p_v.x && y == p_v.y && z == p_v.z && w == p_v.w); } -constexpr bool Vector4i::operator!=(const Vector4i &p_v) const { +bool Vector4i::operator!=(const Vector4i &p_v) const { return (x != p_v.x || y != p_v.y || z != p_v.z || w != p_v.w); } -constexpr bool Vector4i::operator<(const Vector4i &p_v) const { +bool Vector4i::operator<(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -310,7 +312,7 @@ constexpr bool Vector4i::operator<(const Vector4i &p_v) const { } } -constexpr bool Vector4i::operator>(const Vector4i &p_v) const { +bool Vector4i::operator>(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -326,7 +328,7 @@ constexpr bool Vector4i::operator>(const Vector4i &p_v) const { } } -constexpr bool Vector4i::operator<=(const Vector4i &p_v) const { +bool Vector4i::operator<=(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -342,7 +344,7 @@ constexpr bool Vector4i::operator<=(const Vector4i &p_v) const { } } -constexpr bool Vector4i::operator>=(const Vector4i &p_v) const { +bool Vector4i::operator>=(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -362,5 +364,4 @@ void Vector4i::zero() { x = y = z = w = 0; } -template <> -struct is_zero_constructible : std::true_type {}; +#endif // VECTOR4I_H diff --git a/engine/core/object/callable_method_pointer.h b/engine/core/object/callable_method_pointer.h index 7462316d..a12db51c 100644 --- a/engine/core/object/callable_method_pointer.h +++ b/engine/core/object/callable_method_pointer.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CALLABLE_METHOD_POINTER_H +#define CALLABLE_METHOD_POINTER_H #include "core/object/object.h" #include "core/variant/binder_common.h" @@ -81,7 +82,8 @@ class CallableCustomMethodPointer : public CallableCustomMethodPointerBase { struct Data { T *instance; uint64_t object_id; - R (T::*method)(P...); + R(T::*method) + (P...); } data; public: @@ -150,7 +152,8 @@ class CallableCustomMethodPointerC : public CallableCustomMethodPointerBase { struct Data { T *instance; uint64_t object_id; - R (T::*method)(P...) const; + R(T::*method) + (P...) const; } data; public: @@ -223,7 +226,8 @@ Callable create_custom_callable_function_pointer(T *p_instance, template class CallableCustomStaticMethodPointer : public CallableCustomMethodPointerBase { struct Data { - R (*method)(P...); + R(*method) + (P...); } data; public: @@ -288,3 +292,5 @@ Callable create_custom_callable_static_function_pointer( #else #define callable_mp_static(M) create_custom_callable_static_function_pointer(M) #endif + +#endif // CALLABLE_METHOD_POINTER_H diff --git a/engine/core/object/class_db.cpp b/engine/core/object/class_db.cpp index fbc5fcda..e6536fe8 100644 --- a/engine/core/object/class_db.cpp +++ b/engine/core/object/class_db.cpp @@ -35,6 +35,9 @@ #include "core/object/script_language.h" #include "core/version.h" +#define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock); +#define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock); + #ifdef DEBUG_METHODS_ENABLED MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint32_t p_argcount) { @@ -235,13 +238,13 @@ bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_in } bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; return _is_parent_class(p_class, p_inherits); } void ClassDB::get_class_list(List *p_classes) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; for (const KeyValue &E : classes) { p_classes->push_back(E.key); @@ -252,7 +255,7 @@ void ClassDB::get_class_list(List *p_classes) { #ifdef TOOLS_ENABLED void ClassDB::get_extensions_class_list(List *p_classes) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; for (const KeyValue &E : classes) { if (E.value.api != API_EXTENSION && E.value.api != API_EDITOR_EXTENSION) { @@ -265,7 +268,7 @@ void ClassDB::get_extensions_class_list(List *p_classes) { } void ClassDB::get_extension_class_list(const Ref &p_extension, List *p_classes) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; for (const KeyValue &E : classes) { if (E.value.api != API_EXTENSION && E.value.api != API_EDITOR_EXTENSION) { @@ -281,28 +284,28 @@ void ClassDB::get_extension_class_list(const Ref &p_extension, List } #endif -void ClassDB::get_inheriters_from_class(const StringName &p_class, LocalVector &p_classes) { - Locker::Lock lock(Locker::STATE_READ); +void ClassDB::get_inheriters_from_class(const StringName &p_class, List *p_classes) { + OBJTYPE_RLOCK; for (const KeyValue &E : classes) { if (E.key != p_class && _is_parent_class(E.key, p_class)) { - p_classes.push_back(E.key); + p_classes->push_back(E.key); } } } void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List *p_classes) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; for (const KeyValue &E : classes) { - if (E.value.inherits == p_class) { + if (E.key != p_class && _get_parent_class(E.key) == p_class) { p_classes->push_back(E.key); } } } StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -312,7 +315,7 @@ StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) { } bool ClassDB::get_inheritance_chain_nocheck(const StringName &p_class, Vector &r_result) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *start = classes.getptr(p_class); if (!start) { @@ -353,13 +356,13 @@ StringName ClassDB::_get_parent_class(const StringName &p_class) { } StringName ClassDB::get_parent_class(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; return _get_parent_class(p_class); } ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); @@ -369,13 +372,13 @@ ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) { uint32_t ClassDB::get_api_hash(APIType p_api) { #ifdef DEBUG_METHODS_ENABLED - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; if (api_hashes_cache.has(p_api)) { return api_hashes_cache[p_api]; } - uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(GODOT_VERSION_FULL_CONFIG)); + uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); List class_list; for (const KeyValue &E : classes) { @@ -517,12 +520,12 @@ uint32_t ClassDB::get_api_hash(APIType p_api) { } bool ClassDB::class_exists(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; return classes.has(p_class); } void ClassDB::add_compatibility_class(const StringName &p_class, const StringName &p_fallback) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; compat_classes[p_class] = p_fallback; } @@ -533,21 +536,18 @@ StringName ClassDB::get_compatibility_class(const StringName &p_class) { return StringName(); } -Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize, bool p_exposed_only) { +Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize) { ClassInfo *ti; { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ti = classes.getptr(p_class); - if (!_can_instantiate(ti, p_exposed_only)) { + if (!_can_instantiate(ti)) { if (compat_classes.has(p_class)) { ti = classes.getptr(compat_classes[p_class]); } } ERR_FAIL_NULL_V_MSG(ti, nullptr, vformat("Cannot get class '%s'.", String(p_class))); ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, vformat("Class '%s' is disabled.", String(p_class))); - if (p_exposed_only) { - ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class))); - } ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, vformat("Class '%s' or its base class cannot be instantiated.", String(p_class))); } @@ -599,15 +599,11 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require } } -bool ClassDB::_can_instantiate(ClassInfo *p_class_info, bool p_exposed_only) { +bool ClassDB::_can_instantiate(ClassInfo *p_class_info) { if (!p_class_info) { return false; } - if (p_exposed_only && !p_class_info->exposed) { - return false; - } - if (p_class_info->disabled || !p_class_info->creation_func) { return false; } @@ -649,7 +645,7 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class) ClassInfo *ti; { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ti = classes.getptr(p_class); if (!_can_instantiate(ti)) { if (compat_classes.has(p_class)) { @@ -734,7 +730,7 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName & ERR_FAIL_NULL(p_object); ClassInfo *ti; { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ti = classes.getptr(p_class); if (!_can_instantiate(ti)) { if (compat_classes.has(p_class)) { @@ -759,7 +755,7 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName & bool ClassDB::can_instantiate(const StringName &p_class) { String script_path; { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -785,7 +781,7 @@ use_script: bool ClassDB::is_abstract(const StringName &p_class) { String script_path; { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -817,7 +813,7 @@ use_script: bool ClassDB::is_virtual(const StringName &p_class) { String script_path; { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -840,8 +836,8 @@ use_script: return scr.is_valid() && scr->is_valid() && scr->is_abstract(); } -void ClassDB::_add_class(const StringName &p_class, const StringName &p_inherits) { - Locker::Lock lock(Locker::STATE_WRITE); +void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) { + OBJTYPE_WLOCK; const StringName &name = p_class; @@ -884,7 +880,7 @@ static MethodInfo info_from_bind(MethodBind *p_method) { } void ClassDB::get_method_list(const StringName &p_class, List *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -930,7 +926,7 @@ void ClassDB::get_method_list(const StringName &p_class, List *p_met } void ClassDB::get_method_list_with_compatibility(const StringName &p_class, List> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -990,7 +986,7 @@ void ClassDB::get_method_list_with_compatibility(const StringName &p_class, List } bool ClassDB::get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance, bool p_exclude_from_properties) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1040,7 +1036,7 @@ bool ClassDB::get_method_info(const StringName &p_class, const StringName &p_met } MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_name) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1055,7 +1051,7 @@ MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_n } Vector ClassDB::get_method_compatibility_hashes(const StringName &p_class, const StringName &p_name) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1074,7 +1070,7 @@ Vector ClassDB::get_method_compatibility_hashes(const StringName &p_cl } MethodBind *ClassDB::get_method_with_compatibility(const StringName &p_class, const StringName &p_name, uint64_t p_hash, bool *r_method_exists, bool *r_is_deprecated) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1109,7 +1105,7 @@ MethodBind *ClassDB::get_method_with_compatibility(const StringName &p_class, co } void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1146,7 +1142,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName } void ClassDB::get_integer_constant_list(const StringName &p_class, List *p_constants, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1171,7 +1167,7 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List } int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1195,7 +1191,7 @@ int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringNam } bool ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1214,7 +1210,7 @@ bool ClassDB::has_integer_constant(const StringName &p_class, const StringName & } StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1238,7 +1234,7 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S } void ClassDB::get_enum_list(const StringName &p_class, List *p_enums, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1256,7 +1252,7 @@ void ClassDB::get_enum_list(const StringName &p_class, List *p_enums } void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_enum, List *p_constants, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1279,7 +1275,7 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_ void ClassDB::set_method_error_return_values(const StringName &p_class, const StringName &p_method, const Vector &p_values) { #ifdef DEBUG_METHODS_ENABLED - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1290,7 +1286,7 @@ void ClassDB::set_method_error_return_values(const StringName &p_class, const St Vector ClassDB::get_method_error_return_values(const StringName &p_class, const StringName &p_method) { #ifdef DEBUG_METHODS_ENABLED - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL_V(type, Vector()); @@ -1305,7 +1301,7 @@ Vector ClassDB::get_method_error_return_values(const StringName &p_class, } bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1324,7 +1320,7 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool } bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1343,7 +1339,7 @@ bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_na } void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1362,7 +1358,7 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) } void ClassDB::get_signal_list(const StringName &p_class, List *p_signals, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1383,7 +1379,7 @@ void ClassDB::get_signal_list(const StringName &p_class, List *p_sig } bool ClassDB::has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { @@ -1400,7 +1396,7 @@ bool ClassDB::has_signal(const StringName &p_class, const StringName &p_signal, } bool ClassDB::get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { @@ -1417,7 +1413,7 @@ bool ClassDB::get_signal(const StringName &p_class, const StringName &p_signal, } void ClassDB::add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix, int p_indent_depth) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1430,7 +1426,7 @@ void ClassDB::add_property_group(const StringName &p_class, const String &p_name } void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix, int p_indent_depth) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1447,7 +1443,7 @@ void ClassDB::add_property_array_count(const StringName &p_class, const String & } void ClassDB::add_property_array(const StringName &p_class, const StringName &p_path, const String &p_array_element_prefix) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1456,9 +1452,9 @@ void ClassDB::add_property_array(const StringName &p_class, const StringName &p_ // NOTE: For implementation simplicity reasons, this method doesn't allow setters to have optional arguments at the end. void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { - Locker::Lock lock(Locker::STATE_WRITE); - + lock.read_lock(); ClassInfo *type = classes.getptr(p_class); + lock.read_unlock(); ERR_FAIL_NULL(type); @@ -1490,6 +1486,8 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf ERR_FAIL_COND_MSG(type->property_setget.has(p_pinfo.name), vformat("Object '%s' already has property '%s'.", p_class, p_pinfo.name)); #endif + OBJTYPE_WLOCK + type->property_list.push_back(p_pinfo); type->property_map[p_pinfo.name] = p_pinfo; #ifdef DEBUG_METHODS_ENABLED @@ -1520,7 +1518,7 @@ void ClassDB::set_property_default_value(const StringName &p_class, const String void ClassDB::add_linked_property(const StringName &p_class, const String &p_property, const String &p_linked_property) { #ifdef TOOLS_ENABLED - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1536,7 +1534,7 @@ void ClassDB::add_linked_property(const StringName &p_class, const String &p_pro } void ClassDB::get_property_list(const StringName &p_class, List *p_list, bool p_no_inheritance, const Object *p_validator) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; @@ -1579,7 +1577,7 @@ void ClassDB::get_linked_properties_info(const StringName &p_class, const String } bool ClassDB::get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance, const Object *p_validator) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *check = classes.getptr(p_class); while (check) { @@ -1802,7 +1800,7 @@ bool ClassDB::has_property(const StringName &p_class, const StringName &p_proper } void ClassDB::set_method_flags(const StringName &p_class, const StringName &p_method, int p_flags) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; ERR_FAIL_NULL(check); @@ -1827,7 +1825,7 @@ bool ClassDB::has_method(const StringName &p_class, const StringName &p_method, } int ClassDB::get_method_argument_count(const StringName &p_class, const StringName &p_method, bool *r_is_valid, bool p_no_inheritance) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -1866,7 +1864,7 @@ void ClassDB::_bind_compatibility(ClassInfo *type, MethodBind *p_method) { } void ClassDB::_bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; StringName method_name = p_method->get_name(); @@ -1935,7 +1933,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_ StringName mdname = StaticCString::create(method_name); #endif - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ERR_FAIL_NULL_V(p_bind, nullptr); p_bind->set_name(mdname); @@ -1998,7 +1996,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual, const Vector &p_arg_names, bool p_object_core) { ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; #ifdef DEBUG_METHODS_ENABLED MethodInfo mi = p_method; @@ -2013,8 +2011,9 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_ if (p_arg_names.size() != mi.arguments.size()) { WARN_PRINT(vformat("Mismatch argument name count for virtual method: '%s::%s'.", String(p_class), p_method.name)); } else { - for (int64_t i = 0; i < p_arg_names.size(); ++i) { - mi.arguments.write[i].name = p_arg_names[i]; + List::Iterator itr = mi.arguments.begin(); + for (int i = 0; i < p_arg_names.size(); ++itr, ++i) { + itr->name = p_arg_names[i]; } } } @@ -2032,7 +2031,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_ void ClassDB::add_virtual_compatibility_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual, const Vector &p_arg_names, bool p_object_core) { ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; HashMap> &virtual_methods_compat = classes[p_class].virtual_methods_compat; @@ -2067,7 +2066,7 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List *p } Vector ClassDB::get_virtual_method_compatibility_hashes(const StringName &p_class, const StringName &p_name) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -2108,14 +2107,14 @@ void ClassDB::add_extension_class_virtual_method(const StringName &p_class, cons } void ClassDB::set_class_enabled(const StringName &p_class, bool p_enable) { - Locker::Lock lock(Locker::STATE_WRITE); + OBJTYPE_WLOCK; ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); classes[p_class].disabled = !p_enable; } bool ClassDB::is_class_enabled(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); if (!ti || !ti->creation_func) { @@ -2129,7 +2128,7 @@ bool ClassDB::is_class_enabled(const StringName &p_class) { } bool ClassDB::is_class_exposed(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); @@ -2137,7 +2136,7 @@ bool ClassDB::is_class_exposed(const StringName &p_class) { } bool ClassDB::is_class_reloadable(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); @@ -2145,7 +2144,7 @@ bool ClassDB::is_class_reloadable(const StringName &p_class) { } bool ClassDB::is_class_runtime(const StringName &p_class) { - Locker::Lock lock(Locker::STATE_READ); + OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); @@ -2343,9 +2342,7 @@ uint64_t ClassDB::get_native_struct_size(const StringName &p_name) { return native_structs[p_name].struct_size; } -Object *ClassDB::_instantiate_allow_unexposed(const StringName &p_class) { - return _instantiate_internal(p_class, false, true, false); -} +RWLock ClassDB::lock; void ClassDB::cleanup_defaults() { default_values.clear(); @@ -2382,32 +2379,3 @@ bool ClassDB::is_default_array_arg(const Array &p_array) { } // - -ClassDB::Locker::Lock::Lock(Locker::State p_state) { - DEV_ASSERT(p_state != STATE_UNLOCKED); - if (p_state == STATE_READ) { - if (Locker::thread_state == STATE_UNLOCKED) { - state = STATE_READ; - Locker::thread_state = STATE_READ; - Locker::lock.read_lock(); - } - } else if (p_state == STATE_WRITE) { - if (Locker::thread_state == STATE_UNLOCKED) { - state = STATE_WRITE; - Locker::thread_state = STATE_WRITE; - Locker::lock.write_lock(); - } else if (Locker::thread_state == STATE_READ) { - CRASH_NOW_MSG("Lock can't be upgraded from read to write."); - } - } -} - -ClassDB::Locker::Lock::~Lock() { - if (state == STATE_READ) { - Locker::lock.read_unlock(); - Locker::thread_state = STATE_UNLOCKED; - } else if (state == STATE_WRITE) { - Locker::lock.write_unlock(); - Locker::thread_state = STATE_UNLOCKED; - } -} diff --git a/engine/core/object/class_db.h b/engine/core/object/class_db.h index f90b691b..ed9550cc 100644 --- a/engine/core/object/class_db.h +++ b/engine/core/object/class_db.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef CLASS_DB_H +#define CLASS_DB_H #include "core/object/method_bind.h" #include "core/object/object.h" @@ -78,8 +79,6 @@ MethodDefinition D_METHOD(const char *p_name, const VarArgs... p_args) { #endif class ClassDB { - friend class Object; - public: enum APIType { API_CORE, @@ -154,30 +153,7 @@ public: return ret; } - // We need a recursive r/w lock because there are various code paths - // that may in turn invoke other entry points with require locking. - class Locker { - public: - enum State { - STATE_UNLOCKED, - STATE_READ, - STATE_WRITE, - }; - - private: - inline static RWLock lock; - inline thread_local static State thread_state = STATE_UNLOCKED; - - public: - class Lock { - State state = STATE_UNLOCKED; - - public: - explicit Lock(State p_state); - ~Lock(); - }; - }; - + static RWLock lock; static HashMap classes; static HashMap resource_base_extensions; static HashMap compat_classes; @@ -195,7 +171,7 @@ public: static APIType current_api; static HashMap api_hashes_cache; - static void _add_class(const StringName &p_class, const StringName &p_inherits); + static void _add_class2(const StringName &p_class, const StringName &p_inherits); static HashMap> default_values; static HashSet default_values_cached; @@ -218,14 +194,20 @@ private: static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector &p_default_args, bool p_compatibility); static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility); - static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true, bool p_exposed_only = true); + static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true); - static bool _can_instantiate(ClassInfo *p_class_info, bool p_exposed_only = true); + static bool _can_instantiate(ClassInfo *p_class_info); public: + // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! + template + static void _add_class() { + _add_class2(T::get_class_static(), T::get_parent_class_static()); + } + template static void register_class(bool p_virtual = false) { - Locker::Lock lock(Locker::STATE_WRITE); + GLOBAL_LOCK_FUNCTION; static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -240,7 +222,7 @@ public: template static void register_abstract_class() { - Locker::Lock lock(Locker::STATE_WRITE); + GLOBAL_LOCK_FUNCTION; static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -253,7 +235,7 @@ public: template static void register_internal_class() { - Locker::Lock lock(Locker::STATE_WRITE); + GLOBAL_LOCK_FUNCTION; static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -268,7 +250,7 @@ public: template static void register_runtime_class() { - Locker::Lock lock(Locker::STATE_WRITE); + GLOBAL_LOCK_FUNCTION; static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -293,7 +275,7 @@ public: template static void register_custom_instance_class() { - Locker::Lock lock(Locker::STATE_WRITE); + GLOBAL_LOCK_FUNCTION; static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -311,7 +293,7 @@ public: static void get_extension_class_list(const Ref &p_extension, List *p_classes); static ObjectGDExtension *get_placeholder_extension(const StringName &p_class); #endif - static void get_inheriters_from_class(const StringName &p_class, LocalVector &p_classes); + static void get_inheriters_from_class(const StringName &p_class, List *p_classes); static void get_direct_inheriters_from_class(const StringName &p_class, List *p_classes); static StringName get_parent_class_nocheck(const StringName &p_class); static bool get_inheritance_chain_nocheck(const StringName &p_class, Vector &r_result); @@ -409,7 +391,7 @@ public: template static MethodBind *bind_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector &p_default_args = Vector(), bool p_return_nil_is_variant = true) { - Locker::Lock lock(Locker::STATE_WRITE); + GLOBAL_LOCK_FUNCTION; MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant); ERR_FAIL_NULL_V(bind, nullptr); @@ -422,7 +404,7 @@ public: template static MethodBind *bind_compatibility_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector &p_default_args = Vector(), bool p_return_nil_is_variant = true) { - Locker::Lock lock(Locker::STATE_WRITE); + GLOBAL_LOCK_FUNCTION; MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant); ERR_FAIL_NULL_V(bind, nullptr); @@ -516,8 +498,6 @@ public: static void get_native_struct_list(List *r_names); static String get_native_struct_code(const StringName &p_name); static uint64_t get_native_struct_size(const StringName &p_name); // Used for asserting - - static Object *_instantiate_allow_unexposed(const StringName &p_class); // Used to create unexposed classes from GDExtension, typically for unexposed EditorPlugin. }; #define BIND_ENUM_CONSTANT(m_constant) \ @@ -583,3 +563,7 @@ _FORCE_INLINE_ Vector errarray(P... p_args) { } #define GDREGISTER_NATIVE_STRUCT(m_class, m_code) ClassDB::register_native_struct(#m_class, m_code, sizeof(m_class)) + +#include "core/disabled_classes.gen.h" + +#endif // CLASS_DB_H diff --git a/engine/core/object/make_virtuals.py b/engine/core/object/make_virtuals.py index e130edbc..13775ecd 100644 --- a/engine/core/object/make_virtuals.py +++ b/engine/core/object/make_virtuals.py @@ -15,65 +15,57 @@ script_has_method = """ScriptInstance *_script_instance = ((Object *)(this))->ge }""" proto = """#define GDVIRTUAL$VER($ALIAS $RET m_name $ARG)\\ + StringName _gdvirtual_##$VARNAME##_sn = #m_name;\\ + mutable bool _gdvirtual_##$VARNAME##_initialized = false;\\ mutable void *_gdvirtual_##$VARNAME = nullptr;\\ _FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_call($CALLARGS) $CONST {\\ - static const StringName _gdvirtual_##$VARNAME##_sn = _scs_create(#m_name, true);\\ $SCRIPTCALL\\ - if (_get_extension()) {\\ - if (unlikely(!_gdvirtual_##$VARNAME)) {\\ - MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ - uint32_t hash = mi.get_compatibility_hash();\\ - _gdvirtual_##$VARNAME = nullptr;\\ - if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ - _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ - } else if (_get_extension()->get_virtual2) {\\ - _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ - }\\ - _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ - _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME);\\ - if (_gdvirtual_##$VARNAME == nullptr) {\\ - _gdvirtual_##$VARNAME = reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR);\\ - }\\ + if (unlikely(_get_extension() && !_gdvirtual_##$VARNAME##_initialized)) {\\ + MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ + uint32_t hash = mi.get_compatibility_hash();\\ + _gdvirtual_##$VARNAME = nullptr;\\ + if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ + _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + } else if (_get_extension()->get_virtual2) {\\ + _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ }\\ - if (_gdvirtual_##$VARNAME != reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR)) {\\ - $CALLPTRARGS\\ - $CALLPTRRETDEF\\ - if (_get_extension()->call_virtual_with_data) {\\ - _get_extension()->call_virtual_with_data(_get_extension_instance(), &_gdvirtual_##$VARNAME##_sn, _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\ - $CALLPTRRET\\ - } else {\\ - ((GDExtensionClassCallVirtual)_gdvirtual_##$VARNAME)(_get_extension_instance(), $CALLPTRARGPASS, $CALLPTRRETPASS);\\ - $CALLPTRRET\\ - }\\ - return true;\\ + _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ + _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_initialized);\\ + _gdvirtual_##$VARNAME##_initialized = true;\\ + }\\ + if (_gdvirtual_##$VARNAME) {\\ + $CALLPTRARGS\\ + $CALLPTRRETDEF\\ + if (_get_extension()->call_virtual_with_data) {\\ + _get_extension()->call_virtual_with_data(_get_extension_instance(), &_gdvirtual_##$VARNAME##_sn, _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\ + $CALLPTRRET\\ + } else {\\ + ((GDExtensionClassCallVirtual)_gdvirtual_##$VARNAME)(_get_extension_instance(), $CALLPTRARGPASS, $CALLPTRRETPASS);\\ + $CALLPTRRET\\ }\\ + return true;\\ }\\ $REQCHECK\\ $RVOID\\ return false;\\ }\\ _FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_overridden() const {\\ - static const StringName _gdvirtual_##$VARNAME##_sn = _scs_create(#m_name, true);\\ $SCRIPTHASMETHOD\\ - if (_get_extension()) {\\ - if (unlikely(!_gdvirtual_##$VARNAME)) {\\ - MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ - uint32_t hash = mi.get_compatibility_hash();\\ - _gdvirtual_##$VARNAME = nullptr;\\ - if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ - _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ - } else if (_get_extension()->get_virtual2) {\\ - _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ - }\\ - _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ - _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME);\\ - if (_gdvirtual_##$VARNAME == nullptr) {\\ - _gdvirtual_##$VARNAME = reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR);\\ - }\\ - }\\ - if (_gdvirtual_##$VARNAME != reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR)) {\\ - return true;\\ + if (unlikely(_get_extension() && !_gdvirtual_##$VARNAME##_initialized)) {\\ + MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ + uint32_t hash = mi.get_compatibility_hash();\\ + _gdvirtual_##$VARNAME = nullptr;\\ + if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ + _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + } else if (_get_extension()->get_virtual2) {\\ + _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ }\\ + _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ + _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_initialized);\\ + _gdvirtual_##$VARNAME##_initialized = true;\\ + }\\ + if (_gdvirtual_##$VARNAME) {\\ + return true;\\ }\\ return false;\\ }\\ @@ -215,22 +207,24 @@ def run(target, source, env): max_versions = 12 txt = """/* THIS FILE IS GENERATED DO NOT EDIT */ -#pragma once +#ifndef GDVIRTUAL_GEN_H +#define GDVIRTUAL_GEN_H #include "core/object/script_instance.h" -inline constexpr uintptr_t _INVALID_GDVIRTUAL_FUNC_ADDR = static_cast(-1); +#include #ifdef TOOLS_ENABLED -#define _GDVIRTUAL_TRACK(m_virtual)\\ +#define _GDVIRTUAL_TRACK(m_virtual, m_initialized)\\ if (_get_extension()->reloadable) {\\ VirtualMethodTracker *tracker = memnew(VirtualMethodTracker);\\ tracker->method = (void **)&m_virtual;\\ + tracker->initialized = &m_initialized;\\ tracker->next = virtual_method_list;\\ virtual_method_list = tracker;\\ } #else -#define _GDVIRTUAL_TRACK(m_virtual) +#define _GDVIRTUAL_TRACK(m_virtual, m_initialized) #endif #ifndef DISABLE_DEPRECATED @@ -263,5 +257,7 @@ inline constexpr uintptr_t _INVALID_GDVIRTUAL_FUNC_ADDR = static_cast txt += generate_version(i, True, False, False, True) txt += generate_version(i, True, True, False, True) + txt += "#endif // GDVIRTUAL_GEN_H\n" + with open(str(target[0]), "w", encoding="utf-8", newline="\n") as f: f.write(txt) diff --git a/engine/core/object/message_queue.cpp b/engine/core/object/message_queue.cpp index 673e60d6..4b0b1ce6 100644 --- a/engine/core/object/message_queue.cpp +++ b/engine/core/object/message_queue.cpp @@ -226,7 +226,7 @@ void CallQueue::_call_function(const Callable &p_callable, const Variant *p_args Error CallQueue::flush() { LOCK_MUTEX; - if (pages.is_empty()) { + if (pages.size() == 0) { // Never allocated UNLOCK_MUTEX; return OK; // Do nothing. @@ -308,7 +308,7 @@ Error CallQueue::flush() { void CallQueue::clear() { LOCK_MUTEX; - if (pages.is_empty()) { + if (pages.size() == 0) { UNLOCK_MUTEX; return; // Nothing to clear. } diff --git a/engine/core/object/message_queue.h b/engine/core/object/message_queue.h index 8a66d0c1..64e244bd 100644 --- a/engine/core/object/message_queue.h +++ b/engine/core/object/message_queue.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef MESSAGE_QUEUE_H +#define MESSAGE_QUEUE_H #include "core/object/object_id.h" #include "core/os/thread_safe.h" @@ -170,3 +171,5 @@ public: MessageQueue(); ~MessageQueue(); }; + +#endif // MESSAGE_QUEUE_H diff --git a/engine/core/object/method_bind.h b/engine/core/object/method_bind.h index 93683ee6..a07824a0 100644 --- a/engine/core/object/method_bind.h +++ b/engine/core/object/method_bind.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef METHOD_BIND_H +#define METHOD_BIND_H #include "core/variant/binder_common.h" @@ -142,7 +143,8 @@ public: template class MethodBindVarArgBase : public MethodBind { protected: - R (T::*method)(const Variant **, int, Callable::CallError &); + R(T::*method) + (const Variant **, int, Callable::CallError &); MethodInfo method_info; public: @@ -150,7 +152,7 @@ public: if (p_arg < 0) { return _gen_return_type_info(); } else if (p_arg < method_info.arguments.size()) { - return method_info.arguments[p_arg]; + return method_info.arguments.get(p_arg); } else { return PropertyInfo(Variant::NIL, "arg_" + itos(p_arg), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } @@ -191,10 +193,11 @@ public: Vector names; names.resize(method_info.arguments.size()); #endif - for (int64_t i = 0; i < method_info.arguments.size(); ++i) { - at[i + 1] = method_info.arguments[i].type; + int i = 0; + for (List::ConstIterator itr = method_info.arguments.begin(); itr != method_info.arguments.end(); ++itr, ++i) { + at[i + 1] = itr->type; #ifdef DEBUG_METHODS_ENABLED - names.write[i] = method_info.arguments[i].name; + names.write[i] = itr->name; #endif } @@ -256,8 +259,11 @@ class MethodBindVarArgTR : public MethodBindVarArgBase, friend class MethodBindVarArgBase, T, R, true>; public: - GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wmaybe-uninitialized") // Workaround GH-66343 raised only with UBSAN, seems to be a false positive. - +#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) + // Workaround GH-66343 raised only with UBSAN, seems to be a false positive. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { #ifdef TOOLS_ENABLED ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == MethodBind::get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name())); @@ -265,7 +271,9 @@ public: return (static_cast(p_object)->*MethodBindVarArgBase, T, R, true>::method)(p_args, p_arg_count, r_error); } - GODOT_GCC_WARNING_POP +#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif MethodBindVarArgTR( R (T::*p_method)(const Variant **, int, Callable::CallError &), @@ -472,7 +480,8 @@ template template #endif class MethodBindTR : public MethodBind { - R (MB_T::*method)(P...); + R(MB_T::*method) + (P...); protected: virtual Variant::Type _gen_argument_type(int p_arg) const override { @@ -567,7 +576,8 @@ template template #endif class MethodBindTRC : public MethodBind { - R (MB_T::*method)(P...) const; + R(MB_T::*method) + (P...) const; protected: virtual Variant::Type _gen_argument_type(int p_arg) const override { @@ -718,7 +728,8 @@ MethodBind *create_static_method_bind(void (*p_method)(P...)) { template class MethodBindTRS : public MethodBind { - R (*function)(P...); + R(*function) + (P...); protected: virtual Variant::Type _gen_argument_type(int p_arg) const override { @@ -779,3 +790,5 @@ MethodBind *create_static_method_bind(R (*p_method)(P...)) { MethodBind *a = memnew((MethodBindTRS)(p_method)); return a; } + +#endif // METHOD_BIND_H diff --git a/engine/core/object/object.cpp b/engine/core/object/object.cpp index 852d877f..8df107ec 100644 --- a/engine/core/object/object.cpp +++ b/engine/core/object/object.cpp @@ -115,19 +115,10 @@ TypedArray convert_property_list(const List *p_list) { return va; } -TypedArray convert_property_list(const Vector &p_vector) { - TypedArray va; - for (const PropertyInfo &E : p_vector) { - va.push_back(Dictionary(E)); - } - - return va; -} - MethodInfo::operator Dictionary() const { Dictionary d; d["name"] = name; - d["args"] = convert_property_list(arguments); + d["args"] = convert_property_list(&arguments); Array da; for (int i = 0; i < default_arguments.size(); i++) { da.push_back(default_arguments[i]); @@ -249,15 +240,21 @@ void Object::cancel_free() { } void Object::_initialize() { - // Cache the class name in the object for quick reference. - _class_name_ptr = _get_class_namev(); + _class_name_ptr = _get_class_namev(); // Set the direct pointer, which is much faster to obtain, but can only happen after _initialize. _initialize_classv(); + _class_name_ptr = nullptr; // May have been called from a constructor. } void Object::_postinitialize() { notification(NOTIFICATION_POSTINITIALIZE); } +void Object::get_valid_parents_static(List *p_parents) { +} + +void Object::_get_valid_parents_static(List *p_parents) { +} + void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid) { #ifdef TOOLS_ENABLED @@ -905,14 +902,18 @@ Variant Object::call_const(const StringName &p_method, const Variant **p_args, i return ret; } -void Object::_notification_forward(int p_notification) { - // Notify classes starting with Object and ending with most derived subclass. - // e.g. Object -> Node -> Node3D - _notification_forwardv(p_notification); +void Object::notification(int p_notification, bool p_reversed) { + if (p_reversed) { + if (script_instance) { + script_instance->notification(p_notification, p_reversed); + } + } else { + _notificationv(p_notification, p_reversed); + } if (_extension) { if (_extension->notification2) { - _extension->notification2(_extension_instance, p_notification, static_cast(false)); + _extension->notification2(_extension_instance, p_notification, static_cast(p_reversed)); #ifndef DISABLE_DEPRECATED } else if (_extension->notification) { _extension->notification(_extension_instance, p_notification); @@ -920,29 +921,13 @@ void Object::_notification_forward(int p_notification) { } } - if (script_instance) { - script_instance->notification(p_notification, false); - } -} - -void Object::_notification_backward(int p_notification) { - if (script_instance) { - script_instance->notification(p_notification, true); - } - - if (_extension) { - if (_extension->notification2) { - _extension->notification2(_extension_instance, p_notification, static_cast(true)); -#ifndef DISABLE_DEPRECATED - } else if (_extension->notification) { - _extension->notification(_extension_instance, p_notification); -#endif // DISABLE_DEPRECATED + if (p_reversed) { + _notificationv(p_notification, p_reversed); + } else { + if (script_instance) { + script_instance->notification(p_notification, p_reversed); } } - - // Notify classes starting with most derived subclass and ending in Object. - // e.g. Node3D -> Node -> Object - _notification_backwardv(p_notification); } String Object::to_string() { @@ -1095,8 +1080,8 @@ TypedArray Object::_get_method_list_bind() const { get_method_list(&ml); TypedArray ret; - for (const MethodInfo &mi : ml) { - Dictionary d = mi; + for (List::Element *E = ml.front(); E; E = E->next()) { + Dictionary d = E->get(); //va.push_back(d); ret.push_back(d); } @@ -1590,7 +1575,7 @@ void Object::initialize_class() { if (initialized) { return; } - _add_class_to_classdb(get_class_static(), StringName()); + ClassDB::_add_class(); _bind_methods(); _bind_compatibility_methods(); initialized = true; @@ -1655,10 +1640,12 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { } break; case Variant::DICTIONARY: { Dictionary d = p_var; + List keys; + d.get_key_list(&keys); - for (const KeyValue &kv : d) { - _clear_internal_resource_paths(kv.key); - _clear_internal_resource_paths(kv.value); + for (const Variant &E : keys) { + _clear_internal_resource_paths(E); + _clear_internal_resource_paths(d[E]); } } break; default: { @@ -1666,20 +1653,9 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { } } -void Object::_add_class_to_classdb(const StringName &p_class, const StringName &p_inherits) { - ClassDB::_add_class(p_class, p_inherits); -} - -void Object::_get_property_list_from_classdb(const StringName &p_class, List *p_list, bool p_no_inheritance, const Object *p_validator) { - ClassDB::get_property_list(p_class, p_list, p_no_inheritance, p_validator); -} - #ifdef TOOLS_ENABLED -void Object::editor_set_section_unfold(const String &p_section, bool p_unfolded, bool p_initializing) { - if (!p_initializing) { - set_edited(true); - } - +void Object::editor_set_section_unfold(const String &p_section, bool p_unfolded) { + set_edited(true); if (p_unfolded) { editor_section_folding.insert(p_section); } else { @@ -1902,7 +1878,7 @@ Variant::Type Object::get_static_property_type(const StringName &p_property, boo } Variant::Type Object::get_static_property_type_indexed(const Vector &p_path, bool *r_valid) const { - if (p_path.is_empty()) { + if (p_path.size() == 0) { if (r_valid) { *r_valid = false; } @@ -1969,20 +1945,6 @@ uint32_t Object::get_edited_version() const { } #endif -const StringName &Object::get_class_name() const { - if (_extension) { - // Can't put inside the unlikely as constructor can run it. - return _extension->class_name; - } - - if (unlikely(!_class_name_ptr)) { - // While class is initializing / deinitializing, constructors and destructors - // need access to the proper class at the proper stage. - return *_get_class_namev(); - } - return *_class_name_ptr; -} - StringName Object::get_class_name_for_extension(const GDExtension *p_library) const { #ifdef TOOLS_ENABLED // If this is the library this extension comes from and it's a placeholder, we @@ -2130,6 +2092,7 @@ void Object::clear_internal_extension() { // Clear the virtual methods. while (virtual_method_list) { (*virtual_method_list->method) = nullptr; + (*virtual_method_list->initialized) = false; virtual_method_list = virtual_method_list->next; } } diff --git a/engine/core/object/object.h b/engine/core/object/object.h index 1607f827..16d8e19e 100644 --- a/engine/core/object/object.h +++ b/engine/core/object/object.h @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef OBJECT_H +#define OBJECT_H -#include "core/disabled_classes.gen.h" #include "core/extension/gdextension_interface.h" #include "core/object/message_queue.h" #include "core/object/object_id.h" @@ -47,9 +47,6 @@ template class TypedArray; -template -class Ref; - enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_less][,hide_slider][,radians_as_degrees][,degrees][,exp][,suffix:] range. @@ -132,9 +129,6 @@ enum PropertyUsageFlags { PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE, }; -// Respective values are defined by disabled_classes.gen.h -#define GD_IS_CLASS_ENABLED(m_class) m_class::_class_is_enabled - #define ADD_SIGNAL(m_signal) ::ClassDB::add_signal(get_class_static(), m_signal) #define ADD_PROPERTY(m_property, m_setter, m_getter) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter)) #define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index) @@ -215,7 +209,6 @@ struct PropertyInfo { }; TypedArray convert_property_list(const List *p_list); -TypedArray convert_property_list(const Vector &p_vector); enum MethodFlags { METHOD_FLAG_NORMAL = 1, @@ -234,7 +227,7 @@ struct MethodInfo { PropertyInfo return_val; uint32_t flags = METHOD_FLAGS_DEFAULT; int id = 0; - Vector arguments; + List arguments; Vector default_arguments; int return_val_metadata = 0; Vector arguments_metadata; @@ -263,8 +256,8 @@ struct MethodInfo { return_val(PropertyInfo(pinfo.return_value)), flags(pinfo.flags), id(pinfo.id) { - for (uint32_t i = 0; i < pinfo.argument_count; i++) { - arguments.push_back(PropertyInfo(pinfo.arguments[i])); + for (uint32_t j = 0; j < pinfo.argument_count; j++) { + arguments.push_back(PropertyInfo(pinfo.arguments[j])); } const Variant *def_values = (const Variant *)pinfo.default_arguments; for (uint32_t j = 0; j < pinfo.default_argument_count; j++) { @@ -272,12 +265,22 @@ struct MethodInfo { } } + void _push_params(const PropertyInfo &p_param) { + arguments.push_back(p_param); + } + + template + void _push_params(const PropertyInfo &p_param, VarArgs... p_params) { + arguments.push_back(p_param); + _push_params(p_params...); + } + MethodInfo(const String &p_name) { name = p_name; } template MethodInfo(const String &p_name, VarArgs... p_params) { name = p_name; - arguments = Vector{ p_params... }; + _push_params(p_params...); } MethodInfo(Variant::Type ret) { return_val.type = ret; } @@ -290,7 +293,7 @@ struct MethodInfo { MethodInfo(Variant::Type ret, const String &p_name, VarArgs... p_params) { name = p_name; return_val.type = ret; - arguments = Vector{ p_params... }; + _push_params(p_params...); } MethodInfo(const PropertyInfo &p_ret, const String &p_name) { @@ -302,7 +305,7 @@ struct MethodInfo { MethodInfo(const PropertyInfo &p_ret, const String &p_name, VarArgs... p_params) { return_val = p_ret; name = p_name; - arguments = Vector{ p_params... }; + _push_params(p_params...); } }; @@ -393,46 +396,57 @@ struct ObjectGDExtension { * much alone defines the object model. */ -// This is a barebones version of GDCLASS, -// only intended for simple classes deriving from Object -// so that they can support the `Object::cast_to()` method. -#define GDSOFTCLASS(m_class, m_inherits) \ -public: \ - using self_type = m_class; \ - using super_type = m_inherits; \ - static _FORCE_INLINE_ void *get_class_ptr_static() { \ - static int ptr; \ - return &ptr; \ - } \ - virtual bool is_class_ptr(void *p_ptr) const override { \ - return (p_ptr == get_class_ptr_static()) || m_inherits::is_class_ptr(p_ptr); \ - } \ - \ -private: - #define GDCLASS(m_class, m_inherits) \ - GDSOFTCLASS(m_class, m_inherits) \ private: \ void operator=(const m_class &p_rval) {} \ friend class ::ClassDB; \ \ public: \ + typedef m_class self_type; \ static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \ - virtual const StringName *_get_class_namev() const override { \ - return &get_class_static(); \ + virtual String get_class() const override { \ + if (_get_extension()) { \ + return _get_extension()->class_name.operator String(); \ + } \ + return String(#m_class); \ } \ - static const StringName &get_class_static() { \ + virtual const StringName *_get_class_namev() const override { \ static StringName _class_name_static; \ if (unlikely(!_class_name_static)) { \ StringName::assign_static_unique_class_name(&_class_name_static, #m_class); \ } \ - return _class_name_static; \ + return &_class_name_static; \ + } \ + static _FORCE_INLINE_ void *get_class_ptr_static() { \ + static int ptr; \ + return &ptr; \ + } \ + static _FORCE_INLINE_ String get_class_static() { \ + return String(#m_class); \ + } \ + static _FORCE_INLINE_ String get_parent_class_static() { \ + return m_inherits::get_class_static(); \ + } \ + static void get_inheritance_list_static(List *p_inheritance_list) { \ + m_inherits::get_inheritance_list_static(p_inheritance_list); \ + p_inheritance_list->push_back(String(#m_class)); \ } \ virtual bool is_class(const String &p_class) const override { \ if (_get_extension() && _get_extension()->is_class(p_class)) { \ return true; \ } \ return (p_class == (#m_class)) ? true : m_inherits::is_class(p_class); \ + } \ + virtual bool is_class_ptr(void *p_ptr) const override { \ + return (p_ptr == get_class_ptr_static()) ? true : m_inherits::is_class_ptr(p_ptr); \ + } \ + \ + static void get_valid_parents_static(List *p_parents) { \ + if (m_class::_get_valid_parents_static != m_inherits::_get_valid_parents_static) { \ + m_class::_get_valid_parents_static(p_parents); \ + } \ + \ + m_inherits::get_valid_parents_static(p_parents); \ } \ \ protected: \ @@ -450,7 +464,7 @@ public: return; \ } \ m_inherits::initialize_class(); \ - _add_class_to_classdb(get_class_static(), super_type::get_class_static()); \ + ::ClassDB::_add_class(); \ if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \ _bind_methods(); \ } \ @@ -465,7 +479,7 @@ protected: initialize_class(); \ } \ _FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &) const { \ - return (bool (Object::*)(const StringName &, Variant &) const) & m_class::_get; \ + return (bool(Object::*)(const StringName &, Variant &) const) & m_class::_get; \ } \ virtual bool _getv(const StringName &p_name, Variant &r_ret) const override { \ if (m_class::_get_get() != m_inherits::_get_get()) { \ @@ -476,7 +490,7 @@ protected: return m_inherits::_getv(p_name, r_ret); \ } \ _FORCE_INLINE_ bool (Object::*_get_set() const)(const StringName &p_name, const Variant &p_property) { \ - return (bool (Object::*)(const StringName &, const Variant &)) & m_class::_set; \ + return (bool(Object::*)(const StringName &, const Variant &)) & m_class::_set; \ } \ virtual bool _setv(const StringName &p_name, const Variant &p_property) override { \ if (m_inherits::_setv(p_name, p_property)) { \ @@ -488,14 +502,14 @@ protected: return false; \ } \ _FORCE_INLINE_ void (Object::*_get_get_property_list() const)(List * p_list) const { \ - return (void (Object::*)(List *) const) & m_class::_get_property_list; \ + return (void(Object::*)(List *) const) & m_class::_get_property_list; \ } \ virtual void _get_property_listv(List *p_list, bool p_reversed) const override { \ if (!p_reversed) { \ m_inherits::_get_property_listv(p_list, p_reversed); \ } \ p_list->push_back(PropertyInfo(Variant::NIL, get_class_static(), PROPERTY_HINT_NONE, get_class_static(), PROPERTY_USAGE_CATEGORY)); \ - _get_property_list_from_classdb(#m_class, p_list, true, this); \ + ::ClassDB::get_property_list(#m_class, p_list, true, this); \ if (m_class::_get_get_property_list() != m_inherits::_get_get_property_list()) { \ _get_property_list(p_list); \ } \ @@ -504,7 +518,7 @@ protected: } \ } \ _FORCE_INLINE_ void (Object::*_get_validate_property() const)(PropertyInfo & p_property) const { \ - return (void (Object::*)(PropertyInfo &) const) & m_class::_validate_property; \ + return (void(Object::*)(PropertyInfo &) const) & m_class::_validate_property; \ } \ virtual void _validate_propertyv(PropertyInfo &p_property) const override { \ m_inherits::_validate_propertyv(p_property); \ @@ -513,7 +527,7 @@ protected: } \ } \ _FORCE_INLINE_ bool (Object::*_get_property_can_revert() const)(const StringName &p_name) const { \ - return (bool (Object::*)(const StringName &) const) & m_class::_property_can_revert; \ + return (bool(Object::*)(const StringName &) const) & m_class::_property_can_revert; \ } \ virtual bool _property_can_revertv(const StringName &p_name) const override { \ if (m_class::_get_property_can_revert() != m_inherits::_get_property_can_revert()) { \ @@ -524,7 +538,7 @@ protected: return m_inherits::_property_can_revertv(p_name); \ } \ _FORCE_INLINE_ bool (Object::*_get_property_get_revert() const)(const StringName &p_name, Variant &) const { \ - return (bool (Object::*)(const StringName &, Variant &) const) & m_class::_property_get_revert; \ + return (bool(Object::*)(const StringName &, Variant &) const) & m_class::_property_get_revert; \ } \ virtual bool _property_get_revertv(const StringName &p_name, Variant &r_ret) const override { \ if (m_class::_get_property_get_revert() != m_inherits::_get_property_get_revert()) { \ @@ -535,19 +549,18 @@ protected: return m_inherits::_property_get_revertv(p_name, r_ret); \ } \ _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { \ - return (void (Object::*)(int)) & m_class::_notification; \ + return (void(Object::*)(int)) & m_class::_notification; \ } \ - virtual void _notification_forwardv(int p_notification) override { \ - m_inherits::_notification_forwardv(p_notification); \ + virtual void _notificationv(int p_notification, bool p_reversed) override { \ + if (!p_reversed) { \ + m_inherits::_notificationv(p_notification, p_reversed); \ + } \ if (m_class::_get_notification() != m_inherits::_get_notification()) { \ _notification(p_notification); \ } \ - } \ - virtual void _notification_backwardv(int p_notification) override { \ - if (m_class::_get_notification() != m_inherits::_get_notification()) { \ - _notification(p_notification); \ + if (p_reversed) { \ + m_inherits::_notificationv(p_notification, p_reversed); \ } \ - m_inherits::_notification_backwardv(p_notification); \ } \ \ private: @@ -691,11 +704,7 @@ protected: virtual void _validate_propertyv(PropertyInfo &p_property) const {} virtual bool _property_can_revertv(const StringName &p_name) const { return false; } virtual bool _property_get_revertv(const StringName &p_name, Variant &r_property) const { return false; } - - void _notification_forward(int p_notification); - void _notification_backward(int p_notification); - virtual void _notification_forwardv(int p_notification) {} - virtual void _notification_backwardv(int p_notification) {} + virtual void _notificationv(int p_notification, bool p_reversed) {} static void _bind_methods(); static void _bind_compatibility_methods() {} @@ -734,12 +743,18 @@ protected: _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { return &Object::_notification; } + static void get_valid_parents_static(List *p_parents); + static void _get_valid_parents_static(List *p_parents); Variant _call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); virtual const StringName *_get_class_namev() const { - return &get_class_static(); + static StringName _class_name_static; + if (unlikely(!_class_name_static)) { + StringName::assign_static_unique_class_name(&_class_name_static, "Object"); + } + return &_class_name_static; } TypedArray _get_meta_list_bind() const; @@ -751,14 +766,12 @@ protected: friend class ClassDB; friend class PlaceholderExtensionInstance; - static void _add_class_to_classdb(const StringName &p_class, const StringName &p_inherits); - static void _get_property_list_from_classdb(const StringName &p_class, List *p_list, bool p_no_inheritance, const Object *p_validator); - bool _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false); #ifdef TOOLS_ENABLED struct VirtualMethodTracker { void **method; + bool *initialized; VirtualMethodTracker *next; }; @@ -784,18 +797,12 @@ public: template static T *cast_to(Object *p_object) { - // This is like dynamic_cast, but faster. - // The reason is that we can assume no virtual and multiple inheritance. - static_assert(std::is_base_of_v, "T must be derived from Object"); - static_assert(std::is_same_v, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS"); - return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast(p_object) : nullptr; + return p_object ? dynamic_cast(p_object) : nullptr; } template static const T *cast_to(const Object *p_object) { - static_assert(std::is_base_of_v, "T must be derived from Object"); - static_assert(std::is_same_v, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS"); - return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast(p_object) : nullptr; + return p_object ? dynamic_cast(p_object) : nullptr; } enum { @@ -807,16 +814,17 @@ public: }; /* TYPE API */ - static const StringName &get_class_static() { - static StringName _class_name_static; - if (unlikely(!_class_name_static)) { - StringName::assign_static_unique_class_name(&_class_name_static, "Object"); + static void get_inheritance_list_static(List *p_inheritance_list) { p_inheritance_list->push_back("Object"); } + + static String get_class_static() { return "Object"; } + static String get_parent_class_static() { return String(); } + + virtual String get_class() const { + if (_extension) { + return _extension->class_name.operator String(); } - return _class_name_static; + return "Object"; } - - _FORCE_INLINE_ String get_class() const { return get_class_name(); } - virtual String get_save_class() const { return get_class(); } //class stored when saving virtual bool is_class(const String &p_class) const { @@ -827,7 +835,19 @@ public: } virtual bool is_class_ptr(void *p_ptr) const { return get_class_ptr_static() == p_ptr; } - const StringName &get_class_name() const; + _FORCE_INLINE_ const StringName &get_class_name() const { + if (_extension) { + // Can't put inside the unlikely as constructor can run it + return _extension->class_name; + } + + if (unlikely(!_class_name_ptr)) { + // While class is initializing / deinitializing, constructors and destructurs + // need access to the proper class at the proper stage. + return *_get_class_namev(); + } + return *_class_name_ptr; + } StringName get_class_name_for_extension(const GDExtension *p_library) const; @@ -862,17 +882,7 @@ public: return (cerr.error == Callable::CallError::CALL_OK) ? ret : Variant(); } - // Depending on the boolean, we call either the virtual function _notification_backward or _notification_forward. - // - Forward calls subclasses in descending order (e.g. Object -> Node -> Node3D -> extension -> script). - // Backward calls subclasses in descending order (e.g. script -> extension -> Node3D -> Node -> Object). - _FORCE_INLINE_ void notification(int p_notification, bool p_reversed = false) { - if (p_reversed) { - _notification_backward(p_notification); - } else { - _notification_forward(p_notification); - } - } - + void notification(int p_notification, bool p_reversed = false); virtual String to_string(); // Used mainly by script, get and set all INCLUDING string. @@ -964,7 +974,7 @@ public: #ifdef TOOLS_ENABLED virtual void get_argument_options(const StringName &p_function, int p_idx, List *r_options) const; - void editor_set_section_unfold(const String &p_section, bool p_unfolded, bool p_initializing = false); + void editor_set_section_unfold(const String &p_section, bool p_unfolded); bool editor_is_section_unfolded(const String &p_section); const HashSet &editor_get_section_folding() const { return editor_section_folding; } void editor_clear_section_folding() { editor_section_folding.clear(); } @@ -1052,15 +1062,8 @@ public: return object; } - - template - _ALWAYS_INLINE_ static T *get_instance(ObjectID p_instance_id) { - return Object::cast_to(get_instance(p_instance_id)); - } - - template - _ALWAYS_INLINE_ static Ref get_ref(ObjectID p_instance_id); // Defined in ref_counted.h - static void debug_objects(DebugFunc p_func); static int get_object_count(); }; + +#endif // OBJECT_H diff --git a/engine/core/object/object_id.h b/engine/core/object/object_id.h index 2fc66beb..b04e2df1 100644 --- a/engine/core/object/object_id.h +++ b/engine/core/object/object_id.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef OBJECT_ID_H +#define OBJECT_ID_H #include "core/typedefs.h" @@ -59,5 +60,4 @@ public: _ALWAYS_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; } }; -template <> -struct is_zero_constructible : std::true_type {}; +#endif // OBJECT_ID_H diff --git a/engine/core/object/ref_counted.h b/engine/core/object/ref_counted.h index 3bd2b062..927e457d 100644 --- a/engine/core/object/ref_counted.h +++ b/engine/core/object/ref_counted.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef REF_COUNTED_H +#define REF_COUNTED_H #include "core/object/class_db.h" #include "core/templates/safe_refcount.h" @@ -85,10 +86,6 @@ class Ref { //virtual RefCounted * get_reference() const { return reference; } public: - static _FORCE_INLINE_ String get_class_static() { - return T::get_class_static(); - } - _FORCE_INLINE_ bool operator==(const T *p_ptr) const { return reference == p_ptr; } @@ -131,15 +128,6 @@ public: ref(p_from); } - void operator=(Ref &&p_from) { - if (reference == p_from.reference) { - return; - } - unref(); - reference = p_from.reference; - p_from.reference = nullptr; - } - template void operator=(const Ref &p_from) { ref_pointer(Object::cast_to(p_from.ptr())); @@ -172,11 +160,6 @@ public: this->operator=(p_from); } - Ref(Ref &&p_from) { - reference = p_from.reference; - p_from.reference = nullptr; - } - template Ref(const Ref &p_from) { this->operator=(p_from); @@ -198,15 +181,10 @@ public: // do a lot of referencing on references and stuff // mutexes will avoid more crashes? - if (reference) { - // NOTE: `reinterpret_cast` is "safe" here because we know `T` has simple linear - // inheritance to `RefCounted`. This guarantees that `T * == `RefCounted *`, which - // allows us to declare `Ref` with forward declared `T` types. - if (reinterpret_cast(reference)->unreference()) { - memdelete(reinterpret_cast(reference)); - } - reference = nullptr; + if (reference && reference->unreference()) { + memdelete(reference); } + reference = nullptr; } template @@ -255,6 +233,19 @@ struct PtrToArg> { } }; +template +struct PtrToArg &> { + typedef Ref EncodeT; + + _FORCE_INLINE_ static Ref convert(const void *p_ptr) { + if (p_ptr == nullptr) { + return Ref(); + } + // p_ptr points to a RefCounted object + return Ref(*((T *const *)p_ptr)); + } +}; + template struct GetTypeInfo> { static const Variant::Type VARIANT_TYPE = Variant::OBJECT; @@ -265,17 +256,26 @@ struct GetTypeInfo> { } }; +template +struct GetTypeInfo &> { + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static()); + } +}; + template struct VariantInternalAccessor> { static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::object_assign(v, p_ref); } }; -// Zero-constructing Ref initializes reference to nullptr (and thus empty). template -struct is_zero_constructible> : std::true_type {}; +struct VariantInternalAccessor &> { + static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } + static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::object_assign(v, p_ref); } +}; -template -Ref ObjectDB::get_ref(ObjectID p_instance_id) { - return Ref(get_instance(p_instance_id)); -} +#endif // REF_COUNTED_H diff --git a/engine/core/object/script_instance.h b/engine/core/object/script_instance.h index 59b7199c..2c8132ec 100644 --- a/engine/core/object/script_instance.h +++ b/engine/core/object/script_instance.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef SCRIPT_INSTANCE_H +#define SCRIPT_INSTANCE_H #include "core/object/ref_counted.h" @@ -95,3 +96,5 @@ public: virtual ScriptLanguage *get_language() = 0; virtual ~ScriptInstance(); }; + +#endif // SCRIPT_INSTANCE_H diff --git a/engine/core/object/script_language.cpp b/engine/core/object/script_language.cpp index a2c738b6..33bf7ab4 100644 --- a/engine/core/object/script_language.cpp +++ b/engine/core/object/script_language.cpp @@ -633,7 +633,6 @@ void ScriptLanguage::_bind_methods() { BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_PASCAL_CASE); BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_SNAKE_CASE); BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_KEBAB_CASE); - BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_CAMEL_CASE); } bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_value) { diff --git a/engine/core/object/script_language.h b/engine/core/object/script_language.h index c724177f..8158d633 100644 --- a/engine/core/object/script_language.h +++ b/engine/core/object/script_language.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#pragma once +#ifndef SCRIPT_LANGUAGE_H +#define SCRIPT_LANGUAGE_H #include "core/doc_data.h" #include "core/io/resource.h" @@ -246,7 +247,6 @@ public: SCRIPT_NAME_CASING_PASCAL_CASE, SCRIPT_NAME_CASING_SNAKE_CASE, SCRIPT_NAME_CASING_KEBAB_CASE, - SCRIPT_NAME_CASING_CAMEL_CASE, }; struct ScriptTemplate { @@ -505,3 +505,5 @@ public: PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref + +