diff options
Diffstat (limited to 'core')
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; |