feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "engine"]
|
||||
path = engine
|
||||
url = https://github.com/godotengine/godot.git
|
|
@ -5,7 +5,6 @@
|
|||
Diagnostics:
|
||||
Includes:
|
||||
IgnoreHeader:
|
||||
- core/typedefs\.h # Our "main" header, featuring transitive includes; allow everywhere.
|
||||
- \.compat\.inc
|
||||
---
|
||||
# Header-specific conditions.
|
||||
|
|
|
@ -16,5 +16,6 @@ indent_style = space
|
|||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.svg]
|
||||
insert_final_newline = false
|
||||
[{*.props,*.vcxproj}]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
|
|
@ -66,3 +66,9 @@ bb5f390fb9b466be35a5df7651323d7e66afca31
|
|||
|
||||
# Style: Enforce `AllowShortFunctionsOnASingleLine`
|
||||
e06d83860d798b6766b23d6eae48557387a7db85
|
||||
|
||||
# Style: Enforce trailing newlines on svgs
|
||||
7e5baa042639ffa835271703c720e2595e90afb8
|
||||
|
||||
# Style: Replace header guards with `#pragma once`
|
||||
324512e11c1b7663c3cf47bec6ddbe65c6b8db2b
|
||||
|
|
5
engine/.gitignore
vendored
5
engine/.gitignore
vendored
|
@ -263,6 +263,11 @@ 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/
|
||||
|
||||
|
|
|
@ -4,24 +4,22 @@ default_language_version:
|
|||
exclude: |
|
||||
(?x)^(
|
||||
.*thirdparty/.*|
|
||||
.*-so_wrap\.(h|c)|
|
||||
.*-(dll|dylib|so)_wrap\.[ch]|
|
||||
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: v19.1.3
|
||||
rev: v20.1.0
|
||||
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
|
||||
|
@ -31,13 +29,12 @@ repos:
|
|||
files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java|glsl)$
|
||||
args: [--fix, --quiet, --use-color]
|
||||
types_or: [text]
|
||||
exclude: ^tests/python_build/.*
|
||||
additional_dependencies: [clang-tidy==19.1.0]
|
||||
additional_dependencies: [clang-tidy==20.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.9.4
|
||||
rev: v0.11.4
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix]
|
||||
|
@ -48,14 +45,14 @@ repos:
|
|||
types_or: [text]
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.14.1
|
||||
rev: v1.14.1 # Latest version that supports Python 3.8
|
||||
hooks:
|
||||
- id: mypy
|
||||
files: \.py$
|
||||
types_or: [text]
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
rev: v2.4.1
|
||||
hooks:
|
||||
- id: codespell
|
||||
additional_dependencies: [tomli]
|
||||
|
@ -88,6 +85,13 @@ 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
|
||||
|
@ -154,7 +158,6 @@ 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
|
||||
|
|
|
@ -163,6 +163,11 @@ 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.
|
||||
|
@ -200,7 +205,7 @@ License: MPL-2.0
|
|||
|
||||
Files: thirdparty/clipper2/*
|
||||
Comment: Clipper2
|
||||
Copyright: 2010-2024, Angus Johnson
|
||||
Copyright: 2010-2025, Angus Johnson
|
||||
License: BSL-1.0
|
||||
|
||||
Files: thirdparty/cvtt/*
|
||||
|
|
|
@ -14,6 +14,7 @@ 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
|
||||
|
@ -57,7 +58,7 @@ import gles3_builders
|
|||
import glsl_builders
|
||||
import methods
|
||||
import scu_builders
|
||||
from misc.utility.color import STDERR_COLOR, print_error, print_info, print_warning
|
||||
from misc.utility.color import is_stderr_color, print_error, print_info, print_warning
|
||||
from platform_methods import architecture_aliases, architectures, compatibility_platform_aliases
|
||||
|
||||
if ARGUMENTS.get("target", "editor") == "editor":
|
||||
|
@ -166,7 +167,7 @@ opts.Add(
|
|||
"optimize",
|
||||
"Optimization level (by default inferred from 'target' and 'dev_build')",
|
||||
"auto",
|
||||
("auto", "none", "custom", "debug", "speed", "speed_trace", "size"),
|
||||
("auto", "none", "custom", "debug", "speed", "speed_trace", "size", "size_extra"),
|
||||
)
|
||||
)
|
||||
opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", False))
|
||||
|
@ -186,11 +187,12 @@ 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(
|
||||
|
@ -220,6 +222,11 @@ 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))
|
||||
|
@ -236,6 +243,13 @@ 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))
|
||||
|
@ -433,10 +447,19 @@ for tool in custom_tools:
|
|||
env.Tool(tool)
|
||||
|
||||
|
||||
# add default include paths
|
||||
|
||||
# Add default include paths.
|
||||
env.Prepend(CPPPATH=["#"])
|
||||
|
||||
# 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)}"
|
||||
)
|
||||
|
||||
# configure ENV for platform
|
||||
env.platform_exporters = platform_exporters
|
||||
env.platform_apis = platform_apis
|
||||
|
@ -696,83 +719,84 @@ if env["arch"] == "x86_32":
|
|||
|
||||
# Explicitly specify colored output.
|
||||
if methods.using_gcc(env):
|
||||
env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if STDERR_COLOR else "-fno-diagnostics-color"])
|
||||
env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if is_stderr_color() else "-fno-diagnostics-color"])
|
||||
elif methods.using_clang(env) or methods.using_emcc(env):
|
||||
env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if STDERR_COLOR else "-fno-color-diagnostics"])
|
||||
env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if is_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.Append(CCFLAGS=["/Zi", "/FS"])
|
||||
env.Append(LINKFLAGS=["/DEBUG:FULL"])
|
||||
env.AppendUnique(CCFLAGS=["/Zi", "/FS"])
|
||||
env.AppendUnique(LINKFLAGS=["/DEBUG:FULL"])
|
||||
else:
|
||||
env.Append(LINKFLAGS=["/DEBUG:NONE"])
|
||||
env.AppendUnique(LINKFLAGS=["/DEBUG:NONE"])
|
||||
|
||||
if env["optimize"].startswith("speed"):
|
||||
env.Append(CCFLAGS=["/O2"])
|
||||
env.Append(LINKFLAGS=["/OPT:REF"])
|
||||
env["OPTIMIZELEVEL"] = "/O2"
|
||||
env.AppendUnique(LINKFLAGS=["/OPT:REF"])
|
||||
if env["optimize"] == "speed_trace":
|
||||
env.Append(LINKFLAGS=["/OPT:NOICF"])
|
||||
elif env["optimize"] == "size":
|
||||
env.Append(CCFLAGS=["/O1"])
|
||||
env.Append(LINKFLAGS=["/OPT:REF"])
|
||||
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"])
|
||||
elif env["optimize"] == "debug" or env["optimize"] == "none":
|
||||
env.Append(CCFLAGS=["/Od"])
|
||||
env["OPTIMIZELEVEL"] = "/Od"
|
||||
else:
|
||||
if env["debug_symbols"]:
|
||||
if env["platform"] == "windows":
|
||||
if methods.using_clang(env):
|
||||
env.Append(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows.
|
||||
env.AppendUnique(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows.
|
||||
else:
|
||||
env.Append(CCFLAGS=["-gdwarf-5"]) # For gcc, only dwarf-5 symbols seem usable by libbacktrace.
|
||||
env.AppendUnique(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.Append(CCFLAGS=["-gdwarf-4"])
|
||||
env.AppendUnique(CCFLAGS=["-gdwarf-4"])
|
||||
if methods.using_emcc(env):
|
||||
# Emscripten only produces dwarf symbols when using "-g3".
|
||||
env.Append(CCFLAGS=["-g3"])
|
||||
env.AppendUnique(CCFLAGS=["-g3"])
|
||||
# Emscripten linker needs debug symbols options too.
|
||||
env.Append(LINKFLAGS=["-gdwarf-4"])
|
||||
env.Append(LINKFLAGS=["-g3"])
|
||||
env.AppendUnique(LINKFLAGS=["-gdwarf-4"])
|
||||
env.AppendUnique(LINKFLAGS=["-g3"])
|
||||
elif env.dev_build:
|
||||
env.Append(CCFLAGS=["-g3"])
|
||||
env.AppendUnique(CCFLAGS=["-g3"])
|
||||
else:
|
||||
env.Append(CCFLAGS=["-g2"])
|
||||
env.AppendUnique(CCFLAGS=["-g2"])
|
||||
if env["debug_paths_relative"]:
|
||||
# Remap absolute paths to relative paths for debug symbols.
|
||||
project_path = Dir("#").abspath
|
||||
env.Append(CCFLAGS=[f"-ffile-prefix-map={project_path}=."])
|
||||
env.AppendUnique(CCFLAGS=[f"-ffile-prefix-map={project_path}=."])
|
||||
else:
|
||||
if methods.is_apple_clang(env):
|
||||
# Apple Clang, its linker doesn't like -s.
|
||||
env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
|
||||
env.AppendUnique(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
|
||||
else:
|
||||
env.Append(LINKFLAGS=["-s"])
|
||||
env.AppendUnique(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.Append(CCFLAGS=["-O3"])
|
||||
env.Append(LINKFLAGS=["-O3"])
|
||||
env["OPTIMIZELEVEL"] = "-O3"
|
||||
# `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces.
|
||||
elif env["optimize"] == "speed_trace":
|
||||
env.Append(CCFLAGS=["-O2"])
|
||||
env.Append(LINKFLAGS=["-O2"])
|
||||
elif env["optimize"] == "size":
|
||||
env.Append(CCFLAGS=["-Os"])
|
||||
env.Append(LINKFLAGS=["-Os"])
|
||||
env["OPTIMIZELEVEL"] = "-O2"
|
||||
elif env["optimize"].startswith("size"):
|
||||
env["OPTIMIZELEVEL"] = "-Os"
|
||||
if env["optimize"] == "size_extra":
|
||||
env.AppendUnique(CPPDEFINES=["SIZE_EXTRA"])
|
||||
elif env["optimize"] == "debug":
|
||||
env.Append(CCFLAGS=["-Og"])
|
||||
env.Append(LINKFLAGS=["-Og"])
|
||||
env["OPTIMIZELEVEL"] = "-Og"
|
||||
elif env["optimize"] == "none":
|
||||
env.Append(CCFLAGS=["-O0"])
|
||||
env.Append(LINKFLAGS=["-O0"])
|
||||
env["OPTIMIZELEVEL"] = "-O0"
|
||||
|
||||
# Needs to happen after configure to handle "auto".
|
||||
if env["lto"] != "none":
|
||||
|
@ -813,6 +837,7 @@ 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 = [
|
||||
|
@ -830,19 +855,23 @@ if env.msvc and not methods.using_clang(env): # MSVC
|
|||
]
|
||||
|
||||
if env["warnings"] == "extra":
|
||||
env.Append(CCFLAGS=["/W4"] + disabled_warnings)
|
||||
env["WARNLEVEL"] = "/W4"
|
||||
env.AppendUnique(CCFLAGS=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.Append(CCFLAGS=["/W3", "/w34458"] + disabled_warnings)
|
||||
env.AppendUnique(CCFLAGS=["/w34458"] + disabled_warnings)
|
||||
elif env["warnings"] == "moderate":
|
||||
env.Append(CCFLAGS=["/W2"] + disabled_warnings)
|
||||
env["WARNLEVEL"] = "/W2"
|
||||
env.AppendUnique(CCFLAGS=disabled_warnings)
|
||||
else: # 'no'
|
||||
env["WARNLEVEL"] = "/w"
|
||||
# C4267 is particularly finicky & needs to be explicitly disabled.
|
||||
env.Append(CCFLAGS=["/w", "/wd4267"])
|
||||
env.AppendUnique(CCFLAGS=["/wd4267"])
|
||||
|
||||
if env["werror"]:
|
||||
env.Append(CCFLAGS=["/WX"])
|
||||
env.Append(LINKFLAGS=["/WX"])
|
||||
env.AppendUnique(CCFLAGS=["/WX"])
|
||||
env.AppendUnique(LINKFLAGS=["/WX"])
|
||||
|
||||
else: # GCC, Clang
|
||||
common_warnings = []
|
||||
|
@ -861,14 +890,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
|
||||
W_ALL = "-Wall" if not env.msvc else "-W3"
|
||||
# clang-cl will interpret `-Wall` as `-Weverything`, workaround with compatibility cast.
|
||||
env["WARNLEVEL"] = "-Wall" if not env.msvc else "-W3"
|
||||
|
||||
if env["warnings"] == "extra":
|
||||
env.Append(CCFLAGS=[W_ALL, "-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings)
|
||||
env.Append(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"])
|
||||
env.AppendUnique(CCFLAGS=["-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings)
|
||||
env.AppendUnique(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"])
|
||||
if methods.using_gcc(env):
|
||||
env.Append(
|
||||
env.AppendUnique(
|
||||
CCFLAGS=[
|
||||
"-Walloc-zero",
|
||||
"-Wduplicated-branches",
|
||||
|
@ -876,25 +905,38 @@ else: # GCC, Clang
|
|||
"-Wstringop-overflow=4",
|
||||
]
|
||||
)
|
||||
env.Append(CXXFLAGS=["-Wplacement-new=1"])
|
||||
env.AppendUnique(CXXFLAGS=["-Wplacement-new=1", "-Wvirtual-inheritance"])
|
||||
# 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.Append(CCFLAGS=["-Wattribute-alias=2"])
|
||||
env.AppendUnique(CCFLAGS=["-Wattribute-alias=2"])
|
||||
if cc_version_major >= 11: # Broke on MethodBind templates before GCC 11.
|
||||
env.Append(CCFLAGS=["-Wlogical-op"])
|
||||
env.AppendUnique(CCFLAGS=["-Wlogical-op"])
|
||||
elif methods.using_clang(env) or methods.using_emcc(env):
|
||||
env.Append(CCFLAGS=["-Wimplicit-fallthrough"])
|
||||
env.AppendUnique(CCFLAGS=["-Wimplicit-fallthrough"])
|
||||
elif env["warnings"] == "all":
|
||||
env.Append(CCFLAGS=[W_ALL] + common_warnings)
|
||||
env.AppendUnique(CCFLAGS=common_warnings)
|
||||
elif env["warnings"] == "moderate":
|
||||
env.Append(CCFLAGS=[W_ALL, "-Wno-unused"] + common_warnings)
|
||||
env.AppendUnique(CCFLAGS=["-Wno-unused"] + common_warnings)
|
||||
else: # 'no'
|
||||
env.Append(CCFLAGS=["-w"])
|
||||
env["WARNLEVEL"] = "-w"
|
||||
|
||||
if env["werror"]:
|
||||
env.Append(CCFLAGS=["-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"] = ""
|
||||
|
||||
if hasattr(detect, "get_program_suffix"):
|
||||
suffix = "." + detect.get_program_suffix()
|
||||
|
@ -918,6 +960,51 @@ 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 = []
|
||||
|
@ -968,8 +1055,6 @@ 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"]
|
||||
|
@ -989,28 +1074,6 @@ 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),
|
||||
|
@ -1051,6 +1114,14 @@ 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")
|
||||
|
||||
|
@ -1082,11 +1153,11 @@ if "check_c_headers" in env:
|
|||
for header in headers:
|
||||
if conf.CheckCHeader(header):
|
||||
env.AppendUnique(CPPDEFINES=[headers[header]])
|
||||
conf.Finish()
|
||||
|
||||
|
||||
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()
|
||||
# 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()
|
||||
|
|
|
@ -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(CPPPATH=[thirdparty_brotli_dir + "include"])
|
||||
env.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"])
|
||||
env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_brotli_dir + "include"])
|
||||
env.Prepend(CPPEXTPATH=[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(CPPPATH=[thirdparty_clipper_dir + "include"])
|
||||
env.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"])
|
||||
env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_clipper_dir + "include"])
|
||||
env.Prepend(CPPEXTPATH=[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(CPPPATH=[thirdparty_zlib_dir])
|
||||
env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zlib_dir])
|
||||
# Needs to be available in main env too
|
||||
env.Prepend(CPPPATH=[thirdparty_zlib_dir])
|
||||
env.Prepend(CPPEXTPATH=[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(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
|
||||
env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
|
||||
env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
|
||||
env.Prepend(CPPPATH=thirdparty_zstd_dir)
|
||||
env.Prepend(CPPEXTPATH=thirdparty_zstd_dir)
|
||||
# Also needed in main env includes will trigger warnings
|
||||
env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
|
||||
|
||||
|
@ -167,10 +167,9 @@ env.add_source_files(env.core_sources, "*.cpp")
|
|||
|
||||
# Generate disabled classes
|
||||
def disabled_class_builder(target, source, env):
|
||||
with methods.generated_wrapper(target) as file:
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
for c in source[0].read():
|
||||
cs = c.strip()
|
||||
if cs != "":
|
||||
if cs := c.strip():
|
||||
file.write(f"#define ClassDB_Disable_{cs} 1\n")
|
||||
|
||||
|
||||
|
@ -179,49 +178,51 @@ 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(target) as file:
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
file.write(
|
||||
"""\
|
||||
#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)
|
||||
#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())
|
||||
)
|
||||
|
||||
|
||||
env.CommandNoCache("version_generated.gen.h", env.Value(env.version_info), env.Run(version_info_builder))
|
||||
env.CommandNoCache(
|
||||
"version_generated.gen.h",
|
||||
env.Value(methods.get_version_info(env.module_version_string)),
|
||||
env.Run(version_info_builder),
|
||||
)
|
||||
|
||||
|
||||
# Generate version hash
|
||||
def version_hash_builder(target, source, env):
|
||||
with methods.generated_wrapper(target) as file:
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
file.write(
|
||||
"""\
|
||||
#include "core/version.h"
|
||||
|
||||
const char *const VERSION_HASH = "{git_hash}";
|
||||
const uint64_t VERSION_TIMESTAMP = {git_timestamp};
|
||||
""".format(**env.version_info)
|
||||
const char *const GODOT_VERSION_HASH = "{git_hash}";
|
||||
const uint64_t GODOT_VERSION_TIMESTAMP = {git_timestamp};
|
||||
""".format(**source[0].read())
|
||||
)
|
||||
|
||||
|
||||
gen_hash = env.CommandNoCache(
|
||||
"version_hash.gen.cpp", env.Value(env.version_info["git_hash"]), env.Run(version_hash_builder)
|
||||
)
|
||||
gen_hash = env.CommandNoCache("version_hash.gen.cpp", env.Value(methods.get_git_info()), 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(target) as file:
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
file.write(
|
||||
f"""\
|
||||
#include "core/config/project_settings.h"
|
||||
|
@ -251,30 +252,21 @@ env.add_source_files(env.core_sources, gen_encrypt)
|
|||
|
||||
|
||||
# Certificates
|
||||
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",
|
||||
["#thirdparty/certs/ca-certificates.crt", env.Value(env["builtin_certs"]), env.Value(env["system_certs_path"])],
|
||||
env.Run(core_builders.make_certs_header),
|
||||
)
|
||||
|
||||
# Authors
|
||||
env.Depends("#core/authors.gen.h", "../AUTHORS.md")
|
||||
env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header))
|
||||
env.CommandNoCache("#core/authors.gen.h", "#AUTHORS.md", env.Run(core_builders.make_authors_header))
|
||||
|
||||
# Donors
|
||||
env.Depends("#core/donors.gen.h", "../DONORS.md")
|
||||
env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header))
|
||||
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
|
||||
|
|
|
@ -125,17 +125,17 @@ double Engine::get_unfrozen_time_scale() const {
|
|||
|
||||
Dictionary Engine::get_version_info() const {
|
||||
Dictionary dict;
|
||||
dict["major"] = VERSION_MAJOR;
|
||||
dict["minor"] = VERSION_MINOR;
|
||||
dict["patch"] = VERSION_PATCH;
|
||||
dict["hex"] = VERSION_HEX;
|
||||
dict["status"] = VERSION_STATUS;
|
||||
dict["build"] = VERSION_BUILD;
|
||||
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;
|
||||
|
||||
String hash = String(VERSION_HASH);
|
||||
String hash = String(GODOT_VERSION_HASH);
|
||||
dict["hash"] = hash.is_empty() ? String("unknown") : hash;
|
||||
|
||||
dict["timestamp"] = VERSION_TIMESTAMP;
|
||||
dict["timestamp"] = GODOT_VERSION_TIMESTAMP;
|
||||
|
||||
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
|
||||
if ((int)dict["patch"] != 0) {
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
@ -214,5 +213,3 @@ public:
|
|||
Engine();
|
||||
virtual ~Engine();
|
||||
};
|
||||
|
||||
#endif // ENGINE_H
|
||||
|
|
|
@ -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(VERSION_BRANCH);
|
||||
features.append(GODOT_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(VERSION_BRANCH "." _MKSTR(VERSION_PATCH));
|
||||
features.append(VERSION_FULL_CONFIG);
|
||||
features.append(VERSION_FULL_BUILD);
|
||||
features.append(GODOT_VERSION_BRANCH "." _MKSTR(GODOT_VERSION_PATCH));
|
||||
features.append(GODOT_VERSION_FULL_CONFIG);
|
||||
features.append(GODOT_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("\\", "/");
|
||||
cwd = cwd.replace_char('\\', '/');
|
||||
|
||||
// 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, path.size() - sep);
|
||||
return plocal + path.substr(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_slice("/", 1);
|
||||
String group_name = p_name.operator String().get_slicec('/', 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_slice("/", 1);
|
||||
String group_name = p_name.operator String().get_slicec('/', 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(const StringName &p_name) const {
|
||||
Variant ProjectSettings::get_setting_with_override_and_custom_features(const StringName &p_name, const Vector<String> &p_features) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
StringName name = p_name;
|
||||
if (feature_overrides.has(name)) {
|
||||
const LocalVector<Pair<StringName, StringName>> &overrides = feature_overrides[name];
|
||||
for (uint32_t i = 0; i < overrides.size(); i++) {
|
||||
if (OS::get_singleton()->has_feature(overrides[i].first)) { // Custom features are checked in OS.has_feature() already. No need to check twice.
|
||||
if (p_features.has(String(overrides[i].first).to_lower())) {
|
||||
if (props.has(overrides[i].second)) {
|
||||
name = overrides[i].second;
|
||||
break;
|
||||
|
@ -376,12 +376,39 @@ Variant ProjectSettings::get_setting_with_override(const StringName &p_name) con
|
|||
}
|
||||
|
||||
if (!props.has(name)) {
|
||||
WARN_PRINT(vformat("Property not found: '%s'.", String(name)));
|
||||
WARN_PRINT("Property not found: " + String(name));
|
||||
return Variant();
|
||||
}
|
||||
return props[name].variant;
|
||||
}
|
||||
|
||||
Variant ProjectSettings::get_setting_with_override(const StringName &p_name) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const LocalVector<Pair<StringName, StringName>> *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<StringName, VariantContainer>::Element *override_prop = props.find((*overrides)[i].second);
|
||||
if (override_prop) {
|
||||
return override_prop->get().variant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const RBMap<StringName, VariantContainer>::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;
|
||||
|
@ -564,7 +591,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("\\", "/");
|
||||
resource_path = OS::get_singleton()->get_resource_dir().replace_char('\\', '/');
|
||||
if (!resource_path.is_empty() && resource_path[resource_path.length() - 1] == '/') {
|
||||
resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end.
|
||||
}
|
||||
|
@ -685,7 +712,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("\\", "/"); // Windows path to Unix path just in case.
|
||||
resource_path = resource_path.replace_char('\\', '/'); // 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.
|
||||
|
@ -770,8 +797,7 @@ 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;
|
||||
key.parse_utf8(cs.ptr(), slen);
|
||||
String key = String::utf8(cs.ptr(), slen);
|
||||
|
||||
uint32_t vlen = f->get_32();
|
||||
Vector<uint8_t> d;
|
||||
|
@ -1129,7 +1155,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.size());
|
||||
name = name.substr(div + 1);
|
||||
}
|
||||
save_props[category].push_back(name);
|
||||
}
|
||||
|
@ -1141,7 +1167,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
|
|||
save_features += ",";
|
||||
}
|
||||
|
||||
String f = p_custom_features[i].strip_edges().replace("\"", "");
|
||||
String f = p_custom_features[i].strip_edges().remove_char('\"');
|
||||
save_features += f;
|
||||
}
|
||||
|
||||
|
@ -1408,6 +1434,7 @@ 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);
|
||||
|
@ -1434,8 +1461,8 @@ void ProjectSettings::_add_builtin_input_map() {
|
|||
Array events;
|
||||
|
||||
// Convert list of input events into array
|
||||
for (List<Ref<InputEvent>>::Element *I = E.value.front(); I; I = I->next()) {
|
||||
events.push_back(I->get());
|
||||
for (const Ref<InputEvent> &event : E.value) {
|
||||
events.push_back(event);
|
||||
}
|
||||
|
||||
Dictionary action;
|
||||
|
@ -1488,6 +1515,9 @@ 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,
|
||||
|
@ -1497,9 +1527,10 @@ 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 `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);
|
||||
// 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_screen", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), 0);
|
||||
|
||||
GLOBAL_DEF_BASIC("display/window/size/resizable", true);
|
||||
|
@ -1509,6 +1540,8 @@ 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
|
||||
|
@ -1543,8 +1576,13 @@ 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");
|
||||
|
@ -1612,6 +1650,8 @@ 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());
|
||||
|
@ -1620,6 +1660,19 @@ 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/");
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PROJECT_SETTINGS_H
|
||||
#define PROJECT_SETTINGS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/class_db.h"
|
||||
|
||||
|
@ -194,6 +193,7 @@ public:
|
|||
List<String> 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<String> &p_features) const;
|
||||
|
||||
bool is_using_datapack() const;
|
||||
bool is_project_loaded() const;
|
||||
|
@ -243,5 +243,3 @@ 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
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
||||
namespace core_bind {
|
||||
namespace CoreBind {
|
||||
|
||||
// Semaphore
|
||||
|
||||
|
@ -53,10 +53,12 @@ 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 core_bind
|
||||
} // namespace CoreBind
|
||||
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "core/os/thread_safe.h"
|
||||
#include "core/variant/typed_array.h"
|
||||
|
||||
namespace core_bind {
|
||||
namespace CoreBind {
|
||||
|
||||
////// ResourceLoader //////
|
||||
|
||||
|
@ -466,8 +466,8 @@ bool OS::is_restart_on_exit_set() const {
|
|||
Vector<String> OS::get_restart_on_exit_arguments() const {
|
||||
List<String> args = ::OS::get_singleton()->get_restart_on_exit_arguments();
|
||||
Vector<String> args_vector;
|
||||
for (List<String>::Element *E = args.front(); E; E = E->next()) {
|
||||
args_vector.push_back(E->get());
|
||||
for (const String &arg : args) {
|
||||
args_vector.push_back(arg);
|
||||
}
|
||||
|
||||
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);
|
||||
ClassDB::bind_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin);
|
||||
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("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,13 +806,11 @@ Vector<Vector2> 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) {
|
||||
Vector2 s[2] = { p_a, p_b };
|
||||
return ::Geometry2D::get_closest_point_to_segment(p_point, s);
|
||||
return ::Geometry2D::get_closest_point_to_segment(p_point, p_a, p_b);
|
||||
}
|
||||
|
||||
Vector2 Geometry2D::get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) {
|
||||
Vector2 s[2] = { p_a, p_b };
|
||||
return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, s);
|
||||
return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b);
|
||||
}
|
||||
|
||||
bool Geometry2D::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const {
|
||||
|
@ -1069,13 +1067,11 @@ Vector<Vector3> 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) {
|
||||
Vector3 s[2] = { p_a, p_b };
|
||||
return ::Geometry3D::get_closest_point_to_segment(p_point, s);
|
||||
return ::Geometry3D::get_closest_point_to_segment(p_point, p_a, p_b);
|
||||
}
|
||||
|
||||
Vector3 Geometry3D::get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) {
|
||||
Vector3 s[2] = { p_a, p_b };
|
||||
return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, s);
|
||||
return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b);
|
||||
}
|
||||
|
||||
Vector3 Geometry3D::get_triangle_barycentric_coords(const Vector3 &p_point, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) {
|
||||
|
@ -1241,6 +1237,9 @@ Vector<uint8_t> 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);
|
||||
|
@ -1340,6 +1339,7 @@ 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<Thread>();
|
||||
|
||||
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 = Ref<Thread>(ObjectDB::get_instance(th_instance_id));
|
||||
t = ObjectDB::get_ref<Thread>(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 %d: %s.", func_name, t->get_id(), Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce)));
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
List<StringName> classes;
|
||||
::ClassDB::get_inheriters_from_class(p_class, &classes);
|
||||
LocalVector<StringName> 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<String> Engine::get_singleton_list() const {
|
|||
List<::Engine::Singleton> singletons;
|
||||
::Engine::get_singleton()->get_singletons(&singletons);
|
||||
Vector<String> ret;
|
||||
for (List<::Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
|
||||
ret.push_back(E->get().name);
|
||||
for (const ::Engine::Singleton &E : singletons) {
|
||||
ret.push_back(E.name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -2190,4 +2190,4 @@ void EngineDebugger::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("clear_breakpoints"), &EngineDebugger::clear_breakpoints);
|
||||
}
|
||||
|
||||
} // namespace core_bind
|
||||
} // namespace CoreBind
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CORE_BIND_H
|
||||
#define CORE_BIND_H
|
||||
#pragma once
|
||||
|
||||
#include "core/debugger/engine_profiler.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
|
@ -42,7 +41,7 @@ class MainLoop;
|
|||
template <typename T>
|
||||
class TypedArray;
|
||||
|
||||
namespace core_bind {
|
||||
namespace CoreBind {
|
||||
|
||||
class ResourceLoader : public Object {
|
||||
GDCLASS(ResourceLoader, Object);
|
||||
|
@ -458,7 +457,7 @@ public:
|
|||
static void set_thread_safety_checks_enabled(bool p_enabled);
|
||||
};
|
||||
|
||||
namespace special {
|
||||
namespace Special {
|
||||
|
||||
class ClassDB : public Object {
|
||||
GDCLASS(ClassDB, Object);
|
||||
|
@ -524,7 +523,7 @@ public:
|
|||
~ClassDB() {}
|
||||
};
|
||||
|
||||
} // namespace special
|
||||
} // namespace Special
|
||||
|
||||
class Engine : public Object {
|
||||
GDCLASS(Engine, Object);
|
||||
|
@ -652,23 +651,21 @@ public:
|
|||
~EngineDebugger();
|
||||
};
|
||||
|
||||
} // namespace core_bind
|
||||
} // namespace CoreBind
|
||||
|
||||
VARIANT_ENUM_CAST(core_bind::ResourceLoader::ThreadLoadStatus);
|
||||
VARIANT_ENUM_CAST(core_bind::ResourceLoader::CacheMode);
|
||||
VARIANT_ENUM_CAST(CoreBind::ResourceLoader::ThreadLoadStatus);
|
||||
VARIANT_ENUM_CAST(CoreBind::ResourceLoader::CacheMode);
|
||||
|
||||
VARIANT_BITFIELD_CAST(core_bind::ResourceSaver::SaverFlags);
|
||||
VARIANT_BITFIELD_CAST(CoreBind::ResourceSaver::SaverFlags);
|
||||
|
||||
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::OS::RenderingDriver);
|
||||
VARIANT_ENUM_CAST(CoreBind::OS::SystemDir);
|
||||
VARIANT_ENUM_CAST(CoreBind::OS::StdHandleType);
|
||||
|
||||
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::Geometry2D::PolyBooleanOperation);
|
||||
VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyJoinType);
|
||||
VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyEndType);
|
||||
|
||||
VARIANT_ENUM_CAST(core_bind::Thread::Priority);
|
||||
VARIANT_ENUM_CAST(CoreBind::Thread::Priority);
|
||||
|
||||
VARIANT_ENUM_CAST(core_bind::special::ClassDB::APIType);
|
||||
|
||||
#endif // CORE_BIND_H
|
||||
VARIANT_ENUM_CAST(CoreBind::Special::ClassDB::APIType);
|
||||
|
|
|
@ -1,171 +1,104 @@
|
|||
"""Functions used to generate source files during build time"""
|
||||
|
||||
import zlib
|
||||
from collections import OrderedDict
|
||||
from io import TextIOWrapper
|
||||
|
||||
|
||||
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
|
||||
import methods
|
||||
|
||||
|
||||
def make_certs_header(target, source, env):
|
||||
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")
|
||||
buffer = methods.get_buffer(str(source[0]))
|
||||
decomp_size = len(buffer)
|
||||
buffer = methods.compress_buffer(buffer)
|
||||
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
# System certs path. Editor will use them if defined. (for package maintainers)
|
||||
path = env["system_certs_path"]
|
||||
g.write('#define _SYSTEM_CERTS_PATH "%s"\n' % str(path))
|
||||
file.write('#define _SYSTEM_CERTS_PATH "{}"\n'.format(env["system_certs_path"]))
|
||||
if env["builtin_certs"]:
|
||||
# Defined here and not in env so changing it does not trigger a full rebuild.
|
||||
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")
|
||||
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)}
|
||||
}};
|
||||
""")
|
||||
|
||||
|
||||
def make_authors_header(target, source, env):
|
||||
sections = [
|
||||
"Project Founders",
|
||||
"Lead Developer",
|
||||
"Project Manager",
|
||||
"Developers",
|
||||
]
|
||||
sections_id = [
|
||||
"AUTHORS_FOUNDERS",
|
||||
"AUTHORS_LEAD_DEVELOPERS",
|
||||
"AUTHORS_PROJECT_MANAGERS",
|
||||
"AUTHORS_DEVELOPERS",
|
||||
]
|
||||
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
|
||||
|
||||
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
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
|
||||
def close_section():
|
||||
g.write("\t0\n")
|
||||
g.write("};\n")
|
||||
file.write("\tnullptr,\n};\n\n")
|
||||
|
||||
for line in f:
|
||||
if reading:
|
||||
if line.startswith(" "):
|
||||
g.write('\t"' + escape_string(line.strip()) + '",\n')
|
||||
continue
|
||||
if line.startswith("## "):
|
||||
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("## "):
|
||||
if reading:
|
||||
close_section()
|
||||
reading = False
|
||||
for section, section_id in zip(sections, sections_id):
|
||||
if line.strip().endswith(section):
|
||||
current_section = escape_string(section_id)
|
||||
reading = True
|
||||
g.write("const char *const " + current_section + "[] = {\n")
|
||||
break
|
||||
section = SECTIONS[line[3:].strip()]
|
||||
if section:
|
||||
file.write(f"inline constexpr const char *{section}[] = {{\n")
|
||||
reading = True
|
||||
|
||||
if reading:
|
||||
close_section()
|
||||
|
||||
g.write("#endif // AUTHORS_GEN_H\n")
|
||||
|
||||
|
||||
def make_donors_header(target, source, env):
|
||||
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",
|
||||
]
|
||||
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
|
||||
|
||||
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
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
|
||||
def close_section():
|
||||
g.write("\t0\n")
|
||||
g.write("};\n")
|
||||
file.write("\tnullptr,\n};\n\n")
|
||||
|
||||
for line in f:
|
||||
if reading >= 0:
|
||||
if line.startswith(" "):
|
||||
g.write('\t"' + escape_string(line.strip()) + '",\n')
|
||||
continue
|
||||
if line.startswith("## "):
|
||||
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("## "):
|
||||
if reading:
|
||||
close_section()
|
||||
reading = False
|
||||
for section, section_id in zip(sections, sections_id):
|
||||
if line.strip().endswith(section):
|
||||
current_section = escape_string(section_id)
|
||||
reading = True
|
||||
g.write("const char *const " + current_section + "[] = {\n")
|
||||
break
|
||||
section = SECTIONS.get(line[3:].strip())
|
||||
if section:
|
||||
file.write(f"inline constexpr const char *{section}[] = {{\n")
|
||||
reading = True
|
||||
|
||||
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):
|
||||
def __init__(self, license_file: TextIOWrapper):
|
||||
self._license_file = license_file
|
||||
self.line_num = 0
|
||||
self.current = self.next_line()
|
||||
|
@ -188,9 +121,7 @@ def make_license_header(target, source, env):
|
|||
lines.append(self.current.strip())
|
||||
return (tag, lines)
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
projects: dict = OrderedDict()
|
||||
projects = OrderedDict()
|
||||
license_list = []
|
||||
|
||||
with open(src_copyright, "r", encoding="utf-8") as copyright_file:
|
||||
|
@ -212,7 +143,7 @@ def make_license_header(target, source, env):
|
|||
part = {}
|
||||
reader.next_line()
|
||||
|
||||
data_list: list = []
|
||||
data_list = []
|
||||
for project in iter(projects.values()):
|
||||
for part in project:
|
||||
part["file_index"] = len(data_list)
|
||||
|
@ -220,96 +151,76 @@ def make_license_header(target, source, env):
|
|||
part["copyright_index"] = len(data_list)
|
||||
data_list += part["Copyright"]
|
||||
|
||||
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 open(src_license, "r", encoding="utf-8") as file:
|
||||
license_text = file.read()
|
||||
|
||||
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")
|
||||
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)}
|
||||
}};
|
||||
|
||||
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 ComponentCopyrightPart {{
|
||||
const char *license;
|
||||
const char *const *files;
|
||||
const char *const *copyright_statements;
|
||||
int file_count;
|
||||
int copyright_count;
|
||||
}};
|
||||
|
||||
f.write(
|
||||
"struct ComponentCopyright {\n"
|
||||
"\tconst char *name;\n"
|
||||
"\tconst ComponentCopyrightPart *parts;\n"
|
||||
"\tint part_count;\n"
|
||||
"};\n\n"
|
||||
)
|
||||
struct ComponentCopyright {{
|
||||
const char *name;
|
||||
const ComponentCopyrightPart *parts;
|
||||
int part_count;
|
||||
}};
|
||||
|
||||
f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n")
|
||||
""")
|
||||
|
||||
file.write("inline constexpr const char *COPYRIGHT_INFO_DATA[] = {\n")
|
||||
for line in data_list:
|
||||
f.write('\t"' + escape_string(line) + '",\n')
|
||||
f.write("};\n\n")
|
||||
file.write(f'\t"{methods.to_escaped_cstring(line)}",\n')
|
||||
file.write("};\n\n")
|
||||
|
||||
f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n")
|
||||
file.write("inline constexpr 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:
|
||||
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"
|
||||
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"
|
||||
)
|
||||
part_index += 1
|
||||
f.write("};\n\n")
|
||||
file.write("};\n\n")
|
||||
|
||||
f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n")
|
||||
file.write(f"inline constexpr int COPYRIGHT_INFO_COUNT = {len(projects)};\n")
|
||||
|
||||
f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n")
|
||||
file.write("inline constexpr ComponentCopyright COPYRIGHT_INFO[] = {\n")
|
||||
for project_name, project in iter(projects.items()):
|
||||
f.write(
|
||||
'\t{ "'
|
||||
+ escape_string(project_name)
|
||||
+ '", '
|
||||
+ "©RIGHT_PROJECT_PARTS["
|
||||
+ str(part_indexes[project_name])
|
||||
+ "], "
|
||||
+ str(len(project))
|
||||
+ " },\n"
|
||||
file.write(
|
||||
f'\t{{ "{methods.to_escaped_cstring(project_name)}", '
|
||||
+ f"©RIGHT_PROJECT_PARTS[{part_indexes[project_name]}], "
|
||||
+ f"{len(project)} }},\n"
|
||||
)
|
||||
f.write("};\n\n")
|
||||
file.write("};\n\n")
|
||||
|
||||
f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n")
|
||||
file.write(f"inline constexpr int LICENSE_COUNT = {len(license_list)};\n")
|
||||
|
||||
f.write("const char *const LICENSE_NAMES[] = {\n")
|
||||
file.write("inline constexpr const char *LICENSE_NAMES[] = {\n")
|
||||
for license in license_list:
|
||||
f.write('\t"' + escape_string(license[0]) + '",\n')
|
||||
f.write("};\n\n")
|
||||
file.write(f'\t"{methods.to_escaped_cstring(license[0])}",\n')
|
||||
file.write("};\n\n")
|
||||
|
||||
f.write("const char *const LICENSE_BODIES[] = {\n\n")
|
||||
file.write("inline constexpr const char *LICENSE_BODIES[] = {\n\n")
|
||||
for license in license_list:
|
||||
to_raw = []
|
||||
for line in license[1:]:
|
||||
if line == ".":
|
||||
f.write('\t"\\n"\n')
|
||||
to_raw += [""]
|
||||
else:
|
||||
f.write('\t"' + escape_string(line) + '\\n"\n')
|
||||
f.write('\t"",\n\n')
|
||||
f.write("};\n\n")
|
||||
|
||||
f.write("#endif // LICENSE_GEN_H\n")
|
||||
to_raw += [line]
|
||||
file.write(f"{methods.to_raw_cstring(to_raw)},\n\n")
|
||||
file.write("};\n\n")
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CORE_CONSTANTS_H
|
||||
#define CORE_CONSTANTS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/string_name.h"
|
||||
#include "core/templates/hash_map.h"
|
||||
|
@ -47,5 +46,3 @@ public:
|
|||
static bool is_global_enum(const StringName &p_enum);
|
||||
static void get_enum_values(const StringName &p_enum, HashMap<StringName, int64_t> *p_values);
|
||||
};
|
||||
|
||||
#endif // CORE_CONSTANTS_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CORE_GLOBALS_H
|
||||
#define CORE_GLOBALS_H
|
||||
#pragma once
|
||||
|
||||
// Home for state needed from global functions
|
||||
// that cannot be stored in Engine or OS due to e.g. circular includes
|
||||
|
@ -40,5 +39,3 @@ public:
|
|||
static bool print_line_enabled;
|
||||
static bool print_error_enabled;
|
||||
};
|
||||
|
||||
#endif // CORE_GLOBALS_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CORE_STRING_NAMES_H
|
||||
#define CORE_STRING_NAMES_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/string_name.h"
|
||||
|
||||
|
@ -87,5 +86,3 @@ public:
|
|||
};
|
||||
|
||||
#define CoreStringName(m_name) CoreStringNames::get_singleton()->m_name
|
||||
|
||||
#endif // CORE_STRING_NAMES_H
|
||||
|
|
|
@ -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(CPPPATH=["#thirdparty/mbedtls/include"])
|
||||
env_crypto.Prepend(CPPEXTPATH=["#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
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef AES_CONTEXT_H
|
||||
#define AES_CONTEXT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/crypto_core.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
@ -64,5 +63,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(AESContext::Mode);
|
||||
|
||||
#endif // AES_CONTEXT_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/hashing_context.h"
|
||||
#include "core/io/resource.h"
|
||||
|
@ -167,5 +166,3 @@ public:
|
|||
virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override;
|
||||
virtual bool recognize(const Ref<Resource> &p_resource) const override;
|
||||
};
|
||||
|
||||
#endif // CRYPTO_H
|
||||
|
|
|
@ -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, int p_src_len) {
|
||||
int b64len = p_src_len / 3 * 4 + 4 + 1;
|
||||
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;
|
||||
Vector<uint8_t> b64buff;
|
||||
b64buff.resize(b64len);
|
||||
uint8_t *w64 = b64buff.ptrw();
|
||||
|
@ -225,27 +225,27 @@ String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) {
|
|||
return ret ? String() : (const char *)&w64[0];
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
|
||||
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) {
|
||||
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, int p_src_len, unsigned char r_hash[16]) {
|
||||
Error CryptoCore::md5(const uint8_t *p_src, size_t 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, int p_src_len, unsigned char r_hash[20]) {
|
||||
Error CryptoCore::sha1(const uint8_t *p_src, size_t 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, int p_src_len, unsigned char r_hash[32]) {
|
||||
Error CryptoCore::sha256(const uint8_t *p_src, size_t 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;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CRYPTO_CORE_H
|
||||
#define CRYPTO_CORE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
|
@ -107,13 +106,11 @@ 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, 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 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 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]);
|
||||
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]);
|
||||
};
|
||||
|
||||
#endif // CRYPTO_CORE_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef HASHING_CONTEXT_H
|
||||
#define HASHING_CONTEXT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
|
@ -62,5 +61,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(HashingContext::HashType);
|
||||
|
||||
#endif // HASHING_CONTEXT_H
|
||||
|
|
|
@ -36,8 +36,7 @@
|
|||
#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;
|
||||
arr.push_back(frames.size() * 3);
|
||||
Array arr = { frames.size() * 3 };
|
||||
for (const ScriptLanguage::StackInfo &frame : frames) {
|
||||
arr.push_back(frame.file);
|
||||
arr.push_back(frame.line);
|
||||
|
@ -64,10 +63,7 @@ bool DebuggerMarshalls::ScriptStackDump::deserialize(const Array &p_arr) {
|
|||
}
|
||||
|
||||
Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
|
||||
Array arr;
|
||||
arr.push_back(name);
|
||||
arr.push_back(type);
|
||||
arr.push_back(value.get_type());
|
||||
Array arr = { name, type, value.get_type() };
|
||||
|
||||
Variant var = value;
|
||||
if (value.get_type() == Variant::OBJECT && value.get_validated_object() == nullptr) {
|
||||
|
@ -99,20 +95,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);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DEBUGGER_MARSHALLS_H
|
||||
#define DEBUGGER_MARSHALLS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/shortcut.h"
|
||||
#include "core/object/script_language.h"
|
||||
|
@ -73,5 +72,3 @@ struct DebuggerMarshalls {
|
|||
static Array serialize_key_shortcut(const Ref<Shortcut> &p_shortcut);
|
||||
static Ref<Shortcut> deserialize_key_shortcut(const Array &p_keys);
|
||||
};
|
||||
|
||||
#endif // DEBUGGER_MARSHALLS_H
|
||||
|
|
|
@ -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, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)()) {
|
||||
void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector<String> &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,8 +149,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co
|
|||
singleton = memnew(RemoteDebugger(Ref<RemoteDebuggerPeer>(peer)));
|
||||
script_debugger = memnew(ScriptDebugger);
|
||||
// Notify editor of our pid (to allow focus stealing).
|
||||
Array msg;
|
||||
msg.push_back(OS::get_singleton()->get_process_id());
|
||||
Array msg = { OS::get_singleton()->get_process_id() };
|
||||
singleton->send_message("set_pid", msg);
|
||||
}
|
||||
if (!singleton) {
|
||||
|
@ -160,13 +159,14 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co
|
|||
// 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, bp.length()).to_int(), bp.substr(0, sp));
|
||||
singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1).to_int(), bp.substr(0, sp));
|
||||
}
|
||||
|
||||
allow_focus_steal_fn = p_allow_focus_steal_fn;
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ENGINE_DEBUGGER_H
|
||||
#define ENGINE_DEBUGGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/string_name.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
@ -107,7 +106,7 @@ public:
|
|||
|
||||
_FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; }
|
||||
|
||||
static void initialize(const String &p_uri, bool p_skip_breakpoints, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)());
|
||||
static void initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector<String> &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);
|
||||
|
@ -140,5 +139,3 @@ public:
|
|||
|
||||
virtual ~EngineDebugger();
|
||||
};
|
||||
|
||||
#endif // ENGINE_DEBUGGER_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ENGINE_PROFILER_H
|
||||
#define ENGINE_PROFILER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/gdvirtual.gen.inc"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
@ -59,5 +58,3 @@ public:
|
|||
EngineProfiler() {}
|
||||
virtual ~EngineProfiler();
|
||||
};
|
||||
|
||||
#endif // ENGINE_PROFILER_H
|
||||
|
|
|
@ -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<int, HashSet<StringName>> &breakpoints = script_debugger->get_breakpoints();
|
||||
if (breakpoints.size() == 0) {
|
||||
if (breakpoints.is_empty()) {
|
||||
print_line("No Breakpoints.");
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef LOCAL_DEBUGGER_H
|
||||
#define LOCAL_DEBUGGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/debugger/engine_debugger.h"
|
||||
#include "core/object/script_language.h"
|
||||
|
@ -55,5 +54,3 @@ public:
|
|||
LocalDebugger();
|
||||
~LocalDebugger();
|
||||
};
|
||||
|
||||
#endif // LOCAL_DEBUGGER_H
|
||||
|
|
|
@ -95,10 +95,7 @@ public:
|
|||
};
|
||||
|
||||
Error RemoteDebugger::_put_msg(const String &p_message, const Array &p_data) {
|
||||
Array msg;
|
||||
msg.push_back(p_message);
|
||||
msg.push_back(Thread::get_caller_id());
|
||||
msg.push_back(p_data);
|
||||
Array msg = { p_message, Thread::get_caller_id(), p_data };
|
||||
Error err = peer->put_message(msg);
|
||||
if (err != OK) {
|
||||
n_messages_dropped++;
|
||||
|
@ -235,9 +232,7 @@ void RemoteDebugger::flush_output() {
|
|||
types.push_back(MESSAGE_TYPE_LOG);
|
||||
}
|
||||
|
||||
Array arr;
|
||||
arr.push_back(strings);
|
||||
arr.push_back(types);
|
||||
Array arr = { strings, types };
|
||||
_put_msg("output", arr);
|
||||
output_strings.clear();
|
||||
}
|
||||
|
@ -413,17 +408,25 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
|||
}
|
||||
|
||||
ScriptLanguage *script_lang = script_debugger->get_break_language();
|
||||
const String error_str = script_lang ? script_lang->debug_get_error() : "";
|
||||
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();
|
||||
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;
|
||||
}
|
||||
send_message("debug_enter", msg);
|
||||
|
||||
Input::MouseMode mouse_mode = Input::MOUSE_MODE_VISIBLE;
|
||||
|
||||
|
@ -507,8 +510,7 @@ 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;
|
||||
var_size.push_back(local_vals.size() + member_vals.size() + globals_vals.size());
|
||||
Array var_size = { 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);
|
||||
|
@ -530,6 +532,9 @@ 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];
|
||||
|
@ -669,6 +674,9 @@ 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 {
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef REMOTE_DEBUGGER_H
|
||||
#define REMOTE_DEBUGGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/debugger/debugger_marshalls.h"
|
||||
#include "core/debugger/engine_debugger.h"
|
||||
|
@ -122,5 +121,3 @@ public:
|
|||
explicit RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer);
|
||||
~RemoteDebugger();
|
||||
};
|
||||
|
||||
#endif // REMOTE_DEBUGGER_H
|
||||
|
|
|
@ -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.size() == 0) {
|
||||
if (out_queue.is_empty()) {
|
||||
break; // Nothing left to send
|
||||
}
|
||||
mutex.lock();
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef REMOTE_DEBUGGER_PEER_H
|
||||
#define REMOTE_DEBUGGER_PEER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/stream_peer_tcp.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
@ -92,5 +91,3 @@ public:
|
|||
RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_stream = Ref<StreamPeerTCP>());
|
||||
~RemoteDebuggerPeerTCP();
|
||||
};
|
||||
|
||||
#endif // REMOTE_DEBUGGER_PEER_H
|
||||
|
|
|
@ -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].size() == 0) {
|
||||
if (breakpoints[p_line].is_empty()) {
|
||||
breakpoints.erase(p_line);
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,14 @@ 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;
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef SCRIPT_DEBUGGER_H
|
||||
#define SCRIPT_DEBUGGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/script_language.h"
|
||||
#include "core/string/string_name.h"
|
||||
|
@ -40,6 +39,7 @@ class ScriptDebugger {
|
|||
typedef ScriptLanguage::StackInfo StackInfo;
|
||||
|
||||
bool skip_breakpoints = false;
|
||||
bool ignore_error_breaks = false;
|
||||
|
||||
HashMap<int, HashSet<StringName>> breakpoints;
|
||||
|
||||
|
@ -64,6 +64,8 @@ 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 {
|
||||
|
@ -82,5 +84,3 @@ public:
|
|||
Vector<StackInfo> get_error_stack_info() const;
|
||||
ScriptDebugger() {}
|
||||
};
|
||||
|
||||
#endif // SCRIPT_DEBUGGER_H
|
||||
|
|
|
@ -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("\n", " ");
|
||||
return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string().replace_char('\n', ' ');
|
||||
} else if (p_value.get_type() == Variant::DICTIONARY) {
|
||||
return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace("\n", " ");
|
||||
return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace_char('\n', ' ');
|
||||
} else {
|
||||
return p_value.get_construct_string().replace("\n", " ");
|
||||
return p_value.get_construct_string().replace_char('\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.length());
|
||||
p_method.return_enum = p_method.return_enum.substr(1);
|
||||
}
|
||||
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.length());
|
||||
p_argument.enumeration = p_argument.enumeration.substr(1);
|
||||
}
|
||||
p_argument.is_bitfield = p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD;
|
||||
p_argument.type = "int";
|
||||
|
@ -136,11 +136,10 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met
|
|||
|
||||
return_doc_from_retinfo(p_method, p_methodinfo.return_val);
|
||||
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::ConstIterator itr = p_methodinfo.arguments.begin(); itr != p_methodinfo.arguments.end(); ++itr, ++i) {
|
||||
for (int64_t i = 0; i < p_methodinfo.arguments.size(); ++i) {
|
||||
DocData::ArgumentDoc argument;
|
||||
argument_doc_from_arginfo(argument, *itr);
|
||||
int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size());
|
||||
argument_doc_from_arginfo(argument, p_methodinfo.arguments[i]);
|
||||
int64_t 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);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DOC_DATA_H
|
||||
#define DOC_DATA_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/xml_parser.h"
|
||||
#include "core/variant/variant.h"
|
||||
|
@ -115,7 +114,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.size() == 0) {
|
||||
if (arguments.is_empty()) {
|
||||
return false;
|
||||
}
|
||||
return arguments[0].type < p_method.arguments[0].type;
|
||||
|
@ -127,7 +126,7 @@ public:
|
|||
// - 1. Default constructor: Foo()
|
||||
// - 2. Copy constructor: Foo(Foo)
|
||||
// - 3+. Other constructors Foo(Bar, ...) based on first argument's name
|
||||
if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1.
|
||||
if (arguments.is_empty() || p_method.arguments.is_empty()) { // 1.
|
||||
return arguments.size() < p_method.arguments.size();
|
||||
}
|
||||
if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2.
|
||||
|
@ -795,8 +794,8 @@ public:
|
|||
if (p_dict.has("enums")) {
|
||||
enums = p_dict["enums"];
|
||||
}
|
||||
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));
|
||||
for (const KeyValue<Variant, Variant> &kv : enums) {
|
||||
doc.enums[kv.key] = EnumDoc::from_dict(kv.value);
|
||||
}
|
||||
|
||||
Array properties;
|
||||
|
@ -980,5 +979,3 @@ 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
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "error_list.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
const char *error_names[] = {
|
||||
"OK", // OK
|
||||
"Failed", // FAILED
|
||||
|
@ -82,4 +84,4 @@ const char *error_names[] = {
|
|||
"Printer on fire", // ERR_PRINTER_ON_FIRE
|
||||
};
|
||||
|
||||
static_assert(sizeof(error_names) / sizeof(*error_names) == ERR_MAX);
|
||||
static_assert(std::size(error_names) == ERR_MAX);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ERROR_LIST_H
|
||||
#define ERROR_LIST_H
|
||||
#pragma once
|
||||
|
||||
/** Error List. Please never compare an error against FAILED
|
||||
* Either do result != OK , or !result. This way, Error fail
|
||||
|
@ -98,5 +97,3 @@ enum Error {
|
|||
};
|
||||
|
||||
extern const char *error_names[];
|
||||
|
||||
#endif // ERROR_LIST_H
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#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"
|
||||
|
||||
|
@ -187,7 +188,7 @@ void _physics_interpolation_warning(const char *p_function, const char *p_file,
|
|||
} else {
|
||||
String node_name;
|
||||
if (p_id.is_valid()) {
|
||||
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(p_id));
|
||||
Node *node = ObjectDB::get_instance<Node>(p_id);
|
||||
if (node && node->is_inside_tree()) {
|
||||
node_name = "\"" + String(node->get_path()) + "\"";
|
||||
} else {
|
||||
|
|
|
@ -28,15 +28,14 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ERROR_MACROS_H
|
||||
#define ERROR_MACROS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/object_id.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#include <atomic> // We'd normally use safe_refcount.h, but that would cause circular includes.
|
||||
#include <atomic> // IWYU pragma: keep // Used in macro. We'd normally use `safe_refcount.h`, but that would cause circular includes.
|
||||
|
||||
class String;
|
||||
class ObjectID;
|
||||
|
||||
enum ErrorHandlerType {
|
||||
ERR_HANDLER_ERROR,
|
||||
|
@ -62,16 +61,16 @@ void add_error_handler(ErrorHandlerList *p_handler);
|
|||
void remove_error_handler(const ErrorHandlerList *p_handler);
|
||||
|
||||
// Functions used by the error macros.
|
||||
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);
|
||||
_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_asap(const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
|
||||
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();
|
||||
_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 _physics_interpolation_warning(const char *p_function, const char *p_file, int p_line, ObjectID p_id, const char *p_warn_string);
|
||||
|
||||
|
@ -845,5 +844,3 @@ 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
|
||||
|
|
|
@ -96,8 +96,7 @@ static String fix_doc_description(const String &p_bbcode) {
|
|||
// Based on what EditorHelp does.
|
||||
|
||||
return p_bbcode.dedent()
|
||||
.replace("\t", "")
|
||||
.replace("\r", "")
|
||||
.remove_chars("\t\r")
|
||||
.strip_edges();
|
||||
}
|
||||
|
||||
|
@ -107,16 +106,22 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
{
|
||||
//header
|
||||
Dictionary header;
|
||||
header["version_major"] = VERSION_MAJOR;
|
||||
header["version_minor"] = VERSION_MINOR;
|
||||
#if VERSION_PATCH
|
||||
header["version_patch"] = VERSION_PATCH;
|
||||
header["version_major"] = GODOT_VERSION_MAJOR;
|
||||
header["version_minor"] = GODOT_VERSION_MINOR;
|
||||
#if GODOT_VERSION_PATCH
|
||||
header["version_patch"] = GODOT_VERSION_PATCH;
|
||||
#else
|
||||
header["version_patch"] = 0;
|
||||
#endif
|
||||
header["version_status"] = VERSION_STATUS;
|
||||
header["version_build"] = VERSION_BUILD;
|
||||
header["version_full_name"] = VERSION_FULL_NAME;
|
||||
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
|
||||
|
||||
api_dump["header"] = header;
|
||||
}
|
||||
|
@ -278,43 +283,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) \
|
||||
|
@ -970,14 +975,14 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
Array values;
|
||||
List<StringName> enum_constant_list;
|
||||
ClassDB::get_enum_constants(class_name, F, &enum_constant_list, true);
|
||||
for (List<StringName>::Element *G = enum_constant_list.front(); G; G = G->next()) {
|
||||
for (const StringName &enum_constant : enum_constant_list) {
|
||||
Dictionary d3;
|
||||
d3["name"] = String(G->get());
|
||||
d3["value"] = ClassDB::get_integer_constant(class_name, G->get());
|
||||
d3["name"] = String(enum_constant);
|
||||
d3["value"] = ClassDB::get_integer_constant(class_name, enum_constant);
|
||||
|
||||
if (p_include_docs) {
|
||||
for (const DocData::ConstantDoc &constant_doc : class_doc->constants) {
|
||||
if (constant_doc.name == G->get()) {
|
||||
if (constant_doc.name == enum_constant) {
|
||||
d3["description"] = fix_doc_description(constant_doc.description);
|
||||
break;
|
||||
}
|
||||
|
@ -1048,9 +1053,8 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
}
|
||||
|
||||
Array arguments;
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::ConstIterator itr = mi.arguments.begin(); itr != mi.arguments.end(); ++itr, ++i) {
|
||||
const PropertyInfo &pinfo = *itr;
|
||||
for (int64_t i = 0; i < mi.arguments.size(); ++i) {
|
||||
const PropertyInfo &pinfo = mi.arguments[i];
|
||||
Dictionary d3;
|
||||
|
||||
d3["name"] = pinfo.name;
|
||||
|
@ -1175,11 +1179,10 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
|
||||
Array arguments;
|
||||
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::ConstIterator itr = F.arguments.begin(); itr != F.arguments.end(); ++itr, ++i) {
|
||||
for (int64_t i = 0; i < F.arguments.size(); ++i) {
|
||||
Dictionary d3;
|
||||
d3["name"] = itr->name;
|
||||
d3["type"] = get_property_info_type_name(*itr);
|
||||
d3["name"] = F.arguments[i].name;
|
||||
d3["type"] = get_property_info_type_name(F.arguments[i]);
|
||||
if (F.get_argument_meta(i) > 0) {
|
||||
d3["meta"] = get_type_meta_name((GodotTypeInfo::Metadata)F.get_argument_meta(i));
|
||||
}
|
||||
|
@ -1340,16 +1343,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 Variant &key : old_dict.keys()) {
|
||||
if (!new_dict.has(key)) {
|
||||
for (const KeyValue<Variant, Variant> &kv : old_dict) {
|
||||
if (!new_dict.has(kv.key)) {
|
||||
failed = true;
|
||||
print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, key));
|
||||
print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, kv.key));
|
||||
continue;
|
||||
}
|
||||
if (p_allow_name_change && key == "name") {
|
||||
if (p_allow_name_change && kv.key == "name") {
|
||||
continue;
|
||||
}
|
||||
if (!compare_value(path, key, old_dict[key], new_dict[key], p_allow_name_change)) {
|
||||
if (!compare_value(path, kv.key, kv.value, new_dict[kv.key], p_allow_name_change)) {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
@ -1420,25 +1423,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.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
bool added = field.begins_with("+");
|
||||
if (added) {
|
||||
// Meaning this field must either exist or contents may not exist.
|
||||
field = field.substr(1, field.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
bool enum_values = field.begins_with("$");
|
||||
if (enum_values) {
|
||||
// Meaning this field is a list of enum values.
|
||||
field = field.substr(1, field.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
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.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
Variant old_value;
|
||||
|
@ -1598,8 +1601,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 != 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));
|
||||
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));
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EXTENSION_API_DUMP_H
|
||||
#define EXTENSION_API_DUMP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/extension/gdextension.h"
|
||||
|
||||
|
@ -42,5 +41,3 @@ public:
|
|||
static Error validate_extension_json_file(const String &p_path);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // EXTENSION_API_DUMP_H
|
||||
|
|
|
@ -679,6 +679,13 @@ 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<GDExtension *>(p_library);
|
||||
self->get_classes_used_callback = p_callback;
|
||||
#endif
|
||||
}
|
||||
|
||||
HashMap<StringName, GDExtensionInterfaceFunctionPtr> GDExtension::gdextension_interface_functions;
|
||||
|
||||
void GDExtension::register_interface_function(const StringName &p_function_name, GDExtensionInterfaceFunctionPtr p_function_pointer) {
|
||||
|
@ -799,6 +806,7 @@ 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() {
|
||||
|
@ -1034,6 +1042,14 @@ 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<StringName> GDExtensionEditorPlugins::extension_classes;
|
||||
GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_add_plugin = nullptr;
|
||||
GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_remove_plugin = nullptr;
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_H
|
||||
#define GDEXTENSION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/extension/gdextension_interface.h"
|
||||
#include "core/extension/gdextension_loader.h"
|
||||
|
@ -94,6 +93,7 @@ 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,6 +102,7 @@ class GDExtension : public Resource {
|
|||
bool is_reloading = false;
|
||||
Vector<GDExtensionMethodBind *> invalid_methods;
|
||||
Vector<ObjectID> 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);
|
||||
|
@ -156,6 +157,8 @@ 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;
|
||||
|
@ -226,5 +229,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
#endif // GDEXTENSION_H
|
||||
|
|
|
@ -241,11 +241,25 @@ 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 = VERSION_MAJOR;
|
||||
r_godot_version->minor = VERSION_MINOR;
|
||||
r_godot_version->patch = VERSION_PATCH;
|
||||
r_godot_version->string = VERSION_FULL_NAME;
|
||||
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;
|
||||
}
|
||||
|
||||
// Memory Functions
|
||||
|
@ -858,84 +872,82 @@ 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) {
|
||||
memnew_placement(r_dest, String(p_contents));
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_latin1(Span<char>(p_contents, p_contents ? strlen(p_contents) : 0));
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf8_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf8(p_contents);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf8(p_contents);
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf16_chars(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16(p_contents);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf16(p_contents);
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf32_chars(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents) {
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents));
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf32(Span(p_contents, p_contents ? strlen(p_contents) : 0));
|
||||
}
|
||||
|
||||
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, parse.
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16((const char16_t *)p_contents);
|
||||
// wchar_t is 16 bit (UTF-16).
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf16((const char16_t *)p_contents);
|
||||
} else {
|
||||
// wchar_t is 32 bit, copy.
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents));
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_latin1_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
|
||||
memnew_placement(r_dest, String(p_contents, p_size));
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_latin1(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_size) : 0));
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf8_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf8(p_contents, p_size);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_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) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
return (GDExtensionInt)dest->parse_utf8(p_contents, p_size);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
return (GDExtensionInt)dest->append_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) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16(p_contents, p_char_count);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_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) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
return (GDExtensionInt)dest->parse_utf16(p_contents, p_char_count, 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);
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf32_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count) {
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents, 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));
|
||||
}
|
||||
|
||||
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, parse.
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16((const char16_t *)p_contents, p_char_count);
|
||||
// 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);
|
||||
} else {
|
||||
// wchar_t is 32 bit, copy.
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents, p_char_count));
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
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->ascii(true);
|
||||
CharString cs = self->latin1();
|
||||
GDExtensionInt len = cs.length();
|
||||
if (r_text) {
|
||||
const char *s_text = cs.ptr();
|
||||
|
@ -1040,16 +1052,12 @@ 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;
|
||||
tmp.parse_utf8(p_contents);
|
||||
|
||||
String tmp = String::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;
|
||||
tmp.parse_utf8(p_contents, p_size);
|
||||
|
||||
String tmp = String::utf8(p_contents, p_size);
|
||||
memnew_placement(r_dest, StringName(tmp));
|
||||
}
|
||||
|
||||
|
@ -1543,11 +1551,8 @@ static void gdextension_placeholder_script_instance_update(GDExtensionScriptInst
|
|||
properties_list.push_back(PropertyInfo::from_dict(d));
|
||||
}
|
||||
|
||||
List<Variant> keys;
|
||||
values.get_key_list(&keys);
|
||||
|
||||
for (const Variant &E : keys) {
|
||||
values_map.insert(E, values[E]);
|
||||
for (const KeyValue<Variant, Variant> &kv : values) {
|
||||
values_map.insert(kv.key, kv.value);
|
||||
}
|
||||
|
||||
placeholder->update(properties_list, values_map);
|
||||
|
@ -1572,6 +1577,15 @@ 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))));
|
||||
|
@ -1666,7 +1680,10 @@ 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);
|
||||
|
@ -1809,6 +1826,7 @@ 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
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_INTERFACE_H
|
||||
#define GDEXTENSION_INTERFACE_H
|
||||
#pragma once
|
||||
|
||||
/* 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.
|
||||
|
@ -401,6 +400,9 @@ 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 {
|
||||
|
@ -790,9 +792,22 @@ 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.
|
||||
*
|
||||
|
@ -800,6 +815,16 @@ 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 */
|
||||
|
||||
/**
|
||||
|
@ -2721,6 +2746,17 @@ 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 */
|
||||
|
||||
/**
|
||||
|
@ -3078,8 +3114,22 @@ 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
|
||||
|
|
|
@ -307,12 +307,12 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) {
|
|||
|
||||
bool compatible = true;
|
||||
// Check version lexicographically.
|
||||
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];
|
||||
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];
|
||||
} else {
|
||||
compatible = VERSION_PATCH >= compatibility_minimum[2];
|
||||
compatible = GODOT_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 (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_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_PATCH
|
||||
#if GODOT_VERSION_PATCH
|
||||
// #if check to avoid -Wtype-limits warning when 0.
|
||||
else {
|
||||
compatible = VERSION_PATCH <= compatibility_maximum[2];
|
||||
compatible = GODOT_VERSION_PATCH <= compatibility_maximum[2];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_LIBRARY_LOADER_H
|
||||
#define GDEXTENSION_LIBRARY_LOADER_H
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
@ -38,6 +37,8 @@
|
|||
#include "core/os/shared_object.h"
|
||||
|
||||
class GDExtensionLibraryLoader : public GDExtensionLoader {
|
||||
GDSOFTCLASS(GDExtensionLibraryLoader, GDExtensionLoader);
|
||||
|
||||
friend class GDExtensionManager;
|
||||
friend class GDExtension;
|
||||
|
||||
|
@ -81,5 +82,3 @@ public:
|
|||
|
||||
Error parse_gdextension_file(const String &p_path);
|
||||
};
|
||||
|
||||
#endif // GDEXTENSION_LIBRARY_LOADER_H
|
||||
|
|
|
@ -28,14 +28,15 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_LOADER_H
|
||||
#define GDEXTENSION_LOADER_H
|
||||
#pragma once
|
||||
|
||||
#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<GDExtension> &p_extension, GDExtensionInitialization *r_initialization) = 0;
|
||||
|
@ -44,5 +45,3 @@ public:
|
|||
virtual bool has_library_changed() const = 0;
|
||||
virtual bool library_exists() const = 0;
|
||||
};
|
||||
|
||||
#endif // GDEXTENSION_LOADER_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_MANAGER_H
|
||||
#define GDEXTENSION_MANAGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/extension/gdextension.h"
|
||||
|
||||
|
@ -92,5 +91,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(GDExtensionManager::LoadStatus)
|
||||
|
||||
#endif // GDEXTENSION_MANAGER_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_SPECIAL_COMPAT_HASHES_H
|
||||
#define GDEXTENSION_SPECIAL_COMPAT_HASHES_H
|
||||
#pragma once
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
||||
|
@ -58,5 +57,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
#endif // GDEXTENSION_SPECIAL_COMPAT_HASHES_H
|
||||
|
|
|
@ -1,55 +1,37 @@
|
|||
import zlib
|
||||
import methods
|
||||
|
||||
|
||||
def run(target, source, env):
|
||||
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
|
||||
buffer = methods.get_buffer(str(source[0]))
|
||||
decomp_size = len(buffer)
|
||||
buffer = methods.compress_buffer(buffer)
|
||||
|
||||
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)}
|
||||
}};
|
||||
|
||||
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<FileAccess> fa = FileAccess::open(p_path, FileAccess::WRITE);
|
||||
ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path));
|
||||
Vector<uint8_t> 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());
|
||||
};
|
||||
};
|
||||
class GDExtensionInterfaceDump {{
|
||||
public:
|
||||
static void generate_gdextension_interface_file(const String &p_path) {{
|
||||
Ref<FileAccess> fa = FileAccess::open(p_path, FileAccess::WRITE);
|
||||
ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path));
|
||||
Vector<uint8_t> 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
|
||||
"""
|
||||
)
|
||||
""")
|
||||
|
|
|
@ -119,10 +119,7 @@ def generate_ex_version(argcount, const=False, returns=False):
|
|||
def run(target, source, env):
|
||||
max_versions = 12
|
||||
|
||||
txt = """
|
||||
#ifndef GDEXTENSION_WRAPPERS_GEN_H
|
||||
#define GDEXTENSION_WRAPPERS_GEN_H
|
||||
"""
|
||||
txt = "#pragma once"
|
||||
|
||||
for i in range(max_versions + 1):
|
||||
txt += "\n/* Extension Wrapper " + str(i) + " Arguments */\n"
|
||||
|
@ -138,7 +135,5 @@ 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)
|
||||
|
|
|
@ -28,12 +28,9 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DEFAULT_CONTROLLER_MAPPINGS_H
|
||||
#define DEFAULT_CONTROLLER_MAPPINGS_H
|
||||
#pragma once
|
||||
|
||||
class DefaultControllerMappings {
|
||||
public:
|
||||
static const char *mappings[];
|
||||
};
|
||||
|
||||
#endif // DEFAULT_CONTROLLER_MAPPINGS_H
|
||||
|
|
|
@ -219,7 +219,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
|
|||
continue;
|
||||
}
|
||||
|
||||
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
|
||||
String name = pi.name.substr(pi.name.find_char('/') + 1);
|
||||
r_options->push_back(name.quote());
|
||||
}
|
||||
}
|
||||
|
@ -1594,8 +1594,8 @@ void Input::parse_mapping(const String &p_mapping) {
|
|||
continue;
|
||||
}
|
||||
|
||||
String output = entry[idx].get_slice(":", 0).replace(" ", "");
|
||||
String input = entry[idx].get_slice(":", 1).replace(" ", "");
|
||||
String output = entry[idx].get_slicec(':', 0).remove_char(' ');
|
||||
String input = entry[idx].get_slicec(':', 1).remove_char(' ');
|
||||
if (output.length() < 1 || input.length() < 2) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_event.h"
|
||||
#include "core/object/object.h"
|
||||
|
@ -86,7 +85,7 @@ public:
|
|||
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
|
||||
|
||||
private:
|
||||
BitField<MouseButtonMask> mouse_button_mask;
|
||||
BitField<MouseButtonMask> mouse_button_mask = MouseButtonMask::NONE;
|
||||
|
||||
RBSet<Key> key_label_pressed;
|
||||
RBSet<Key> physical_keys_pressed;
|
||||
|
@ -403,5 +402,3 @@ public:
|
|||
|
||||
VARIANT_ENUM_CAST(Input::MouseMode);
|
||||
VARIANT_ENUM_CAST(Input::CursorShape);
|
||||
|
||||
#endif // INPUT_H
|
||||
|
|
|
@ -2,18 +2,22 @@
|
|||
|
||||
from collections import OrderedDict
|
||||
|
||||
import methods
|
||||
|
||||
|
||||
def make_default_controller_mappings(target, source, env):
|
||||
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')
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
file.write("""\
|
||||
#include "core/input/default_controller_mappings.h"
|
||||
|
||||
#include "core/typedefs.h"
|
||||
|
||||
""")
|
||||
|
||||
# ensure mappings have a consistent order
|
||||
platform_mappings: dict = OrderedDict()
|
||||
for src_path in source:
|
||||
with open(str(src_path), "r", encoding="utf-8") as f:
|
||||
platform_mappings = OrderedDict()
|
||||
for src_path in map(str, source):
|
||||
with open(src_path, "r", encoding="utf-8") as f:
|
||||
# read mapping file and skip header
|
||||
mapping_file_lines = f.readlines()[2:]
|
||||
|
||||
|
@ -32,28 +36,28 @@ def make_default_controller_mappings(target, source, env):
|
|||
line_parts = line.split(",")
|
||||
guid = line_parts[0]
|
||||
if guid in platform_mappings[current_platform]:
|
||||
g.write(
|
||||
file.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": "#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",
|
||||
PLATFORM_VARIABLES = {
|
||||
"Linux": "LINUXBSD",
|
||||
"Windows": "WINDOWS",
|
||||
"Mac OS X": "MACOS",
|
||||
"Android": "ANDROID",
|
||||
"iOS": "IOS",
|
||||
"Web": "WEB",
|
||||
}
|
||||
|
||||
g.write("const char* DefaultControllerMappings::mappings[] = {\n")
|
||||
file.write("const char *DefaultControllerMappings::mappings[] = {\n")
|
||||
for platform, mappings in platform_mappings.items():
|
||||
variable = platform_variables[platform]
|
||||
g.write("{}\n".format(variable))
|
||||
variable = PLATFORM_VARIABLES[platform]
|
||||
file.write(f"#ifdef {variable}_ENABLED\n")
|
||||
for mapping in mappings.values():
|
||||
g.write('\t"{}",\n'.format(mapping))
|
||||
g.write("#endif\n")
|
||||
file.write(f'\t"{mapping}",\n')
|
||||
file.write(f"#endif // {variable}_ENABLED\n")
|
||||
|
||||
g.write("\tnullptr\n};\n")
|
||||
file.write("\tnullptr\n};\n")
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef INPUT_ENUMS_H
|
||||
#define INPUT_ENUMS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/error/error_macros.h"
|
||||
|
||||
|
@ -138,4 +137,10 @@ inline MouseButtonMask mouse_button_to_mask(MouseButton button) {
|
|||
return MouseButtonMask(1 << ((int)button - 1));
|
||||
}
|
||||
|
||||
#endif // INPUT_ENUMS_H
|
||||
constexpr MouseButtonMask operator|(MouseButtonMask p_a, MouseButtonMask p_b) {
|
||||
return static_cast<MouseButtonMask>(static_cast<int>(p_a) | static_cast<int>(p_b));
|
||||
}
|
||||
|
||||
constexpr MouseButtonMask &operator|=(MouseButtonMask &p_a, MouseButtonMask p_b) {
|
||||
return p_a = p_a | p_b;
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
|
|||
}
|
||||
|
||||
BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
|
||||
BitField<KeyModifierMask> mask;
|
||||
BitField<KeyModifierMask> 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 | (int64_t)get_modifiers_mask();
|
||||
return keycode | get_modifiers_mask();
|
||||
}
|
||||
|
||||
Key InputEventKey::get_physical_keycode_with_modifiers() const {
|
||||
return physical_keycode | (int64_t)get_modifiers_mask();
|
||||
return physical_keycode | get_modifiers_mask();
|
||||
}
|
||||
|
||||
Key InputEventKey::get_key_label_with_modifiers() const {
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef INPUT_EVENT_H
|
||||
#define INPUT_EVENT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_enums.h"
|
||||
#include "core/io/resource.h"
|
||||
|
@ -209,7 +208,7 @@ public:
|
|||
class InputEventMouse : public InputEventWithModifiers {
|
||||
GDCLASS(InputEventMouse, InputEventWithModifiers);
|
||||
|
||||
BitField<MouseButtonMask> button_mask;
|
||||
BitField<MouseButtonMask> button_mask = MouseButtonMask::NONE;
|
||||
|
||||
Vector2 pos;
|
||||
Vector2 global_pos;
|
||||
|
@ -595,5 +594,3 @@ public:
|
|||
|
||||
InputEventShortcut();
|
||||
};
|
||||
|
||||
#endif // INPUT_EVENT_H
|
||||
|
|
|
@ -47,6 +47,8 @@ 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);
|
||||
|
@ -106,7 +108,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, pi.name.length());
|
||||
String name = pi.name.substr(pi.name.find_char('/') + 1);
|
||||
r_options->push_back(name.quote());
|
||||
}
|
||||
}
|
||||
|
@ -181,6 +183,25 @@ 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<Ref<InputEvent>> &inputs = input_map[p_action].inputs;
|
||||
for (Ref<InputEventKey> 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));
|
||||
|
||||
|
@ -304,7 +325,7 @@ void InputMap::load_from_project_settings() {
|
|||
continue;
|
||||
}
|
||||
|
||||
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
|
||||
String name = pi.name.substr(pi.name.find_char('/') + 1);
|
||||
|
||||
Dictionary action = GLOBAL_GET(pi.name);
|
||||
float deadzone = action.has("deadzone") ? (float)action["deadzone"] : DEFAULT_DEADZONE;
|
||||
|
@ -344,6 +365,7 @@ 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") },
|
||||
|
@ -397,17 +419,21 @@ 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 {
|
||||
int len = sizeof(_builtin_action_display_names) / sizeof(_BuiltinActionDisplayName);
|
||||
constexpr int len = std::size(_builtin_action_display_names);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (_builtin_action_display_names[i].name == p_name) {
|
||||
|
@ -487,6 +513,9 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
|
|||
inputs.push_back(InputEventKey::create_reference(Key::END));
|
||||
default_builtin_cache.insert("ui_end", inputs);
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
default_builtin_cache.insert("ui_accessibility_drag_and_drop", inputs);
|
||||
|
||||
// ///// UI basic Shortcuts /////
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
|
@ -499,6 +528,10 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
|
|||
inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::CMD_OR_CTRL));
|
||||
default_builtin_cache.insert("ui_copy", inputs);
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
inputs.push_back(InputEventKey::create_reference(Key::M | KeyModifierMask::CTRL));
|
||||
default_builtin_cache.insert("ui_focus_mode", inputs);
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
inputs.push_back(InputEventKey::create_reference(Key::V | KeyModifierMask::CMD_OR_CTRL));
|
||||
inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::SHIFT));
|
||||
|
@ -772,6 +805,22 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
|
|||
inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE));
|
||||
default_builtin_cache.insert("ui_graph_delete", inputs);
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::CMD_OR_CTRL));
|
||||
default_builtin_cache.insert("ui_graph_follow_left", inputs);
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::ALT));
|
||||
default_builtin_cache.insert("ui_graph_follow_left.macos", inputs);
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::CMD_OR_CTRL));
|
||||
default_builtin_cache.insert("ui_graph_follow_right", inputs);
|
||||
|
||||
inputs = List<Ref<InputEvent>>();
|
||||
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<Ref<InputEvent>>();
|
||||
inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE));
|
||||
|
@ -789,6 +838,12 @@ const HashMap<String, List<Ref<InputEvent>>> &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<Ref<InputEvent>>();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef INPUT_MAP_H
|
||||
#define INPUT_MAP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_event.h"
|
||||
#include "core/object/class_db.h"
|
||||
|
@ -86,6 +85,8 @@ 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<InputEvent> &p_event);
|
||||
|
@ -116,5 +117,3 @@ public:
|
|||
InputMap();
|
||||
~InputMap();
|
||||
};
|
||||
|
||||
#endif // INPUT_MAP_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef SHORTCUT_H
|
||||
#define SHORTCUT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_event.h"
|
||||
#include "core/io/resource.h"
|
||||
|
@ -55,5 +54,3 @@ public:
|
|||
|
||||
static bool is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2);
|
||||
};
|
||||
|
||||
#endif // SHORTCUT_H
|
||||
|
|
|
@ -42,6 +42,12 @@
|
|||
#include <brotli/decode.h>
|
||||
#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: {
|
||||
|
@ -187,12 +193,22 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
|
|||
return total;
|
||||
} break;
|
||||
case MODE_ZSTD: {
|
||||
ZSTD_DCtx *dctx = ZSTD_createDCtx();
|
||||
if (zstd_long_distance_matching) {
|
||||
ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size);
|
||||
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;
|
||||
}
|
||||
int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size);
|
||||
ZSTD_freeDCtx(dctx);
|
||||
|
||||
int ret = ZSTD_decompressDCtx(current_zstd_d_ctx, p_dst, p_dst_max_size, p_src, p_src_size);
|
||||
return ret;
|
||||
} break;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef COMPRESSION_H
|
||||
#define COMPRESSION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/vector.h"
|
||||
#include "core/typedefs.h"
|
||||
|
@ -56,5 +55,3 @@ 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<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode);
|
||||
};
|
||||
|
||||
#endif // COMPRESSION_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CONFIG_FILE_H
|
||||
#define CONFIG_FILE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
@ -78,5 +77,3 @@ public:
|
|||
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
|
||||
Error save_encrypted_pass(const String &p_path, const String &p_pass);
|
||||
};
|
||||
|
||||
#endif // CONFIG_FILE_H
|
||||
|
|
|
@ -146,7 +146,7 @@ Error DirAccess::make_dir_recursive(const String &p_dir) {
|
|||
full_dir = p_dir;
|
||||
}
|
||||
|
||||
full_dir = full_dir.replace("\\", "/");
|
||||
full_dir = full_dir.replace_char('\\', '/');
|
||||
|
||||
String base;
|
||||
|
||||
|
@ -336,7 +336,7 @@ Ref<DirAccess> 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().replace("-", "").replace("T", "").replace(":", "");
|
||||
String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:");
|
||||
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,6 +626,10 @@ 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);
|
||||
|
@ -671,6 +675,7 @@ 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");
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DIR_ACCESS_H
|
||||
#define DIR_ACCESS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
@ -169,10 +168,9 @@ 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
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DTLS_SERVER_H
|
||||
#define DTLS_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/net_socket.h"
|
||||
#include "core/io/packet_peer_dtls.h"
|
||||
|
@ -53,5 +52,3 @@ public:
|
|||
|
||||
DTLSServer() {}
|
||||
};
|
||||
|
||||
#endif // DTLS_SERVER_H
|
||||
|
|
|
@ -104,7 +104,7 @@ Ref<FileAccess> 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().replace("-", "").replace("T", "").replace(":", "");
|
||||
String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:");
|
||||
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("\\", "/");
|
||||
String r_path = p_path.replace_char('\\', '/');
|
||||
|
||||
switch (_access_type) {
|
||||
case ACCESS_RESOURCES: {
|
||||
|
@ -313,9 +313,15 @@ uint16_t FileAccess::get_16() const {
|
|||
uint16_t data = 0;
|
||||
get_buffer(reinterpret_cast<uint8_t *>(&data), sizeof(uint16_t));
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
data = BSWAP16(data);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
data = BSWAP16(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -324,9 +330,15 @@ uint32_t FileAccess::get_32() const {
|
|||
uint32_t data = 0;
|
||||
get_buffer(reinterpret_cast<uint8_t *>(&data), sizeof(uint32_t));
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
data = BSWAP32(data);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
data = BSWAP32(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -335,9 +347,15 @@ uint64_t FileAccess::get_64() const {
|
|||
uint64_t data = 0;
|
||||
get_buffer(reinterpret_cast<uint8_t *>(&data), sizeof(uint64_t));
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
data = BSWAP64(data);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
data = BSWAP64(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -429,7 +447,7 @@ class CharBuffer {
|
|||
public:
|
||||
_FORCE_INLINE_ CharBuffer() :
|
||||
buffer(stack_buffer),
|
||||
capacity(sizeof(stack_buffer) / sizeof(char)) {
|
||||
capacity(std::size(stack_buffer)) {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void push_back(char c) {
|
||||
|
@ -565,7 +583,7 @@ String FileAccess::get_as_utf8_string(bool p_skip_cr) const {
|
|||
w[len] = 0;
|
||||
|
||||
String s;
|
||||
s.parse_utf8((const char *)w, len, p_skip_cr);
|
||||
s.append_utf8((const char *)w, len, p_skip_cr);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -574,25 +592,43 @@ 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<uint8_t *>(&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<uint8_t *>(&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<uint8_t *>(&p_dest), sizeof(uint64_t));
|
||||
}
|
||||
|
@ -629,8 +665,29 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
|
|||
Ref<FileAccess> fa = create_for_path(p_file);
|
||||
ERR_FAIL_COND_V_MSG(fa.is_null(), 0, vformat("Cannot create FileAccess for path '%s'.", p_file));
|
||||
|
||||
uint64_t mt = fa->_get_modified_time(p_file);
|
||||
return mt;
|
||||
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<FileAccess> 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<FileAccess> 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);
|
||||
}
|
||||
|
||||
BitField<FileAccess::UnixPermissionFlags> FileAccess::get_unix_permissions(const String &p_file) {
|
||||
|
@ -723,9 +780,7 @@ String FileAccess::get_pascal_string() {
|
|||
get_buffer((uint8_t *)cs.ptr(), sl);
|
||||
cs[sl] = 0;
|
||||
|
||||
String ret;
|
||||
ret.parse_utf8(cs.ptr(), sl);
|
||||
return ret;
|
||||
return String::utf8(cs.ptr(), sl);
|
||||
}
|
||||
|
||||
bool FileAccess::store_line(const String &p_line) {
|
||||
|
@ -817,7 +872,7 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) {
|
|||
}
|
||||
|
||||
String ret;
|
||||
ret.parse_utf8((const char *)array.ptr(), array.size());
|
||||
ret.append_utf8((const char *)array.ptr(), array.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -931,7 +986,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<uint8_t>(FileAccess::*)(int64_t) const) & FileAccess::get_buffer);
|
||||
ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector<uint8_t> (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));
|
||||
|
@ -950,7 +1005,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<uint8_t> &)) & FileAccess::store_buffer);
|
||||
ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (bool (FileAccess::*)(const Vector<uint8_t> &))&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);
|
||||
|
@ -963,6 +1018,8 @@ 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);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_H
|
||||
#define FILE_ACCESS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/compression.h"
|
||||
#include "core/math/math_defs.h"
|
||||
|
@ -87,7 +86,11 @@ public:
|
|||
typedef void (*FileCloseFailNotify)(const String &);
|
||||
|
||||
typedef Ref<FileAccess> (*CreateFunc)();
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
bool big_endian = true;
|
||||
#else
|
||||
bool big_endian = false;
|
||||
#endif
|
||||
bool real_is_double = false;
|
||||
|
||||
virtual BitField<UnixPermissionFlags> _get_unix_permissions(const String &p_file) = 0;
|
||||
|
@ -105,6 +108,8 @@ 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;
|
||||
|
@ -239,6 +244,8 @@ 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<FileAccess::UnixPermissionFlags> get_unix_permissions(const String &p_file);
|
||||
static Error set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions);
|
||||
|
||||
|
@ -273,5 +280,3 @@ public:
|
|||
VARIANT_ENUM_CAST(FileAccess::CompressionMode);
|
||||
VARIANT_ENUM_CAST(FileAccess::ModeFlags);
|
||||
VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags);
|
||||
|
||||
#endif // FILE_ACCESS_H
|
||||
|
|
|
@ -247,7 +247,11 @@ bool FileAccessCompressed::eof_reached() const {
|
|||
}
|
||||
|
||||
uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
|
||||
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
|
||||
if (p_length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERR_FAIL_NULL_V(p_dst, -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.");
|
||||
|
||||
|
@ -256,29 +260,38 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con
|
|||
return 0;
|
||||
}
|
||||
|
||||
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++;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
} else {
|
||||
read_block--;
|
||||
at_end = true;
|
||||
if (i + 1 < p_length) {
|
||||
read_eof = true;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
if (dst_idx == p_length) {
|
||||
// We're done! We read back all that was requested.
|
||||
return p_length;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
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;
|
||||
|
@ -332,6 +345,22 @@ 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<FileAccess::UnixPermissionFlags> FileAccessCompressed::_get_unix_permissions(const String &p_file) {
|
||||
if (f.is_valid()) {
|
||||
return f->_get_unix_permissions(p_file);
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_COMPRESSED_H
|
||||
#define FILE_ACCESS_COMPRESSED_H
|
||||
#pragma once
|
||||
|
||||
#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,6 +94,8 @@ 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<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
|
||||
|
||||
|
@ -107,5 +109,3 @@ public:
|
|||
FileAccessCompressed() {}
|
||||
virtual ~FileAccessCompressed();
|
||||
};
|
||||
|
||||
#endif // FILE_ACCESS_COMPRESSED_H
|
||||
|
|
|
@ -30,9 +30,17 @@
|
|||
|
||||
#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<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic, const Vector<uint8_t> &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);
|
||||
|
@ -48,9 +56,15 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
|
|||
key = p_key;
|
||||
if (p_iv.is_empty()) {
|
||||
iv.resize(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);
|
||||
if (unlikely(!_fae_static_rng)) {
|
||||
_fae_static_rng = memnew(CryptoCore::RandomGenerator);
|
||||
if (_fae_static_rng->init() != 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);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
} else {
|
||||
ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER);
|
||||
|
@ -265,7 +279,27 @@ bool FileAccessEncrypted::file_exists(const String &p_name) {
|
|||
}
|
||||
|
||||
uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
BitField<FileAccess::UnixPermissionFlags> FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
|
||||
|
|
|
@ -28,14 +28,16 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_ENCRYPTED_H
|
||||
#define FILE_ACCESS_ENCRYPTED_H
|
||||
#pragma once
|
||||
|
||||
#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,
|
||||
|
@ -57,6 +59,8 @@ private:
|
|||
|
||||
void _close();
|
||||
|
||||
static CryptoCore::RandomGenerator *_fae_static_rng;
|
||||
|
||||
public:
|
||||
Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true, const Vector<uint8_t> &p_iv = Vector<uint8_t>());
|
||||
Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode);
|
||||
|
@ -87,6 +91,8 @@ 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<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
|
||||
|
||||
|
@ -97,8 +103,8 @@ public:
|
|||
|
||||
virtual void close() override;
|
||||
|
||||
static void deinitialize();
|
||||
|
||||
FileAccessEncrypted() {}
|
||||
~FileAccessEncrypted();
|
||||
};
|
||||
|
||||
#endif // FILE_ACCESS_ENCRYPTED_H
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_MEMORY_H
|
||||
#define FILE_ACCESS_MEMORY_H
|
||||
#pragma once
|
||||
|
||||
#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,6 +66,9 @@ 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<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
|
||||
|
||||
|
@ -78,5 +81,3 @@ public:
|
|||
|
||||
FileAccessMemory() {}
|
||||
};
|
||||
|
||||
#endif // FILE_ACCESS_MEMORY_H
|
||||
|
|
|
@ -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 > 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));
|
||||
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));
|
||||
|
||||
uint32_t pack_flags = f->get_32();
|
||||
uint64_t file_base = f->get_64();
|
||||
|
@ -306,9 +306,7 @@ 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;
|
||||
path.parse_utf8(cs.ptr(), sl);
|
||||
|
||||
String path = String::utf8(cs.ptr(), sl);
|
||||
uint64_t ofs = f->get_64();
|
||||
uint64_t size = f->get_64();
|
||||
uint8_t md5[16];
|
||||
|
@ -550,7 +548,7 @@ String DirAccessPack::get_drive(int p_drive) {
|
|||
}
|
||||
|
||||
PackedData::PackedDir *DirAccessPack::_find_dir(const String &p_dir) {
|
||||
String nd = p_dir.replace("\\", "/");
|
||||
String nd = p_dir.replace_char('\\', '/');
|
||||
|
||||
// Special handling since simplify_path() will forbid it
|
||||
if (p_dir == "..") {
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_PACK_H
|
||||
#define FILE_ACCESS_PACK_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
@ -127,6 +126,8 @@ public:
|
|||
_FORCE_INLINE_ Ref<FileAccess> 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<DirAccess> try_open_directory(const String &p_path);
|
||||
_FORCE_INLINE_ bool has_directory(const String &p_path);
|
||||
|
||||
|
@ -156,6 +157,7 @@ public:
|
|||
};
|
||||
|
||||
class FileAccessPack : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessPack, FileAccess);
|
||||
PackedData::PackedFile pf;
|
||||
|
||||
mutable uint64_t pos;
|
||||
|
@ -165,6 +167,8 @@ class FileAccessPack : public FileAccess {
|
|||
Ref<FileAccess> 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<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
|
||||
|
||||
|
@ -200,6 +204,19 @@ 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<PathMD5, PackedFile, PathMD5>::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<FileAccess> PackedData::try_open_path(const String &p_path) {
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
|
@ -225,6 +242,7 @@ bool PackedData::has_directory(const String &p_path) {
|
|||
}
|
||||
|
||||
class DirAccessPack : public DirAccess {
|
||||
GDSOFTCLASS(DirAccessPack, DirAccess);
|
||||
PackedData::PackedDir *current;
|
||||
|
||||
List<String> list_dirs;
|
||||
|
@ -272,5 +290,3 @@ Ref<DirAccess> PackedData::try_open_directory(const String &p_path) {
|
|||
}
|
||||
return da;
|
||||
}
|
||||
|
||||
#endif // FILE_ACCESS_PACK_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_ZIP_H
|
||||
#define FILE_ACCESS_ZIP_H
|
||||
#pragma once
|
||||
|
||||
#ifdef MINIZIP_ENABLED
|
||||
|
||||
|
@ -74,6 +73,7 @@ public:
|
|||
};
|
||||
|
||||
class FileAccessZip : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessZip, FileAccess);
|
||||
unzFile zfile = nullptr;
|
||||
unz_file_info64 file_info;
|
||||
|
||||
|
@ -102,7 +102,9 @@ 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; } // todo
|
||||
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<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
|
||||
|
||||
|
@ -118,5 +120,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // MINIZIP_ENABLED
|
||||
|
||||
#endif // FILE_ACCESS_ZIP_H
|
||||
|
|
|
@ -70,10 +70,9 @@ Error HTTPClient::_request(Method p_method, const String &p_url, const Vector<St
|
|||
|
||||
String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
|
||||
String query = "";
|
||||
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]];
|
||||
for (const KeyValue<Variant, Variant> &kv : p_dict) {
|
||||
String encoded_key = String(kv.key).uri_encode();
|
||||
const Variant &value = kv.value;
|
||||
switch (value.get_type()) {
|
||||
case Variant::ARRAY: {
|
||||
// Repeat the key with every values
|
||||
|
@ -118,7 +117,7 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() {
|
|||
continue;
|
||||
}
|
||||
String key = s.substr(0, sp).strip_edges();
|
||||
String value = s.substr(sp + 1, s.length()).strip_edges();
|
||||
String value = s.substr(sp + 1).strip_edges();
|
||||
ret[key] = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef HTTP_CLIENT_H
|
||||
#define HTTP_CLIENT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/crypto.h"
|
||||
#include "core/io/ip.h"
|
||||
|
@ -205,5 +204,3 @@ public:
|
|||
VARIANT_ENUM_CAST(HTTPClient::ResponseCode)
|
||||
VARIANT_ENUM_CAST(HTTPClient::Method);
|
||||
VARIANT_ENUM_CAST(HTTPClient::Status);
|
||||
|
||||
#endif // HTTP_CLIENT_H
|
||||
|
|
|
@ -50,13 +50,13 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, Ref<TLSOp
|
|||
|
||||
String host_lower = conn_host.to_lower();
|
||||
if (host_lower.begins_with("http://")) {
|
||||
conn_host = conn_host.substr(7, conn_host.length() - 7);
|
||||
conn_host = conn_host.substr(7);
|
||||
tls_options.unref();
|
||||
} else if (host_lower.begins_with("https://")) {
|
||||
if (tls_options.is_null()) {
|
||||
tls_options = TLSOptions::client();
|
||||
}
|
||||
conn_host = conn_host.substr(8, conn_host.length() - 8);
|
||||
conn_host = conn_host.substr(8);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(tls_options.is_valid() && tls_options->is_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(VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n";
|
||||
request += "User-Agent: GodotEngine/" + String(GODOT_VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n";
|
||||
}
|
||||
if (add_accept) {
|
||||
request += "Accept: */*\r\n";
|
||||
|
@ -483,8 +483,7 @@ 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;
|
||||
response.parse_utf8((const char *)response_str.ptr(), response_str.size());
|
||||
String response = String::utf8((const char *)response_str.ptr(), response_str.size());
|
||||
Vector<String> responses = response.split("\n");
|
||||
body_size = -1;
|
||||
chunked = false;
|
||||
|
@ -508,11 +507,11 @@ Error HTTPClientTCP::poll() {
|
|||
continue;
|
||||
}
|
||||
if (s.begins_with("content-length:")) {
|
||||
body_size = s.substr(s.find_char(':') + 1, s.length()).strip_edges().to_int();
|
||||
body_size = s.substr(s.find_char(':') + 1).strip_edges().to_int();
|
||||
body_left = body_size;
|
||||
|
||||
} else if (s.begins_with("transfer-encoding:")) {
|
||||
String encoding = header.substr(header.find_char(':') + 1, header.length()).strip_edges();
|
||||
String encoding = header.substr(header.find_char(':') + 1).strip_edges();
|
||||
if (encoding == "chunked") {
|
||||
chunked = true;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef HTTP_CLIENT_TCP_H
|
||||
#define HTTP_CLIENT_TCP_H
|
||||
#pragma once
|
||||
|
||||
#include "http_client.h"
|
||||
|
||||
|
@ -100,5 +99,3 @@ public:
|
|||
void set_https_proxy(const String &p_host, int p_port) override;
|
||||
HTTPClientTCP();
|
||||
};
|
||||
|
||||
#endif // HTTP_CLIENT_TCP_H
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#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"
|
||||
|
@ -89,11 +88,13 @@ 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.
|
||||
|
||||
|
@ -105,6 +106,7 @@ 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.
|
||||
|
||||
|
@ -571,7 +573,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.size() == 0 || p_new_format == format) {
|
||||
if (data.is_empty() || p_new_format == format) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -796,7 +798,7 @@ Image::Format Image::get_format() const {
|
|||
}
|
||||
|
||||
static double _bicubic_interp_kernel(double x) {
|
||||
x = ABS(x);
|
||||
x = Math::abs(x);
|
||||
|
||||
double bc = 0;
|
||||
|
||||
|
@ -1139,7 +1141,7 @@ bool Image::is_size_po2() const {
|
|||
}
|
||||
|
||||
void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats.");
|
||||
|
||||
int w = next_power_of_2(width);
|
||||
int h = next_power_of_2(height);
|
||||
|
@ -1158,7 +1160,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(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats.");
|
||||
|
||||
bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */;
|
||||
|
||||
|
@ -1461,8 +1463,7 @@ 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(!_can_modify(format), "Cannot crop in compressed or custom image formats.");
|
||||
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot crop in compressed 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.");
|
||||
|
@ -1515,7 +1516,7 @@ void Image::crop(int p_width, int p_height) {
|
|||
}
|
||||
|
||||
void Image::rotate_90(ClockDirection p_direction) {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed 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));
|
||||
|
||||
|
@ -1633,7 +1634,7 @@ void Image::rotate_90(ClockDirection p_direction) {
|
|||
}
|
||||
|
||||
void Image::rotate_180() {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed 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));
|
||||
|
||||
|
@ -1667,7 +1668,7 @@ void Image::rotate_180() {
|
|||
}
|
||||
|
||||
void Image::flip_y() {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_y in compressed image formats.");
|
||||
|
||||
bool used_mipmaps = has_mipmaps();
|
||||
if (used_mipmaps) {
|
||||
|
@ -1697,7 +1698,7 @@ void Image::flip_y() {
|
|||
}
|
||||
|
||||
void Image::flip_x() {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_x in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_x in compressed image formats.");
|
||||
|
||||
bool used_mipmaps = has_mipmaps();
|
||||
if (used_mipmaps) {
|
||||
|
@ -1789,10 +1790,6 @@ 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 <typename Component, int CC, bool renormalize,
|
||||
void (*average_func)(Component &, const Component &, const Component &, const Component &, const Component &),
|
||||
void (*renormalize_func)(Component *)>
|
||||
|
@ -1926,7 +1923,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(!_can_modify(format));
|
||||
ERR_FAIL_COND(is_compressed());
|
||||
|
||||
new_data.resize((width / 2) * (height / 2) * get_format_pixel_size(format));
|
||||
ERR_FAIL_COND(data.is_empty() || new_data.is_empty());
|
||||
|
@ -1963,7 +1960,7 @@ void Image::normalize() {
|
|||
}
|
||||
|
||||
Error Image::generate_mipmaps(bool p_renormalize) {
|
||||
ERR_FAIL_COND_V_MSG(!_can_modify(format), ERR_UNAVAILABLE, "Cannot generate mipmaps in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_V_MSG(is_compressed(), ERR_UNAVAILABLE, "Cannot generate mipmaps from compressed 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.");
|
||||
|
||||
|
@ -2180,7 +2177,7 @@ void Image::clear_mipmaps() {
|
|||
}
|
||||
|
||||
bool Image::is_empty() const {
|
||||
return (data.size() == 0);
|
||||
return (data.is_empty());
|
||||
}
|
||||
|
||||
Vector<uint8_t> Image::get_data() const {
|
||||
|
@ -2297,7 +2294,7 @@ void Image::initialize_data(const char **p_xpm) {
|
|||
switch (status) {
|
||||
case READING_HEADER: {
|
||||
String line_str = line_ptr;
|
||||
line_str.replace("\t", " ");
|
||||
line_str.replace_char('\t', ' ');
|
||||
|
||||
size_width = line_str.get_slicec(' ', 0).to_int();
|
||||
size_height = line_str.get_slicec(' ', 1).to_int();
|
||||
|
@ -2441,47 +2438,75 @@ void Image::initialize_data(const char **p_xpm) {
|
|||
}
|
||||
|
||||
bool Image::is_invisible() const {
|
||||
if (format == FORMAT_L8 || format == FORMAT_RGB8 || format == FORMAT_RG8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t len = data.size();
|
||||
int w, h;
|
||||
int64_t len;
|
||||
_get_mipmap_offset_and_size(1, len, w, h);
|
||||
|
||||
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: {
|
||||
for (int i = 0; i < (len >> 1); i++) {
|
||||
DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]);
|
||||
}
|
||||
const int pixel_count = len / 2;
|
||||
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
|
||||
|
||||
for (int i = 0; i < pixel_count; i++) {
|
||||
if ((pixeldata[i] & 0xFF00) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case FORMAT_RGBA8: {
|
||||
for (int i = 0; i < (len >> 2); i++) {
|
||||
DETECT_NON_ALPHA(data_ptr[(i << 2) + 3])
|
||||
const int pixel_count = len / 4;
|
||||
const uint32_t *pixeldata = reinterpret_cast<const uint32_t *>(data.ptr());
|
||||
|
||||
for (int i = 0; i < pixel_count; i++) {
|
||||
if ((pixeldata[i] & 0xFF000000) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case FORMAT_RGBA4444: {
|
||||
const int pixel_count = len / 2;
|
||||
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
|
||||
|
||||
case FORMAT_DXT3:
|
||||
case FORMAT_DXT5: {
|
||||
detected = true;
|
||||
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<const uint16_t *>(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<const uint32_t *>(data.ptr());
|
||||
|
||||
for (int i = 0; i < pixel_count; i += 4) {
|
||||
if ((pixeldata[i + 3] & 0x7FFFFFFF) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
// Formats that are compressed or don't support alpha channels are presumed to be visible.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !detected;
|
||||
// Every pixel has been checked, the image is invisible.
|
||||
return true;
|
||||
}
|
||||
|
||||
Image::AlphaMode Image::detect_alpha() const {
|
||||
|
@ -2603,6 +2628,21 @@ Vector<uint8_t> Image::save_exr_to_buffer(bool p_grayscale) const {
|
|||
return save_exr_buffer_func(Ref<Image>((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>((Image *)this));
|
||||
}
|
||||
|
||||
Vector<uint8_t> Image::save_dds_to_buffer() const {
|
||||
if (save_dds_buffer_func == nullptr) {
|
||||
return Vector<uint8_t>();
|
||||
}
|
||||
return save_dds_buffer_func(Ref<Image>((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;
|
||||
|
@ -2682,6 +2722,19 @@ 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.");
|
||||
|
@ -2863,7 +2916,7 @@ void Image::blit_rect(const Ref<Image> &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(!_can_modify(format), "Cannot blit_rect in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot blit_rect in compressed image formats.");
|
||||
|
||||
Rect2i src_rect;
|
||||
Rect2i dest_rect;
|
||||
|
@ -3043,10 +3096,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.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill in compressed image formats.");
|
||||
|
||||
uint8_t *dst_data_ptr = data.ptrw();
|
||||
|
||||
|
@ -3059,10 +3112,10 @@ void Image::fill(const Color &p_color) {
|
|||
}
|
||||
|
||||
void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill rect in compressed image formats.");
|
||||
|
||||
Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect.abs());
|
||||
if (!r.has_area()) {
|
||||
|
@ -3278,7 +3331,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, 33)) << 5;
|
||||
rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 63)) << 5;
|
||||
rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 11;
|
||||
|
||||
((uint16_t *)ptr)[ofs] = rgba;
|
||||
|
@ -3366,7 +3419,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(!_can_modify(format), "Cannot adjust_bcs in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot adjust_bcs in compressed image formats.");
|
||||
|
||||
uint8_t *w = data.ptrw();
|
||||
uint32_t pixel_size = get_format_pixel_size(format);
|
||||
|
@ -3524,6 +3577,9 @@ 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));
|
||||
|
||||
|
@ -3577,6 +3633,7 @@ 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));
|
||||
|
@ -3677,7 +3734,7 @@ void Image::normal_map_to_xy() {
|
|||
}
|
||||
|
||||
Ref<Image> Image::rgbe_to_srgb() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return Ref<Image>();
|
||||
}
|
||||
|
||||
|
@ -3724,7 +3781,7 @@ Ref<Image> Image::get_image_from_mipmap(int p_mipmap) const {
|
|||
}
|
||||
|
||||
void Image::bump_map_to_normal_map(float bump_scale) {
|
||||
ERR_FAIL_COND(!_can_modify(format));
|
||||
ERR_FAIL_COND(is_compressed());
|
||||
clear_mipmaps();
|
||||
convert(Image::FORMAT_RF);
|
||||
|
||||
|
@ -3799,7 +3856,7 @@ bool Image::detect_signed(bool p_include_mips) const {
|
|||
}
|
||||
|
||||
void Image::srgb_to_linear() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3830,7 +3887,7 @@ void Image::srgb_to_linear() {
|
|||
}
|
||||
|
||||
void Image::linear_to_srgb() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3861,7 +3918,7 @@ void Image::linear_to_srgb() {
|
|||
}
|
||||
|
||||
void Image::premultiply_alpha() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3883,7 +3940,7 @@ void Image::premultiply_alpha() {
|
|||
}
|
||||
|
||||
void Image::fix_alpha_edges() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4072,6 +4129,14 @@ Error Image::load_bmp_from_buffer(const Vector<uint8_t> &p_array) {
|
|||
return _load_from_buffer(p_array, _bmp_mem_loader_func);
|
||||
}
|
||||
|
||||
Error Image::load_dds_from_buffer(const Vector<uint8_t> &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<uint8_t> &p_array, float scale) {
|
||||
ERR_FAIL_NULL_V_MSG(
|
||||
_svg_scalable_mem_loader_func,
|
||||
|
@ -4266,10 +4331,10 @@ Dictionary Image::compute_image_metrics(const Ref<Image> p_compared_image, bool
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Dictionary result;
|
||||
result["max"] = INFINITY;
|
||||
result["mean"] = INFINITY;
|
||||
result["mean_squared"] = INFINITY;
|
||||
result["root_mean_squared"] = INFINITY;
|
||||
result["max"] = Math::INF;
|
||||
result["mean"] = Math::INF;
|
||||
result["mean_squared"] = Math::INF;
|
||||
result["root_mean_squared"] = Math::INF;
|
||||
result["peak_snr"] = 0.0f;
|
||||
|
||||
ERR_FAIL_COND_V(p_compared_image.is_null(), result);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IMAGE_H
|
||||
#define IMAGE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/math/color.h"
|
||||
|
@ -59,6 +58,9 @@ typedef Vector<uint8_t> (*SaveWebPBufferFunc)(const Ref<Image> &p_img, const boo
|
|||
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
|
||||
typedef Vector<uint8_t> (*SaveEXRBufferFunc)(const Ref<Image> &p_img, bool p_grayscale);
|
||||
|
||||
typedef Error (*SaveDDSFunc)(const String &p_path, const Ref<Image> &p_img);
|
||||
typedef Vector<uint8_t> (*SaveDDSBufferFunc)(const Ref<Image> &p_img);
|
||||
|
||||
class Image : public Resource {
|
||||
GDCLASS(Image, Resource);
|
||||
|
||||
|
@ -186,10 +188,12 @@ 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.
|
||||
|
||||
|
@ -201,6 +205,7 @@ 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.
|
||||
|
||||
|
@ -251,7 +256,6 @@ 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<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest, Rect2i &r_clipped_src_rect, Rect2i &r_clipped_dest_rect) const;
|
||||
|
||||
|
@ -334,9 +338,11 @@ public:
|
|||
static Ref<Image> 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<uint8_t> save_png_to_buffer() const;
|
||||
Vector<uint8_t> save_jpg_to_buffer(float p_quality = 0.75) const;
|
||||
Vector<uint8_t> save_exr_to_buffer(bool p_grayscale = false) const;
|
||||
Vector<uint8_t> 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<uint8_t> save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const;
|
||||
|
@ -373,6 +379,8 @@ 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();
|
||||
|
@ -403,6 +411,7 @@ public:
|
|||
Error load_tga_from_buffer(const Vector<uint8_t> &p_array);
|
||||
Error load_bmp_from_buffer(const Vector<uint8_t> &p_array);
|
||||
Error load_ktx_from_buffer(const Vector<uint8_t> &p_array);
|
||||
Error load_dds_from_buffer(const Vector<uint8_t> &p_array);
|
||||
|
||||
Error load_svg_from_buffer(const Vector<uint8_t> &p_array, float scale = 1.0);
|
||||
Error load_svg_from_string(const String &p_svg_str, float scale = 1.0);
|
||||
|
@ -442,5 +451,3 @@ VARIANT_ENUM_CAST(Image::UsedChannels)
|
|||
VARIANT_ENUM_CAST(Image::AlphaMode)
|
||||
VARIANT_ENUM_CAST(Image::RoughnessChannel)
|
||||
VARIANT_ENUM_CAST(Image::ASTCFormat)
|
||||
|
||||
#endif // IMAGE_H
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IMAGE_LOADER_H
|
||||
#define IMAGE_LOADER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/core_bind.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
@ -108,5 +107,3 @@ 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
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IP_H
|
||||
#define IP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/ip_address.h"
|
||||
#include "core/os/os.h"
|
||||
|
@ -110,5 +109,3 @@ public:
|
|||
|
||||
VARIANT_ENUM_CAST(IP::Type);
|
||||
VARIANT_ENUM_CAST(IP::ResolverStatus);
|
||||
|
||||
#endif // IP_H
|
||||
|
|
|
@ -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, p_string.length() - p_start);
|
||||
ip = p_string.substr(p_start);
|
||||
} else {
|
||||
ip = p_string;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IP_ADDRESS_H
|
||||
#define IP_ADDRESS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
|
@ -96,4 +95,6 @@ public:
|
|||
IPAddress() { clear(); }
|
||||
};
|
||||
|
||||
#endif // IP_ADDRESS_H
|
||||
// Zero-constructing IPAddress initializes field, valid, and wildcard to 0 (and thus empty).
|
||||
template <>
|
||||
struct is_zero_constructible<IPAddress> : std::true_type {};
|
||||
|
|
|
@ -122,8 +122,7 @@ 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());
|
||||
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
LocalVector<Variant> keys = d.get_key_list();
|
||||
|
||||
if (p_sort_keys) {
|
||||
keys.sort_custom<StringLikeVariantOrder>();
|
||||
|
@ -664,201 +663,96 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_
|
|||
|
||||
case Variant::VECTOR2: {
|
||||
const Vector2 v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
|
||||
Array args = { v.x, v.y };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR2I: {
|
||||
const Vector2i v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
|
||||
Array args = { v.x, v.y };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::RECT2: {
|
||||
const Rect2 r = p_variant;
|
||||
|
||||
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);
|
||||
|
||||
Array args = { r.position.x, r.position.y, r.size.width, r.size.height };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::RECT2I: {
|
||||
const Rect2i r = p_variant;
|
||||
|
||||
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);
|
||||
|
||||
Array args = { r.position.x, r.position.y, r.size.width, r.size.height };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR3: {
|
||||
const Vector3 v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
|
||||
Array args = { v.x, v.y, v.z };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR3I: {
|
||||
const Vector3i v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
|
||||
Array args = { v.x, v.y, v.z };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::TRANSFORM2D: {
|
||||
const Transform2D t = p_variant;
|
||||
|
||||
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);
|
||||
|
||||
Array args = { t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR4: {
|
||||
const Vector4 v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
args.push_back(v.w);
|
||||
|
||||
Array args = { v.x, v.y, v.z, v.w };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR4I: {
|
||||
const Vector4i v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
args.push_back(v.w);
|
||||
|
||||
Array args = { v.x, v.y, v.z, v.w };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::PLANE: {
|
||||
const Plane p = p_variant;
|
||||
|
||||
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);
|
||||
|
||||
Array args = { p.normal.x, p.normal.y, p.normal.z, p.d };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::QUATERNION: {
|
||||
const Quaternion q = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(q.x);
|
||||
args.push_back(q.y);
|
||||
args.push_back(q.z);
|
||||
args.push_back(q.w);
|
||||
|
||||
Array args = { q.x, q.y, q.z, q.w };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::AABB: {
|
||||
const AABB aabb = p_variant;
|
||||
|
||||
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);
|
||||
|
||||
Array args = { aabb.position.x, aabb.position.y, aabb.position.z, aabb.size.x, aabb.size.y, aabb.size.z };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::BASIS: {
|
||||
const Basis b = p_variant;
|
||||
|
||||
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);
|
||||
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 };
|
||||
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::TRANSFORM3D: {
|
||||
const Transform3D t = p_variant;
|
||||
|
||||
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);
|
||||
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 };
|
||||
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::PROJECTION: {
|
||||
const Projection p = p_variant;
|
||||
|
||||
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);
|
||||
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 };
|
||||
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::COLOR: {
|
||||
const Color c = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(c.r);
|
||||
args.push_back(c.g);
|
||||
args.push_back(c.b);
|
||||
args.push_back(c.a);
|
||||
|
||||
Array args = { c.r, c.g, c.b, c.a };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
|
||||
|
@ -922,12 +816,9 @@ 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.");
|
||||
|
||||
List<Variant> 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));
|
||||
for (const KeyValue<Variant, Variant> &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));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef JSON_H
|
||||
#define JSON_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
|
@ -125,5 +124,3 @@ public:
|
|||
virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override;
|
||||
virtual bool recognize(const Ref<Resource> &p_resource) const override;
|
||||
};
|
||||
|
||||
#endif // JSON_H
|
||||
|
|
|
@ -36,10 +36,9 @@
|
|||
#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)
|
||||
|
@ -156,7 +155,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(":", ".");
|
||||
String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace_char(':', '.');
|
||||
String backup_name = base_path.get_basename() + timestamp;
|
||||
if (!base_path.get_extension().is_empty()) {
|
||||
backup_name += "." + base_path.get_extension();
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
@ -109,5 +108,3 @@ public:
|
|||
|
||||
virtual ~CompositeLogger();
|
||||
};
|
||||
|
||||
#endif // LOGGER_H
|
||||
|
|
|
@ -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.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA);
|
||||
ERR_FAIL_COND_V(str.append_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.operator String() : EncodedObjectAsID::get_class_static(), buf, r_len);
|
||||
_encode_string(p_full_objects ? p_type.class_name : 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,19 +1849,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
|||
}
|
||||
r_len += 4;
|
||||
|
||||
List<Variant> keys;
|
||||
dict.get_key_list(&keys);
|
||||
|
||||
for (const Variant &key : keys) {
|
||||
for (const KeyValue<Variant, Variant> &kv : dict) {
|
||||
int len;
|
||||
Error err = encode_variant(key, buf, len, p_full_objects, p_depth + 1);
|
||||
Error err = encode_variant(kv.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(key);
|
||||
const Variant *value = dict.getptr(kv.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);
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MARSHALLS_H
|
||||
#define MARSHALLS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
@ -226,5 +225,3 @@ 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<float> vector3_to_float32_array(const Vector3 *vecs, size_t count);
|
||||
|
||||
#endif // MARSHALLS_H
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue