summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub1
-rw-r--r--core/config/SCsub1
-rw-r--r--core/config/engine.cpp8
-rw-r--r--core/config/engine.h3
-rw-r--r--core/core_bind.cpp17
-rw-r--r--core/core_bind.h5
-rw-r--r--core/core_constants.cpp1
-rw-r--r--core/crypto/SCsub1
-rw-r--r--core/debugger/SCsub1
-rw-r--r--core/debugger/remote_debugger.cpp36
-rw-r--r--core/error/SCsub1
-rw-r--r--core/extension/SCsub1
-rw-r--r--core/extension/extension_api_dump.cpp1
-rw-r--r--core/extension/gdextension_library_loader.cpp4
-rw-r--r--core/extension/gdextension_library_loader.h1
-rw-r--r--core/extension/gdextension_loader.h1
-rw-r--r--core/extension/gdextension_manager.cpp3
-rw-r--r--core/extension/make_wrappers.py4
-rw-r--r--core/input/SCsub1
-rw-r--r--core/input/input_builders.py2
-rw-r--r--core/io/SCsub1
-rw-r--r--core/io/file_access_pack.cpp16
-rw-r--r--core/io/file_access_pack.h3
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/pck_packer.cpp12
-rw-r--r--core/io/pck_packer.h4
-rw-r--r--core/io/resource.cpp19
-rw-r--r--core/io/resource.h5
-rw-r--r--core/io/resource_importer.cpp2
-rw-r--r--core/io/resource_importer.h2
-rw-r--r--core/math/SCsub1
-rw-r--r--core/math/convex_hull.cpp2
-rw-r--r--core/math/transform_2d.h13
-rw-r--r--core/math/vector4.h6
-rw-r--r--core/object/SCsub1
-rw-r--r--core/object/callable_method_pointer.h137
-rw-r--r--core/object/make_virtuals.py30
-rw-r--r--core/object/object.h9
-rw-r--r--core/object/script_language_extension.h132
-rw-r--r--core/object/undo_redo.cpp8
-rw-r--r--core/object/undo_redo.h1
-rw-r--r--core/os/SCsub1
-rw-r--r--core/string/SCsub1
-rw-r--r--core/string/ustring.cpp50
-rw-r--r--core/string/ustring.h3
-rw-r--r--core/templates/SCsub1
-rw-r--r--core/variant/SCsub1
-rw-r--r--core/variant/binder_common.h4
-rw-r--r--core/variant/variant_call.cpp31
-rw-r--r--core/variant/variant_op.h30
50 files changed, 406 insertions, 215 deletions
diff --git a/core/SCsub b/core/SCsub
index c8267ae960..8bda230b87 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/config/SCsub b/core/config/SCsub
index bf70285490..1417a258c1 100644
--- a/core/config/SCsub
+++ b/core/config/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/config/engine.cpp b/core/config/engine.cpp
index 9cdc21fe8e..d77c913314 100644
--- a/core/config/engine.cpp
+++ b/core/config/engine.cpp
@@ -267,6 +267,14 @@ bool Engine::is_extra_gpu_memory_tracking_enabled() const {
return extra_gpu_memory_tracking;
}
+void Engine::set_print_to_stdout(bool p_enabled) {
+ CoreGlobals::print_line_enabled = p_enabled;
+}
+
+bool Engine::is_printing_to_stdout() const {
+ return CoreGlobals::print_line_enabled;
+}
+
void Engine::set_print_error_messages(bool p_enabled) {
CoreGlobals::print_error_enabled = p_enabled;
}
diff --git a/core/config/engine.h b/core/config/engine.h
index f858eba328..a0b1ffa981 100644
--- a/core/config/engine.h
+++ b/core/config/engine.h
@@ -128,6 +128,9 @@ public:
void set_time_scale(double p_scale);
double get_time_scale() const;
+ void set_print_to_stdout(bool p_enabled);
+ bool is_printing_to_stdout() const;
+
void set_print_error_messages(bool p_enabled);
bool is_printing_error_messages() const;
void print_header(const String &p_string) const;
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index bbfbb6e3cd..891e3a28c9 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -184,6 +184,10 @@ void ResourceSaver::remove_resource_format_saver(Ref<ResourceFormatSaver> p_form
::ResourceSaver::remove_resource_format_saver(p_format_saver);
}
+ResourceUID::ID ResourceSaver::get_resource_id_for_path(const String &p_path, bool p_generate) {
+ return ::ResourceSaver::get_resource_id_for_path(p_path, p_generate);
+}
+
ResourceSaver *ResourceSaver::singleton = nullptr;
void ResourceSaver::_bind_methods() {
@@ -191,6 +195,7 @@ void ResourceSaver::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_recognized_extensions", "type"), &ResourceSaver::get_recognized_extensions);
ClassDB::bind_method(D_METHOD("add_resource_format_saver", "format_saver", "at_front"), &ResourceSaver::add_resource_format_saver, DEFVAL(false));
ClassDB::bind_method(D_METHOD("remove_resource_format_saver", "format_saver"), &ResourceSaver::remove_resource_format_saver);
+ ClassDB::bind_method(D_METHOD("get_resource_id_for_path", "path", "generate"), &ResourceSaver::get_resource_id_for_path, DEFVAL(false));
BIND_BITFIELD_FLAG(FLAG_NONE);
BIND_BITFIELD_FLAG(FLAG_RELATIVE_PATHS);
@@ -1848,6 +1853,14 @@ String Engine::get_write_movie_path() const {
return ::Engine::get_singleton()->get_write_movie_path();
}
+void Engine::set_print_to_stdout(bool p_enabled) {
+ ::Engine::get_singleton()->set_print_to_stdout(p_enabled);
+}
+
+bool Engine::is_printing_to_stdout() const {
+ return ::Engine::get_singleton()->is_printing_to_stdout();
+}
+
void Engine::set_print_error_messages(bool p_enabled) {
::Engine::get_singleton()->set_print_error_messages(p_enabled);
}
@@ -1916,10 +1929,14 @@ void Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_write_movie_path"), &Engine::get_write_movie_path);
+ ClassDB::bind_method(D_METHOD("set_print_to_stdout", "enabled"), &Engine::set_print_to_stdout);
+ ClassDB::bind_method(D_METHOD("is_printing_to_stdout"), &Engine::is_printing_to_stdout);
+
ClassDB::bind_method(D_METHOD("set_print_error_messages", "enabled"), &Engine::set_print_error_messages);
ClassDB::bind_method(D_METHOD("is_printing_error_messages"), &Engine::is_printing_error_messages);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "print_error_messages"), "set_print_error_messages", "is_printing_error_messages");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "print_to_stdout"), "set_print_to_stdout", "is_printing_to_stdout");
ADD_PROPERTY(PropertyInfo(Variant::INT, "physics_ticks_per_second"), "set_physics_ticks_per_second", "get_physics_ticks_per_second");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_physics_steps_per_frame"), "set_max_physics_steps_per_frame", "get_max_physics_steps_per_frame");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_fps"), "set_max_fps", "get_max_fps");
diff --git a/core/core_bind.h b/core/core_bind.h
index 2a31e64425..ce0bde3c05 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -116,6 +116,8 @@ public:
void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front);
void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
+ ResourceUID::ID get_resource_id_for_path(const String &p_path, bool p_generate = false);
+
ResourceSaver() { singleton = this; }
};
@@ -567,6 +569,9 @@ public:
// `set_write_movie_path()` is not exposed to the scripting API as changing it at run-time has no effect.
String get_write_movie_path() const;
+ void set_print_to_stdout(bool p_enabled);
+ bool is_printing_to_stdout() const;
+
void set_print_error_messages(bool p_enabled);
bool is_printing_error_messages() const;
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 68af5abf66..25da49fa5c 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -677,6 +677,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_HIDE_QUATERNION_EDIT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_TOOL_BUTTON);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE);
diff --git a/core/crypto/SCsub b/core/crypto/SCsub
index 8cff3cf679..3cea6bfb47 100644
--- a/core/crypto/SCsub
+++ b/core/crypto/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/debugger/SCsub b/core/debugger/SCsub
index 19a6549225..ab81175894 100644
--- a/core/debugger/SCsub
+++ b/core/debugger/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index e2ed7245a2..fc1b7b74f9 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -37,6 +37,7 @@
#include "core/debugger/script_debugger.h"
#include "core/input/input.h"
#include "core/io/resource_loader.h"
+#include "core/math/expression.h"
#include "core/object/script_language.h"
#include "core/os/os.h"
#include "servers/display_server.h"
@@ -529,6 +530,41 @@ 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 == "evaluate") {
+ String expression_str = data[0];
+ int frame = data[1];
+
+ ScriptInstance *breaked_instance = script_debugger->get_break_language()->debug_get_stack_level_instance(frame);
+ if (!breaked_instance) {
+ break;
+ }
+
+ List<String> locals;
+ List<Variant> local_vals;
+
+ script_debugger->get_break_language()->debug_get_stack_level_locals(frame, &locals, &local_vals);
+ ERR_FAIL_COND(locals.size() != local_vals.size());
+
+ PackedStringArray locals_vector;
+ for (const String &S : locals) {
+ locals_vector.append(S);
+ }
+
+ Array local_vals_array;
+ for (const Variant &V : local_vals) {
+ local_vals_array.append(V);
+ }
+
+ Expression expression;
+ expression.parse(expression_str, locals_vector);
+ const Variant return_val = expression.execute(local_vals_array, breaked_instance->get_owner());
+
+ DebuggerMarshalls::ScriptStackVariable stvar;
+ stvar.name = expression_str;
+ stvar.value = return_val;
+ stvar.type = 3;
+
+ send_message("evaluation_return", stvar.serialize());
} else {
bool captured = false;
ERR_CONTINUE(_try_capture(command, data, captured) != OK);
diff --git a/core/error/SCsub b/core/error/SCsub
index dfd6248a94..08089d31b0 100644
--- a/core/error/SCsub
+++ b/core/error/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/extension/SCsub b/core/extension/SCsub
index 6ab2d2b0a6..8688ca5b6e 100644
--- a/core/extension/SCsub
+++ b/core/extension/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 4042d6b80d..c5f7502c12 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -1017,6 +1017,7 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
d2["name"] = String(method_name);
d2["is_const"] = (F.flags & METHOD_FLAG_CONST) ? true : false;
d2["is_static"] = (F.flags & METHOD_FLAG_STATIC) ? true : false;
+ d2["is_required"] = (F.flags & METHOD_FLAG_VIRTUAL_REQUIRED) ? true : false;
d2["is_vararg"] = false;
d2["is_virtual"] = true;
// virtual functions have no hash since no MethodBind is involved
diff --git a/core/extension/gdextension_library_loader.cpp b/core/extension/gdextension_library_loader.cpp
index 5ba4933c35..d5f2eb668f 100644
--- a/core/extension/gdextension_library_loader.cpp
+++ b/core/extension/gdextension_library_loader.cpp
@@ -259,6 +259,10 @@ bool GDExtensionLibraryLoader::has_library_changed() const {
return false;
}
+bool GDExtensionLibraryLoader::library_exists() const {
+ return FileAccess::exists(resource_path);
+}
+
Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) {
resource_path = p_path;
diff --git a/core/extension/gdextension_library_loader.h b/core/extension/gdextension_library_loader.h
index f4372a75d4..f781611b30 100644
--- a/core/extension/gdextension_library_loader.h
+++ b/core/extension/gdextension_library_loader.h
@@ -77,6 +77,7 @@ public:
virtual void close_library() override;
virtual bool is_library_open() const override;
virtual bool has_library_changed() const override;
+ virtual bool library_exists() const override;
Error parse_gdextension_file(const String &p_path);
};
diff --git a/core/extension/gdextension_loader.h b/core/extension/gdextension_loader.h
index 7d779858b7..2289550329 100644
--- a/core/extension/gdextension_loader.h
+++ b/core/extension/gdextension_loader.h
@@ -42,6 +42,7 @@ public:
virtual void close_library() = 0;
virtual bool is_library_open() const = 0;
virtual bool has_library_changed() const = 0;
+ virtual bool library_exists() const = 0;
};
#endif // GDEXTENSION_LOADER_H
diff --git a/core/extension/gdextension_manager.cpp b/core/extension/gdextension_manager.cpp
index 01efe0d96e..fff938858f 100644
--- a/core/extension/gdextension_manager.cpp
+++ b/core/extension/gdextension_manager.cpp
@@ -302,7 +302,8 @@ bool GDExtensionManager::ensure_extensions_loaded(const HashSet<String> &p_exten
for (const String &loaded_extension : loaded_extensions) {
if (!p_extensions.has(loaded_extension)) {
// The extension may not have a .gdextension file.
- if (!FileAccess::exists(loaded_extension)) {
+ const Ref<GDExtension> extension = GDExtensionManager::get_singleton()->get_extension(loaded_extension);
+ if (!extension->get_loader()->library_exists()) {
extensions_removed.push_back(loaded_extension);
}
}
diff --git a/core/extension/make_wrappers.py b/core/extension/make_wrappers.py
index 54f4fd5579..665b6f0f91 100644
--- a/core/extension/make_wrappers.py
+++ b/core/extension/make_wrappers.py
@@ -55,10 +55,10 @@ def generate_mod_version(argcount, const=False, returns=False):
proto_ex = """
#define EXBIND$VER($RETTYPE m_name$ARG) \\
-GDVIRTUAL$VER($RETTYPE_##m_name$ARG)\\
+GDVIRTUAL$VER_REQUIRED($RETTYPE_##m_name$ARG)\\
virtual $RETVAL m_name($FUNCARGS) $CONST override { \\
$RETPRE\\
- GDVIRTUAL_REQUIRED_CALL(_##m_name$CALLARGS$RETREF);\\
+ GDVIRTUAL_CALL(_##m_name$CALLARGS$RETREF);\\
$RETPOST\\
}
"""
diff --git a/core/input/SCsub b/core/input/SCsub
index d8e6f33156..521f7702e4 100644
--- a/core/input/SCsub
+++ b/core/input/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/input/input_builders.py b/core/input/input_builders.py
index ae848f4e7c..3685e726b4 100644
--- a/core/input/input_builders.py
+++ b/core/input/input_builders.py
@@ -33,7 +33,7 @@ def make_default_controller_mappings(target, source, env):
guid = line_parts[0]
if guid in platform_mappings[current_platform]:
g.write(
- "// WARNING - DATABASE {} OVERWROTE PRIOR MAPPING: {} {}\n".format(
+ "// WARNING: DATABASE {} OVERWROTE PRIOR MAPPING: {} {}\n".format(
src_path, current_platform, platform_mappings[current_platform][guid]
)
)
diff --git a/core/io/SCsub b/core/io/SCsub
index 19a6549225..ab81175894 100644
--- a/core/io/SCsub
+++ b/core/io/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index eec27ce0aa..1340382eaa 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -102,6 +102,22 @@ void PackedData::add_pack_source(PackSource *p_source) {
}
}
+uint8_t *PackedData::get_file_hash(const String &p_path) {
+ PathMD5 pmd5(p_path.md5_buffer());
+ HashMap<PathMD5, PackedFile, PathMD5>::Iterator E = files.find(pmd5);
+ if (!E || E->value.offset == 0) {
+ return nullptr;
+ }
+
+ return E->value.md5;
+}
+
+void PackedData::clear() {
+ files.clear();
+ _free_packed_dirs(root);
+ root = memnew(PackedDir);
+}
+
PackedData *PackedData::singleton = nullptr;
PackedData::PackedData() {
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 595a36bca4..57b7a5f87f 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -111,6 +111,7 @@ private:
public:
void add_pack_source(PackSource *p_source);
void add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource
+ uint8_t *get_file_hash(const String &p_path);
void set_disabled(bool p_disabled) { disabled = p_disabled; }
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
@@ -118,6 +119,8 @@ public:
static PackedData *get_singleton() { return singleton; }
Error add_pack(const String &p_path, bool p_replace_files, uint64_t p_offset);
+ void clear();
+
_FORCE_INLINE_ Ref<FileAccess> try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 0329ace313..614f81c42a 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -299,7 +299,7 @@ Ref<StreamPeer> PacketPeerStream::get_stream_peer() const {
void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
ERR_FAIL_COND_MSG(p_max_size < 0, "Max size of input buffer size cannot be smaller than 0.");
- //warning may lose packets
+ // WARNING: May lose packets.
ERR_FAIL_COND_MSG(ring_buffer.data_left(), "Buffer in use, resizing would cause loss of data.");
ring_buffer.resize(nearest_shift(next_power_of_2(p_max_size + 4)) - 1);
input_buffer.resize(next_power_of_2(p_max_size + 4));
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index a7c715c318..93179d9a11 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -47,12 +47,12 @@ static int _get_pad(int p_alignment, int p_n) {
}
void PCKPacker::_bind_methods() {
- ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(32), DEFVAL("0000000000000000000000000000000000000000000000000000000000000000"), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("pck_start", "pck_path", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(32), DEFVAL("0000000000000000000000000000000000000000000000000000000000000000"), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false));
ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false));
}
-Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &p_key, bool p_encrypt_directory) {
+Error PCKPacker::pck_start(const String &p_pck_path, int p_alignment, const String &p_key, bool p_encrypt_directory) {
ERR_FAIL_COND_V_MSG((p_key.is_empty() || !p_key.is_valid_hex_number(false) || p_key.length() != 64), ERR_CANT_CREATE, "Invalid Encryption Key (must be 64 characters long).");
ERR_FAIL_COND_V_MSG(p_alignment <= 0, ERR_CANT_CREATE, "Invalid alignment, must be greater then 0.");
@@ -83,8 +83,8 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &
}
enc_dir = p_encrypt_directory;
- file = FileAccess::open(p_file, FileAccess::WRITE);
- ERR_FAIL_COND_V_MSG(file.is_null(), ERR_CANT_CREATE, "Can't open file to write: " + String(p_file) + ".");
+ file = FileAccess::open(p_pck_path, FileAccess::WRITE);
+ ERR_FAIL_COND_V_MSG(file.is_null(), ERR_CANT_CREATE, "Can't open file to write: " + String(p_pck_path) + ".");
alignment = p_alignment;
@@ -106,7 +106,7 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &
return OK;
}
-Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encrypt) {
+Error PCKPacker::add_file(const String &p_pck_path, const String &p_src, bool p_encrypt) {
ERR_FAIL_COND_V_MSG(file.is_null(), ERR_INVALID_PARAMETER, "File must be opened before use.");
Ref<FileAccess> f = FileAccess::open(p_src, FileAccess::READ);
@@ -117,7 +117,7 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encr
File pf;
// Simplify path here and on every 'files' access so that paths that have extra '/'
// symbols in them still match to the MD5 hash for the saved path.
- pf.path = p_file.simplify_path();
+ pf.path = p_pck_path.simplify_path();
pf.src_path = p_src;
pf.ofs = ofs;
pf.size = f->get_length();
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 8764fc90a0..5aac833532 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -58,8 +58,8 @@ class PCKPacker : public RefCounted {
Vector<File> files;
public:
- Error pck_start(const String &p_file, int p_alignment = 32, const String &p_key = "0000000000000000000000000000000000000000000000000000000000000000", bool p_encrypt_directory = false);
- Error add_file(const String &p_file, const String &p_src, bool p_encrypt = false);
+ Error pck_start(const String &p_pck_path, int p_alignment = 32, const String &p_key = "0000000000000000000000000000000000000000000000000000000000000000", bool p_encrypt_directory = false);
+ Error add_file(const String &p_pck_path, const String &p_src, bool p_encrypt = false);
Error flush(bool p_verbose = false);
PCKPacker() {}
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 6177cba6a4..5f8a4b85a4 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -96,6 +96,7 @@ String Resource::get_path() const {
void Resource::set_path_cache(const String &p_path) {
path_cache = p_path;
+ GDVIRTUAL_CALL(_set_path_cache, p_path);
}
String Resource::generate_scene_unique_id() {
@@ -188,6 +189,7 @@ void Resource::disconnect_changed(const Callable &p_callable) {
}
void Resource::reset_state() {
+ GDVIRTUAL_CALL(_reset_state);
}
Error Resource::copy_from(const Ref<Resource> &p_resource) {
@@ -495,9 +497,9 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
}
}
-#ifdef TOOLS_ENABLED
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void Resource::set_id_for_path(const String &p_path, const String &p_id) {
+#ifdef TOOLS_ENABLED
if (p_id.is_empty()) {
ResourceCache::path_cache_lock.write_lock();
ResourceCache::resource_path_cache[p_path].erase(get_path());
@@ -507,9 +509,11 @@ void Resource::set_id_for_path(const String &p_path, const String &p_id) {
ResourceCache::resource_path_cache[p_path][get_path()] = p_id;
ResourceCache::path_cache_lock.write_unlock();
}
+#endif
}
String Resource::get_id_for_path(const String &p_path) const {
+#ifdef TOOLS_ENABLED
ResourceCache::path_cache_lock.read_lock();
if (ResourceCache::resource_path_cache[p_path].has(get_path())) {
String result = ResourceCache::resource_path_cache[p_path][get_path()];
@@ -519,13 +523,16 @@ String Resource::get_id_for_path(const String &p_path) const {
ResourceCache::path_cache_lock.read_unlock();
return "";
}
-}
+#else
+ return "";
#endif
+}
void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path);
ClassDB::bind_method(D_METHOD("take_over_path", "path"), &Resource::_take_over_path);
ClassDB::bind_method(D_METHOD("get_path"), &Resource::get_path);
+ ClassDB::bind_method(D_METHOD("set_path_cache", "path"), &Resource::set_path_cache);
ClassDB::bind_method(D_METHOD("set_name", "name"), &Resource::set_name);
ClassDB::bind_method(D_METHOD("get_name"), &Resource::get_name);
ClassDB::bind_method(D_METHOD("get_rid"), &Resource::get_rid);
@@ -533,6 +540,12 @@ void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_local_to_scene"), &Resource::is_local_to_scene);
ClassDB::bind_method(D_METHOD("get_local_scene"), &Resource::get_local_scene);
ClassDB::bind_method(D_METHOD("setup_local_to_scene"), &Resource::setup_local_to_scene);
+ ClassDB::bind_method(D_METHOD("reset_state"), &Resource::reset_state);
+
+ ClassDB::bind_method(D_METHOD("set_id_for_path", "path", "id"), &Resource::set_id_for_path);
+ ClassDB::bind_method(D_METHOD("get_id_for_path", "path"), &Resource::get_id_for_path);
+
+ ClassDB::bind_method(D_METHOD("is_built_in"), &Resource::is_built_in);
ClassDB::bind_static_method("Resource", D_METHOD("generate_scene_unique_id"), &Resource::generate_scene_unique_id);
ClassDB::bind_method(D_METHOD("set_scene_unique_id", "id"), &Resource::set_scene_unique_id);
@@ -552,6 +565,8 @@ void Resource::_bind_methods() {
GDVIRTUAL_BIND(_setup_local_to_scene);
GDVIRTUAL_BIND(_get_rid);
+ GDVIRTUAL_BIND(_reset_state);
+ GDVIRTUAL_BIND(_set_path_cache, "path");
}
Resource::Resource() :
diff --git a/core/io/resource.h b/core/io/resource.h
index 2c1a431255..8966c0233c 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -89,6 +89,9 @@ protected:
GDVIRTUAL0RC(RID, _get_rid);
+ GDVIRTUAL1C(_set_path_cache, String);
+ GDVIRTUAL0(_reset_state);
+
public:
static Node *(*_get_local_scene_func)(); //used by editor
static void (*_update_configuration_warning)(); //used by editor
@@ -144,11 +147,9 @@ public:
virtual RID get_rid() const; // some resources may offer conversion to RID
-#ifdef TOOLS_ENABLED
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void set_id_for_path(const String &p_path, const String &p_id);
String get_id_for_path(const String &p_path) const;
-#endif
Resource();
~Resource();
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index a572dd562e..1ae50d2d0d 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -507,7 +507,7 @@ bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) con
for (int i = 0; i < importers.size(); i++) {
if (importers[i]->get_importer_name() == pat.importer) {
- if (!importers[i]->are_import_settings_valid(p_path)) { //importer thinks this is not valid
+ if (!importers[i]->are_import_settings_valid(p_path, pat.metadata)) { //importer thinks this is not valid
return false;
}
}
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index 6ea5d0972a..221f38494b 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -153,7 +153,7 @@ public:
virtual void import_threaded_end() {}
virtual Error import_group_file(const String &p_group_file, const HashMap<String, HashMap<StringName, Variant>> &p_source_file_options, const HashMap<String, String> &p_base_paths) { return ERR_UNAVAILABLE; }
- virtual bool are_import_settings_valid(const String &p_path) const { return true; }
+ virtual bool are_import_settings_valid(const String &p_path, const Dictionary &p_meta) const { return true; }
virtual String get_import_settings_string() const { return String(); }
};
diff --git a/core/math/SCsub b/core/math/SCsub
index c8fdac207e..6ea3ab6b12 100644
--- a/core/math/SCsub
+++ b/core/math/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp
index 80662c1b07..620a7541e4 100644
--- a/core/math/convex_hull.cpp
+++ b/core/math/convex_hull.cpp
@@ -204,7 +204,7 @@ public:
static Int128 mul(uint64_t a, uint64_t b);
Int128 operator-() const {
- return Int128((uint64_t) - (int64_t)low, ~high + (low == 0));
+ return Int128(uint64_t(-int64_t(low)), ~high + (low == 0));
}
Int128 operator+(const Int128 &b) const {
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 476577508f..1ee7d3d84f 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -39,16 +39,19 @@
class String;
struct [[nodiscard]] Transform2D {
- // Warning #1: basis of Transform2D is stored differently from Basis. In terms of columns array, the basis matrix looks like "on paper":
+ // WARNING: The basis of Transform2D is stored differently from Basis.
+ // In terms of columns array, the basis matrix looks like "on paper":
// M = (columns[0][0] columns[1][0])
// (columns[0][1] columns[1][1])
- // This is such that the columns, which can be interpreted as basis vectors of the coordinate system "painted" on the object, can be accessed as columns[i].
- // Note that this is the opposite of the indices in mathematical texts, meaning: $M_{12}$ in a math book corresponds to columns[1][0] here.
+ // This is such that the columns, which can be interpreted as basis vectors
+ // of the coordinate system "painted" on the object, can be accessed as columns[i].
+ // NOTE: This is the opposite of the indices in mathematical texts,
+ // meaning: $M_{12}$ in a math book corresponds to columns[1][0] here.
// This requires additional care when working with explicit indices.
// See https://en.wikipedia.org/wiki/Row-_and_column-major_order for further reading.
- // Warning #2: 2D be aware that unlike 3D code, 2D code uses a left-handed coordinate system: Y-axis points down,
- // and angle is measure from +X to +Y in a clockwise-fashion.
+ // WARNING: Be aware that unlike 3D code, 2D code uses a left-handed coordinate system:
+ // Y-axis points down, and angle is measure from +X to +Y in a clockwise-fashion.
Vector2 columns[3];
diff --git a/core/math/vector4.h b/core/math/vector4.h
index 8632f69f57..9197e3587a 100644
--- a/core/math/vector4.h
+++ b/core/math/vector4.h
@@ -55,16 +55,16 @@ struct [[nodiscard]] Vector4 {
real_t z;
real_t w;
};
- real_t components[4] = { 0, 0, 0, 0 };
+ real_t coord[4] = { 0, 0, 0, 0 };
};
_FORCE_INLINE_ real_t &operator[](int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 4);
- return components[p_axis];
+ return coord[p_axis];
}
_FORCE_INLINE_ const real_t &operator[](int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 4);
- return components[p_axis];
+ return coord[p_axis];
}
Vector4::Axis min_axis_index() const;
diff --git a/core/object/SCsub b/core/object/SCsub
index 7c00bb719e..3d0d2c14dd 100644
--- a/core/object/SCsub
+++ b/core/object/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/object/callable_method_pointer.h b/core/object/callable_method_pointer.h
index 1b29e1778a..86c66593bd 100644
--- a/core/object/callable_method_pointer.h
+++ b/core/object/callable_method_pointer.h
@@ -37,6 +37,8 @@
#include "core/variant/binder_common.h"
#include "core/variant/callable.h"
+#include <type_traits>
+
class CallableCustomMethodPointerBase : public CallableCustom {
uint32_t *comp_ptr = nullptr;
uint32_t comp_size;
@@ -77,12 +79,13 @@ public:
virtual uint32_t hash() const;
};
-template <typename T, typename... P>
+template <typename T, typename R, typename... P>
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
struct Data {
T *instance;
uint64_t object_id;
- void (T::*method)(P...);
+ R(T::*method)
+ (P...);
} data;
public:
@@ -100,10 +103,14 @@ public:
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
- call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
+ if constexpr (std::is_same<R, void>::value) {
+ call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
+ } else {
+ call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+ }
}
- CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
+ CallableCustomMethodPointer(T *p_instance, R (T::*p_method)(P...)) {
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
data.instance = p_instance;
data.object_id = p_instance->get_instance_id();
@@ -118,7 +125,7 @@ Callable create_custom_callable_function_pointer(T *p_instance,
const char *p_func_text,
#endif
void (T::*p_method)(P...)) {
- typedef CallableCustomMethodPointer<T, P...> CCMP; // Messes with memnew otherwise.
+ typedef CallableCustomMethodPointer<T, void, P...> CCMP; // Messes with memnew otherwise.
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
#ifdef DEBUG_METHODS_ENABLED
ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -126,51 +133,13 @@ Callable create_custom_callable_function_pointer(T *p_instance,
return Callable(ccmp);
}
-// VERSION WITH RETURN
-
-template <typename T, typename R, typename... P>
-class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
- struct Data {
- T *instance;
- uint64_t object_id;
- R(T::*method)
- (P...);
- } data;
-
-public:
- virtual ObjectID get_object() const {
- if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
- return ObjectID();
- }
- return data.instance->get_instance_id();
- }
-
- virtual int get_argument_count(bool &r_is_valid) const {
- r_is_valid = true;
- return sizeof...(P);
- }
-
- virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
- ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
- call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
- }
-
- CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
- memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
- data.instance = p_instance;
- data.object_id = p_instance->get_instance_id();
- data.method = p_method;
- _setup((uint32_t *)&data, sizeof(Data));
- }
-};
-
template <typename T, typename R, typename... P>
Callable create_custom_callable_function_pointer(T *p_instance,
#ifdef DEBUG_METHODS_ENABLED
const char *p_func_text,
#endif
R (T::*p_method)(P...)) {
- typedef CallableCustomMethodPointerRet<T, R, P...> CCMP; // Messes with memnew otherwise.
+ typedef CallableCustomMethodPointer<T, R, P...> CCMP; // Messes with memnew otherwise.
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
#ifdef DEBUG_METHODS_ENABLED
ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -178,10 +147,10 @@ Callable create_custom_callable_function_pointer(T *p_instance,
return Callable(ccmp);
}
-// CONST VERSION WITH RETURN
+// CONST VERSION
template <typename T, typename R, typename... P>
-class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
+class CallableCustomMethodPointerC : public CallableCustomMethodPointerBase {
struct Data {
T *instance;
uint64_t object_id;
@@ -204,10 +173,14 @@ public:
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
- call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+ if constexpr (std::is_same<R, void>::value) {
+ call_with_variant_argsc(data.instance, data.method, p_arguments, p_argcount, r_call_error);
+ } else {
+ call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+ }
}
- CallableCustomMethodPointerRetC(T *p_instance, R (T::*p_method)(P...) const) {
+ CallableCustomMethodPointerC(T *p_instance, R (T::*p_method)(P...) const) {
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
data.instance = p_instance;
data.object_id = p_instance->get_instance_id();
@@ -216,13 +189,27 @@ public:
}
};
+template <typename T, typename... P>
+Callable create_custom_callable_function_pointer(T *p_instance,
+#ifdef DEBUG_METHODS_ENABLED
+ const char *p_func_text,
+#endif
+ void (T::*p_method)(P...) const) {
+ typedef CallableCustomMethodPointerC<T, void, P...> CCMP; // Messes with memnew otherwise.
+ CCMP *ccmp = memnew(CCMP(p_instance, p_method));
+#ifdef DEBUG_METHODS_ENABLED
+ ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
+#endif
+ return Callable(ccmp);
+}
+
template <typename T, typename R, typename... P>
Callable create_custom_callable_function_pointer(T *p_instance,
#ifdef DEBUG_METHODS_ENABLED
const char *p_func_text,
#endif
R (T::*p_method)(P...) const) {
- typedef CallableCustomMethodPointerRetC<T, R, P...> CCMP; // Messes with memnew otherwise.
+ typedef CallableCustomMethodPointerC<T, R, P...> CCMP; // Messes with memnew otherwise.
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
#ifdef DEBUG_METHODS_ENABLED
ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -238,10 +225,11 @@ Callable create_custom_callable_function_pointer(T *p_instance,
// STATIC VERSIONS
-template <typename... P>
+template <typename R, typename... P>
class CallableCustomStaticMethodPointer : public CallableCustomMethodPointerBase {
struct Data {
- void (*method)(P...);
+ R(*method)
+ (P...);
} data;
public:
@@ -259,24 +247,27 @@ public:
}
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
- call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
- r_return_value = Variant();
+ if constexpr (std::is_same<R, void>::value) {
+ call_with_variant_args_static(data.method, p_arguments, p_argcount, r_call_error);
+ } else {
+ call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+ }
}
- CallableCustomStaticMethodPointer(void (*p_method)(P...)) {
+ CallableCustomStaticMethodPointer(R (*p_method)(P...)) {
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
data.method = p_method;
_setup((uint32_t *)&data, sizeof(Data));
}
};
-template <typename T, typename... P>
+template <typename... P>
Callable create_custom_callable_static_function_pointer(
#ifdef DEBUG_METHODS_ENABLED
const char *p_func_text,
#endif
void (*p_method)(P...)) {
- typedef CallableCustomStaticMethodPointer<P...> CCMP; // Messes with memnew otherwise.
+ typedef CallableCustomStaticMethodPointer<void, P...> CCMP; // Messes with memnew otherwise.
CCMP *ccmp = memnew(CCMP(p_method));
#ifdef DEBUG_METHODS_ENABLED
ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -285,44 +276,12 @@ Callable create_custom_callable_static_function_pointer(
}
template <typename R, typename... P>
-class CallableCustomStaticMethodPointerRet : public CallableCustomMethodPointerBase {
- struct Data {
- R(*method)
- (P...);
- } data;
-
-public:
- virtual bool is_valid() const override {
- return true;
- }
-
- virtual ObjectID get_object() const override {
- return ObjectID();
- }
-
- virtual int get_argument_count(bool &r_is_valid) const override {
- r_is_valid = true;
- return sizeof...(P);
- }
-
- virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
- call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
- }
-
- CallableCustomStaticMethodPointerRet(R (*p_method)(P...)) {
- memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
- data.method = p_method;
- _setup((uint32_t *)&data, sizeof(Data));
- }
-};
-
-template <typename R, typename... P>
Callable create_custom_callable_static_function_pointer(
#ifdef DEBUG_METHODS_ENABLED
const char *p_func_text,
#endif
R (*p_method)(P...)) {
- typedef CallableCustomStaticMethodPointerRet<R, P...> CCMP; // Messes with memnew otherwise.
+ typedef CallableCustomStaticMethodPointer<R, P...> CCMP; // Messes with memnew otherwise.
CCMP *ccmp = memnew(CCMP(p_method));
#ifdef DEBUG_METHODS_ENABLED
ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 7a85753072..3df26e3b73 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -2,7 +2,6 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
StringName _gdvirtual_##m_name##_sn = #m_name;\\
mutable bool _gdvirtual_##m_name##_initialized = false;\\
mutable void *_gdvirtual_##m_name = nullptr;\\
- template <bool required>\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST {\\
ScriptInstance *_script_instance = ((Object *)(this))->get_script_instance();\\
if (_script_instance) {\\
@@ -36,10 +35,8 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
}\\
return true;\\
}\\
- if (required) {\\
- ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");\\
- $RVOID\\
- }\\
+ $REQCHECK\\
+ $RVOID\\
return false;\\
}\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const {\\
@@ -73,10 +70,11 @@ proto = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
"""
-def generate_version(argcount, const=False, returns=False):
+def generate_version(argcount, const=False, returns=False, required=False):
s = proto
sproto = str(argcount)
method_info = ""
+ method_flags = "METHOD_FLAG_VIRTUAL"
if returns:
sproto += "R"
s = s.replace("$RET", "m_ret,")
@@ -86,17 +84,27 @@ def generate_version(argcount, const=False, returns=False):
method_info += "\t\tmethod_info.return_val_metadata = GetTypeInfo<m_ret>::METADATA;"
else:
s = s.replace("$RET ", "")
- s = s.replace("\t\t\t$RVOID\\\n", "")
+ s = s.replace("\t\t$RVOID\\\n", "")
s = s.replace("\t\t\t$CALLPTRRETDEF\\\n", "")
if const:
sproto += "C"
+ method_flags += " | METHOD_FLAG_CONST"
s = s.replace("$CONST", "const")
- s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL | METHOD_FLAG_CONST")
else:
s = s.replace("$CONST ", "")
- s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL")
+ if required:
+ sproto += "_REQUIRED"
+ method_flags += " | METHOD_FLAG_VIRTUAL_REQUIRED"
+ s = s.replace(
+ "$REQCHECK",
+ 'ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");',
+ )
+ else:
+ s = s.replace("\t\t$REQCHECK\\\n", "")
+
+ s = s.replace("$METHOD_FLAGS", method_flags)
s = s.replace("$VER", sproto)
argtext = ""
callargtext = ""
@@ -198,6 +206,10 @@ def run(target, source, env):
txt += generate_version(i, False, True)
txt += generate_version(i, True, False)
txt += generate_version(i, True, True)
+ txt += generate_version(i, False, False, True)
+ txt += generate_version(i, False, True, True)
+ txt += generate_version(i, True, False, True)
+ txt += generate_version(i, True, True, True)
txt += "#endif // GDVIRTUAL_GEN_H\n"
diff --git a/core/object/object.h b/core/object/object.h
index 763e2974b9..110d2790c5 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -87,6 +87,7 @@ enum PropertyHint {
PROPERTY_HINT_PASSWORD,
PROPERTY_HINT_LAYERS_AVOIDANCE,
PROPERTY_HINT_DICTIONARY_TYPE,
+ PROPERTY_HINT_TOOL_BUTTON,
PROPERTY_HINT_MAX,
};
@@ -215,6 +216,7 @@ enum MethodFlags {
METHOD_FLAG_VARARG = 16,
METHOD_FLAG_STATIC = 32,
METHOD_FLAG_OBJECT_CORE = 64,
+ METHOD_FLAG_VIRTUAL_REQUIRED = 128,
METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL,
};
@@ -368,11 +370,8 @@ struct ObjectGDExtension {
#endif
};
-#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__)
-#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__)
-
-#define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__)
-#define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__)
+#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
+#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__)
#ifdef DEBUG_METHODS_ENABLED
#define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__));
diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h
index bc773c5ad3..d2dce34d4f 100644
--- a/core/object/script_language_extension.h
+++ b/core/object/script_language_extension.h
@@ -57,16 +57,16 @@ public:
EXBIND1RC(bool, inherits_script, const Ref<Script> &)
EXBIND0RC(StringName, get_instance_base_type)
- GDVIRTUAL1RC(GDExtensionPtr<void>, _instance_create, Object *)
+ GDVIRTUAL1RC_REQUIRED(GDExtensionPtr<void>, _instance_create, Object *)
virtual ScriptInstance *instance_create(Object *p_this) override {
GDExtensionPtr<void> ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_instance_create, p_this, ret);
+ GDVIRTUAL_CALL(_instance_create, p_this, ret);
return reinterpret_cast<ScriptInstance *>(ret.operator void *());
}
- GDVIRTUAL1RC(GDExtensionPtr<void>, _placeholder_instance_create, Object *)
+ GDVIRTUAL1RC_REQUIRED(GDExtensionPtr<void>, _placeholder_instance_create, Object *)
PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override {
GDExtensionPtr<void> ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_placeholder_instance_create, p_this, ret);
+ GDVIRTUAL_CALL(_placeholder_instance_create, p_this, ret);
return reinterpret_cast<PlaceHolderScriptInstance *>(ret.operator void *());
}
@@ -76,12 +76,12 @@ public:
EXBIND1(set_source_code, const String &)
EXBIND1R(Error, reload, bool)
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_documentation)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_documentation)
GDVIRTUAL0RC(String, _get_class_icon_path)
#ifdef TOOLS_ENABLED
virtual Vector<DocData::ClassDoc> get_documentation() const override {
TypedArray<Dictionary> doc;
- GDVIRTUAL_REQUIRED_CALL(_get_documentation, doc);
+ GDVIRTUAL_CALL(_get_documentation, doc);
Vector<DocData::ClassDoc> class_doc;
for (int i = 0; i < doc.size(); i++) {
@@ -114,10 +114,10 @@ public:
return Script::get_script_method_argument_count(p_method, r_is_valid);
}
- GDVIRTUAL1RC(Dictionary, _get_method_info, const StringName &)
+ GDVIRTUAL1RC_REQUIRED(Dictionary, _get_method_info, const StringName &)
virtual MethodInfo get_method_info(const StringName &p_method) const override {
Dictionary mi;
- GDVIRTUAL_REQUIRED_CALL(_get_method_info, p_method, mi);
+ GDVIRTUAL_CALL(_get_method_info, p_method, mi);
return MethodInfo::from_dict(mi);
}
@@ -133,47 +133,47 @@ public:
EXBIND0RC(ScriptLanguage *, get_language)
EXBIND1RC(bool, has_script_signal, const StringName &)
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_signal_list)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_signal_list)
virtual void get_script_signal_list(List<MethodInfo> *r_signals) const override {
TypedArray<Dictionary> sl;
- GDVIRTUAL_REQUIRED_CALL(_get_script_signal_list, sl);
+ GDVIRTUAL_CALL(_get_script_signal_list, sl);
for (int i = 0; i < sl.size(); i++) {
r_signals->push_back(MethodInfo::from_dict(sl[i]));
}
}
- GDVIRTUAL1RC(bool, _has_property_default_value, const StringName &)
- GDVIRTUAL1RC(Variant, _get_property_default_value, const StringName &)
+ GDVIRTUAL1RC_REQUIRED(bool, _has_property_default_value, const StringName &)
+ GDVIRTUAL1RC_REQUIRED(Variant, _get_property_default_value, const StringName &)
virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const override {
bool has_dv = false;
- if (!GDVIRTUAL_REQUIRED_CALL(_has_property_default_value, p_property, has_dv) || !has_dv) {
+ if (!GDVIRTUAL_CALL(_has_property_default_value, p_property, has_dv) || !has_dv) {
return false;
}
Variant ret;
- GDVIRTUAL_REQUIRED_CALL(_get_property_default_value, p_property, ret);
+ GDVIRTUAL_CALL(_get_property_default_value, p_property, ret);
r_value = ret;
return true;
}
EXBIND0(update_exports)
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_method_list)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_method_list)
virtual void get_script_method_list(List<MethodInfo> *r_methods) const override {
TypedArray<Dictionary> sl;
- GDVIRTUAL_REQUIRED_CALL(_get_script_method_list, sl);
+ GDVIRTUAL_CALL(_get_script_method_list, sl);
for (int i = 0; i < sl.size(); i++) {
r_methods->push_back(MethodInfo::from_dict(sl[i]));
}
}
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_property_list)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_script_property_list)
virtual void get_script_property_list(List<PropertyInfo> *r_propertys) const override {
TypedArray<Dictionary> sl;
- GDVIRTUAL_REQUIRED_CALL(_get_script_property_list, sl);
+ GDVIRTUAL_CALL(_get_script_property_list, sl);
for (int i = 0; i < sl.size(); i++) {
r_propertys->push_back(PropertyInfo::from_dict(sl[i]));
}
@@ -181,21 +181,21 @@ public:
EXBIND1RC(int, get_member_line, const StringName &)
- GDVIRTUAL0RC(Dictionary, _get_constants)
+ GDVIRTUAL0RC_REQUIRED(Dictionary, _get_constants)
virtual void get_constants(HashMap<StringName, Variant> *p_constants) override {
Dictionary constants;
- GDVIRTUAL_REQUIRED_CALL(_get_constants, constants);
+ GDVIRTUAL_CALL(_get_constants, constants);
List<Variant> keys;
constants.get_key_list(&keys);
for (const Variant &K : keys) {
p_constants->insert(K, constants[K]);
}
}
- GDVIRTUAL0RC(TypedArray<StringName>, _get_members)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<StringName>, _get_members)
virtual void get_members(HashSet<StringName> *p_members) override {
TypedArray<StringName> members;
- GDVIRTUAL_REQUIRED_CALL(_get_members, members);
+ GDVIRTUAL_CALL(_get_members, members);
for (int i = 0; i < members.size(); i++) {
p_members->insert(members[i]);
}
@@ -203,11 +203,11 @@ public:
EXBIND0RC(bool, is_placeholder_fallback_enabled)
- GDVIRTUAL0RC(Variant, _get_rpc_config)
+ GDVIRTUAL0RC_REQUIRED(Variant, _get_rpc_config)
virtual Variant get_rpc_config() const override {
Variant ret;
- GDVIRTUAL_REQUIRED_CALL(_get_rpc_config, ret);
+ GDVIRTUAL_CALL(_get_rpc_config, ret);
return ret;
}
@@ -233,22 +233,22 @@ public:
/* EDITOR FUNCTIONS */
- GDVIRTUAL0RC(Vector<String>, _get_reserved_words)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_reserved_words)
virtual void get_reserved_words(List<String> *p_words) const override {
Vector<String> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_reserved_words, ret);
+ GDVIRTUAL_CALL(_get_reserved_words, ret);
for (int i = 0; i < ret.size(); i++) {
p_words->push_back(ret[i]);
}
}
EXBIND1RC(bool, is_control_flow_keyword, const String &)
- GDVIRTUAL0RC(Vector<String>, _get_comment_delimiters)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_comment_delimiters)
virtual void get_comment_delimiters(List<String> *p_words) const override {
Vector<String> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_comment_delimiters, ret);
+ GDVIRTUAL_CALL(_get_comment_delimiters, ret);
for (int i = 0; i < ret.size(); i++) {
p_words->push_back(ret[i]);
}
@@ -264,11 +264,11 @@ public:
}
}
- GDVIRTUAL0RC(Vector<String>, _get_string_delimiters)
+ GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_string_delimiters)
virtual void get_string_delimiters(List<String> *p_words) const override {
Vector<String> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_string_delimiters, ret);
+ GDVIRTUAL_CALL(_get_string_delimiters, ret);
for (int i = 0; i < ret.size(); i++) {
p_words->push_back(ret[i]);
}
@@ -276,11 +276,11 @@ public:
EXBIND3RC(Ref<Script>, make_template, const String &, const String &, const String &)
- GDVIRTUAL1RC(TypedArray<Dictionary>, _get_built_in_templates, StringName)
+ GDVIRTUAL1RC_REQUIRED(TypedArray<Dictionary>, _get_built_in_templates, StringName)
virtual Vector<ScriptTemplate> get_built_in_templates(const StringName &p_object) override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_built_in_templates, p_object, ret);
+ GDVIRTUAL_CALL(_get_built_in_templates, p_object, ret);
Vector<ScriptTemplate> stret;
for (int i = 0; i < ret.size(); i++) {
Dictionary d = ret[i];
@@ -304,10 +304,10 @@ public:
EXBIND0R(bool, is_using_templates)
- GDVIRTUAL6RC(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool)
+ GDVIRTUAL6RC_REQUIRED(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool)
virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, HashSet<int> *r_safe_lines = nullptr) const override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret);
+ GDVIRTUAL_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret);
if (!ret.has("valid")) {
return false;
}
@@ -371,10 +371,10 @@ public:
}
EXBIND1RC(String, validate_path, const String &)
- GDVIRTUAL0RC(Object *, _create_script)
+ GDVIRTUAL0RC_REQUIRED(Object *, _create_script)
Script *create_script() const override {
Object *ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_create_script, ret);
+ GDVIRTUAL_CALL(_create_script, ret);
return Object::cast_to<Script>(ret);
}
#ifndef DISABLE_DEPRECATED
@@ -400,11 +400,11 @@ public:
return ScriptNameCasing::SCRIPT_NAME_CASING_SNAKE_CASE;
}
- GDVIRTUAL3RC(Dictionary, _complete_code, const String &, const String &, Object *)
+ GDVIRTUAL3RC_REQUIRED(Dictionary, _complete_code, const String &, const String &, Object *)
virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<CodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_complete_code, p_code, p_path, p_owner, ret);
+ GDVIRTUAL_CALL(_complete_code, p_code, p_path, p_owner, ret);
if (!ret.has("result")) {
return ERR_UNAVAILABLE;
}
@@ -449,11 +449,11 @@ public:
return result;
}
- GDVIRTUAL4RC(Dictionary, _lookup_code, const String &, const String &, const String &, Object *)
+ GDVIRTUAL4RC_REQUIRED(Dictionary, _lookup_code, const String &, const String &, const String &, Object *)
virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret);
+ GDVIRTUAL_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret);
if (!ret.has("result")) {
return ERR_UNAVAILABLE;
}
@@ -474,10 +474,10 @@ public:
return result;
}
- GDVIRTUAL3RC(String, _auto_indent_code, const String &, int, int)
+ GDVIRTUAL3RC_REQUIRED(String, _auto_indent_code, const String &, int, int)
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {
String ret;
- GDVIRTUAL_REQUIRED_CALL(_auto_indent_code, p_code, p_from_line, p_to_line, ret);
+ GDVIRTUAL_CALL(_auto_indent_code, p_code, p_from_line, p_to_line, ret);
p_code = ret;
}
EXBIND2(add_global_constant, const StringName &, const Variant &)
@@ -496,10 +496,10 @@ public:
EXBIND1RC(String, debug_get_stack_level_function, int)
EXBIND1RC(String, debug_get_stack_level_source, int)
- GDVIRTUAL3R(Dictionary, _debug_get_stack_level_locals, int, int, int)
+ GDVIRTUAL3R_REQUIRED(Dictionary, _debug_get_stack_level_locals, int, int, int)
virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret);
+ GDVIRTUAL_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret);
if (ret.size() == 0) {
return;
}
@@ -516,10 +516,10 @@ public:
}
}
}
- GDVIRTUAL3R(Dictionary, _debug_get_stack_level_members, int, int, int)
+ GDVIRTUAL3R_REQUIRED(Dictionary, _debug_get_stack_level_members, int, int, int)
virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret);
+ GDVIRTUAL_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret);
if (ret.size() == 0) {
return;
}
@@ -536,17 +536,17 @@ public:
}
}
}
- GDVIRTUAL1R(GDExtensionPtr<void>, _debug_get_stack_level_instance, int)
+ GDVIRTUAL1R_REQUIRED(GDExtensionPtr<void>, _debug_get_stack_level_instance, int)
virtual ScriptInstance *debug_get_stack_level_instance(int p_level) override {
GDExtensionPtr<void> ret = nullptr;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_instance, p_level, ret);
+ GDVIRTUAL_CALL(_debug_get_stack_level_instance, p_level, ret);
return reinterpret_cast<ScriptInstance *>(ret.operator void *());
}
- GDVIRTUAL2R(Dictionary, _debug_get_globals, int, int)
+ GDVIRTUAL2R_REQUIRED(Dictionary, _debug_get_globals, int, int)
virtual void debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret);
+ GDVIRTUAL_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret);
if (ret.size() == 0) {
return;
}
@@ -566,10 +566,10 @@ public:
EXBIND4R(String, debug_parse_stack_level_expression, int, const String &, int, int)
- GDVIRTUAL0R(TypedArray<Dictionary>, _debug_get_current_stack_info)
+ GDVIRTUAL0R_REQUIRED(TypedArray<Dictionary>, _debug_get_current_stack_info)
virtual Vector<StackInfo> debug_get_current_stack_info() override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_debug_get_current_stack_info, ret);
+ GDVIRTUAL_CALL(_debug_get_current_stack_info, ret);
Vector<StackInfo> sret;
for (const Variant &var : ret) {
StackInfo si;
@@ -590,29 +590,29 @@ public:
EXBIND2(reload_tool_script, const Ref<Script> &, bool)
/* LOADER FUNCTIONS */
- GDVIRTUAL0RC(PackedStringArray, _get_recognized_extensions)
+ GDVIRTUAL0RC_REQUIRED(PackedStringArray, _get_recognized_extensions)
virtual void get_recognized_extensions(List<String> *p_extensions) const override {
PackedStringArray ret;
- GDVIRTUAL_REQUIRED_CALL(_get_recognized_extensions, ret);
+ GDVIRTUAL_CALL(_get_recognized_extensions, ret);
for (int i = 0; i < ret.size(); i++) {
p_extensions->push_back(ret[i]);
}
}
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_functions)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_public_functions)
virtual void get_public_functions(List<MethodInfo> *p_functions) const override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_public_functions, ret);
+ GDVIRTUAL_CALL(_get_public_functions, ret);
for (const Variant &var : ret) {
MethodInfo mi = MethodInfo::from_dict(var);
p_functions->push_back(mi);
}
}
- GDVIRTUAL0RC(Dictionary, _get_public_constants)
+ GDVIRTUAL0RC_REQUIRED(Dictionary, _get_public_constants)
virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_get_public_constants, ret);
+ GDVIRTUAL_CALL(_get_public_constants, ret);
for (int i = 0; i < ret.size(); i++) {
Dictionary d = ret[i];
ERR_CONTINUE(!d.has("name"));
@@ -620,10 +620,10 @@ public:
p_constants->push_back(Pair<String, Variant>(d["name"], d["value"]));
}
}
- GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_annotations)
+ GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_public_annotations)
virtual void get_public_annotations(List<MethodInfo> *p_annotations) const override {
TypedArray<Dictionary> ret;
- GDVIRTUAL_REQUIRED_CALL(_get_public_annotations, ret);
+ GDVIRTUAL_CALL(_get_public_annotations, ret);
for (const Variant &var : ret) {
MethodInfo mi = MethodInfo::from_dict(var);
p_annotations->push_back(mi);
@@ -634,19 +634,19 @@ public:
EXBIND0(profiling_stop)
EXBIND1(profiling_set_save_native_calls, bool)
- GDVIRTUAL2R(int, _profiling_get_accumulated_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
+ GDVIRTUAL2R_REQUIRED(int, _profiling_get_accumulated_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret);
+ GDVIRTUAL_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret);
return ret;
}
- GDVIRTUAL2R(int, _profiling_get_frame_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
+ GDVIRTUAL2R_REQUIRED(int, _profiling_get_frame_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int)
virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override {
int ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_profiling_get_frame_data, p_info_arr, p_info_max, ret);
+ GDVIRTUAL_CALL(_profiling_get_frame_data, p_info_arr, p_info_max, ret);
return ret;
}
@@ -654,11 +654,11 @@ public:
EXBIND1RC(bool, handles_global_class_type, const String &)
- GDVIRTUAL1RC(Dictionary, _get_global_class_name, const String &)
+ GDVIRTUAL1RC_REQUIRED(Dictionary, _get_global_class_name, const String &)
virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override {
Dictionary ret;
- GDVIRTUAL_REQUIRED_CALL(_get_global_class_name, p_path, ret);
+ GDVIRTUAL_CALL(_get_global_class_name, p_path, ret);
if (!ret.has("name")) {
return String();
}
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp
index 4d67cd930e..03537dbeb1 100644
--- a/core/object/undo_redo.cpp
+++ b/core/object/undo_redo.cpp
@@ -48,7 +48,7 @@ void UndoRedo::Operation::delete_reference() {
}
}
-void UndoRedo::_discard_redo() {
+void UndoRedo::discard_redo() {
if (current_action == actions.size() - 1) {
return;
}
@@ -89,7 +89,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode, bool p_back
uint64_t ticks = OS::get_singleton()->get_ticks_msec();
if (action_level == 0) {
- _discard_redo();
+ discard_redo();
// Check if the merge operation is valid
if (p_mode != MERGE_DISABLE && actions.size() && actions[actions.size() - 1].name == p_name && actions[actions.size() - 1].backward_undo_ops == p_backward_undo_ops && actions[actions.size() - 1].last_tick + 800 > ticks) {
@@ -288,7 +288,7 @@ void UndoRedo::end_force_keep_in_merge_ends() {
}
void UndoRedo::_pop_history_tail() {
- _discard_redo();
+ discard_redo();
if (!actions.size()) {
return;
@@ -455,7 +455,7 @@ String UndoRedo::get_action_name(int p_id) {
void UndoRedo::clear_history(bool p_increase_version) {
ERR_FAIL_COND(action_level > 0);
- _discard_redo();
+ discard_redo();
while (actions.size()) {
_pop_history_tail();
diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h
index 19d178635c..ded962670c 100644
--- a/core/object/undo_redo.h
+++ b/core/object/undo_redo.h
@@ -129,6 +129,7 @@ public:
int get_current_action();
String get_action_name(int p_id);
void clear_history(bool p_increase_version = true);
+ void discard_redo();
bool has_undo() const;
bool has_redo() const;
diff --git a/core/os/SCsub b/core/os/SCsub
index 19a6549225..ab81175894 100644
--- a/core/os/SCsub
+++ b/core/os/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/string/SCsub b/core/string/SCsub
index 3217166f18..b06e32eb88 100644
--- a/core/string/SCsub
+++ b/core/string/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 2683addd4b..e6f7492a18 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -221,18 +221,35 @@ void CharString::copy_from(const char *p_cstr) {
/* String */
/*************************************************************************/
-Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path) const {
- // Splits the URL into scheme, host, port, path. Strip credentials when present.
+Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const {
+ // Splits the URL into scheme, host, port, path, fragment. Strip credentials when present.
String base = *this;
r_scheme = "";
r_host = "";
r_port = 0;
r_path = "";
+ r_fragment = "";
+
int pos = base.find("://");
// Scheme
if (pos != -1) {
- r_scheme = base.substr(0, pos + 3).to_lower();
- base = base.substr(pos + 3, base.length() - pos - 3);
+ bool is_scheme_valid = true;
+ for (int i = 0; i < pos; i++) {
+ if (!is_ascii_alphanumeric_char(base[i]) && base[i] != '+' && base[i] != '-' && base[i] != '.') {
+ is_scheme_valid = false;
+ break;
+ }
+ }
+ if (is_scheme_valid) {
+ r_scheme = base.substr(0, pos + 3).to_lower();
+ base = base.substr(pos + 3, base.length() - pos - 3);
+ }
+ }
+ pos = base.find("#");
+ // Fragment
+ if (pos != -1) {
+ r_fragment = base.substr(pos + 1);
+ base = base.substr(0, pos);
}
pos = base.find("/");
// Path
@@ -4626,7 +4643,7 @@ bool String::is_absolute_path() const {
String String::validate_ascii_identifier() const {
if (is_empty()) {
- return "_"; // Empty string is not a valid identifier;
+ return "_"; // Empty string is not a valid identifier.
}
String result;
@@ -4647,6 +4664,29 @@ String String::validate_ascii_identifier() const {
return result;
}
+String String::validate_unicode_identifier() const {
+ if (is_empty()) {
+ return "_"; // Empty string is not a valid identifier.
+ }
+
+ String result;
+ if (is_unicode_identifier_start(operator[](0))) {
+ result = *this;
+ } else {
+ result = "_" + *this;
+ }
+
+ int len = result.length();
+ char32_t *buffer = result.ptrw();
+ for (int i = 0; i < len; i++) {
+ if (!is_unicode_identifier_continue(buffer[i])) {
+ buffer[i] = '_';
+ }
+ }
+
+ return result;
+}
+
bool String::is_valid_ascii_identifier() const {
int len = length();
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 11f15031f9..aa62c9cb18 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -452,7 +452,7 @@ public:
String c_escape_multiline() const;
String c_unescape() const;
String json_escape() const;
- Error parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path) const;
+ Error parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const;
String property_name_encode() const;
@@ -460,6 +460,7 @@ public:
static String get_invalid_node_name_characters(bool p_allow_internal = false);
String validate_node_name() const;
String validate_ascii_identifier() const;
+ String validate_unicode_identifier() const;
String validate_filename() const;
bool is_valid_ascii_identifier() const;
diff --git a/core/templates/SCsub b/core/templates/SCsub
index 8c4c843a33..7f806d5609 100644
--- a/core/templates/SCsub
+++ b/core/templates/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/variant/SCsub b/core/variant/SCsub
index 7f4c8b7788..8264503a22 100644
--- a/core/variant/SCsub
+++ b/core/variant/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index fa49767d46..0aa49f6d68 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -466,7 +466,7 @@ void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, con
return;
}
#endif
- call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
+ call_with_variant_argsc_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
template <typename T, typename... P>
@@ -830,7 +830,7 @@ void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_ar
}
template <typename... P>
-void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
+void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 63fb5e8d94..ab33c9db55 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -657,7 +657,23 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c
} \
};
+#define VARCALL_PACKED_GETTER(m_packed_type, m_return_type) \
+ static m_return_type func_##m_packed_type##_get(m_packed_type *p_instance, int64_t p_index) { \
+ return p_instance->get(p_index); \
+ }
+
struct _VariantCall {
+ VARCALL_PACKED_GETTER(PackedByteArray, uint8_t)
+ VARCALL_PACKED_GETTER(PackedColorArray, Color)
+ VARCALL_PACKED_GETTER(PackedFloat32Array, float)
+ VARCALL_PACKED_GETTER(PackedFloat64Array, double)
+ VARCALL_PACKED_GETTER(PackedInt32Array, int32_t)
+ VARCALL_PACKED_GETTER(PackedInt64Array, int64_t)
+ VARCALL_PACKED_GETTER(PackedStringArray, String)
+ VARCALL_PACKED_GETTER(PackedVector2Array, Vector2)
+ VARCALL_PACKED_GETTER(PackedVector3Array, Vector3)
+ VARCALL_PACKED_GETTER(PackedVector4Array, Vector4)
+
static String func_PackedByteArray_get_string_from_ascii(PackedByteArray *p_instance) {
String s;
if (p_instance->size() > 0) {
@@ -2268,6 +2284,7 @@ static void _register_variant_builtin_methods_misc() {
bind_method(Dictionary, duplicate, sarray("deep"), varray(false));
bind_method(Dictionary, get, sarray("key", "default"), varray(Variant()));
bind_method(Dictionary, get_or_add, sarray("key", "default"), varray(Variant()));
+ bind_method(Dictionary, set, sarray("key", "value"), varray());
bind_method(Dictionary, is_typed, sarray(), varray());
bind_method(Dictionary, is_typed_key, sarray(), varray());
bind_method(Dictionary, is_typed_value, sarray(), varray());
@@ -2293,6 +2310,8 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, clear, sarray(), varray());
bind_method(Array, hash, sarray(), varray());
bind_method(Array, assign, sarray("array"), varray());
+ bind_method(Array, get, sarray("index"), varray());
+ bind_method(Array, set, sarray("index", "value"), varray());
bind_method(Array, push_back, sarray("value"), varray());
bind_method(Array, push_front, sarray("value"), varray());
bind_method(Array, append, sarray("value"), varray());
@@ -2337,6 +2356,18 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, make_read_only, sarray(), varray());
bind_method(Array, is_read_only, sarray(), varray());
+ /* Packed*Array get (see VARCALL_PACKED_GETTER macro) */
+ bind_function(PackedByteArray, get, _VariantCall::func_PackedByteArray_get, sarray("index"), varray());
+ bind_function(PackedColorArray, get, _VariantCall::func_PackedColorArray_get, sarray("index"), varray());
+ bind_function(PackedFloat32Array, get, _VariantCall::func_PackedFloat32Array_get, sarray("index"), varray());
+ bind_function(PackedFloat64Array, get, _VariantCall::func_PackedFloat64Array_get, sarray("index"), varray());
+ bind_function(PackedInt32Array, get, _VariantCall::func_PackedInt32Array_get, sarray("index"), varray());
+ bind_function(PackedInt64Array, get, _VariantCall::func_PackedInt64Array_get, sarray("index"), varray());
+ bind_function(PackedStringArray, get, _VariantCall::func_PackedStringArray_get, sarray("index"), varray());
+ bind_function(PackedVector2Array, get, _VariantCall::func_PackedVector2Array_get, sarray("index"), varray());
+ bind_function(PackedVector3Array, get, _VariantCall::func_PackedVector3Array_get, sarray("index"), varray());
+ bind_function(PackedVector4Array, get, _VariantCall::func_PackedVector4Array_get, sarray("index"), varray());
+
/* Byte Array */
bind_method(PackedByteArray, size, sarray(), varray());
bind_method(PackedByteArray, is_empty, sarray(), varray());
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
index ac39a4135f..0bd8b830e0 100644
--- a/core/variant/variant_op.h
+++ b/core/variant/variant_op.h
@@ -923,7 +923,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -948,7 +951,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -976,7 +982,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), right->get_validated_object(), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -1003,7 +1012,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -1492,7 +1504,10 @@ public:
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
Object *l = right->get_validated_object();
- ERR_FAIL_NULL(l);
+ if (unlikely(!l)) {
+ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false;
+ ERR_FAIL_MSG("Invalid base object for 'in'.");
+ }
const String &a = *VariantGetInternalPtr<String>::get_ptr(left);
bool valid;
@@ -1526,7 +1541,10 @@ public:
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
Object *l = right->get_validated_object();
- ERR_FAIL_NULL(l);
+ if (unlikely(!l)) {
+ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false;
+ ERR_FAIL_MSG("Invalid base object for 'in'.");
+ }
const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left);
bool valid;