diff options
371 files changed, 4027 insertions, 2432 deletions
diff --git a/.clang-tidy b/.clang-tidy index fa57c94a21..659b91013d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements,readability-redundant-member-init' +Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,cppcoreguidelines-pro-type-member-init,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements,readability-redundant-member-init' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false @@ -13,6 +13,10 @@ CheckOptions: value: '1' - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: '1' + - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays + value: '1' + - key: cppcoreguidelines-pro-type-member-init.UseAssignment + value: '1' - key: google-readability-function-size.StatementThreshold value: '800' - key: google-readability-namespace-comments.ShortNamespaceLines diff --git a/SConstruct b/SConstruct index af01329933..01f1ae638e 100644 --- a/SConstruct +++ b/SConstruct @@ -618,10 +618,10 @@ if selected_platform in platform_list: env.Append(CXXFLAGS=["-Wno-error=cpp"]) if cc_version_major == 7: # Bogus warning fixed in 8+. env.Append(CCFLAGS=["-Wno-error=strict-overflow"]) + if cc_version_major >= 12: # False positives in our error macros, see GH-58747. + env.Append(CCFLAGS=["-Wno-error=return-type"]) elif methods.using_clang(env) or methods.using_emcc(env): env.Append(CXXFLAGS=["-Wno-error=#warnings"]) - else: # always enable those errors - env.Append(CCFLAGS=["-Werror=return-type"]) if hasattr(detect, "get_program_suffix"): suffix = "." + detect.get_program_suffix() diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 06bfc0c562..79fa6a0895 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -321,9 +321,9 @@ bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const { struct _VCSort { String name; - Variant::Type type; - int order; - uint32_t flags; + Variant::Type type = Variant::VARIANT_MAX; + int order = 0; + uint32_t flags = 0; bool operator<(const _VCSort &p_vcs) const { return order == p_vcs.order ? name < p_vcs.name : order < p_vcs.order; } }; diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 8308c4fe53..0f0b8ed63f 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -58,15 +58,15 @@ ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const return (ThreadLoadStatus)tls; } -RES ResourceLoader::load_threaded_get(const String &p_path) { +Ref<Resource> ResourceLoader::load_threaded_get(const String &p_path) { Error error; - RES res = ::ResourceLoader::load_threaded_get(p_path, &error); + Ref<Resource> res = ::ResourceLoader::load_threaded_get(p_path, &error); return res; } -RES ResourceLoader::load(const String &p_path, const String &p_type_hint, CacheMode p_cache_mode) { +Ref<Resource> ResourceLoader::load(const String &p_path, const String &p_type_hint, CacheMode p_cache_mode) { Error err = OK; - RES ret = ::ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err); + Ref<Resource> ret = ::ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err); ERR_FAIL_COND_V_MSG(err != OK, ret, "Error loading resource: '" + p_path + "'."); return ret; @@ -137,12 +137,12 @@ void ResourceLoader::_bind_methods() { ////// ResourceSaver ////// -Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path '" + String(p_path) + "'."); return ::ResourceSaver::save(p_path, p_resource, p_flags); } -Vector<String> ResourceSaver::get_recognized_extensions(const RES &p_resource) { +Vector<String> ResourceSaver::get_recognized_extensions(const Ref<Resource> &p_resource) { ERR_FAIL_COND_V_MSG(p_resource.is_null(), Vector<String>(), "It's not a reference to a valid Resource object."); List<String> exts; ::ResourceSaver::get_recognized_extensions(p_resource, &exts); @@ -1970,7 +1970,7 @@ Variant ClassDB::instantiate(const StringName &p_class) const { RefCounted *r = Object::cast_to<RefCounted>(obj); if (r) { - return REF(r); + return Ref<RefCounted>(r); } else { return obj; } diff --git a/core/core_bind.h b/core/core_bind.h index bc68be3f62..f6f2791006 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -73,9 +73,9 @@ public: Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false); ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = Array()); - RES load_threaded_get(const String &p_path); + Ref<Resource> load_threaded_get(const String &p_path); - RES load(const String &p_path, const String &p_type_hint = "", CacheMode p_cache_mode = CACHE_MODE_REUSE); + Ref<Resource> load(const String &p_path, const String &p_type_hint = "", CacheMode p_cache_mode = CACHE_MODE_REUSE); Vector<String> get_recognized_extensions_for_type(const String &p_type); void set_abort_on_missing_resources(bool p_abort); PackedStringArray get_dependencies(const String &p_path); @@ -107,8 +107,8 @@ public: static ResourceSaver *get_singleton() { return singleton; } - Error save(const String &p_path, const RES &p_resource, uint32_t p_flags); - Vector<String> get_recognized_extensions(const RES &p_resource); + Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags); + Vector<String> get_recognized_extensions(const Ref<Resource> &p_resource); ResourceSaver() { singleton = this; } }; diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 98b720ab65..2a514b68d8 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -41,7 +41,7 @@ struct _CoreConstant { StringName enum_name; bool ignore_value_in_docs = false; #endif - const char *name; + const char *name = nullptr; int value = 0; _CoreConstant() {} diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index f62d2cce1f..d0fd4feaa5 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -141,7 +141,7 @@ void Crypto::_bind_methods() { /// Resource loader/saver -RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { String el = p_path.get_extension().to_lower(); if (el == "crt") { X509Certificate *cert = X509Certificate::create(); @@ -185,7 +185,7 @@ String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const return ""; } -Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverCrypto::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { Error err; Ref<X509Certificate> cert = p_resource; Ref<CryptoKey> key = p_resource; @@ -201,7 +201,7 @@ Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resourc return OK; } -void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceFormatSaverCrypto::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource); const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource); if (cert) { @@ -215,6 +215,6 @@ void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, } } -bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const { +bool ResourceFormatSaverCrypto::recognize(const Ref<Resource> &p_resource) const { return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource); } diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 9de2c16fbc..fb4f7dd88f 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -117,7 +117,7 @@ public: class ResourceFormatLoaderCrypto : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -125,9 +125,9 @@ public: class ResourceFormatSaverCrypto : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; - virtual bool recognize(const RES &p_resource) const; + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; + virtual bool recognize(const Ref<Resource> &p_resource) const; }; #endif // CRYPTO_H diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index a312ce4ebd..a1d54f9c6d 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -1069,4 +1069,6 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) { gdni.classdb_register_extension_class_property_subgroup = nullptr; gdni.classdb_register_extension_class_signal = nullptr; gdni.classdb_unregister_extension_class = nullptr; + + gdni.get_library_path = nullptr; } diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 2bac52dc4a..ad4c8917df 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -545,6 +545,9 @@ typedef struct { void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix); void (*classdb_register_extension_class_signal)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); void (*classdb_unregister_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */ + + void (*get_library_path)(const GDNativeExtensionClassLibraryPtr p_library, GDNativeStringPtr r_path); + } GDNativeInterface; /* INITIALIZATION */ diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp index 076d04a5eb..5c02cb9190 100644 --- a/core/extension/native_extension.cpp +++ b/core/extension/native_extension.cpp @@ -261,8 +261,14 @@ void NativeExtension::_unregister_extension_class(const GDNativeExtensionClassLi self->extension_classes.erase(class_name); } +void NativeExtension::_get_library_path(const GDNativeExtensionClassLibraryPtr p_library, GDNativeStringPtr r_path) { + NativeExtension *self = static_cast<NativeExtension *>(p_library); + + *(String *)r_path = self->library_path; +} + Error NativeExtension::open_library(const String &p_path, const String &p_entry_symbol) { - Error err = OS::get_singleton()->open_dynamic_library(p_path, library, true); + Error err = OS::get_singleton()->open_dynamic_library(p_path, library, true, &library_path); if (err != OK) { return err; } @@ -354,9 +360,10 @@ void NativeExtension::initialize_native_extensions() { gdnative_interface.classdb_register_extension_class_property_subgroup = _register_extension_class_property_subgroup; gdnative_interface.classdb_register_extension_class_signal = _register_extension_class_signal; gdnative_interface.classdb_unregister_extension_class = _unregister_extension_class; + gdnative_interface.get_library_path = _get_library_path; } -RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> NativeExtensionResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<ConfigFile> config; config.instantiate(); @@ -367,14 +374,14 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or } if (err != OK) { - return RES(); + return Ref<Resource>(); } if (!config->has_section_key("configuration", "entry_symbol")) { if (r_error) { *r_error = ERR_INVALID_DATA; } - return RES(); + return Ref<Resource>(); } String entry_symbol = config->get_value("configuration", "entry_symbol"); @@ -406,7 +413,7 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or if (r_error) { *r_error = ERR_FILE_NOT_FOUND; } - return RES(); + return Ref<Resource>(); } if (!library_path.is_resource_file()) { @@ -423,7 +430,7 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or } if (err != OK) { - return RES(); + return Ref<Resource>(); } return lib; diff --git a/core/extension/native_extension.h b/core/extension/native_extension.h index ebfedfb29a..028a627b2e 100644 --- a/core/extension/native_extension.h +++ b/core/extension/native_extension.h @@ -39,6 +39,7 @@ class NativeExtension : public Resource { GDCLASS(NativeExtension, Resource) void *library = nullptr; // pointer if valid, + String library_path; struct Extension { ObjectNativeExtension native_extension; @@ -54,6 +55,7 @@ class NativeExtension : public Resource { static void _register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix); static void _register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count); static void _unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); + static void _get_library_path(const GDNativeExtensionClassLibraryPtr p_library, GDNativeStringPtr r_path); GDNativeInitialization initialization; int32_t level_initialized = -1; @@ -90,7 +92,7 @@ VARIANT_ENUM_CAST(NativeExtension::InitializationLevel) class NativeExtensionResourceLoader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/input/input.cpp b/core/input/input.cpp index c0c029fda0..40cea2cd80 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -74,7 +74,7 @@ void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr; Input::MouseMode (*Input::get_mouse_mode_func)() = nullptr; void (*Input::warp_mouse_func)(const Vector2 &p_position) = nullptr; Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr; -void (*Input::set_custom_mouse_cursor_func)(const RES &, Input::CursorShape, const Vector2 &) = nullptr; +void (*Input::set_custom_mouse_cursor_func)(const Ref<Resource> &, Input::CursorShape, const Vector2 &) = nullptr; Input *Input::get_singleton() { return singleton; @@ -850,7 +850,7 @@ Input::CursorShape Input::get_current_cursor_shape() const { return get_current_cursor_shape_func(); } -void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void Input::set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (Engine::get_singleton()->is_editor_hint()) { return; } diff --git a/core/input/input.h b/core/input/input.h index 42016f2417..5a7cb84ece 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -113,10 +113,10 @@ private: int mouse_from_touch_index = -1; struct VelocityTrack { - uint64_t last_tick; + uint64_t last_tick = 0; Vector2 velocity; Vector2 accum; - float accum_t; + float accum_t = 0.0f; float min_ref_frame; float max_ref_frame; @@ -219,7 +219,7 @@ private: static void (*warp_mouse_func)(const Vector2 &p_position); static CursorShape (*get_current_cursor_shape_func)(); - static void (*set_custom_mouse_cursor_func)(const RES &, CursorShape, const Vector2 &); + static void (*set_custom_mouse_cursor_func)(const Ref<Resource> &, CursorShape, const Vector2 &); EventDispatchFunc event_dispatch_function = nullptr; @@ -305,7 +305,7 @@ public: CursorShape get_default_cursor_shape() const; void set_default_cursor_shape(CursorShape p_shape); CursorShape get_current_cursor_shape() const; - void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()); + void set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()); void parse_mapping(String p_mapping); void joy_button(int p_device, JoyButton p_button, bool p_pressed); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index 6afbf6adf5..214d391c95 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -86,15 +86,15 @@ class FileAccessNetwork : public FileAccess { Semaphore page_sem; Mutex buffer_mutex; bool opened = false; - uint64_t total_size; + uint64_t total_size = 0; mutable uint64_t pos = 0; - int32_t id; + int32_t id = -1; mutable bool eof_flag = false; mutable int32_t last_page = -1; mutable uint8_t *last_page_buff = nullptr; - int32_t page_size; - int32_t read_ahead; + int32_t page_size = 0; + int32_t read_ahead = 0; mutable int waiting_on_page = -1; @@ -108,7 +108,8 @@ class FileAccessNetwork : public FileAccess { mutable Error response; - uint64_t exists_modtime; + uint64_t exists_modtime = 0; + friend class FileAccessNetworkClient; void _queue_page(int32_t p_page) const; void _respond(uint64_t p_len, Error p_status); diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 2504aeedc4..ae58d99a66 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -80,7 +80,7 @@ class FileAccessZip : public FileAccess { unzFile zfile = nullptr; unz_file_info64 file_info; - mutable bool at_eof; + mutable bool at_eof = false; void _close(); diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 2ccc95f0de..9cf7c9caba 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -111,13 +111,13 @@ void ImageLoader::cleanup() { ///////////////// -RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); if (f.is_null()) { if (r_error) { *r_error = ERR_CANT_OPEN; } - return RES(); + return Ref<Resource>(); } uint8_t header[4] = { 0, 0, 0, 0 }; @@ -128,7 +128,7 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin if (r_error) { *r_error = ERR_FILE_UNRECOGNIZED; } - ERR_FAIL_V(RES()); + ERR_FAIL_V(Ref<Resource>()); } String extension = f->get_pascal_string(); @@ -146,7 +146,7 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin if (r_error) { *r_error = ERR_FILE_UNRECOGNIZED; } - ERR_FAIL_V(RES()); + ERR_FAIL_V(Ref<Resource>()); } Ref<Image> image; @@ -158,7 +158,7 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin if (r_error) { *r_error = err; } - return RES(); + return Ref<Resource>(); } if (r_error) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 9409617268..c91d382c25 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -72,7 +72,7 @@ public: class ResourceFormatLoaderImage : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 52674150bb..5156a5cb99 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -74,8 +74,7 @@ struct _IP_ResolverPrivate { Semaphore sem; Thread thread; - //Semaphore* semaphore; - bool thread_abort; + bool thread_abort = false; void resolve_queues() { for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) { diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 87fb4c825c..bb9606c94b 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -601,7 +601,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } if (Object::cast_to<RefCounted>(obj)) { - REF ref = REF(Object::cast_to<RefCounted>(obj)); + Ref<RefCounted> ref = Ref<RefCounted>(Object::cast_to<RefCounted>(obj)); r_variant = ref; } else { r_variant = obj; diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 96efffd49b..e6535c67a4 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -208,13 +208,13 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res } Variant p = get(E.name); if (p.get_type() == Variant::OBJECT) { - RES sr = p; + Ref<Resource> sr = p; if (sr.is_valid()) { if (sr->is_local_to_scene()) { if (remap_cache.has(sr)) { p = remap_cache[sr]; } else { - RES dupe = sr->duplicate_for_local_scene(p_for_scene, remap_cache); + Ref<Resource> dupe = sr->duplicate_for_local_scene(p_for_scene, remap_cache); p = dupe; remap_cache[sr] = dupe; } @@ -240,7 +240,7 @@ void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, R } Variant p = get(E.name); if (p.get_type() == Variant::OBJECT) { - RES sr = p; + Ref<Resource> sr = p; if (sr.is_valid()) { if (sr->is_local_to_scene()) { if (!remap_cache.has(sr)) { @@ -269,7 +269,7 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const { if ((p.get_type() == Variant::DICTIONARY || p.get_type() == Variant::ARRAY)) { r->set(E.name, p.duplicate(p_subresources)); } else if (p.get_type() == Variant::OBJECT && (p_subresources || (E.usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) { - RES sr = p; + Ref<Resource> sr = p; if (sr.is_valid()) { r->set(E.name, sr->duplicate(p_subresources)); } @@ -321,7 +321,7 @@ void Resource::notify_change_to_owners() { Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE_MSG(!obj, "Object was deleted, while still owning a resource."); //wtf //TODO store string - obj->call("resource_changed", RES(this)); + obj->call("resource_changed", Ref<Resource>(this)); } } @@ -335,7 +335,7 @@ uint32_t Resource::hash_edited_version() const { for (const PropertyInfo &E : plist) { if (E.usage & PROPERTY_USAGE_STORAGE && E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_RESOURCE_TYPE) { - RES res = get(E.name); + Ref<Resource> res = get(E.name); if (res.is_valid()) { hash = hash_djb2_one_32(res->hash_edited_version(), hash); } diff --git a/core/io/resource.h b/core/io/resource.h index 8068000f32..43ae104da5 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -150,8 +150,6 @@ public: ~Resource(); }; -typedef Ref<Resource> RES; - class ResourceCache { friend class Resource; friend class ResourceLoader; //need the lock diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index c535c2bfeb..c9eb0e5234 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -388,7 +388,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { path = remaps[path]; } - RES res = ResourceLoader::load(path, exttype); + Ref<Resource> res = ResourceLoader::load(path, exttype); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); @@ -696,7 +696,7 @@ Error ResourceLoaderBinary::load() { } if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE && ResourceCache::has(path)) { - RES cached = ResourceCache::get(path); + Ref<Resource> cached = ResourceCache::get(path); if (cached.is_valid()) { //already loaded, don't do anything stage++; @@ -717,7 +717,7 @@ Error ResourceLoaderBinary::load() { String t = get_unicode_string(); - RES res; + Ref<Resource> res; if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) { //use the existing one @@ -745,7 +745,7 @@ Error ResourceLoaderBinary::load() { ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + "."); } - res = RES(r); + res = Ref<Resource>(r); if (!path.is_empty() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it } @@ -1026,7 +1026,7 @@ String ResourceLoaderBinary::recognize(Ref<FileAccess> p_f) { return type; } -RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -1034,7 +1034,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi Error err; Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Cannot open file '" + p_path + "'."); ResourceLoaderBinary loader; loader.cache_mode = p_cache_mode; @@ -1052,7 +1052,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi } if (err) { - return RES(); + return Ref<Resource>(); } return loader.resource; } @@ -1178,7 +1178,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons err = loader.load(); ERR_FAIL_COND_V(err != ERR_FILE_EOF, ERR_FILE_CORRUPT); - RES res = loader.get_resource(); + Ref<Resource> res = loader.get_resource(); ERR_FAIL_COND_V(!res.is_valid(), ERR_FILE_CORRUPT); return ResourceFormatSaverBinary::singleton->save(p_path, res); @@ -1287,6 +1287,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons fw->store_8(b); b = f->get_8(); } + f.unref(); bool all_ok = fw->get_error() == OK; @@ -1352,7 +1353,7 @@ void ResourceFormatSaverBinaryInstance::_pad_buffer(Ref<FileAccess> f, int p_byt } } -void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) { +void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const Variant &p_property, Map<Ref<Resource>, int> &resource_map, Map<Ref<Resource>, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) { switch (p_property.get_type()) { case Variant::NIL: { f->store_32(VARIANT_NIL); @@ -1561,7 +1562,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V } break; case Variant::OBJECT: { f->store_32(VARIANT_OBJECT); - RES res = p_property; + Ref<Resource> res = p_property; if (res.is_null()) { f->store_32(OBJECT_EMPTY); return; // don't save it @@ -1727,7 +1728,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant, bool p_main) { switch (p_variant.get_type()) { case Variant::OBJECT: { - RES res = p_variant; + Ref<Resource> res = p_variant; if (res.is_null() || external_resources.has(res)) { return; @@ -1755,7 +1756,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant if (E.usage & PROPERTY_USAGE_STORAGE) { Variant value = res->get(E.name); if (E.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { - RES sres = value; + Ref<Resource> sres = value; if (sres.is_valid()) { NonPersistentKey npk; npk.base = res; @@ -1832,7 +1833,7 @@ int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string) return strings.size() - 1; } -Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { Error err; Ref<FileAccess> f; if (p_flags & ResourceSaver::FLAG_COMPRESS) { @@ -1902,7 +1903,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p List<ResourceData> resources; { - for (const RES &E : saved_resources) { + for (const Ref<Resource> &E : saved_resources) { ResourceData &rd = resources.push_back(ResourceData())->get(); rd.type = E->get_class(); @@ -1949,10 +1950,10 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p // save external resource table f->store_32(external_resources.size()); //amount of external resources - Vector<RES> save_order; + Vector<Ref<Resource>> save_order; save_order.resize(external_resources.size()); - for (const KeyValue<RES, int> &E : external_resources) { + for (const KeyValue<Ref<Resource>, int> &E : external_resources) { save_order.write[E.value] = E.key; } @@ -1969,7 +1970,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p Vector<uint64_t> ofs_pos; Set<String> used_unique_ids; - for (RES &r : saved_resources) { + for (Ref<Resource> &r : saved_resources) { if (r->is_built_in()) { if (!r->get_scene_unique_id().is_empty()) { if (used_unique_ids.has(r->get_scene_unique_id())) { @@ -1981,9 +1982,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p } } - Map<RES, int> resource_map; + Map<Ref<Resource>, int> resource_map; int res_index = 0; - for (RES &r : saved_resources) { + for (Ref<Resource> &r : saved_resources) { if (r->is_built_in()) { if (r->get_scene_unique_id().is_empty()) { String new_id; @@ -2044,17 +2045,17 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p return OK; } -Error ResourceFormatSaverBinary::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverBinary::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { String local_path = ProjectSettings::get_singleton()->localize_path(p_path); ResourceFormatSaverBinaryInstance saver; return saver.save(local_path, p_resource, p_flags); } -bool ResourceFormatSaverBinary::recognize(const RES &p_resource) const { +bool ResourceFormatSaverBinary::recognize(const Ref<Resource> &p_resource) const { return true; //all recognized } -void ResourceFormatSaverBinary::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceFormatSaverBinary::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { String base = p_resource->get_base_extension().to_lower(); p_extensions->push_back(base); if (base != "res") { diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 72a3c6751d..92d4e4eeaa 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -50,7 +50,7 @@ class ResourceLoaderBinary { ResourceUID::ID uid = ResourceUID::INVALID_ID; Vector<char> str_buf; - List<RES> resource_cache; + List<Ref<Resource>> resource_cache; Vector<StringName> string_map; @@ -60,7 +60,7 @@ class ResourceLoaderBinary { String path; String type; ResourceUID::ID uid = ResourceUID::INVALID_ID; - RES cache; + Ref<Resource> cache; }; bool using_named_scene_ids = false; @@ -75,7 +75,7 @@ class ResourceLoaderBinary { }; Vector<IntResource> internal_resources; - Map<String, RES> internal_index_cache; + Map<String, Ref<Resource>> internal_index_cache; String get_unicode_string(); void _advance_padding(uint32_t p_len); @@ -89,7 +89,7 @@ class ResourceLoaderBinary { Error parse_variant(Variant &r_v); - Map<String, RES> dependency_cache; + Map<String, Ref<Resource>> dependency_cache; public: void set_local_path(const String &p_local_path); @@ -107,7 +107,7 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; @@ -127,20 +127,20 @@ class ResourceFormatSaverBinaryInstance { bool big_endian; bool takeover_paths; String magic; - Set<RES> resource_set; + Set<Ref<Resource>> resource_set; struct NonPersistentKey { //for resource properties generated on the fly - RES base; + Ref<Resource> base; StringName property; bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; } }; - Map<NonPersistentKey, RES> non_persistent_map; + Map<NonPersistentKey, Ref<Resource>> non_persistent_map; Map<StringName, int> string_map; Vector<StringName> strings; - Map<RES, int> external_resources; - List<RES> saved_resources; + Map<Ref<Resource>, int> external_resources; + List<Ref<Resource>> saved_resources; struct Property { int name_idx; @@ -167,16 +167,16 @@ public: // Amount of reserved 32-bit fields in resource header RESERVED_FIELDS = 11 }; - Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - static void write_variant(Ref<FileAccess> f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo()); + Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + static void write_variant(Ref<FileAccess> f, const Variant &p_property, Map<Ref<Resource>, int> &resource_map, Map<Ref<Resource>, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo()); }; class ResourceFormatSaverBinary : public ResourceFormatSaver { public: static ResourceFormatSaverBinary *singleton; - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual bool recognize(const RES &p_resource) const; - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual bool recognize(const Ref<Resource> &p_resource) const; + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; ResourceFormatSaverBinary(); }; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index b4f73b3b25..984cf06d2b 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -114,7 +114,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy return OK; } -RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { PathAndType pat; Error err = _get_path_and_type(p_path, pat); @@ -123,10 +123,10 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_ *r_error = err; } - return RES(); + return Ref<Resource>(); } - RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_cache_mode, r_error, p_use_sub_threads, r_progress); + Ref<Resource> res = ResourceLoader::_load(pat.path, p_path, pat.type, p_cache_mode, r_error, p_use_sub_threads, r_progress); #ifdef TOOLS_ENABLED if (res.is_valid()) { diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 2fffc16ad8..b3d777847b 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -58,7 +58,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { public: static ResourceFormatImporter *get_singleton() { return singleton; } - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index fe9693aa20..c8cebd672a 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -125,14 +125,14 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) } } -RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Variant res; if (GDVIRTUAL_CALL(_load, p_path, p_original_path, p_use_sub_threads, p_cache_mode, res)) { if (res.get_type() == Variant::INT) { // Error code, abort. if (r_error) { *r_error = (Error)res.operator int64_t(); } - return RES(); + return Ref<Resource>(); } else { // Success, pass on result. if (r_error) { *r_error = OK; @@ -141,7 +141,7 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa } } - ERR_FAIL_V_MSG(RES(), "Failed to load resource '" + p_path + "'. ResourceFormatLoader::load was not implemented for this resource type."); + ERR_FAIL_V_MSG(Ref<Resource>(), "Failed to load resource '" + p_path + "'. ResourceFormatLoader::load was not implemented for this resource type."); } void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { @@ -185,7 +185,7 @@ void ResourceFormatLoader::_bind_methods() { /////////////////////////////////// -RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress) { +Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress) { bool found = false; // Try all loaders and pick the first match for the type hint @@ -194,7 +194,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c continue; } found = true; - RES res = loader[i]->load(p_path, !p_original_path.is_empty() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode); + Ref<Resource> res = loader[i]->load(p_path, !p_original_path.is_empty() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode); if (res.is_null()) { continue; } @@ -202,15 +202,15 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c return res; } - ERR_FAIL_COND_V_MSG(found, RES(), + ERR_FAIL_COND_V_MSG(found, Ref<Resource>(), vformat("Failed loading resource: %s. Make sure resources have been imported by opening the project in the editor at least once.", p_path)); #ifdef TOOLS_ENABLED Ref<FileAccess> file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES); - ERR_FAIL_COND_V_MSG(!file_check->file_exists(p_path), RES(), "Resource file not found: " + p_path + "."); + ERR_FAIL_COND_V_MSG(!file_check->file_exists(p_path), Ref<Resource>(), "Resource file not found: " + p_path + "."); #endif - ERR_FAIL_V_MSG(RES(), "No loader found for resource: " + p_path + "."); + ERR_FAIL_V_MSG(Ref<Resource>(), "No loader found for resource: " + p_path + "."); } void ResourceLoader::_thread_load_function(void *p_userdata) { @@ -342,7 +342,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & Resource **rptr = ResourceCache::resources.getptr(local_path); if (rptr) { - RES res(*rptr); + Ref<Resource> res(*rptr); //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached if (res.is_valid()) { //referencing is fine @@ -427,7 +427,7 @@ ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const return status; } -RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { +Ref<Resource> ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { String local_path = _validate_local_path(p_path); thread_load_mutex->lock(); @@ -436,7 +436,7 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { if (r_error) { *r_error = ERR_INVALID_PARAMETER; } - return RES(); + return Ref<Resource>(); } ThreadLoadTask &load_task = thread_load_tasks[local_path]; @@ -480,11 +480,11 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { if (r_error) { *r_error = ERR_INVALID_PARAMETER; } - return RES(); + return Ref<Resource>(); } } - RES resource = load_task.resource; + Ref<Resource> resource = load_task.resource; if (r_error) { *r_error = load_task.error; } @@ -504,7 +504,7 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { return resource; } -RES ResourceLoader::load(const String &p_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error) { +Ref<Resource> ResourceLoader::load(const String &p_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -522,7 +522,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour *r_error = err; } thread_load_mutex->unlock(); - return RES(); + return Ref<Resource>(); } thread_load_mutex->unlock(); @@ -535,7 +535,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour Resource **rptr = ResourceCache::resources.getptr(local_path); if (rptr) { - RES res(*rptr); + Ref<Resource> res(*rptr); //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached if (res.is_valid()) { @@ -575,16 +575,16 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour String path = _path_remap(local_path, &xl_remapped); if (path.is_empty()) { - ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed."); + ERR_FAIL_V_MSG(Ref<Resource>(), "Remapping '" + local_path + "' failed."); } print_verbose("Loading resource: " + path); float p; - RES res = _load(path, local_path, p_type_hint, p_cache_mode, r_error, false, &p); + Ref<Resource> res = _load(path, local_path, p_type_hint, p_cache_mode, r_error, false, &p); if (res.is_null()) { print_verbose("Failed loading resource: " + path); - return RES(); + return Ref<Resource>(); } if (xl_remapped) { diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index a3fdefa0f1..15ecfacf4a 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -61,7 +61,7 @@ protected: GDVIRTUAL4RC(Variant, _load, String, String, bool, int) public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual bool exists(const String &p_path) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; @@ -85,7 +85,7 @@ typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text); typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type); typedef Error (*ResourceLoaderImport)(const String &p_path); -typedef void (*ResourceLoadedCallback)(RES p_resource, const String &p_path); +typedef void (*ResourceLoadedCallback)(Ref<Resource> p_resource, const String &p_path); class ResourceLoader { enum { @@ -121,7 +121,7 @@ private: friend class ResourceFormatImporter; friend class ResourceInteractiveLoader; // Internal load function. - static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress); + static Ref<Resource> _load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress); static ResourceLoadedCallback _loaded_callback; @@ -138,7 +138,7 @@ private: ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS; ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; Error error = OK; - RES resource; + Ref<Resource> resource; bool xl_remapped = false; bool use_sub_threads = false; bool start_next = true; @@ -161,9 +161,9 @@ private: public: static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, const String &p_source_resource = String()); static ThreadLoadStatus load_threaded_get_status(const String &p_path, float *r_progress = nullptr); - static RES load_threaded_get(const String &p_path, Error *r_error = nullptr); + static Ref<Resource> load_threaded_get(const String &p_path, Error *r_error = nullptr); - static RES load(const String &p_path, const String &p_type_hint = "", ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, Error *r_error = nullptr); + static Ref<Resource> load(const String &p_path, const String &p_type_hint = "", ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, Error *r_error = nullptr); static bool exists(const String &p_path, const String &p_type_hint = ""); static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions); diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index c883e8502f..2f5c5b54dd 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -41,7 +41,7 @@ bool ResourceSaver::timestamp_on_save = false; ResourceSavedCallback ResourceSaver::save_callback = nullptr; ResourceSaverGetResourceIDForPath ResourceSaver::save_get_id_for_path = nullptr; -Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaver::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { int64_t res; if (GDVIRTUAL_CALL(_save, p_path, p_resource, p_flags, res)) { return (Error)res; @@ -50,7 +50,7 @@ Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uin return ERR_METHOD_NOT_FOUND; } -bool ResourceFormatSaver::recognize(const RES &p_resource) const { +bool ResourceFormatSaver::recognize(const Ref<Resource> &p_resource) const { bool success; if (GDVIRTUAL_CALL(_recognize, p_resource, success)) { return success; @@ -59,7 +59,7 @@ bool ResourceFormatSaver::recognize(const RES &p_resource) const { return false; } -void ResourceFormatSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceFormatSaver::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { PackedStringArray exts; if (GDVIRTUAL_CALL(_get_recognized_extensions, p_resource, exts)) { const String *r = exts.ptr(); @@ -75,7 +75,7 @@ void ResourceFormatSaver::_bind_methods() { GDVIRTUAL_BIND(_get_recognized_extensions, "resource"); } -Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { String extension = p_path.get_extension(); Error err = ERR_FILE_UNRECOGNIZED; @@ -102,7 +102,7 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t String local_path = ProjectSettings::get_singleton()->localize_path(p_path); - RES rwcopy = p_resource; + Ref<Resource> rwcopy = p_resource; if (p_flags & FLAG_CHANGE_PATH) { rwcopy->set_path(local_path); } @@ -139,7 +139,7 @@ void ResourceSaver::set_save_callback(ResourceSavedCallback p_callback) { save_callback = p_callback; } -void ResourceSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) { +void ResourceSaver::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) { for (int i = 0; i < saver_count; i++) { saver[i]->get_recognized_extensions(p_resource, p_extensions); } diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index ebc3be91a1..088317bfbe 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -41,14 +41,14 @@ class ResourceFormatSaver : public RefCounted { protected: static void _bind_methods(); - GDVIRTUAL3R(int64_t, _save, String, RES, uint32_t) - GDVIRTUAL1RC(bool, _recognize, RES) - GDVIRTUAL1RC(Vector<String>, _get_recognized_extensions, RES) + GDVIRTUAL3R(int64_t, _save, String, Ref<Resource>, uint32_t) + GDVIRTUAL1RC(bool, _recognize, Ref<Resource>) + GDVIRTUAL1RC(Vector<String>, _get_recognized_extensions, Ref<Resource>) public: - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual bool recognize(const RES &p_resource) const; - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual bool recognize(const Ref<Resource> &p_resource) const; + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; virtual ~ResourceFormatSaver() {} }; @@ -81,8 +81,8 @@ public: FLAG_REPLACE_SUBRESOURCE_PATHS = 64, }; - static Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = (uint32_t)FLAG_NONE); - static void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions); + static Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = (uint32_t)FLAG_NONE); + static void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions); static void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front = false); static void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver); diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index ae1ad304d7..f36eb7c763 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -34,7 +34,7 @@ #include "core/string/translation.h" #include "core/string/translation_po.h" -RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { +Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { if (r_error) { *r_error = ERR_FILE_CORRUPT; } @@ -49,7 +49,7 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { uint16_t version_maj = f->get_16(); uint16_t version_min = f->get_16(); - ERR_FAIL_COND_V_MSG(version_maj > 1, RES(), vformat("Unsupported MO file %s, version %d.%d.", path, version_maj, version_min)); + ERR_FAIL_COND_V_MSG(version_maj > 1, Ref<Resource>(), vformat("Unsupported MO file %s, version %d.%d.", path, version_maj, version_min)); uint32_t num_strings = f->get_32(); uint32_t id_table_offset = f->get_32(); @@ -170,14 +170,14 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { // If we reached last line and it's not a content line, break, otherwise let processing that last loop if (is_eof && l.is_empty()) { if (status == STATUS_READING_ID || status == STATUS_READING_CONTEXT || (status == STATUS_READING_PLURAL && plural_index != plural_forms - 1)) { - ERR_FAIL_V_MSG(RES(), "Unexpected EOF while reading PO file at: " + path + ":" + itos(line)); + ERR_FAIL_V_MSG(Ref<Resource>(), "Unexpected EOF while reading PO file at: " + path + ":" + itos(line)); } else { break; } } if (l.begins_with("msgctxt")) { - ERR_FAIL_COND_V_MSG(status != STATUS_READING_STRING && status != STATUS_READING_PLURAL, RES(), "Unexpected 'msgctxt', was expecting 'msgid_plural' or 'msgstr' before 'msgctxt' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status != STATUS_READING_STRING && status != STATUS_READING_PLURAL, Ref<Resource>(), "Unexpected 'msgctxt', was expecting 'msgid_plural' or 'msgstr' before 'msgctxt' while parsing: " + path + ":" + itos(line)); // In PO file, "msgctxt" appears before "msgid". If we encounter a "msgctxt", we add what we have read // and set "entered_context" to true to prevent adding twice. @@ -185,7 +185,7 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { if (status == STATUS_READING_STRING) { translation->add_message(msg_id, msg_str, msg_context); } else if (status == STATUS_READING_PLURAL) { - ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); translation->add_plural_message(msg_id, msgs_plural, msg_context); } } @@ -197,9 +197,9 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { if (l.begins_with("msgid_plural")) { if (plural_forms == 0) { - ERR_FAIL_V_MSG(RES(), "PO file uses 'msgid_plural' but 'Plural-Forms' is invalid or missing in header: " + path + ":" + itos(line)); + ERR_FAIL_V_MSG(Ref<Resource>(), "PO file uses 'msgid_plural' but 'Plural-Forms' is invalid or missing in header: " + path + ":" + itos(line)); } else if (status != STATUS_READING_ID) { - ERR_FAIL_V_MSG(RES(), "Unexpected 'msgid_plural', was expecting 'msgid' before 'msgid_plural' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_V_MSG(Ref<Resource>(), "Unexpected 'msgid_plural', was expecting 'msgid' before 'msgid_plural' while parsing: " + path + ":" + itos(line)); } // We don't record the message in "msgid_plural" itself as tr_n(), TTRN(), RTRN() interfaces provide the plural string already. // We just have to reset variables related to plurals for "msgstr[]" later on. @@ -209,14 +209,14 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { msgs_plural.resize(plural_forms); status = STATUS_READING_PLURAL; } else if (l.begins_with("msgid")) { - ERR_FAIL_COND_V_MSG(status == STATUS_READING_ID, RES(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status == STATUS_READING_ID, Ref<Resource>(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line)); if (!msg_id.is_empty()) { if (!skip_this && !entered_context) { if (status == STATUS_READING_STRING) { translation->add_message(msg_id, msg_str, msg_context); } else if (status == STATUS_READING_PLURAL) { - ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); translation->add_plural_message(msg_id, msgs_plural, msg_context); } } @@ -245,11 +245,11 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { } if (l.begins_with("msgstr[")) { - ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, RES(), "Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Ref<Resource>(), "Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: " + path + ":" + itos(line)); plural_index++; // Increment to add to the next slot in vector msgs_plural. l = l.substr(9, l.length()).strip_edges(); } else if (l.begins_with("msgstr")) { - ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, RES(), "Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Ref<Resource>(), "Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: " + path + ":" + itos(line)); l = l.substr(6, l.length()).strip_edges(); status = STATUS_READING_STRING; } @@ -262,7 +262,7 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { continue; // Nothing to read or comment. } - ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, RES(), "Invalid line '" + l + "' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Ref<Resource>(), "Invalid line '" + l + "' while parsing: " + path + ":" + itos(line)); l = l.substr(1, l.length()); // Find final quote, ignoring escaped ones (\"). @@ -284,7 +284,7 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { escape_next = false; } - ERR_FAIL_COND_V_MSG(end_pos == -1, RES(), "Expected '\"' at end of message while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(end_pos == -1, Ref<Resource>(), "Expected '\"' at end of message while parsing: " + path + ":" + itos(line)); l = l.substr(0, end_pos); l = l.c_unescape(); @@ -296,7 +296,7 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { } else if (status == STATUS_READING_CONTEXT) { msg_context += l; } else if (status == STATUS_READING_PLURAL && plural_index >= 0) { - ERR_FAIL_COND_V_MSG(plural_index >= plural_forms, RES(), "Unexpected plural form while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index >= plural_forms, Ref<Resource>(), "Unexpected plural form while parsing: " + path + ":" + itos(line)); msgs_plural.write[plural_index] = msgs_plural[plural_index] + l; } @@ -314,13 +314,13 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { } } else if (status == STATUS_READING_PLURAL) { if (!skip_this && !msg_id.is_empty()) { - ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); translation->add_plural_message(msg_id, msgs_plural, msg_context); } } } - ERR_FAIL_COND_V_MSG(config.is_empty(), RES(), "No config found in file: " + path + "."); + ERR_FAIL_COND_V_MSG(config.is_empty(), Ref<Resource>(), "No config found in file: " + path + "."); Vector<String> configs = config.split("\n"); for (int i = 0; i < configs.size(); i++) { @@ -344,13 +344,13 @@ RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) { return translation; } -RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_V_MSG(f.is_null(), RES(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(f.is_null(), Ref<Resource>(), "Cannot open file '" + p_path + "'."); return load_translation(f, r_error); } diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index 7da361cf24..4477ad7714 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -37,8 +37,8 @@ class TranslationLoaderPO : public ResourceFormatLoader { public: - static RES load_translation(Ref<FileAccess> f, Error *r_error = nullptr); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + static Ref<Resource> load_translation(Ref<FileAccess> f, Error *r_error = nullptr); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index 23a0b5dd54..996f4f4d67 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -666,7 +666,7 @@ public: face_pool.reset(true); } - Vertex *vertex_list; + Vertex *vertex_list = nullptr; void compute(const Vector3 *p_coords, int32_t p_count); diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp index 46b7d99b43..31fade5a99 100644 --- a/core/math/geometry_2d.cpp +++ b/core/math/geometry_2d.cpp @@ -74,14 +74,14 @@ Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> p struct _AtlasWorkRect { Size2i s; Point2i p; - int idx; + int idx = 0; _FORCE_INLINE_ bool operator<(const _AtlasWorkRect &p_r) const { return s.width > p_r.s.width; }; }; struct _AtlasWorkRectResult { Vector<_AtlasWorkRect> result; - int max_w; - int max_h; + int max_w = 0; + int max_h = 0; }; void Geometry2D::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size) { diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index 65fcf67664..a088b30d17 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -61,8 +61,8 @@ static int __bsr_clz32(uint32_t x) { class RandomPCG { pcg32_random_t pcg; - uint64_t current_seed; // The seed the current generator state started from. - uint64_t current_inc; + uint64_t current_seed = 0; // The seed the current generator state started from. + uint64_t current_inc = 0; public: static const uint64_t DEFAULT_SEED = 12047754176567800795U; diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 61ce965bc3..593f27b7cf 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -39,190 +39,13 @@ #ifdef DEBUG_METHODS_ENABLED -MethodDefinition D_METHOD(const char *p_name) { +MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint32_t p_argcount) { MethodDefinition md; md.name = StaticCString::create(p_name); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.push_back(StaticCString::create(p_arg1)); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(2); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(3); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(4); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(5); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(6); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(7); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - md.args.write[6] = StaticCString::create(p_arg7); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(8); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - md.args.write[6] = StaticCString::create(p_arg7); - md.args.write[7] = StaticCString::create(p_arg8); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(9); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - md.args.write[6] = StaticCString::create(p_arg7); - md.args.write[7] = StaticCString::create(p_arg8); - md.args.write[8] = StaticCString::create(p_arg9); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(10); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - md.args.write[6] = StaticCString::create(p_arg7); - md.args.write[7] = StaticCString::create(p_arg8); - md.args.write[8] = StaticCString::create(p_arg9); - md.args.write[9] = StaticCString::create(p_arg10); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(11); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - md.args.write[6] = StaticCString::create(p_arg7); - md.args.write[7] = StaticCString::create(p_arg8); - md.args.write[8] = StaticCString::create(p_arg9); - md.args.write[9] = StaticCString::create(p_arg10); - md.args.write[10] = StaticCString::create(p_arg11); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(12); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - md.args.write[6] = StaticCString::create(p_arg7); - md.args.write[7] = StaticCString::create(p_arg8); - md.args.write[8] = StaticCString::create(p_arg9); - md.args.write[9] = StaticCString::create(p_arg10); - md.args.write[10] = StaticCString::create(p_arg11); - md.args.write[11] = StaticCString::create(p_arg12); - return md; -} - -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13) { - MethodDefinition md; - md.name = StaticCString::create(p_name); - md.args.resize(13); - md.args.write[0] = StaticCString::create(p_arg1); - md.args.write[1] = StaticCString::create(p_arg2); - md.args.write[2] = StaticCString::create(p_arg3); - md.args.write[3] = StaticCString::create(p_arg4); - md.args.write[4] = StaticCString::create(p_arg5); - md.args.write[5] = StaticCString::create(p_arg6); - md.args.write[6] = StaticCString::create(p_arg7); - md.args.write[7] = StaticCString::create(p_arg8); - md.args.write[8] = StaticCString::create(p_arg9); - md.args.write[9] = StaticCString::create(p_arg10); - md.args.write[10] = StaticCString::create(p_arg11); - md.args.write[11] = StaticCString::create(p_arg12); - md.args.write[12] = StaticCString::create(p_arg13); + md.args.resize(p_argcount); + for (uint32_t i = 0; i < p_argcount; i++) { + md.args.write[i] = StaticCString::create(*p_args[i]); + } return md; } diff --git a/core/object/class_db.h b/core/object/class_db.h index 333a3307e2..d4e1fc4e76 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -35,10 +35,6 @@ #include "core/object/object.h" #include "core/string/print_string.h" -/** To bind more then 6 parameters include this: - * - */ - // Makes callable_mp readily available in all classes connecting signals. // Needs to come after method_bind and object have been included. #include "core/object/callable_method_pointer.h" @@ -57,20 +53,18 @@ struct MethodDefinition { name(p_name) {} }; -MethodDefinition D_METHOD(const char *p_name); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12); -MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13); +MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint32_t p_argcount); + +template <typename... VarArgs> +MethodDefinition D_METHOD(const char *p_name, const VarArgs... p_args) { + const char *args[sizeof...(p_args) + 1] = { p_args..., nullptr }; // +1 makes sure zero sized arrays are also supported. + const char *const *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + + return D_METHODP(p_name, sizeof...(p_args) == 0 ? nullptr : (const char *const **)argptrs, sizeof...(p_args)); +} #else diff --git a/core/object/object.cpp b/core/object/object.cpp index 897b5d18de..1defd85a14 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1476,7 +1476,7 @@ String Object::tr_n(const StringName &p_message, const StringName &p_message_plu void Object::_clear_internal_resource_paths(const Variant &p_var) { switch (p_var.get_type()) { case Variant::OBJECT: { - RES r = p_var; + Ref<Resource> r = p_var; if (!r.is_valid()) { return; } diff --git a/core/object/ref_counted.cpp b/core/object/ref_counted.cpp index c9a7b2a608..726e2c012c 100644 --- a/core/object/ref_counted.cpp +++ b/core/object/ref_counted.cpp @@ -108,7 +108,7 @@ Variant WeakRef::get_ref() const { } RefCounted *r = cast_to<RefCounted>(obj); if (r) { - return REF(r); + return Ref<RefCounted>(r); } return obj; @@ -118,7 +118,7 @@ void WeakRef::set_obj(Object *p_object) { ref = p_object ? p_object->get_instance_id() : ObjectID(); } -void WeakRef::set_ref(const REF &p_ref) { +void WeakRef::set_ref(const Ref<RefCounted> &p_ref) { ref = p_ref.is_valid() ? p_ref->get_instance_id() : ObjectID(); } diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index dcacf19890..bd06a84bd8 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -234,8 +234,6 @@ public: } }; -typedef Ref<RefCounted> REF; - class WeakRef : public RefCounted { GDCLASS(WeakRef, RefCounted); @@ -247,7 +245,7 @@ protected: public: Variant get_ref() const; void set_obj(Object *p_object); - void set_ref(const REF &p_ref); + void set_ref(const Ref<RefCounted> &p_ref); WeakRef() {} }; diff --git a/core/object/script_language.h b/core/object/script_language.h index 69002c81f4..f58ef45743 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -323,7 +323,7 @@ public: String display; String insert_text; Color font_color; - RES icon; + Ref<Resource> icon; Variant default_value; Vector<Pair<int, int>> matches; int location = LOCATION_OTHER; diff --git a/core/os/os.h b/core/os/os.h index 9ec0dd7728..a7cf3f1679 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -54,7 +54,6 @@ class OS { bool _single_window = false; String _local_clipboard; int _exit_code = EXIT_FAILURE; // unexpected exit is marked as failure - int _orientation; bool _allow_hidpi = false; bool _allow_layered = false; bool _stdout_enabled = true; @@ -68,7 +67,7 @@ class OS { // for the user interface we keep a record of the current display driver // so we can retrieve the rendering drivers available int _display_driver_id = -1; - String _current_rendering_driver_name = ""; + String _current_rendering_driver_name; protected: void _set_logger(CompositeLogger *p_logger); @@ -138,7 +137,7 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; } + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) { return ERR_UNAVAILABLE; } virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; } virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; } diff --git a/core/os/pool_allocator.h b/core/os/pool_allocator.h index 27a936ed78..a7a8523aa4 100644 --- a/core/os/pool_allocator.h +++ b/core/os/pool_allocator.h @@ -77,20 +77,20 @@ private: Entry *entry_array = nullptr; int *entry_indices = nullptr; - int entry_max; - int entry_count; + int entry_max = 0; + int entry_count = 0; uint8_t *pool = nullptr; void *mem_ptr = nullptr; - int pool_size; + int pool_size = 0; - int free_mem; - int free_mem_peak; + int free_mem = 0; + int free_mem_peak = 0; - unsigned int check_count; - int align; + unsigned int check_count = 0; + int align = 1; - bool needs_locking; + bool needs_locking = false; inline int entry_end(const Entry &p_entry) const { return p_entry.pos + aligned(p_entry.len); diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp index 07b58f2418..93429744fc 100644 --- a/core/string/optimized_translation.cpp +++ b/core/string/optimized_translation.cpp @@ -37,9 +37,9 @@ extern "C" { } struct CompressedString { - int orig_len; + int orig_len = 0; CharString compressed; - int offset; + int offset = 0; }; void OptimizedTranslation::generate(const Ref<Translation> &p_from) { diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index a2b1e4c428..5d998d22d4 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -4427,7 +4427,7 @@ String String::sprintf(const Array &values, bool *error) const { int min_chars = 0; int min_decimals = 0; bool in_decimals = false; - bool pad_with_zeroes = false; + bool pad_with_zeros = false; bool left_justified = false; bool show_sign = false; @@ -4480,7 +4480,7 @@ String String::sprintf(const Array &values, bool *error) const { // Padding. int pad_chars_count = (value < 0 || show_sign) ? min_chars - 1 : min_chars; - String pad_char = pad_with_zeroes ? String("0") : String(" "); + String pad_char = pad_with_zeros ? String("0") : String(" "); if (left_justified) { str = str.rpad(pad_chars_count, pad_char); } else { @@ -4488,10 +4488,13 @@ String String::sprintf(const Array &values, bool *error) const { } // Sign. - if (show_sign && value >= 0) { - str = str.insert(pad_with_zeroes ? 0 : str.length() - number_len, "+"); - } else if (value < 0) { - str = str.insert(pad_with_zeroes ? 0 : str.length() - number_len, "-"); + if (show_sign || value < 0) { + String sign_char = value < 0 ? "-" : "+"; + if (left_justified) { + str = str.insert(0, sign_char); + } else { + str = str.insert(pad_with_zeros ? 0 : str.length() - number_len, sign_char); + } } formatted += str; @@ -4520,13 +4523,9 @@ String String::sprintf(const Array &values, bool *error) const { // Padding. Leave room for sign later if required. int pad_chars_count = (is_negative || show_sign) ? min_chars - 1 : min_chars; - String pad_char = pad_with_zeroes ? String("0") : String(" "); + String pad_char = pad_with_zeros ? String("0") : String(" "); if (left_justified) { - if (pad_with_zeroes) { - return "left justification cannot be used with zeros as the padding"; - } else { - str = str.rpad(pad_chars_count, pad_char); - } + str = str.rpad(pad_chars_count, pad_char); } else { str = str.lpad(pad_chars_count, pad_char); } @@ -4537,7 +4536,7 @@ String String::sprintf(const Array &values, bool *error) const { if (left_justified) { str = str.insert(0, sign_char); } else { - str = str.insert(pad_with_zeroes ? 0 : str.length() - initial_len, sign_char); + str = str.insert(pad_with_zeros ? 0 : str.length() - initial_len, sign_char); } } @@ -4626,7 +4625,11 @@ String String::sprintf(const Array &values, bool *error) const { min_decimals += n; } else { if (c == '0' && min_chars == 0) { - pad_with_zeroes = true; + if (left_justified) { + WARN_PRINT("'0' flag ignored with '-' flag in string format"); + } else { + pad_with_zeros = true; + } } else { min_chars *= 10; min_chars += n; @@ -4675,7 +4678,7 @@ String String::sprintf(const Array &values, bool *error) const { // Back to defaults: min_chars = 0; min_decimals = 6; - pad_with_zeroes = false; + pad_with_zeros = false; left_justified = false; show_sign = false; in_decimals = false; diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index c41af32c3f..e79da748e9 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -3341,27 +3341,7 @@ String Variant::get_construct_string() const { } String Variant::get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - return "'" + String(p_method) + "': " + err_text; + return get_call_error_text(nullptr, p_method, p_argptrs, p_argcount, ce); } String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { @@ -3386,37 +3366,20 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, return "Call OK"; } - String class_name = p_base->get_class(); - Ref<Resource> script = p_base->get_script(); - if (script.is_valid() && script->get_path().is_resource_file()) { - class_name += "(" + script->get_path().get_file() + ")"; + String base_text; + if (p_base) { + base_text = p_base->get_class(); + Ref<Resource> script = p_base->get_script(); + if (script.is_valid() && script->get_path().is_resource_file()) { + base_text += "(" + script->get_path().get_file() + ")"; + } + base_text += "::"; } - return "'" + class_name + "::" + String(p_method) + "': " + err_text; + return "'" + base_text + String(p_method) + "': " + err_text; } String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - - return String(p_callable) + " : " + err_text; + return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, p_argcount, ce); } String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) { diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 9dae0720d9..cc7e84203f 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -949,20 +949,20 @@ struct _VariantCall { _VariantCall::ConstantData *_VariantCall::constant_data = nullptr; struct VariantBuiltInMethodInfo { - void (*call)(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error); - Variant::ValidatedBuiltInMethod validated_call; - Variant::PTRBuiltInMethod ptrcall; + void (*call)(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) = nullptr; + Variant::ValidatedBuiltInMethod validated_call = nullptr; + Variant::PTRBuiltInMethod ptrcall = nullptr; Vector<Variant> default_arguments; Vector<String> argument_names; - bool is_const; - bool is_static; - bool has_return_type; - bool is_vararg; + bool is_const = false; + bool is_static = false; + bool has_return_type = false; + bool is_vararg = false; Variant::Type return_type; - int argument_count; - Variant::Type (*get_argument_type)(int p_arg); + int argument_count = 0; + Variant::Type (*get_argument_type)(int p_arg) = nullptr; }; typedef OAHashMap<StringName, VariantBuiltInMethodInfo> BuiltinMethodMap; diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 351f4ae253..6b12b054a0 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -31,11 +31,11 @@ #include "variant_construct.h" struct VariantConstructData { - void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error); - Variant::ValidatedConstructor validated_construct; - Variant::PTRConstructor ptr_construct; - Variant::Type (*get_argument_type)(int); - int argument_count; + void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error) = nullptr; + Variant::ValidatedConstructor validated_construct = nullptr; + Variant::PTRConstructor ptr_construct = nullptr; + Variant::Type (*get_argument_type)(int) = nullptr; + int argument_count = 0; Vector<String> arg_names; }; diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 205b7fd93f..2864d0c956 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -806,7 +806,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, return ERR_PARSE_ERROR; } - REF ref = REF(Object::cast_to<RefCounted>(obj)); + Ref<RefCounted> ref = Ref<RefCounted>(Object::cast_to<RefCounted>(obj)); get_token(p_stream, token, line, r_err_str); if (token.type != TK_COMMA) { @@ -887,7 +887,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } if (p_res_parser && id == "Resource" && p_res_parser->func) { - RES res; + Ref<Resource> res; Error err = p_res_parser->func(p_res_parser->userdata, p_stream, res, line, r_err_str); if (err) { return err; @@ -895,7 +895,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = res; } else if (p_res_parser && id == "ExtResource" && p_res_parser->ext_func) { - RES res; + Ref<Resource> res; Error err = p_res_parser->ext_func(p_res_parser->userdata, p_stream, res, line, r_err_str); if (err) { return err; @@ -903,7 +903,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = res; } else if (p_res_parser && id == "SubResource" && p_res_parser->sub_func) { - RES res; + Ref<Resource> res; Error err = p_res_parser->sub_func(p_res_parser->userdata, p_stream, res, line, r_err_str); if (err) { return err; @@ -914,7 +914,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, get_token(p_stream, token, line, r_err_str); if (token.type == TK_STRING) { String path = token.value; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { r_err_str = "Can't load resource at path: '" + path + "'."; return ERR_PARSE_ERROR; @@ -1624,7 +1624,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str break; // don't save it } - RES res = p_variant; + Ref<Resource> res = p_variant; if (res.is_valid()) { //is resource String res_text; diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h index 07d89d30cb..70ca8d8cb5 100644 --- a/core/variant/variant_parser.h +++ b/core/variant/variant_parser.h @@ -138,7 +138,7 @@ public: class VariantWriter { public: typedef Error (*StoreStringFunc)(void *ud, const String &p_string); - typedef String (*EncodeResourceFunc)(void *ud, const RES &p_resource); + typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource); static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count = 0); static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 62ab4a343e..09097e30e0 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -805,16 +805,16 @@ INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color) INDEXED_SETGET_STRUCT_DICT(Dictionary) struct VariantIndexedSetterGetterInfo { - void (*setter)(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob); - void (*getter)(const Variant *base, int64_t index, Variant *value, bool *oob); + void (*setter)(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) = nullptr; + void (*getter)(const Variant *base, int64_t index, Variant *value, bool *oob) = nullptr; - Variant::ValidatedIndexedSetter validated_setter; - Variant::ValidatedIndexedGetter validated_getter; + Variant::ValidatedIndexedSetter validated_setter = nullptr; + Variant::ValidatedIndexedGetter validated_getter = nullptr; - Variant::PTRIndexedSetter ptr_setter; - Variant::PTRIndexedGetter ptr_getter; + Variant::PTRIndexedSetter ptr_setter = nullptr; + Variant::PTRIndexedGetter ptr_getter = nullptr; - uint64_t (*get_indexed_size)(const Variant *base); + uint64_t (*get_indexed_size)(const Variant *base) = nullptr; Variant::Type index_type; @@ -1018,13 +1018,13 @@ struct VariantKeyedSetGetObject { }; struct VariantKeyedSetterGetterInfo { - Variant::ValidatedKeyedSetter validated_setter; - Variant::ValidatedKeyedGetter validated_getter; - Variant::ValidatedKeyedChecker validated_checker; + Variant::ValidatedKeyedSetter validated_setter = nullptr; + Variant::ValidatedKeyedGetter validated_getter = nullptr; + Variant::ValidatedKeyedChecker validated_checker = nullptr; - Variant::PTRKeyedSetter ptr_setter; - Variant::PTRKeyedGetter ptr_getter; - Variant::PTRKeyedChecker ptr_checker; + Variant::PTRKeyedSetter ptr_setter = nullptr; + Variant::PTRKeyedGetter ptr_getter = nullptr; + Variant::PTRKeyedChecker ptr_checker = nullptr; bool valid = false; }; diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 6ed85815be..66badce268 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -435,7 +435,7 @@ struct VariantUtilityFunctions { r_error.error = Callable::CallError::CALL_OK; if (obj.is_ref_counted()) { Ref<WeakRef> wref = memnew(WeakRef); - REF r = obj; + Ref<RefCounted> r = obj; if (r.is_valid()) { wref->set_ref(r); } @@ -1110,14 +1110,14 @@ static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) { register_utility_function<Func_##m_func>(#m_func, m_args) struct VariantUtilityFunctionInfo { - void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - Variant::ValidatedUtilityFunction validated_call_utility; - Variant::PTRUtilityFunction ptr_call_utility; + void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = nullptr; + Variant::ValidatedUtilityFunction validated_call_utility = nullptr; + Variant::PTRUtilityFunction ptr_call_utility = nullptr; Vector<String> argnames; - bool is_vararg; - bool returns_value; - int argcount; - Variant::Type (*get_arg_type)(int); + bool is_vararg = false; + bool returns_value = false; + int argcount = 0; + Variant::Type (*get_arg_type)(int) = nullptr; Variant::Type return_type; Variant::UtilityFunctionType type; }; diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 0021b2f857..a40b851efc 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -457,6 +457,7 @@ rotation = lerp_angle(min_angle, max_angle, elapsed) elapsed += delta [/codeblock] + [b]Note:[/b] This method lerps through the shortest path between [code]from[/code] and [code]to[/code]. However, when these two angles are approximately [code]PI + k * TAU[/code] apart for any integer [code]k[/code], it's not obvious which way they lerp due to floating-point precision errors. For example, [code]lerp_angle(0, PI, weight)[/code] lerps counter-clockwise, while [code]lerp_angle(0, PI + 5 * TAU, weight)[/code] lerps clockwise. </description> </method> <method name="linear2db"> diff --git a/doc/classes/AnimationNodeStateMachine.xml b/doc/classes/AnimationNodeStateMachine.xml index 2cafdf8aaa..6140dd799f 100644 --- a/doc/classes/AnimationNodeStateMachine.xml +++ b/doc/classes/AnimationNodeStateMachine.xml @@ -39,12 +39,6 @@ Adds a transition between the given nodes. </description> </method> - <method name="get_end_node" qualifiers="const"> - <return type="String" /> - <description> - Returns the graph's end node. - </description> - </method> <method name="get_graph_offset" qualifiers="const"> <return type="Vector2" /> <description> @@ -72,12 +66,6 @@ Returns the given node's coordinates. Used for display in the editor. </description> </method> - <method name="get_start_node" qualifiers="const"> - <return type="String" /> - <description> - Returns the graph's end node. - </description> - </method> <method name="get_transition" qualifiers="const"> <return type="AnimationNodeStateMachineTransition" /> <argument index="0" name="idx" type="int" /> @@ -157,13 +145,6 @@ <description> </description> </method> - <method name="set_end_node"> - <return type="void" /> - <argument index="0" name="name" type="StringName" /> - <description> - Sets the given node as the graph end point. - </description> - </method> <method name="set_graph_offset"> <return type="void" /> <argument index="0" name="offset" type="Vector2" /> @@ -179,12 +160,5 @@ Sets the node's coordinates. Used for display in the editor. </description> </method> - <method name="set_start_node"> - <return type="void" /> - <argument index="0" name="name" type="StringName" /> - <description> - Sets the given node as the graph start point. - </description> - </method> </methods> </class> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 4b6f6eec67..f3e2c4b308 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -59,6 +59,7 @@ <members> <member name="albedo_color" type="Color" setter="set_albedo" getter="get_albedo" default="Color(1, 1, 1, 1)"> The material's base color. + [b]Note:[/b] If [member detail_enabled] is [code]true[/code] and a [member detail_albedo] texture is specified, [member albedo_color] will [i]not[/i] modulate the detail texture. This can be used to color partial areas of a material by not specifying an albedo texture and using a transparent [member detail_albedo] texture instead. </member> <member name="albedo_tex_force_srgb" type="bool" setter="set_flag" getter="get_flag" default="false"> Forces a conversion of the [member albedo_texture] from sRGB space to linear space. @@ -148,19 +149,20 @@ Determines when depth rendering takes place. See [enum DepthDrawMode]. See also [member transparency]. </member> <member name="detail_albedo" type="Texture2D" setter="set_texture" getter="get_texture"> - Texture that specifies the color of the detail overlay. + Texture that specifies the color of the detail overlay. [member detail_albedo]'s alpha channel is used as a mask, even when the material is opaque. To use a dedicated texture as a mask, see [member detail_mask]. + [b]Note:[/b] [member detail_albedo] is [i]not[/i] modulated by [member albedo_color]. </member> <member name="detail_blend_mode" type="int" setter="set_detail_blend_mode" getter="get_detail_blend_mode" enum="BaseMaterial3D.BlendMode" default="0"> Specifies how the [member detail_albedo] should blend with the current [code]ALBEDO[/code]. See [enum BlendMode] for options. </member> <member name="detail_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> - If [code]true[/code], enables the detail overlay. Detail is a second texture that gets mixed over the surface of the object based on [member detail_mask]. This can be used to add variation to objects, or to blend between two different albedo/normal textures. + If [code]true[/code], enables the detail overlay. Detail is a second texture that gets mixed over the surface of the object based on [member detail_mask] and [member detail_albedo]'s alpha channel. This can be used to add variation to objects, or to blend between two different albedo/normal textures. </member> <member name="detail_mask" type="Texture2D" setter="set_texture" getter="get_texture"> - Texture used to specify how the detail textures get blended with the base textures. + Texture used to specify how the detail textures get blended with the base textures. [member detail_mask] can be used together with [member detail_albedo]'s alpha channel (if any). </member> <member name="detail_normal" type="Texture2D" setter="set_texture" getter="get_texture"> - Texture that specifies the per-pixel normal of the detail overlay. + Texture that specifies the per-pixel normal of the detail overlay. The [member detail_normal] texture only uses the red and green channels; the blue and alpha channels are ignored. The normal read from [member detail_normal] is oriented around the surface normal provided by the [Mesh]. [b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. </member> <member name="detail_uv_layer" type="int" setter="set_detail_uv" getter="get_detail_uv" enum="BaseMaterial3D.DetailUV" default="0"> @@ -262,9 +264,10 @@ The strength of the normal map's effect. </member> <member name="normal_texture" type="Texture2D" setter="set_texture" getter="get_texture"> - Texture used to specify the normal at a given pixel. The [code]normal_texture[/code] only uses the red and green channels; the blue and alpha channels are ignored. The normal read from [code]normal_texture[/code] is oriented around the surface normal provided by the [Mesh]. + Texture used to specify the normal at a given pixel. The [member normal_texture] only uses the red and green channels; the blue and alpha channels are ignored. The normal read from [member normal_texture] is oriented around the surface normal provided by the [Mesh]. [b]Note:[/b] The mesh must have both normals and tangents defined in its vertex data. Otherwise, the normal map won't render correctly and will only appear to darken the whole surface. If creating geometry with [SurfaceTool], you can use [method SurfaceTool.generate_normals] and [method SurfaceTool.generate_tangents] to automatically generate normals and tangents respectively. [b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. + [b]Note:[/b] If [member detail_enabled] is [code]true[/code], the [member detail_albedo] texture is drawn [i]below[/i] the [member normal_texture]. To display a normal map [i]above[/i] the [member detail_albedo] texture, use [member detail_normal] instead. </member> <member name="orm_texture" type="Texture2D" setter="set_texture" getter="get_texture"> </member> @@ -709,7 +712,7 @@ Used to read from the alpha channel of a texture. </constant> <constant name="TEXTURE_CHANNEL_GRAYSCALE" value="4" enum="TextureChannel"> - Currently unused. + Used to read from the linear (non-perceptual) average of the red, green and blue channels of a texture. </constant> <constant name="EMISSION_OP_ADD" value="0" enum="EmissionOperator"> Adds the emission color to the color from the emission texture. diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index ede3a1e199..cec504584c 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -104,6 +104,19 @@ <description> </description> </method> + <method name="get_display_cutouts" qualifiers="const"> + <return type="Array" /> + <description> + Returns an [Array] of [Rect2], each of which is the bounding rectangle for a display cutout or notch. These are non-functional areas on edge-to-edge screens used by cameras and sensors. Returns an empty array if the device does not have cutouts. See also [method get_display_safe_area]. + [b]Note:[/b] Currently only implemented on Android. Other platforms will return an empty array even if they do have display cutouts or notches. + </description> + </method> + <method name="get_display_safe_area" qualifiers="const"> + <return type="Rect2i" /> + <description> + Returns the unobscured area of the display where interactive controls should be rendered. See also [method get_display_cutouts]. + </description> + </method> <method name="get_name" qualifiers="const"> <return type="String" /> <description> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index e5e7efd315..9da360915b 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -51,16 +51,17 @@ The global color saturation value of the rendered scene (default value is 1). Effective only if [code]adjustment_enabled[/code] is [code]true[/code]. </member> <member name="ambient_light_color" type="Color" setter="set_ambient_light_color" getter="get_ambient_light_color" default="Color(0, 0, 0, 1)"> - The ambient light's [Color]. + The ambient light's [Color]. Only effective if [member ambient_light_sky_contribution] is lower than [code]1.0[/code] (exclusive). </member> <member name="ambient_light_energy" type="float" setter="set_ambient_light_energy" getter="get_ambient_light_energy" default="1.0"> - The ambient light's energy. The higher the value, the stronger the light. + The ambient light's energy. The higher the value, the stronger the light. Only effective if [member ambient_light_sky_contribution] is lower than [code]1.0[/code] (exclusive). </member> <member name="ambient_light_sky_contribution" type="float" setter="set_ambient_light_sky_contribution" getter="get_ambient_light_sky_contribution" default="1.0"> Defines the amount of light that the sky brings on the scene. A value of [code]0.0[/code] means that the sky's light emission has no effect on the scene illumination, thus all ambient illumination is provided by the ambient light. On the contrary, a value of [code]1.0[/code] means that [i]all[/i] the light that affects the scene is provided by the sky, thus the ambient light parameter has no effect on the scene. [b]Note:[/b] [member ambient_light_sky_contribution] is internally clamped between [code]0.0[/code] and [code]1.0[/code] (inclusive). </member> <member name="ambient_light_source" type="int" setter="set_ambient_source" getter="get_ambient_source" enum="Environment.AmbientSource" default="0"> + The ambient light source to use for rendering materials and global illumination. </member> <member name="auto_exposure_enabled" type="bool" setter="set_tonemap_auto_exposure_enabled" getter="is_tonemap_auto_exposure_enabled" default="false"> If [code]true[/code], enables the tonemapping auto exposure mode of the scene renderer. If [code]true[/code], the renderer will automatically determine the exposure setting to adapt to the scene's illumination and the observed light. @@ -97,6 +98,7 @@ This is useful to simulate [url=https://en.wikipedia.org/wiki/Aerial_perspective]aerial perspective[/url] in large scenes with low density fog. However, it is not very useful for high-density fog, as the sky will shine through. When set to [code]1.0[/code], the fog color comes completely from the [Sky]. If set to [code]0.0[/code], aerial perspective is disabled. </member> <member name="fog_density" type="float" setter="set_fog_density" getter="get_fog_density" default="0.001"> + The exponential fog density to use. Higher values result in a more dense fog. </member> <member name="fog_enabled" type="bool" setter="set_fog_enabled" getter="is_fog_enabled" default="false"> If [code]true[/code], fog effects are enabled. @@ -108,10 +110,13 @@ The density used to increase fog as height decreases. To make fog increase as height increases, use a negative value. </member> <member name="fog_light_color" type="Color" setter="set_fog_light_color" getter="get_fog_light_color" default="Color(0.5, 0.6, 0.7, 1)"> + The fog's color. </member> <member name="fog_light_energy" type="float" setter="set_fog_light_energy" getter="get_fog_light_energy" default="1.0"> + The fog's brightness. Higher values result in brighter fog. </member> <member name="fog_sun_scatter" type="float" setter="set_fog_sun_scatter" getter="get_fog_sun_scatter" default="0.0"> + If set above [code]0.0[/code], renders the scene's directional light(s) in the fog color depending on the view angle. This can be used to give the impression that the sun is "piercing" through the fog. </member> <member name="glow_blend_mode" type="int" setter="set_glow_blend_mode" getter="get_glow_blend_mode" enum="Environment.GlowBlendMode" default="2"> The glow blending mode. @@ -132,7 +137,7 @@ The lower threshold of the HDR glow. When using the OpenGL renderer (which doesn't support HDR), this needs to be below [code]1.0[/code] for glow to be visible. A value of [code]0.9[/code] works well in this case. </member> <member name="glow_intensity" type="float" setter="set_glow_intensity" getter="get_glow_intensity" default="0.8"> - The overall brightness multiplier of the glow effect. When using the OpenGL renderer, this should be increased to 1.5 to compensate for the lack of HDR rendering. + The overall brightness multiplier of the glow effect. When using the OpenGL renderer, this should be increased to [code]1.5[/code] to compensate for the lack of HDR rendering. </member> <member name="glow_levels/1" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0"> The intensity of the 1st level of glow. This is the most "local" level (least blurry). @@ -163,6 +168,7 @@ How strong of an impact the [member glow_map] should have on the overall glow effect. A strength of [code]0.0[/code] means the glow map has no effect on the overall glow effect. A strength of [code]1.0[/code] means the glow has a full effect on the overall glow effect (and can turn off glow entirely in specific areas of the screen if the glow map has black areas). </member> <member name="glow_mix" type="float" setter="set_glow_mix" getter="get_glow_mix" default="0.05"> + When using the [constant GLOW_BLEND_MODE_MIX] [member glow_blend_mode], this controls how much the source image is blended with the glow layer. A value of [code]0.0[/code] makes the glow rendering invisible, while a value of [code]1.0[/code] is equivalent to [constant GLOW_BLEND_MODE_REPLACE]. </member> <member name="glow_normalized" type="bool" setter="set_glow_normalized" getter="is_glow_normalized" default="false"> If [code]true[/code], glow levels will be normalized so that summed together their intensities equal [code]1.0[/code]. @@ -171,10 +177,15 @@ The strength of the glow effect. This applies as the glow is blurred across the screen and increases the distance and intensity of the blur. When using the OpenGL renderer, this should be increased to 1.3 to compensate for the lack of HDR rendering. </member> <member name="reflected_light_source" type="int" setter="set_reflection_source" getter="get_reflection_source" enum="Environment.ReflectionSource" default="0"> + The reflected (specular) light source. </member> <member name="sdfgi_bounce_feedback" type="float" setter="set_sdfgi_bounce_feedback" getter="get_sdfgi_bounce_feedback" default="0.5"> + The energy multiplier applied to light every time it bounces from a surface when using SDFGI. Values greater than [code]0.0[/code] will simulate multiple bounces, resulting in a more realistic appearance. Increasing [member sdfgi_bounce_feedback] generally has no performance impact. See also [member sdfgi_energy]. + [b]Note:[/b] Values greater than [code]0.5[/code] can cause infinite feedback loops and should be avoided in scenes with bright materials. + [b]Note:[/b] If [member sdfgi_bounce_feedback] is [code]0.0[/code], indirect lighting will not be represented in reflections as light will only bounce one time. </member> <member name="sdfgi_cascade0_distance" type="float" setter="set_sdfgi_cascade0_distance" getter="get_sdfgi_cascade0_distance" default="12.8"> + [b]Note:[/b] This property is linked to [member sdfgi_min_cell_size] and [member sdfgi_max_distance]. Changing its value will automatically change those properties as well. </member> <member name="sdfgi_cascades" type="int" setter="set_sdfgi_cascades" getter="get_sdfgi_cascades" default="4"> The number of cascades to use for SDFGI (between 1 and 8). A higher number of cascades allows displaying SDFGI further away while preserving detail up close, at the cost of performance. When using SDFGI on small-scale levels, [member sdfgi_cascades] can often be decreased between [code]1[/code] and [code]4[/code] to improve performance. @@ -185,27 +196,39 @@ [b]Note:[/b] Meshes should have sufficiently thick walls to avoid light leaks (avoid one-sided walls). For interior levels, enclose your level geometry in a sufficiently large box and bridge the loops to close the mesh. </member> <member name="sdfgi_energy" type="float" setter="set_sdfgi_energy" getter="get_sdfgi_energy" default="1.0"> + The energy multiplier to use for SDFGI. Higher values will result in brighter indirect lighting and reflections. See also [member sdfgi_bounce_feedback]. </member> <member name="sdfgi_max_distance" type="float" setter="set_sdfgi_max_distance" getter="get_sdfgi_max_distance" default="204.8"> + The maximum distance at which SDFGI is visible. Beyond this distance, environment lighting or other sources of GI such as [ReflectionProbe] will be used as a fallback. + [b]Note:[/b] This property is linked to [member sdfgi_min_cell_size] and [member sdfgi_cascade0_distance]. Changing its value will automatically change those properties as well. </member> <member name="sdfgi_min_cell_size" type="float" setter="set_sdfgi_min_cell_size" getter="get_sdfgi_min_cell_size" default="0.2"> + The cell size to use for the closest SDFGI cascade (in 3D units). Lower values allow SDFGI to be more precise up close, at the cost of making SDFGI updates more demanding. This can cause stuttering when the camera moves fast. Higher values allow SDFGI to cover more ground, while also reducing the performance impact of SDFGI updates. + [b]Note:[/b] This property is linked to [member sdfgi_max_distance] and [member sdfgi_cascade0_distance]. Changing its value will automatically change those properties as well. </member> <member name="sdfgi_normal_bias" type="float" setter="set_sdfgi_normal_bias" getter="get_sdfgi_normal_bias" default="1.1"> + The normal bias to use for SDFGI probes. Increasing this value can reduce visible streaking artifacts on sloped surfaces, at the cost of increased light leaking. </member> <member name="sdfgi_probe_bias" type="float" setter="set_sdfgi_probe_bias" getter="get_sdfgi_probe_bias" default="1.1"> + The constant bias to use for SDFGI probes. Increasing this value can reduce visible streaking artifacts on sloped surfaces, at the cost of increased light leaking. </member> <member name="sdfgi_read_sky_light" type="bool" setter="set_sdfgi_read_sky_light" getter="is_sdfgi_reading_sky_light" default="true"> + If [code]true[/code], SDFGI takes the environment lighting into account. This should be set to [code]false[/code] for interior scenes. </member> <member name="sdfgi_use_occlusion" type="bool" setter="set_sdfgi_use_occlusion" getter="is_sdfgi_using_occlusion" default="false"> + If [code]true[/code], SDFGI uses an occlusion detection approach to reduce light leaking. Occlusion may however introduce dark blotches in certain spots, which may be undesired in mostly outdoor scenes. [member sdfgi_use_occlusion] has a performance impact and should only be enabled when needed. </member> <member name="sdfgi_y_scale" type="int" setter="set_sdfgi_y_scale" getter="get_sdfgi_y_scale" enum="Environment.SDFGIYScale" default="1"> + The Y scale to use for SDFGI cells. Lower values will result in SDFGI cells being packed together more closely on the Y axis. This is used to balance between quality and covering a lot of vertical ground. [member sdfgi_y_scale] should be set depending on how vertical your scene is (and how fast your camera may move on the Y axis). </member> <member name="sky" type="Sky" setter="set_sky" getter="get_sky"> The [Sky] resource used for this [Environment]. </member> <member name="sky_custom_fov" type="float" setter="set_sky_custom_fov" getter="get_sky_custom_fov" default="0.0"> + If set to a value greater than [code]0.0[/code], overrides the field of view to use for sky rendering. If set to [code]0.0[/code], the same FOV as the current [Camera3D] is used for sky rendering. </member> <member name="sky_rotation" type="Vector3" setter="set_sky_rotation" getter="get_sky_rotation" default="Vector3(0, 0, 0)"> + The rotation to use for sky rendering. </member> <member name="ssao_ao_channel_affect" type="float" setter="set_ssao_ao_channel_affect" getter="get_ssao_ao_channel_affect" default="0.0"> The screen-space ambient occlusion intensity on materials that have an AO texture defined. Values higher than [code]0[/code] will make the SSAO effect visible in areas darkened by AO textures. @@ -265,13 +288,13 @@ The maximum number of steps for screen-space reflections. Higher values are slower. </member> <member name="tonemap_exposure" type="float" setter="set_tonemap_exposure" getter="get_tonemap_exposure" default="1.0"> - The default exposure used for tonemapping. + The default exposure used for tonemapping. Higher values result in a brighter image. See also [member tonemap_white]. </member> <member name="tonemap_mode" type="int" setter="set_tonemapper" getter="get_tonemapper" enum="Environment.ToneMapper" default="0"> The tonemapping mode to use. Tonemapping is the process that "converts" HDR values to be suitable for rendering on a LDR display. (Godot doesn't support rendering on HDR displays yet.) </member> <member name="tonemap_white" type="float" setter="set_tonemap_white" getter="get_tonemap_white" default="1.0"> - The white reference value for tonemapping. Only effective if the [member tonemap_mode] isn't set to [constant TONE_MAPPER_LINEAR]. + The white reference value for tonemapping (also called "whitepoint"). Higher values can make highlights look less blown out, and will also slightly darken the whole scene as a result. Only effective if the [member tonemap_mode] isn't set to [constant TONE_MAPPER_LINEAR]. See also [member tonemap_exposure]. </member> <member name="volumetric_fog_albedo" type="Color" setter="set_volumetric_fog_albedo" getter="get_volumetric_fog_albedo" default="Color(1, 1, 1, 1)"> The [Color] of the volumetric fog when interacting with lights. Mist and fog have an albedo close to [code]Color(1, 1, 1, 1)[/code] while smoke has a darker albedo. @@ -336,10 +359,10 @@ Gather ambient light from whichever source is specified as the background. </constant> <constant name="AMBIENT_SOURCE_DISABLED" value="1" enum="AmbientSource"> - Disable ambient light. + Disable ambient light. This provides a slight performance boost over [constant AMBIENT_SOURCE_SKY]. </constant> <constant name="AMBIENT_SOURCE_COLOR" value="2" enum="AmbientSource"> - Specify a specific [Color] for ambient light. + Specify a specific [Color] for ambient light. This provides a slight performance boost over [constant AMBIENT_SOURCE_SKY]. </constant> <constant name="AMBIENT_SOURCE_SKY" value="3" enum="AmbientSource"> Gather ambient light from the [Sky] regardless of what the background is. @@ -348,22 +371,23 @@ Use the background for reflections. </constant> <constant name="REFLECTION_SOURCE_DISABLED" value="1" enum="ReflectionSource"> - Disable reflections. + Disable reflections. This provides a slight performance boost over other options. </constant> <constant name="REFLECTION_SOURCE_SKY" value="2" enum="ReflectionSource"> Use the [Sky] for reflections regardless of what the background is. </constant> <constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper"> - Linear tonemapper operator. Reads the linear data and passes it on unmodified. + Linear tonemapper operator. Reads the linear data and passes it on unmodified. This can cause bright lighting to look blown out, with noticeable clipping in the output colors. </constant> <constant name="TONE_MAPPER_REINHARDT" value="1" enum="ToneMapper"> - Reinhardt tonemapper operator. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code]. + Reinhardt tonemapper operator. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code]. This avoids clipping bright highlights, but the resulting image can look a bit dull. </constant> <constant name="TONE_MAPPER_FILMIC" value="2" enum="ToneMapper"> - Filmic tonemapper operator. + Filmic tonemapper operator. This avoids clipping bright highlights, with a resulting image that usually looks more vivid than [constant TONE_MAPPER_REINHARDT]. </constant> <constant name="TONE_MAPPER_ACES" value="3" enum="ToneMapper"> - Academy Color Encoding System tonemapper operator. + Use the Academy Color Encoding System tonemapper. ACES is slightly more expensive than other options, but it handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. ACES typically has a more contrasted output compared to [constant TONE_MAPPER_REINHARDT] and [constant TONE_MAPPER_FILMIC]. + [b]Note:[/b] This tonemapping operator is called "ACES Fitted" in Godot 3.x. </constant> <constant name="GLOW_BLEND_MODE_ADDITIVE" value="0" enum="GlowBlendMode"> Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources. @@ -381,10 +405,13 @@ Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect. </constant> <constant name="SDFGI_Y_SCALE_50_PERCENT" value="0" enum="SDFGIYScale"> + Use 50% scale for SDFGI on the Y (vertical) axis. SDFGI cells will be twice as short as they are wide. This allows providing increased GI detail and reduced light leaking with thin floors and ceilings. This is usually the best choice for scenes that don't feature much verticality. </constant> <constant name="SDFGI_Y_SCALE_75_PERCENT" value="1" enum="SDFGIYScale"> + Use 75% scale for SDFGI on the Y (vertical) axis. This is a balance between the 50% and 100% SDFGI Y scales. </constant> <constant name="SDFGI_Y_SCALE_100_PERCENT" value="2" enum="SDFGIYScale"> + Use 100% scale for SDFGI on the Y (vertical) axis. SDFGI cells will be as tall as they are wide. This is usually the best choice for highly vertical scenes. The downside is that light leaking may become more noticeable with thin floors and ceilings. </constant> </constants> </class> diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml index fbb53715c4..1bd52ab2dc 100644 --- a/doc/classes/Label3D.xml +++ b/doc/classes/Label3D.xml @@ -98,12 +98,22 @@ <member name="outline_modulate" type="Color" setter="set_outline_modulate" getter="get_outline_modulate" default="Color(0, 0, 0, 1)"> The tint of [Font]'s outline. </member> + <member name="outline_render_priority" type="int" setter="set_outline_render_priority" getter="get_outline_render_priority" default="-1"> + Sets the render priority for the text outline. Higher priority objects will be sorted in front of lower priority objects. + [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). + </member> <member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0"> Text outline size. </member> <member name="pixel_size" type="float" setter="set_pixel_size" getter="get_pixel_size" default="0.01"> The size of one pixel's width on the label to scale it in 3D. </member> + <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" default="0"> + Sets the render priority for the text. Higher priority objects will be sorted in front of lower priority objects. + [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). + </member> <member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag" default="false"> If [code]true[/code], the [Light3D] in the [Environment] has effects on the label. </member> diff --git a/doc/classes/NavigationRegion2D.xml b/doc/classes/NavigationRegion2D.xml index b1165174a2..5cd2e035b6 100644 --- a/doc/classes/NavigationRegion2D.xml +++ b/doc/classes/NavigationRegion2D.xml @@ -10,6 +10,14 @@ </description> <tutorials> </tutorials> + <methods> + <method name="get_region_rid" qualifiers="const"> + <return type="RID" /> + <description> + Returns the [RID] of this region on the [NavigationServer2D]. Combined with [method NavigationServer2D.map_get_closest_point_owner] can be used to identify the [NavigationRegion2D] closest to a point on the merged navigation map. + </description> + </method> + </methods> <members> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> Determines if the [NavigationRegion2D] is enabled or disabled. diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml index e007633a1e..b27410ed74 100644 --- a/doc/classes/NavigationRegion3D.xml +++ b/doc/classes/NavigationRegion3D.xml @@ -16,6 +16,12 @@ Bakes the [NavigationMesh]. The baking is done in a separate thread because navigation baking is not a cheap operation. This can be done at runtime. When it is completed, it automatically sets the new [NavigationMesh]. </description> </method> + <method name="get_region_rid" qualifiers="const"> + <return type="RID" /> + <description> + Returns the [RID] of this region on the [NavigationServer3D]. Combined with [method NavigationServer3D.map_get_closest_point_owner] can be used to identify the [NavigationRegion3D] closest to a point on the merged navigation map. + </description> + </method> </methods> <members> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index f7a3be48cf..42844794b0 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -157,7 +157,7 @@ <description> Connects a [code]signal[/code] to a [code]callable[/code]. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the [Callable]'s method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants. [b]Note:[/b] This method is the legacy implementation for connecting signals. The recommended modern approach is to use [method Signal.connect] and to use [method Callable.bind] to add and validate parameter binds. Both syntaxes are shown below. - A signal can only be connected once to a [Callable]. It will throw an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections. + A signal can only be connected once to a [Callable]. It will print an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections. If the callable's target is destroyed in the game's lifecycle, the connection will be lost. [b]Examples with recommended syntax:[/b] Connecting signals is one of the most common operations in Godot and the API gives many options to do so, which are described further down. The code block below shows the recommended approach for both GDScript and C#. @@ -245,7 +245,7 @@ } [/csharp] [/codeblocks] - While all options have the same outcome ([code]button[/code]'s [signal BaseButton.button_down] signal will be connected to [code]_on_button_down[/code]), option 3 offers the best validation: it will throw a compile-time error if either the [code]button_down[/code] signal or the [code]_on_button_down[/code] callable are undefined. On the other hand, option 2 only relies on string names and will only be able to validate either names at runtime: it will throw a runtime error if [code]"button_down"[/code] doesn't correspond to a signal, or if [code]"_on_button_down"[/code] is not a registered method in the object [code]self[/code]. The main reason for using options 1, 2, or 4 would be if you actually need to use strings (e.g. to connect signals programmatically based on strings read from a configuration file). Otherwise, option 3 is the recommended (and fastest) method. + While all options have the same outcome ([code]button[/code]'s [signal BaseButton.button_down] signal will be connected to [code]_on_button_down[/code]), option 3 offers the best validation: it will print a compile-time error if either the [code]button_down[/code] signal or the [code]_on_button_down[/code] callable are undefined. On the other hand, option 2 only relies on string names and will only be able to validate either names at runtime: it will print a runtime error if [code]"button_down"[/code] doesn't correspond to a signal, or if [code]"_on_button_down"[/code] is not a registered method in the object [code]self[/code]. The main reason for using options 1, 2, or 4 would be if you actually need to use strings (e.g. to connect signals programmatically based on strings read from a configuration file). Otherwise, option 3 is the recommended (and fastest) method. [b]Parameter bindings and passing:[/b] For legacy or language-specific reasons, there are also several ways to bind parameters to signals. One can pass a [code]binds[/code] [Array] to [method Object.connect] or [method Signal.connect], or use the recommended [method Callable.bind] method to create a new callable from an existing one, with the given parameter binds. One can also pass additional parameters when emitting the signal with [method emit_signal]. The examples below show the relationship between those two types of parameters. @@ -297,7 +297,7 @@ <argument index="1" name="callable" type="Callable" /> <description> Disconnects a [code]signal[/code] from a given [code]callable[/code]. - If you try to disconnect a connection that does not exist, the method will throw an error. Use [method is_connected] to ensure that the connection exists. + If you try to disconnect a connection that does not exist, the method will print an error. Use [method is_connected] to ensure that the connection exists. </description> </method> <method name="emit_signal" qualifiers="vararg"> diff --git a/doc/classes/Performance.xml b/doc/classes/Performance.xml index 3b8e481519..bcaf38fd06 100644 --- a/doc/classes/Performance.xml +++ b/doc/classes/Performance.xml @@ -69,7 +69,7 @@ [/codeblocks] The debugger calls the callable to get the value of custom monitor. The callable must return a number. Callables are called with arguments supplied in argument array. - [b]Note:[/b] It throws an error if given id is already present. + [b]Note:[/b] It prints an error if given id is already present. </description> </method> <method name="get_custom_monitor"> @@ -77,7 +77,7 @@ <argument index="0" name="id" type="StringName" /> <description> Returns the value of custom monitor with given id. The callable is called to get the value of custom monitor. - [b]Note:[/b] It throws an error if the given id is absent. + [b]Note:[/b] It prints an error if the given id is absent. </description> </method> <method name="get_custom_monitor_names"> @@ -119,7 +119,7 @@ <argument index="0" name="id" type="StringName" /> <description> Removes the custom monitor with given id. - [b]Note:[/b] It throws an error if the given id is already absent. + [b]Note:[/b] It prints an error if the given id is already absent. </description> </method> </methods> diff --git a/doc/classes/PhysicalSkyMaterial.xml b/doc/classes/PhysicalSkyMaterial.xml index 3e85074e41..716eaaeeba 100644 --- a/doc/classes/PhysicalSkyMaterial.xml +++ b/doc/classes/PhysicalSkyMaterial.xml @@ -12,7 +12,7 @@ </tutorials> <members> <member name="dither_strength" type="float" setter="set_dither_strength" getter="get_dither_strength" default="1.0"> - Sets the amount of dithering to use. Dithering helps reduce banding that appears from the smooth changes in color in the sky. Use the lowest value possible, higher amounts may add fuzziness to the sky. + The amount of dithering to use. Dithering helps reduce banding that appears from the smooth changes in color in the sky. Use the lowest value possible for your given sky settings, as higher amounts may add fuzziness to the sky. </member> <member name="exposure" type="float" setter="set_exposure" getter="get_exposure" default="0.1"> Sets the exposure of the sky. Higher exposure values make the entire sky brighter. diff --git a/doc/classes/ProceduralSkyMaterial.xml b/doc/classes/ProceduralSkyMaterial.xml index bf33232406..88283bcf24 100644 --- a/doc/classes/ProceduralSkyMaterial.xml +++ b/doc/classes/ProceduralSkyMaterial.xml @@ -11,6 +11,9 @@ <tutorials> </tutorials> <members> + <member name="dither_strength" type="float" setter="set_dither_strength" getter="get_dither_strength" default="1.0"> + The amount of dithering to use. Dithering helps reduce banding that appears from the smooth changes in color in the sky. Use the lowest value possible for your given sky settings, as higher amounts may add fuzziness to the sky. + </member> <member name="ground_bottom_color" type="Color" setter="set_ground_bottom_color" getter="get_ground_bottom_color" default="Color(0.2, 0.169, 0.133, 1)"> Color of the ground at the bottom. Blends with [member ground_horizon_color]. </member> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 5bb83c8ffd..d21e2b5bca 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -4159,16 +4159,17 @@ Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect. </constant> <constant name="ENV_TONE_MAPPER_LINEAR" value="0" enum="EnvironmentToneMapper"> - Output color as they came in. + Output color as they came in. This can cause bright lighting to look blown out, with noticeable clipping in the output colors. </constant> <constant name="ENV_TONE_MAPPER_REINHARD" value="1" enum="EnvironmentToneMapper"> - Use the Reinhard tonemapper. + Use the Reinhard tonemapper. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code]. This avoids clipping bright highlights, but the resulting image can look a bit dull. </constant> <constant name="ENV_TONE_MAPPER_FILMIC" value="2" enum="EnvironmentToneMapper"> - Use the filmic tonemapper. + Use the filmic tonemapper. This avoids clipping bright highlights, with a resulting image that usually looks more vivid than [constant ENV_TONE_MAPPER_REINHARD]. </constant> <constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper"> - Use the ACES tonemapper. + Use the Academy Color Encoding System tonemapper. ACES is slightly more expensive than other options, but it handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. ACES typically has a more contrasted output compared to [constant ENV_TONE_MAPPER_REINHARD] and [constant ENV_TONE_MAPPER_FILMIC]. + [b]Note:[/b] This tonemapping operator is called "ACES Fitted" in Godot 3.x. </constant> <constant name="ENV_SSR_ROUGHNESS_QUALITY_DISABLED" value="0" enum="EnvironmentSSRRoughnessQuality"> Lowest quality of roughness filter for screen-space reflections. Rough materials will not have blurrier screen-space reflections compared to smooth (non-rough) materials. This is the fastest option. diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index ddff766b17..970f5125cd 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -91,6 +91,7 @@ <return type="Node" /> <argument index="0" name="group" type="StringName" /> <description> + Returns the first node in the specified group, or [code]null[/code] if the group is empty or does not exist. </description> </method> <method name="get_frame" qualifiers="const"> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 9733fa3a26..41b02b6dc9 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -75,6 +75,11 @@ <member name="pixel_size" type="float" setter="set_pixel_size" getter="get_pixel_size" default="0.01"> The size of one pixel's width on the sprite to scale it in 3D. </member> + <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" default="0"> + Sets the render priority for the sprite. Higher priority objects will be sorted in front of lower priority objects. + [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). + </member> <member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag" default="false"> If [code]true[/code], the [Light3D] in the [Environment] has effects on the sprite. </member> diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 0aa486cbb5..3858f2bbd0 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -53,7 +53,7 @@ public: // RasterizerCanvasGLES3 *canvas; // RasterizerSceneGLES3 *scene; - GLES3::Config *config; + GLES3::Config *config = nullptr; struct Resources { GLuint mipmap_blur_fbo; diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index 14579e6535..15281064af 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -141,7 +141,7 @@ private: static bool shader_cache_save_debug; bool shader_cache_dir_valid = false; - GLint max_image_units; + GLint max_image_units = 0; enum StageType { STAGE_TYPE_VERTEX, diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index bb4352ce9a..0646881b72 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -51,47 +51,47 @@ private: static Config *singleton; public: - bool use_nearest_mip_filter; - bool use_skeleton_software; + bool use_nearest_mip_filter = false; + bool use_skeleton_software = false; - int max_vertex_texture_image_units; - int max_texture_image_units; - int max_texture_size; - int max_uniform_buffer_size; + int max_vertex_texture_image_units = 0; + int max_texture_image_units = 0; + int max_texture_size = 0; + int max_uniform_buffer_size = 0; // TODO implement wireframe in OpenGL // bool generate_wireframes; Set<String> extensions; - bool float_texture_supported; - bool s3tc_supported; - bool latc_supported; - bool rgtc_supported; - bool bptc_supported; - bool etc_supported; - bool etc2_supported; - bool srgb_decode_supported; - - bool keep_original_textures; - - bool force_vertex_shading; - - bool use_rgba_2d_shadows; - bool use_rgba_3d_shadows; - - bool support_32_bits_indices; - bool support_write_depth; - bool support_half_float_vertices; - bool support_npot_repeat_mipmap; - bool support_depth_cubemaps; - bool support_shadow_cubemaps; - bool support_anisotropic_filter; - float anisotropic_level; - - GLuint depth_internalformat; - GLuint depth_type; - GLuint depth_buffer_internalformat; + bool float_texture_supported = false; + bool s3tc_supported = false; + bool latc_supported = false; + bool rgtc_supported = false; + bool bptc_supported = false; + bool etc_supported = false; + bool etc2_supported = false; + bool srgb_decode_supported = false; + + bool keep_original_textures = false; + + bool force_vertex_shading = false; + + bool use_rgba_2d_shadows = false; + bool use_rgba_3d_shadows = false; + + bool support_32_bits_indices = false; + bool support_write_depth = false; + bool support_half_float_vertices = false; + bool support_npot_repeat_mipmap = false; + bool support_depth_cubemaps = false; + bool support_shadow_cubemaps = false; + bool support_anisotropic_filter = false; + float anisotropic_level = 0.0f; + + GLuint depth_internalformat = 0; + GLuint depth_type = 0; + GLuint depth_buffer_internalformat = 0; // in some cases the legacy render didn't orphan. We will mark these // so the user can switch orphaning off for them. diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 09bd24d011..d14d26346c 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -392,26 +392,60 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy float *gui = (float *)data; if (p_array_size > 0) { - const PackedVector3Array &a = value; - int s = a.size(); + if (value.get_type() == Variant::PACKED_COLOR_ARRAY) { + const PackedColorArray &a = value; + int s = a.size(); - for (int i = 0, j = 0; i < p_array_size; i++, j += 4) { - if (i < s) { - gui[j] = a[i].x; - gui[j + 1] = a[i].y; - gui[j + 2] = a[i].z; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + for (int i = 0, j = 0; i < p_array_size; i++, j += 4) { + if (i < s) { + Color color = a[i]; + if (p_linear_color) { + color = color.srgb_to_linear(); + } + gui[j] = color.r; + gui[j + 1] = color.g; + gui[j + 2] = color.b; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored + } + } else { + const PackedVector3Array &a = value; + int s = a.size(); + + for (int i = 0, j = 0; i < p_array_size; i++, j += 4) { + if (i < s) { + gui[j] = a[i].x; + gui[j + 1] = a[i].y; + gui[j + 2] = a[i].z; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored } - gui[j + 3] = 0; // ignored } } else { - Vector3 v = value; - gui[0] = v.x; - gui[1] = v.y; - gui[2] = v.z; + if (value.get_type() == Variant::COLOR) { + Color v = value; + + if (p_linear_color) { + v = v.srgb_to_linear(); + } + + gui[0] = v.r; + gui[1] = v.g; + gui[2] = v.b; + } else { + Vector3 v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + } } } break; case ShaderLanguage::TYPE_VEC4: { @@ -925,7 +959,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S //value=E.value.default_value; } else { //zero because it was not provided - if (E.value.type == ShaderLanguage::TYPE_VEC4 && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { //colors must be set as black, with alpha as 1.0 _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color); } else { @@ -2198,7 +2232,7 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { } String path = value; - RES resource = ResourceLoader::load(path); + Ref<Resource> resource = ResourceLoader::load(path); ERR_CONTINUE(resource.is_null()); value = resource; } diff --git a/drivers/gles3/texture_loader_gles3.cpp b/drivers/gles3/texture_loader_gles3.cpp index 8c8724686d..ba4ddb3b37 100644 --- a/drivers/gles3/texture_loader_gles3.cpp +++ b/drivers/gles3/texture_loader_gles3.cpp @@ -37,7 +37,7 @@ #include <string.h> -RES ResourceFormatGLES2Texture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatGLES2Texture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { unsigned int width = 8; unsigned int height = 8; diff --git a/drivers/gles3/texture_loader_gles3.h b/drivers/gles3/texture_loader_gles3.h index 54ddf80a96..6873858b89 100644 --- a/drivers/gles3/texture_loader_gles3.h +++ b/drivers/gles3/texture_loader_gles3.h @@ -38,7 +38,7 @@ class ResourceFormatGLES2Texture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp index 8633d2dc4e..704ddca726 100644 --- a/drivers/png/resource_saver_png.cpp +++ b/drivers/png/resource_saver_png.cpp @@ -35,7 +35,7 @@ #include "drivers/png/png_driver_common.h" #include "scene/resources/texture.h" -Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceSaverPNG::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { Ref<ImageTexture> texture = p_resource; ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as PNG."); @@ -72,11 +72,11 @@ Vector<uint8_t> ResourceSaverPNG::save_image_to_buffer(const Ref<Image> &p_img) return buffer; } -bool ResourceSaverPNG::recognize(const RES &p_resource) const { +bool ResourceSaverPNG::recognize(const Ref<Resource> &p_resource) const { return (p_resource.is_valid() && p_resource->is_class("ImageTexture")); } -void ResourceSaverPNG::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceSaverPNG::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { if (Object::cast_to<ImageTexture>(*p_resource)) { p_extensions->push_back("png"); } diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h index f39e52c7ec..1a681faaec 100644 --- a/drivers/png/resource_saver_png.h +++ b/drivers/png/resource_saver_png.h @@ -39,9 +39,9 @@ public: static Error save_image(const String &p_path, const Ref<Image> &p_img); static Vector<uint8_t> save_image_to_buffer(const Ref<Image> &p_img); - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual bool recognize(const RES &p_resource) const; - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual bool recognize(const Ref<Resource> &p_resource) const; + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; ResourceSaverPNG(); }; diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index 4fea7cd154..69530de337 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -46,8 +46,8 @@ class DirAccessUnix : public DirAccess { static Ref<DirAccess> create_fs(); String current_dir; - bool _cisdir; - bool _cishidden; + bool _cisdir = false; + bool _cishidden = false; protected: virtual String fix_unicode_name(const char *p_name) const { return String::utf8(p_name); } diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 3b5e1bf91d..12e2113364 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -429,7 +429,7 @@ String OS_Unix::get_locale() const { return locale; } -Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { +Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { String path = p_path; if (FileAccess::exists(path) && path.is_relative_path()) { @@ -450,6 +450,11 @@ Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror()); + + if (r_resolved_path != nullptr) { + *r_resolved_path = path; + } + return OK; } diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 460ba4b9e1..6116574528 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -55,7 +55,7 @@ public: virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) override; // Should return cryptographycally-safe random bytes. - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 7d9bd19309..219d48a9f5 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -886,8 +886,8 @@ class RenderingDeviceVulkan : public RenderingDevice { DrawList *draw_list = nullptr; // One for regular draw lists, multiple for split. uint32_t draw_list_subpass_count = 0; uint32_t draw_list_count = 0; - VkRenderPass draw_list_render_pass; - VkFramebuffer draw_list_vkframebuffer; + VkRenderPass draw_list_render_pass = VK_NULL_HANDLE; + VkFramebuffer draw_list_vkframebuffer = VK_NULL_HANDLE; #ifdef DEBUG_ENABLED FramebufferFormatID draw_list_framebuffer_format = INVALID_ID; #endif diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 8c0111714c..365ee3c9b0 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -185,27 +185,27 @@ private: */ bool enabled_debug_report = false; - PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT; - PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT; - PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT; - PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT; - PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT; - PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT; - PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT; - PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; - PFN_vkDebugReportMessageEXT DebugReportMessageEXT; - PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; - PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR; - PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR; - PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR; - PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR; - PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR; - PFN_vkQueuePresentKHR fpQueuePresentKHR; - PFN_vkGetRefreshCycleDurationGOOGLE fpGetRefreshCycleDurationGOOGLE; - PFN_vkGetPastPresentationTimingGOOGLE fpGetPastPresentationTimingGOOGLE; + PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT = nullptr; + PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT = nullptr; + PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT = nullptr; + PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT = nullptr; + PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT = nullptr; + PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT = nullptr; + PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT = nullptr; + PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT = nullptr; + PFN_vkDebugReportMessageEXT DebugReportMessageEXT = nullptr; + PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT = nullptr; + PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR = nullptr; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR = nullptr; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR = nullptr; + PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR = nullptr; + PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR = nullptr; + PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR = nullptr; + PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR = nullptr; + PFN_vkQueuePresentKHR fpQueuePresentKHR = nullptr; + PFN_vkGetRefreshCycleDurationGOOGLE fpGetRefreshCycleDurationGOOGLE = nullptr; + PFN_vkGetPastPresentationTimingGOOGLE fpGetPastPresentationTimingGOOGLE = nullptr; VkDebugUtilsMessengerEXT dbg_messenger = VK_NULL_HANDLE; VkDebugReportCallbackEXT dbg_debug_report = VK_NULL_HANDLE; diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h index dcb6502440..f228f66771 100644 --- a/editor/animation_bezier_editor.h +++ b/editor/animation_bezier_editor.h @@ -53,7 +53,7 @@ class AnimationBezierTrackEdit : public Control { float play_position_pos = 0; Ref<Animation> animation; - int selected_track; + int selected_track = 0; Vector<Rect2> view_rects; @@ -98,8 +98,8 @@ class AnimationBezierTrackEdit : public Control { bool moving_selection_attempt = false; IntPair select_single_attempt; bool moving_selection = false; - int moving_selection_from_key; - int moving_selection_from_track; + int moving_selection_from_key = 0; + int moving_selection_from_track = 0; Vector2 moving_selection_offset; @@ -114,7 +114,7 @@ class AnimationBezierTrackEdit : public Control { int moving_handle_track = 0; Vector2 moving_handle_left; Vector2 moving_handle_right; - int moving_handle_mode; // value from Animation::HandleMode + int moving_handle_mode = 0; // value from Animation::HandleMode void _clear_selection(); void _clear_selection_for_anim(const Ref<Animation> &p_anim); @@ -136,8 +136,8 @@ class AnimationBezierTrackEdit : public Control { Rect2 point_rect; Rect2 in_rect; Rect2 out_rect; - int track; - int key; + int track = 0; + int key = 0; }; Vector<EditPoint> edit_points; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index e724d4ccdb..c425613262 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -358,7 +358,7 @@ public: setting = true; undo_redo->create_action(TTR("Anim Change Keyframe Value"), UndoRedo::MERGE_ENDS); - RES prev = animation->audio_track_get_key_stream(track, key); + Ref<Resource> prev = animation->audio_track_get_key_stream(track, key); undo_redo->add_do_method(animation.ptr(), "audio_track_set_key_stream", track, key, stream); undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_stream", track, key, prev); undo_redo->add_do_method(this, "_update_obj", animation); @@ -992,7 +992,7 @@ public: setting = true; undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS); } - RES prev = animation->audio_track_get_key_stream(track, key); + Ref<Resource> prev = animation->audio_track_get_key_stream(track, key); undo_redo->add_do_method(animation.ptr(), "audio_track_set_key_stream", track, key, stream); undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_stream", track, key, prev); update_obj = true; @@ -1886,10 +1886,7 @@ void AnimationTimelineEdit::_bind_methods() { AnimationTimelineEdit::AnimationTimelineEdit() { name_limit = 150 * EDSCALE; - zoom = nullptr; - track_edit = nullptr; - play_position_pos = 0; play_position = memnew(Control); play_position->set_mouse_filter(MOUSE_FILTER_PASS); add_child(play_position); @@ -2531,7 +2528,7 @@ bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant return false; } - RES res; + Ref<Resource> res; Vector<StringName> leftover_path; Node *node = root->get_node_and_resource(animation->track_get_path(track), res, leftover_path); @@ -2692,7 +2689,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const { } break; case Animation::TYPE_AUDIO: { String stream_name = "null"; - RES stream = animation->audio_track_get_key_stream(track, key_idx); + Ref<Resource> stream = animation->audio_track_get_key_stream(track, key_idx); if (stream.is_valid()) { if (stream->get_path().is_resource_file()) { stream_name = stream->get_path().get_file(); @@ -3217,17 +3214,6 @@ void AnimationTrackEdit::_bind_methods() { } AnimationTrackEdit::AnimationTrackEdit() { - undo_redo = nullptr; - timeline = nullptr; - root = nullptr; - path = nullptr; - path_popup = nullptr; - menu = nullptr; - dropping_at = 0; - - select_single_attempt = -1; - - play_position_pos = 0; play_position = memnew(Control); play_position->set_mouse_filter(MOUSE_FILTER_PASS); add_child(play_position); @@ -4128,7 +4114,7 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b return PropertyInfo(); } - RES res; + Ref<Resource> res; Vector<StringName> leftover_path; Node *node = root->get_node_and_resource(path, res, leftover_path, true); @@ -4424,7 +4410,7 @@ void AnimationTrackEditor::_update_tracks() { NodePath path = animation->track_get_path(i); if (root && root->has_node_and_resource(path)) { - RES res; + Ref<Resource> res; NodePath base_path; Vector<StringName> leftover_path; Node *node = root->get_node_and_resource(path, res, leftover_path, true); @@ -5030,7 +5016,7 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) { } break; case Animation::TYPE_AUDIO: { Dictionary ak; - ak["stream"] = RES(); + ak["stream"] = Ref<Resource>(); ak["start_offset"] = 0; ak["end_offset"] = 0; @@ -6029,7 +6015,7 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) { Variant::Type valid_type = Variant::NIL; Object *obj = nullptr; - RES res; + Ref<Resource> res; Vector<StringName> leftover_path; Node *node = root->get_node_and_resource(p_animation->track_get_path(i), res, leftover_path); @@ -6238,8 +6224,6 @@ void AnimationTrackEditor::_pick_track_filter_input(const Ref<InputEvent> &p_ie) } AnimationTrackEditor::AnimationTrackEditor() { - root = nullptr; - undo_redo = EditorNode::get_singleton()->get_undo_redo(); main_panel = memnew(PanelContainer); @@ -6452,8 +6436,6 @@ AnimationTrackEditor::AnimationTrackEditor() { insert_confirm_reset->set_text(TTR("Create RESET Track(s)", "")); insert_confirm_reset->set_pressed(EDITOR_GET("editors/animation/default_create_reset_tracks")); ichb->add_child(insert_confirm_reset); - key_edit = nullptr; - multi_key_edit = nullptr; box_selection = memnew(Control); add_child(box_selection); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 92b203d183..bd66a4b2df 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -54,10 +54,10 @@ class AnimationTimelineEdit : public Range { Ref<Animation> animation; AnimationTrackEdit *track_edit = nullptr; - int name_limit; + int name_limit = 0; Range *zoom = nullptr; Range *h_scroll = nullptr; - float play_position_pos; + float play_position_pos = 0.0f; HBoxContainer *len_hb = nullptr; EditorSpinSlider *length = nullptr; @@ -86,8 +86,8 @@ class AnimationTimelineEdit : public Range { bool dragging_timeline = false; bool dragging_hsize = false; - float dragging_hsize_from; - float dragging_hsize_at; + float dragging_hsize_from = 0.0f; + float dragging_hsize_at = 0.0f; virtual void gui_input(const Ref<InputEvent> &p_event) override; void _track_added(int p_track); @@ -145,17 +145,18 @@ class AnimationTrackEdit : public Control { MENU_KEY_ADD_RESET, MENU_KEY_DELETE }; + AnimationTimelineEdit *timeline = nullptr; UndoRedo *undo_redo = nullptr; Popup *path_popup = nullptr; LineEdit *path = nullptr; Node *root = nullptr; Control *play_position = nullptr; //separate control used to draw so updates for only position changed are much faster - float play_position_pos; + float play_position_pos = 0.0f; NodePath node_path; Ref<Animation> animation; - int track; + int track = 0; Rect2 check_rect; Rect2 path_rect; @@ -187,12 +188,12 @@ class AnimationTrackEdit : public Control { Ref<Texture2D> _get_key_type_icon() const; - mutable int dropping_at; - float insert_at_pos; + mutable int dropping_at = 0; + float insert_at_pos = 0.0f; bool moving_selection_attempt = false; - int select_single_attempt; + int select_single_attempt = -1; bool moving_selection = false; - float moving_selection_from_ofs; + float moving_selection_from_ofs = 0.0f; bool in_group = false; AnimationTrackEditor *editor = nullptr; @@ -341,7 +342,7 @@ class AnimationTrackEditor : public VBoxContainer { PropertySelector *prop_selector = nullptr; PropertySelector *method_selector = nullptr; SceneTreeDialog *pick_track = nullptr; - int adding_track_type; + int adding_track_type = 0; NodePath adding_track_path; bool keying = false; @@ -353,7 +354,7 @@ class AnimationTrackEditor : public VBoxContainer { Variant value; String query; bool advance = false; - }; /* insert_data;*/ + }; Label *insert_confirm_text = nullptr; CheckBox *insert_confirm_bezier = nullptr; @@ -388,8 +389,8 @@ class AnimationTrackEditor : public VBoxContainer { void _timeline_value_changed(double); - float insert_key_from_track_call_ofs; - int insert_key_from_track_call_track; + float insert_key_from_track_call_ofs = 0.0f; + int insert_key_from_track_call_track = 0; void _insert_key_from_track(float p_ofs, int p_track); void _add_method_key(const String &p_method); @@ -415,7 +416,7 @@ class AnimationTrackEditor : public VBoxContainer { void _key_deselected(int p_key, int p_track); bool moving_selection = false; - float moving_selection_offset; + float moving_selection_offset = 0.0f; void _move_selection_begin(); void _move_selection(float p_offset); void _move_selection_commit(); @@ -459,7 +460,7 @@ class AnimationTrackEditor : public VBoxContainer { void _edit_menu_about_to_popup(); void _edit_menu_pressed(int p_option); - int last_menu_track_opt; + int last_menu_track_opt = 0; void _cleanup_animation(Ref<Animation> p_animation); diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index d07881e28e..cd40b53919 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -966,7 +966,6 @@ void AnimationTrackEditTypeAudio::_bind_methods() { AnimationTrackEditTypeAudio::AnimationTrackEditTypeAudio() { AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", callable_mp(this, &AnimationTrackEditTypeAudio::_preview_changed)); - len_resizing = false; } bool AnimationTrackEditTypeAudio::can_drop_data(const Point2 &p_point, const Variant &p_data) const { diff --git a/editor/animation_track_editor_plugins.h b/editor/animation_track_editor_plugins.h index adfe517356..e3cafaa97d 100644 --- a/editor/animation_track_editor_plugins.h +++ b/editor/animation_track_editor_plugins.h @@ -115,10 +115,10 @@ class AnimationTrackEditTypeAudio : public AnimationTrackEdit { void _preview_changed(ObjectID p_which); bool len_resizing = false; - bool len_resizing_start; - int len_resizing_index; - float len_resizing_from_px; - float len_resizing_rel; + bool len_resizing_start = false; + int len_resizing_index = 0; + float len_resizing_from_px = 0.0f; + float len_resizing_rel = 0.0f; bool over_drag_position = false; protected: diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index c9868bc3c2..7c00cf351c 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -657,10 +657,6 @@ void FindReplaceBar::_bind_methods() { } FindReplaceBar::FindReplaceBar() { - results_count = -1; - results_count_to_current = -1; - needs_to_count_results = true; - vbc_lineedit = memnew(VBoxContainer); add_child(vbc_lineedit); vbc_lineedit->set_alignment(BoxContainer::ALIGNMENT_CENTER); diff --git a/editor/code_editor.h b/editor/code_editor.h index bb1791940e..e2441cec2b 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -84,10 +84,10 @@ class FindReplaceBar : public HBoxContainer { uint32_t flags = 0; - int result_line; - int result_col; - int results_count; - int results_count_to_current; + int result_line = 0; + int result_col = 0; + int results_count = -1; + int results_count_to_current = -1; bool replace_all_mode = false; bool preserve_cursor = false; diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index 4b1b8363dd..f8f15b32af 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -111,7 +111,7 @@ private: StringName signal; LineEdit *dst_method = nullptr; ConnectDialogBinds *cdbinds = nullptr; - bool edit_mode; + bool edit_mode = false; NodePath dst_path; VBoxContainer *vbc_right = nullptr; diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.h b/editor/debugger/debug_adapter/debug_adapter_protocol.h index e4760bea54..66db75c634 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.h +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.h @@ -111,9 +111,9 @@ private: String _current_request; Ref<DAPeer> _current_peer; - int breakpoint_id; - int stackframe_id; - int variable_id; + int breakpoint_id = 0; + int stackframe_id = 0; + int variable_id = 0; List<DAP::Breakpoint> breakpoint_list; Map<DAP::StackFrame, List<int>> stackframe_list; Map<int, Array> variable_list; diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index 936b8ca626..854c050793 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -157,7 +157,7 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) { if (path.contains("::")) { // built-in resource String base_path = path.get_slice("::", 0); - RES dependency = ResourceLoader::load(base_path); + Ref<Resource> dependency = ResourceLoader::load(base_path); if (dependency.is_valid()) { remote_dependencies.insert(dependency); } @@ -166,7 +166,7 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) { if (pinfo.hint_string == "Script") { if (debugObj->get_script() != var) { - debugObj->set_script(REF()); + debugObj->set_script(Ref<RefCounted>()); Ref<Script> script(var); if (!script.is_null()) { ScriptInstance *script_instance = script->placeholder_instance_create(debugObj); diff --git a/editor/debugger/editor_debugger_inspector.h b/editor/debugger/editor_debugger_inspector.h index 8f523bfbdc..2bf5bf3419 100644 --- a/editor/debugger/editor_debugger_inspector.h +++ b/editor/debugger/editor_debugger_inspector.h @@ -69,7 +69,7 @@ class EditorDebuggerInspector : public EditorInspector { private: ObjectID inspected_object_id; Map<ObjectID, EditorDebuggerRemoteObject *> remote_objects; - Set<RES> remote_dependencies; + Set<Ref<Resource>> remote_dependencies; EditorDebuggerRemoteObject *variables = nullptr; void _object_selected(ObjectID p_object); diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h index 36f99113ad..b4fbb90301 100644 --- a/editor/debugger/editor_debugger_node.h +++ b/editor/debugger/editor_debugger_node.h @@ -124,7 +124,7 @@ protected: void _remote_object_requested(ObjectID p_id, int p_debugger); void _save_node_requested(ObjectID p_id, const String &p_file, int p_debugger); - void _clear_execution(REF p_script) { + void _clear_execution(Ref<RefCounted> p_script) { emit_signal(SNAME("clear_execution"), p_script); } diff --git a/editor/debugger/editor_performance_profiler.h b/editor/debugger/editor_performance_profiler.h index a917ddbe28..ab0e43de2f 100644 --- a/editor/debugger/editor_performance_profiler.h +++ b/editor/debugger/editor_performance_profiler.h @@ -66,7 +66,7 @@ private: Control *monitor_draw = nullptr; Label *info_message = nullptr; StringName marker_key; - int marker_frame; + int marker_frame = 0; const int MARGIN = 4; const int POINT_SEPARATION = 5; const int MARKER_MARGIN = 2; diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 4e2e8634e5..50f3b19cc2 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -662,9 +662,6 @@ EditorProfiler::EditorProfiler() { int metric_size = CLAMP(int(EDITOR_GET("debugger/profiler_frame_history_size")), 60, 1024); frame_metrics.resize(metric_size); - total_metrics = 0; - last_metric = -1; - hover_metric = -1; EDITOR_DEF("debugger/profiler_frame_max_functions", 64); @@ -682,7 +679,4 @@ EditorProfiler::EditorProfiler() { plot_sigs.insert("physics_frame_time"); plot_sigs.insert("category_frame_time"); - - seeking = false; - graph_height = 1; } diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h index 34f34be7c3..1a65e2e3d6 100644 --- a/editor/debugger/editor_profiler.h +++ b/editor/debugger/editor_profiler.h @@ -106,18 +106,18 @@ private: SpinBox *cursor_metric_edit = nullptr; Vector<Metric> frame_metrics; - int total_metrics; - int last_metric; + int total_metrics = 0; + int last_metric = -1; - int max_functions; + int max_functions = 0; - bool updating_frame; + bool updating_frame = false; - int hover_metric; + int hover_metric = -1; - float graph_height; + float graph_height = 1.0f; - bool seeking; + bool seeking = false; Timer *frame_delay = nullptr; Timer *plot_delay = nullptr; diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 2f33a0bc31..503c03bafe 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -782,7 +782,6 @@ EditorVisualProfiler::EditorVisualProfiler() { graph = memnew(TextureRect); graph->set_ignore_texture_size(true); graph->set_mouse_filter(MOUSE_FILTER_STOP); - //graph->set_ignore_mouse(false); graph->connect("draw", callable_mp(this, &EditorVisualProfiler::_graph_tex_draw)); graph->connect("gui_input", callable_mp(this, &EditorVisualProfiler::_graph_tex_input)); graph->connect("mouse_exited", callable_mp(this, &EditorVisualProfiler::_graph_tex_mouse_exit)); @@ -792,11 +791,6 @@ EditorVisualProfiler::EditorVisualProfiler() { int metric_size = CLAMP(int(EDITOR_GET("debugger/profiler_frame_history_size")), 60, 1024); frame_metrics.resize(metric_size); - last_metric = -1; - //cursor_metric=-1; - hover_metric = -1; - - //display_mode=DISPLAY_FRAME_TIME; frame_delay = memnew(Timer); frame_delay->set_wait_time(0.1); @@ -809,12 +803,4 @@ EditorVisualProfiler::EditorVisualProfiler() { plot_delay->set_one_shot(true); add_child(plot_delay); plot_delay->connect("timeout", callable_mp(this, &EditorVisualProfiler::_update_plot)); - - seeking = false; - graph_height_cpu = 1; - graph_height_gpu = 1; - - graph_limit = 1000 / 60.0; - - //activate->set_disabled(true); } diff --git a/editor/debugger/editor_visual_profiler.h b/editor/debugger/editor_visual_profiler.h index 14eacca02d..4e5169da9e 100644 --- a/editor/debugger/editor_visual_profiler.h +++ b/editor/debugger/editor_visual_profiler.h @@ -83,21 +83,20 @@ private: SpinBox *cursor_metric_edit = nullptr; Vector<Metric> frame_metrics; - int last_metric; + int last_metric = -1; - StringName selected_area; + int hover_metric = -1; - bool updating_frame; + StringName selected_area; - //int cursor_metric; - int hover_metric; + bool updating_frame = false; - float graph_height_cpu; - float graph_height_gpu; + float graph_height_cpu = 1.0f; + float graph_height_gpu = 1.0f; - float graph_limit; + float graph_limit = 1000.0f / 60; - bool seeking; + bool seeking = false; Timer *frame_delay = nullptr; Timer *plot_delay = nullptr; diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 877af41160..cd5a4f16e4 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -129,6 +129,7 @@ EditorAbout::EditorAbout() { vbc->add_child(hbc); _logo = memnew(TextureRect); + _logo->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); hbc->add_child(_logo); VBoxContainer *version_info_vbc = memnew(VBoxContainer); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 4474d6893a..d34bc521f1 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -1263,7 +1263,6 @@ void EditorAudioBuses::_bind_methods() { } EditorAudioBuses::EditorAudioBuses() { - drop_end = nullptr; top_hb = memnew(HBoxContainer); add_child(top_hb); diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h index 81a6e5b86d..70c0712b52 100644 --- a/editor/editor_audio_buses.h +++ b/editor/editor_audio_buses.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORAUDIOBUSES_H -#define EDITORAUDIOBUSES_H +#ifndef EDITOR_AUDIO_BUSES_H +#define EDITOR_AUDIO_BUSES_H #include "editor/editor_plugin.h" #include "scene/gui/box_container.h" @@ -192,7 +192,7 @@ class EditorAudioBuses : public VBoxContainer { void _new_layout(); EditorFileDialog *file_dialog = nullptr; - bool new_layout; + bool new_layout = false; void _file_dialog_callback(const String &p_string); @@ -275,4 +275,4 @@ public: ~AudioBusesEditorPlugin(); }; -#endif // EDITORAUDIOBUSES_H +#endif // EDITOR_AUDIO_BUSES_H diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 49bf24f864..3b38ff9163 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -396,7 +396,7 @@ void EditorAutoloadSettings::_autoload_text_changed(const String p_name) { } Node *EditorAutoloadSettings::_create_autoload(const String &p_path) { - RES res = ResourceLoader::load(p_path); + Ref<Resource> res = ResourceLoader::load(p_path); ERR_FAIL_COND_V_MSG(res.is_null(), nullptr, "Can't autoload: " + p_path + "."); Node *n = nullptr; Ref<PackedScene> scn = res; diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index a58a279faa..7ce483d788 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -82,7 +82,7 @@ void EditorSelectionHistory::add_object(ObjectID p_object, const String &p_prope RefCounted *r = Object::cast_to<RefCounted>(obj); _Object o; if (r) { - o.ref = REF(r); + o.ref = Ref<RefCounted>(r); } o.object = p_object; o.property = p_property; diff --git a/editor/editor_data.h b/editor/editor_data.h index 0a9f40b714..1e9b8af490 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -46,7 +46,7 @@ class EditorPlugin; class EditorSelectionHistory { // Stores the object & property (if relevant). struct _Object { - REF ref; + Ref<RefCounted> ref; ObjectID object; String property; bool inspector_only = false; diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 0ed0e9bcd7..0129a6453d 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -1583,11 +1583,9 @@ bool EditorFileDialog::are_previews_enabled() { EditorFileDialog::EditorFileDialog() { show_hidden_files = default_show_hidden_files; display_mode = default_display_mode; - local_history_pos = 0; VBoxContainer *vbc = memnew(VBoxContainer); add_child(vbc); - mode = FILE_MODE_SAVE_FILE; set_title(TTR("Save a File")); ED_SHORTCUT("file_dialog/go_back", TTR("Go Back"), KeyModifierMask::ALT | Key::LEFT); @@ -1795,7 +1793,6 @@ EditorFileDialog::EditorFileDialog() { item_vb->add_child(file_box); dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); - access = ACCESS_RESOURCES; _update_drives(); connect("confirmed", callable_mp(this, &EditorFileDialog::_action_pressed)); @@ -1808,7 +1805,6 @@ EditorFileDialog::EditorFileDialog() { filter->connect("item_selected", callable_mp(this, &EditorFileDialog::_filter_selected)); confirm_save = memnew(ConfirmationDialog); - //confirm_save->set_as_top_level(true); add_child(confirm_save); confirm_save->connect("confirmed", callable_mp(this, &EditorFileDialog::_save_confirm_pressed)); @@ -1843,9 +1839,6 @@ EditorFileDialog::EditorFileDialog() { if (register_func) { register_func(this); } - - preview_wheel_timeout = 0; - preview_wheel_index = 0; } EditorFileDialog::~EditorFileDialog() { diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index db2a2ab09f..0460576bc5 100644 --- a/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORFILEDIALOG_H -#define EDITORFILEDIALOG_H +#ifndef EDITOR_FILE_DIALOG_H +#define EDITOR_FILE_DIALOG_H #include "core/io/dir_access.h" #include "editor/plugins/editor_preview_plugins.h" @@ -88,11 +88,11 @@ private: LineEdit *makedirname = nullptr; Button *makedir = nullptr; - Access access; + Access access = ACCESS_RESOURCES; VBoxContainer *vbox = nullptr; - FileMode mode; - bool can_create_dir; + FileMode mode = FILE_MODE_SAVE_FILE; + bool can_create_dir = false; LineEdit *dir = nullptr; Button *dir_prev = nullptr; @@ -130,15 +130,15 @@ private: ItemList *recent = nullptr; Vector<String> local_history; - int local_history_pos; + int local_history_pos = 0; void _push_history(); Vector<String> filters; bool previews_enabled = true; bool preview_waiting = false; - int preview_wheel_index; - float preview_wheel_timeout; + int preview_wheel_index = 0; + float preview_wheel_timeout = 0.0f; static bool default_show_hidden_files; static DisplayMode default_display_mode; @@ -257,4 +257,4 @@ VARIANT_ENUM_CAST(EditorFileDialog::FileMode); VARIANT_ENUM_CAST(EditorFileDialog::Access); VARIANT_ENUM_CAST(EditorFileDialog::DisplayMode); -#endif // EDITORFILEDIALOG_H +#endif // EDITOR_FILE_DIALOG_H diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 548f05217e..76c7023b46 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -48,7 +48,7 @@ Vector<String> EditorFolding::_get_unfolds(const Object *p_object) { return sections; } -void EditorFolding::save_resource_folding(const RES &p_resource, const String &p_path) { +void EditorFolding::save_resource_folding(const Ref<Resource> &p_resource, const String &p_path) { Ref<ConfigFile> config; config.instantiate(); Vector<String> unfolds = _get_unfolds(p_resource.ptr()); @@ -68,7 +68,7 @@ void EditorFolding::_set_unfolds(Object *p_object, const Vector<String> &p_unfol } } -void EditorFolding::load_resource_folding(RES p_resource, const String &p_path) { +void EditorFolding::load_resource_folding(Ref<Resource> p_resource, const String &p_path) { Ref<ConfigFile> config; config.instantiate(); @@ -87,7 +87,7 @@ void EditorFolding::load_resource_folding(RES p_resource, const String &p_path) _set_unfolds(p_resource.ptr(), unfolds); } -void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, Set<RES> &resources) { +void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, Set<Ref<Resource>> &resources) { if (p_root != p_node) { if (!p_node->get_owner()) { return; //not owned, bye @@ -112,7 +112,7 @@ void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p for (const PropertyInfo &E : plist) { if (E.usage & PROPERTY_USAGE_EDITOR) { if (E.type == Variant::OBJECT) { - RES res = p_node->get(E.name); + Ref<Resource> res = p_node->get(E.name); if (res.is_valid() && !resources.has(res) && !res->get_path().is_empty() && !res->get_path().is_resource_file()) { Vector<String> res_unfolds = _get_unfolds(res.ptr()); resource_folds.push_back(res->get_path()); @@ -140,7 +140,7 @@ void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path config.instantiate(); Array unfolds, res_unfolds; - Set<RES> resources; + Set<Ref<Resource>> resources; Array nodes_folded; _fill_folds(p_scene, p_scene, unfolds, res_unfolds, nodes_folded, resources); @@ -193,9 +193,9 @@ void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) { for (int i = 0; i < res_unfolds.size(); i += 2) { String path2 = res_unfolds[i]; - RES res; + Ref<Resource> res; if (ResourceCache::has(path2)) { - res = RES(ResourceCache::get(path2)); + res = Ref<Resource>(ResourceCache::get(path2)); } if (res.is_null()) { continue; @@ -220,7 +220,7 @@ bool EditorFolding::has_folding_data(const String &p_path) { return FileAccess::exists(file); } -void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) { +void EditorFolding::_do_object_unfolds(Object *p_object, Set<Ref<Resource>> &resources) { List<PropertyInfo> plist; p_object->get_property_list(&plist); String group_base; @@ -261,7 +261,7 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) { } if (E.type == Variant::OBJECT) { - RES res = p_object->get(E.name); + Ref<Resource> res = p_object->get(E.name); if (res.is_valid() && !resources.has(res) && !res->get_path().is_empty() && !res->get_path().is_resource_file()) { resources.insert(res); _do_object_unfolds(res.ptr(), resources); @@ -275,7 +275,7 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) { } } -void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, Set<RES> &resources) { +void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, Set<Ref<Resource>> &resources) { if (p_root != p_node) { if (!p_node->get_owner()) { return; //not owned, bye @@ -293,7 +293,7 @@ void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, Set<RES> &resou } void EditorFolding::unfold_scene(Node *p_scene) { - Set<RES> resources; + Set<Ref<Resource>> resources; _do_node_unfolds(p_scene, p_scene, resources); } diff --git a/editor/editor_folding.h b/editor/editor_folding.h index 442d710d71..86f4643ed8 100644 --- a/editor/editor_folding.h +++ b/editor/editor_folding.h @@ -37,14 +37,14 @@ class EditorFolding { Vector<String> _get_unfolds(const Object *p_object); void _set_unfolds(Object *p_object, const Vector<String> &p_unfolds); - void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, Set<RES> &resources); + void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, Set<Ref<Resource>> &resources); - void _do_object_unfolds(Object *p_object, Set<RES> &resources); - void _do_node_unfolds(Node *p_root, Node *p_node, Set<RES> &resources); + void _do_object_unfolds(Object *p_object, Set<Ref<Resource>> &resources); + void _do_node_unfolds(Node *p_root, Node *p_node, Set<Ref<Resource>> &resources); public: - void save_resource_folding(const RES &p_resource, const String &p_path); - void load_resource_folding(RES p_resource, const String &p_path); + void save_resource_folding(const Ref<Resource> &p_resource, const String &p_path); + void load_resource_folding(Ref<Resource> p_resource, const String &p_path); void save_scene_folding(const Node *p_scene, const String &p_path); void load_scene_folding(Node *p_scene, const String &p_path); diff --git a/editor/editor_help.h b/editor/editor_help.h index 054fd84af6..e289f91414 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -56,7 +56,7 @@ class FindBar : public HBoxContainer { RichTextLabel *rich_text_label = nullptr; - int results_count; + int results_count = 0; void _hide_bar(); @@ -112,7 +112,7 @@ class EditorHelp : public VBoxContainer { Map<String, int> constant_line; Map<String, int> enum_line; Map<String, Map<String, int>> enum_values_line; - int description_line; + int description_line = 0; RichTextLabel *class_desc = nullptr; HSplitContainer *h_split = nullptr; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 9a30c6a1e3..076e5e3731 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -3472,7 +3472,7 @@ void EditorInspector::_object_id_selected(const String &p_path, ObjectID p_id) { emit_signal(SNAME("object_id_selected"), p_id); } -void EditorInspector::_resource_selected(const String &p_path, RES p_resource) { +void EditorInspector::_resource_selected(const String &p_path, Ref<Resource> p_resource) { emit_signal(SNAME("resource_selected"), p_resource, p_path); } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index c5bcbe0725..75536a5a24 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -490,7 +490,7 @@ class EditorInspector : public ScrollContainer { void _property_checked(const String &p_path, bool p_checked); void _property_pinned(const String &p_path, bool p_pinned); - void _resource_selected(const String &p_path, RES p_resource); + void _resource_selected(const String &p_path, Ref<Resource> p_resource); void _property_selected(const String &p_path, int p_focusable); void _object_id_selected(const String &p_path, ObjectID p_id); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3d52686378..f4caa29a47 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1178,7 +1178,7 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d Error err; - RES res; + Ref<Resource> res; if (ResourceLoader::exists(p_resource, "")) { res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); } else if (textfile_extensions.has(p_resource.get_extension())) { @@ -1420,7 +1420,7 @@ void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) { ERR_FAIL_COND_MSG(err != OK, "Cannot save config file to '" + path + "'."); } -bool EditorNode::_find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags) { +bool EditorNode::_find_and_save_resource(Ref<Resource> p_res, Map<Ref<Resource>, bool> &processed, int32_t flags) { if (p_res.is_null()) { return false; } @@ -1446,7 +1446,7 @@ bool EditorNode::_find_and_save_resource(RES p_res, Map<RES, bool> &processed, i } } -bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> &processed, int32_t flags) { +bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<Ref<Resource>, bool> &processed, int32_t flags) { bool ret_changed = false; List<PropertyInfo> pi; obj->get_property_list(&pi); @@ -1457,7 +1457,7 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> switch (E.type) { case Variant::OBJECT: { - RES res = obj->get(E.name); + Ref<Resource> res = obj->get(E.name); if (_find_and_save_resource(res, processed, flags)) { ret_changed = true; @@ -1469,7 +1469,7 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> int len = varray.size(); for (int i = 0; i < len; i++) { const Variant &v = varray.get(i); - RES res = v; + Ref<Resource> res = v; if (_find_and_save_resource(res, processed, flags)) { ret_changed = true; } @@ -1482,7 +1482,7 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> d.get_key_list(&keys); for (const Variant &F : keys) { Variant v = d[F]; - RES res = v; + Ref<Resource> res = v; if (_find_and_save_resource(res, processed, flags)) { ret_changed = true; } @@ -1496,7 +1496,7 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> return ret_changed; } -void EditorNode::_save_edited_subresources(Node *scene, Map<RES, bool> &processed, int32_t flags) { +void EditorNode::_save_edited_subresources(Node *scene, Map<Ref<Resource>, bool> &processed, int32_t flags) { _find_and_save_edited_subresources(scene, processed, flags); for (int i = 0; i < scene->get_child_count(); i++) { @@ -1637,7 +1637,7 @@ static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Reso for (const PropertyInfo &E : plist) { if (E.type == Variant::OBJECT && E.usage & PROPERTY_USAGE_STORAGE && !(E.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)) { - RES res = p_resource->get(E.name); + Ref<Resource> res = p_resource->get(E.name); if (res.is_null()) { continue; } @@ -2043,7 +2043,7 @@ bool EditorNode::item_has_editor(Object *p_object) { return editor_data.get_subeditors(p_object).size() > 0; } -void EditorNode::edit_item_resource(RES p_resource) { +void EditorNode::edit_item_resource(Ref<Resource> p_resource) { edit_item(p_resource.ptr()); } @@ -2128,7 +2128,7 @@ void EditorNode::_save_default_environment() { Ref<Environment> fallback = get_tree()->get_root()->get_world_3d()->get_fallback_environment(); if (fallback.is_valid() && fallback->get_path().is_resource_file()) { - Map<RES, bool> processed; + Map<Ref<Resource>, bool> processed; _find_and_save_edited_subresources(fallback.ptr(), processed, 0); save_resource_in_path(fallback, fallback->get_path()); } @@ -2166,7 +2166,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { ObjectID current = editor_history.get_current(); Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; - RES res = Object::cast_to<Resource>(current_obj); + Ref<Resource> res = Object::cast_to<Resource>(current_obj); if (p_skip_foreign && res.is_valid()) { if (res->get_path().find("::") > -1 && res->get_path().get_slice("::", 0) != editor_data.get_scene_path(get_current_tab())) { // Trying to edit resource that belongs to another scene; abort. @@ -3762,7 +3762,7 @@ void EditorNode::open_request(const String &p_path) { load_scene(p_path); // As it will be opened in separate tab. } -void EditorNode::edit_foreign_resource(RES p_resource) { +void EditorNode::edit_foreign_resource(Ref<Resource> p_resource) { load_scene(p_resource->get_path().get_slice("::", 0)); InspectorDock::get_singleton()->call_deferred("edit_resource", p_resource); } @@ -5699,7 +5699,7 @@ void EditorNode::_rendering_driver_selected(int p_which) { _update_rendering_driver_color(); } -void EditorNode::_resource_saved(RES p_resource, const String &p_path) { +void EditorNode::_resource_saved(Ref<Resource> p_resource, const String &p_path) { if (EditorFileSystem::get_singleton()) { EditorFileSystem::get_singleton()->update_file(p_path); } @@ -5707,7 +5707,7 @@ void EditorNode::_resource_saved(RES p_resource, const String &p_path) { singleton->editor_folding.save_resource_folding(p_resource, p_path); } -void EditorNode::_resource_loaded(RES p_resource, const String &p_path) { +void EditorNode::_resource_loaded(Ref<Resource> p_resource, const String &p_path) { singleton->editor_folding.load_resource_folding(p_resource, p_path); } @@ -5905,11 +5905,10 @@ EditorNode::EditorNode() { // Only if no touchscreen ui hint, disable emulation just in case. id->set_emulate_touch_from_mouse(false); } - DisplayServer::get_singleton()->cursor_set_custom_image(RES()); + DisplayServer::get_singleton()->cursor_set_custom_image(Ref<Resource>()); } singleton = this; - last_checked_version = 0; TranslationServer::get_singleton()->set_enabled(false); // Load settings. @@ -6263,8 +6262,6 @@ EditorNode::EditorNode() { dock_vb->add_child(dock_float); dock_select_popup->reset_size(); - dock_select_rect_over_idx = -1; - dock_popup_selected_idx = -1; for (int i = 0; i < DOCK_SLOT_MAX; i++) { dock_slot[i]->set_custom_minimum_size(Size2(170, 0) * EDSCALE); @@ -6811,7 +6808,6 @@ EditorNode::EditorNode() { // Define corresponding default layout. const String docks_section = "docks"; - overridden_default_layout = -1; default_layout.instantiate(); // Dock numbers are based on DockSlot enum value + 1. default_layout->set_value(docks_section, "dock_3", "Scene,Import"); @@ -6890,8 +6886,6 @@ EditorNode::EditorNode() { Button *output_button = add_bottom_panel_item(TTR("Output"), log); log->set_tool_button(output_button); - old_split_ofs = 0; - center_split->connect("resized", callable_mp(this, &EditorNode::_vp_resized)); native_shader_source_visualizer = memnew(EditorNativeShaderSourceVisualizer); @@ -7157,7 +7151,6 @@ EditorNode::EditorNode() { } update_spinner_step_msec = OS::get_singleton()->get_ticks_msec(); update_spinner_step_frame = Engine::get_singleton()->get_frames_drawn(); - update_spinner_step = 0; editor_plugin_screen = nullptr; editor_plugins_over = memnew(EditorPluginList); @@ -7191,9 +7184,6 @@ EditorNode::EditorNode() { open_imported->connect("custom_action", callable_mp(this, &EditorNode::_inherit_imported)); gui_base->add_child(open_imported); - saved_version = 1; - _last_instantiated_scene = nullptr; - quick_open = memnew(EditorQuickOpen); gui_base->add_child(quick_open); quick_open->connect("quick_open", callable_mp(this, &EditorNode::_quick_opened)); diff --git a/editor/editor_node.h b/editor/editor_node.h index 82118b8b70..bcbb4d734a 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -283,7 +283,7 @@ private: ConfirmationDialog *video_restart_dialog = nullptr; - int rendering_driver_current; + int rendering_driver_current = 0; String rendering_driver_request; // Split containers. @@ -305,12 +305,12 @@ private: PopupMenu *scene_tabs_context_menu = nullptr; Panel *tab_preview_panel = nullptr; TextureRect *tab_preview = nullptr; - int tab_closing_idx; + int tab_closing_idx = 0; bool exiting = false; bool dimmed = false; - int old_split_ofs; + int old_split_ofs = 0; VSplitContainer *top_split = nullptr; HBoxContainer *bottom_hb = nullptr; Control *vp_base = nullptr; @@ -363,7 +363,7 @@ private: EditorAbout *about = nullptr; AcceptDialog *warning = nullptr; - int overridden_default_layout; + int overridden_default_layout = -1; Ref<ConfigFile> default_layout; PopupMenu *editor_layouts = nullptr; EditorLayoutsDialog *layout_dialog = nullptr; @@ -412,8 +412,8 @@ private: TabContainer *dock_slot[DOCK_SLOT_MAX]; Timer *dock_drag_timer = nullptr; bool docks_visible = true; - int dock_popup_selected_idx; - int dock_select_rect_over_idx; + int dock_popup_selected_idx = -1; + int dock_select_rect_over_idx = -1; HBoxContainer *tabbar_container = nullptr; Button *distraction_free = nullptr; @@ -446,24 +446,24 @@ private: bool unsaved_cache = true; bool waiting_for_first_scan = true; - int current_menu_option; + int current_menu_option = 0; SubViewport *scene_root = nullptr; // Root of the scene being edited. Object *current = nullptr; Ref<Resource> saving_resource; - uint64_t update_spinner_step_msec; - uint64_t update_spinner_step_frame; - int update_spinner_step; + uint64_t update_spinner_step_msec = 0; + uint64_t update_spinner_step_frame = 0; + int update_spinner_step = 0; String _tmp_import_path; String external_file; String open_navigate; String run_custom_filename; - uint64_t saved_version; - uint64_t last_checked_version; + uint64_t saved_version = 1; + uint64_t last_checked_version = 0; DynamicFontImportSettings *fontdata_import_settings = nullptr; SceneImportSettings *scene_import_settings = nullptr; @@ -503,8 +503,8 @@ private: static void _file_access_close_error_notify(const String &p_str); static void _print_handler(void *p_this, const String &p_string, bool p_error); - static void _resource_saved(RES p_resource, const String &p_path); - static void _resource_loaded(RES p_resource, const String &p_path); + static void _resource_saved(Ref<Resource> p_resource, const String &p_path); + static void _resource_loaded(Ref<Resource> p_resource, const String &p_path); void _build_icon_type_cache(); @@ -593,9 +593,9 @@ private: void _remove_edited_scene(bool p_change_tab = true); void _remove_scene(int index, bool p_change_tab = true); - bool _find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags); - bool _find_and_save_edited_subresources(Object *obj, Map<RES, bool> &processed, int32_t flags); - void _save_edited_subresources(Node *scene, Map<RES, bool> &processed, int32_t flags); + bool _find_and_save_resource(Ref<Resource> p_res, Map<Ref<Resource>, bool> &processed, int32_t flags); + bool _find_and_save_edited_subresources(Object *obj, Map<Ref<Resource>, bool> &processed, int32_t flags); + void _save_edited_subresources(Node *scene, Map<Ref<Resource>, bool> &processed, int32_t flags); void _mark_unsaved_scenes(); void _find_node_types(Node *p_node, int &count_2d, int &count_3d); @@ -755,14 +755,14 @@ public: void push_item(Object *p_object, const String &p_property = "", bool p_inspector_only = false); void edit_item(Object *p_object); - void edit_item_resource(RES p_resource); + void edit_item_resource(Ref<Resource> p_resource); bool item_has_editor(Object *p_object); void hide_top_editors(); void select_editor_by_name(const String &p_name); void open_request(const String &p_path); - void edit_foreign_resource(RES p_resource); + void edit_foreign_resource(Ref<Resource> p_resource); bool is_changing_scene() const; diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 581a807e27..9541033fe8 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2974,13 +2974,13 @@ void EditorPropertyResource::_set_read_only(bool p_read_only) { resource_picker->set_editable(!p_read_only); }; -void EditorPropertyResource::_resource_selected(const RES &p_resource, bool p_edit) { +void EditorPropertyResource::_resource_selected(const Ref<Resource> &p_resource, bool p_edit) { if (p_resource->is_built_in() && !p_resource->get_path().is_empty()) { String parent = p_resource->get_path().get_slice("::", 0); List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions); - if (extensions.find(parent.get_extension()) && (!EditorNode::get_singleton()->get_edited_scene() || EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path() == parent)) { + if (extensions.find(parent.get_extension()) && (!EditorNode::get_singleton()->get_edited_scene() || EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path() != parent)) { // If the resource belongs to another scene, edit it in that scene instead. EditorNode::get_singleton()->call_deferred("edit_foreign_resource", p_resource); return; @@ -2996,7 +2996,7 @@ void EditorPropertyResource::_resource_selected(const RES &p_resource, bool p_ed } } -void EditorPropertyResource::_resource_changed(const RES &p_resource) { +void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) { // Make visual script the correct type. Ref<Script> s = p_resource; if (get_edited_object() && s.is_valid()) { @@ -3009,14 +3009,14 @@ void EditorPropertyResource::_resource_changed(const RES &p_resource) { Resource *r = Object::cast_to<Resource>(get_edited_object()); if (r && r->get_path().is_resource_file()) { EditorNode::get_singleton()->show_warning(TTR("Can't create a ViewportTexture on resources saved as a file.\nResource needs to belong to a scene.")); - emit_changed(get_edited_property(), RES()); + emit_changed(get_edited_property(), Ref<Resource>()); update_property(); return; } if (r && !r->is_local_to_scene()) { EditorNode::get_singleton()->show_warning(TTR("Can't create a ViewportTexture on this resource because it's not set as local to scene.\nPlease switch on the 'local to scene' property on it (and all resources containing it up to a node).")); - emit_changed(get_edited_property(), RES()); + emit_changed(get_edited_property(), Ref<Resource>()); update_property(); return; } @@ -3051,7 +3051,7 @@ void EditorPropertyResource::_sub_inspector_property_keyed(const String &p_prope emit_signalp(SNAME("property_keyed_with_value"), argp, 3); } -void EditorPropertyResource::_sub_inspector_resource_selected(const RES &p_resource, const String &p_property) { +void EditorPropertyResource::_sub_inspector_resource_selected(const Ref<Resource> &p_resource, const String &p_property) { emit_signal(SNAME("resource_selected"), String(get_edited_property()) + ":" + p_property, p_resource); } @@ -3060,7 +3060,7 @@ void EditorPropertyResource::_sub_inspector_object_id_selected(int p_id) { } void EditorPropertyResource::_open_editor_pressed() { - RES res = get_edited_object()->get(get_edited_property()); + Ref<Resource> res = get_edited_object()->get(get_edited_property()); if (res.is_valid()) { // May clear the editor so do it deferred. EditorNode::get_singleton()->call_deferred(SNAME("edit_item_resource"), res); @@ -3072,7 +3072,7 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) { return; } - RES res = get_edited_object()->get(get_edited_property()); + Ref<Resource> res = get_edited_object()->get(get_edited_property()); if (!res.is_valid()) { return; } @@ -3218,7 +3218,7 @@ void EditorPropertyResource::setup(Object *p_object, const String &p_path, const } void EditorPropertyResource::update_property() { - RES res = get_edited_object()->get(get_edited_property()); + Ref<Resource> res = get_edited_object()->get(get_edited_property()); if (use_sub_inspector) { if (res.is_valid() != resource_picker->is_toggle_mode()) { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 1f40a7fe7b..ebac984bbd 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -724,13 +724,13 @@ class EditorPropertyResource : public EditorProperty { bool updating_theme = false; bool opened_editor = false; - void _resource_selected(const RES &p_resource, bool p_edit); - void _resource_changed(const RES &p_resource); + void _resource_selected(const Ref<Resource> &p_resource, bool p_edit); + void _resource_changed(const Ref<Resource> &p_resource); void _viewport_selected(const NodePath &p_path); void _sub_inspector_property_keyed(const String &p_property, const Variant &p_value, bool p_advance); - void _sub_inspector_resource_selected(const RES &p_resource, const String &p_property); + void _sub_inspector_resource_selected(const Ref<Resource> &p_resource, const String &p_property); void _sub_inspector_object_id_selected(int p_id); void _open_editor_pressed(); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index ffbe50285c..85f5ed848c 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -455,7 +455,7 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d for (int i = 0; i < files.size(); i++) { String file = files[i]; - RES res = ResourceLoader::load(file); + Ref<Resource> res = ResourceLoader::load(file); if (res.is_valid()) { array.call("push_back", res); } diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 3c68a715c3..3158c03dcc 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -50,7 +50,7 @@ void EditorResourcePicker::_update_resource() { preview_rect->set_texture(Ref<Texture2D>()); assign_button->set_custom_minimum_size(Size2(1, 1)); - if (edited_resource == RES()) { + if (edited_resource == Ref<Resource>()) { assign_button->set_icon(Ref<Texture2D>()); assign_button->set_text(TTR("[empty]")); assign_button->set_tooltip(""); @@ -117,7 +117,7 @@ void EditorResourcePicker::_resource_selected() { } void EditorResourcePicker::_file_selected(const String &p_path) { - RES loaded_resource = ResourceLoader::load(p_path); + Ref<Resource> loaded_resource = ResourceLoader::load(p_path); ERR_FAIL_COND_MSG(loaded_resource.is_null(), "Cannot load resource from path '" + p_path + "'."); if (!base_type.is_empty()) { @@ -184,7 +184,7 @@ void EditorResourcePicker::_update_menu_items() { } // Add options to copy/paste resource. - RES cb = EditorSettings::get_singleton()->get_resource_clipboard(); + Ref<Resource> cb = EditorSettings::get_singleton()->get_resource_clipboard(); bool paste_valid = false; if (cb.is_valid()) { if (base_type.is_empty()) { @@ -278,7 +278,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } break; case OBJ_MENU_CLEAR: { - edited_resource = RES(); + edited_resource = Ref<Resource>(); emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } break; @@ -391,7 +391,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { EditorNode::get_editor_data().instantiate_object_properties(obj); - edited_resource = RES(resp); + edited_resource = Ref<Resource>(resp); emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } break; @@ -809,9 +809,9 @@ Vector<String> EditorResourcePicker::get_allowed_types() const { return types; } -void EditorResourcePicker::set_edited_resource(RES p_resource) { +void EditorResourcePicker::set_edited_resource(Ref<Resource> p_resource) { if (!p_resource.is_valid()) { - edited_resource = RES(); + edited_resource = Ref<Resource>(); _update_resource(); return; } @@ -837,7 +837,7 @@ void EditorResourcePicker::set_edited_resource(RES p_resource) { _update_resource(); } -RES EditorResourcePicker::get_edited_resource() { +Ref<Resource> EditorResourcePicker::get_edited_resource() { return edited_resource; } diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index cd7e507984..e63280e3b6 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -45,7 +45,7 @@ class EditorResourcePicker : public HBoxContainer { static HashMap<StringName, List<StringName>> allowed_types_cache; String base_type; - RES edited_resource; + Ref<Resource> edited_resource; bool editable = true; bool dropping = false; @@ -113,8 +113,8 @@ public: String get_base_type() const; Vector<String> get_allowed_types() const; - void set_edited_resource(RES p_resource); - RES get_edited_resource(); + void set_edited_resource(Ref<Resource> p_resource); + Ref<Resource> get_edited_resource(); void set_toggle_mode(bool p_enable); bool is_toggle_mode() const; diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 8541918e88..6d5b20e591 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -48,7 +48,7 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const { ERR_FAIL_V_MSG(false, "EditorResourcePreviewGenerator::_handles needs to be overridden."); } -Ref<Texture2D> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorResourcePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Texture2D> preview; if (GDVIRTUAL_CALL(_generate, p_from, p_size, preview)) { return preview; @@ -62,7 +62,7 @@ Ref<Texture2D> EditorResourcePreviewGenerator::generate_from_path(const String & return preview; } - RES res = ResourceLoader::load(p_path); + Ref<Resource> res = ResourceLoader::load(p_path); if (!res.is_valid()) { return res; } diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index 938902a6ad..769340c36f 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -44,14 +44,14 @@ protected: static void _bind_methods(); GDVIRTUAL1RC(bool, _handles, String) - GDVIRTUAL2RC(Ref<Texture2D>, _generate, RES, Vector2i) + GDVIRTUAL2RC(Ref<Texture2D>, _generate, Ref<Resource>, Vector2i) GDVIRTUAL2RC(Ref<Texture2D>, _generate_from_path, String, Vector2i) GDVIRTUAL0RC(bool, _generate_small_preview_automatically) GDVIRTUAL0RC(bool, _can_generate_small_preview) public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; virtual Ref<Texture2D> generate_from_path(const String &p_path, const Size2 &p_size) const; virtual bool generate_small_preview_automatically() const; diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 32d28cd3a7..ec8130e862 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -656,10 +656,7 @@ void EditorSpinSlider::_ensure_input_popup() { } EditorSpinSlider::EditorSpinSlider() { - grabbing_spinner_dist_cache = 0; - pre_grab_value = 0; set_focus_mode(FOCUS_ALL); - updown_offset = -1; grabber = memnew(TextureRect); add_child(grabber); grabber->hide(); @@ -668,5 +665,4 @@ EditorSpinSlider::EditorSpinSlider() { grabber->connect("mouse_entered", callable_mp(this, &EditorSpinSlider::_grabber_mouse_entered)); grabber->connect("mouse_exited", callable_mp(this, &EditorSpinSlider::_grabber_mouse_exited)); grabber->connect("gui_input", callable_mp(this, &EditorSpinSlider::_grabber_gui_input)); - grabber_range = 1; } diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h index fc9f6b8722..f0adf5b7a1 100644 --- a/editor/editor_spin_slider.h +++ b/editor/editor_spin_slider.h @@ -40,41 +40,42 @@ class EditorSpinSlider : public Range { String label; String suffix; - int updown_offset; + int updown_offset = -1; bool hover_updown = false; bool mouse_hover = false; TextureRect *grabber = nullptr; - int grabber_range; + int grabber_range = 1; bool mouse_over_spin = false; bool mouse_over_grabber = false; bool mousewheel_over_grabber = false; bool grabbing_grabber = false; - int grabbing_from; - float grabbing_ratio; + int grabbing_from = 0; + float grabbing_ratio = 0.0f; bool grabbing_spinner_attempt = false; bool grabbing_spinner = false; bool read_only = false; - float grabbing_spinner_dist_cache; + float grabbing_spinner_dist_cache = 0.0f; Vector2 grabbing_spinner_mouse_pos; - double pre_grab_value; + double pre_grab_value = 0.0; Popup *value_input_popup = nullptr; LineEdit *value_input = nullptr; bool value_input_just_closed = false; bool value_input_dirty = false; + bool hide_slider = false; + bool flat = false; + void _grabber_gui_input(const Ref<InputEvent> &p_event); void _value_input_closed(); void _value_input_submitted(const String &); void _value_focus_exited(); void _value_input_gui_input(const Ref<InputEvent> &p_event); - bool hide_slider = false; - bool flat = false; void _evaluate_input_text(); diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index 46fb767c00..0a59ecf1b3 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -311,9 +311,6 @@ void EditorFileServer::stop() { EditorFileServer::EditorFileServer() { server.instantiate(); - quit = false; - active = false; - cmd = CMD_NONE; thread.start(_thread_start, this); EDITOR_DEF("filesystem/file_server/port", 6010); diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index ccebd1465d..7e771db55f 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h @@ -63,12 +63,12 @@ class EditorFileServer : public Object { Mutex wait_mutex; Thread thread; static void _thread_start(void *); - bool quit; - Command cmd; + bool quit = false; + Command cmd = CMD_NONE; String password; - int port; - bool active; + int port = 0; + bool active = false; public: void start(); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 33c6ce9622..41356c1d56 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2025,6 +2025,16 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } } break; + case FILE_COPY_UID: { + if (!p_selected.is_empty()) { + ResourceUID::ID uid = ResourceLoader::get_resource_uid(p_selected[0]); + if (uid != ResourceUID::INVALID_ID) { + String uid_string = ResourceUID::get_singleton()->id_to_text(uid); + DisplayServer::get_singleton()->clipboard_set(uid_string); + } + } + } break; + case FILE_NEW_RESOURCE: { new_resource_dialog->popup_create(true); } break; @@ -2070,7 +2080,7 @@ void FileSystemDock::_resource_created() { } EditorNode::get_singleton()->push_item(r); - EditorNode::get_singleton()->save_resource_as(RES(r), fpath); + EditorNode::get_singleton()->save_resource_as(Ref<Resource>(r), fpath); } void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { @@ -2550,6 +2560,9 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str if (p_paths.size() == 1) { p_popup->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/copy_path"), FILE_COPY_PATH); + if (ResourceLoader::get_resource_uid(p_paths[0]) != ResourceUID::INVALID_ID) { + p_popup->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/copy_uid"), FILE_COPY_UID); + } if (p_paths[0] != "res://") { p_popup->add_icon_shortcut(get_theme_icon(SNAME("Rename"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/rename"), FILE_RENAME); p_popup->add_icon_shortcut(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/duplicate"), FILE_DUPLICATE); @@ -2771,6 +2784,8 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { _tree_rmb_option(FILE_DUPLICATE); } else if (ED_IS_SHORTCUT("filesystem_dock/copy_path", p_event)) { _tree_rmb_option(FILE_COPY_PATH); + } else if (ED_IS_SHORTCUT("filesystem_dock/copy_uid", p_event)) { + _tree_rmb_option(FILE_COPY_UID); } else if (ED_IS_SHORTCUT("filesystem_dock/delete", p_event)) { _tree_rmb_option(FILE_REMOVE); } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { @@ -2999,6 +3014,7 @@ FileSystemDock::FileSystemDock() { // `KeyModifierMask::CMD | Key::C` conflicts with other editor shortcuts. ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::C); + ED_SHORTCUT("filesystem_dock/copy_uid", TTR("Copy UID")); ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KeyModifierMask::CMD | Key::D); ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), Key::KEY_DELETE); ED_SHORTCUT("filesystem_dock/rename", TTR("Rename..."), Key::F2); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 15fade2d95..736651c17c 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -94,6 +94,7 @@ private: FILE_NEW_SCENE, FILE_SHOW_IN_EXPLORER, FILE_COPY_PATH, + FILE_COPY_UID, FILE_NEW_RESOURCE, FILE_NEW_TEXTFILE, FOLDER_EXPAND_ALL, diff --git a/editor/icons/RandomNumberGenerator.svg b/editor/icons/RandomNumberGenerator.svg new file mode 100644 index 0000000000..214a7452ed --- /dev/null +++ b/editor/icons/RandomNumberGenerator.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.0000004 0c-7.63857653 0-8.0000004.36172395-8.0000004 8.0066027 0 7.6431663.32714821 7.9720723 7.9277171 7.9929163 3.4504629.00951 5.0807119-.12114 5.9272279-.475116 1.794714-.750503 2.145055-1.974798 2.145055-7.5178003 0-7.64487875-.361425-8.0066027-7.9999996-8.0066027zm-4.0341882 2.0158259c1.7899451 0 2.786201 2.0256492 1.6859585 3.4255356-.8444948 1.0744791-2.3331923 1.1725336-3.2879122.2170288-1.3527384-1.3538547-.3466043-3.6425644 1.6019537-3.6425644zm4.0869355 3.7383699c1.7899399 0 2.7862023 2.0236959 1.6859586 3.4235804-.8444989 1.0745018-2.3331926 1.1744878-3.2879123.218984-1.3527384-1.3538549-.3466055-3.6425644 1.6019537-3.6425644zm4.0615383 3.9690852c1.09547.036419 2.143101.848375 2.143101 2.113587 0 1.788519-2.569649 2.876024-3.713797 1.571993-.9034489-1.029694-.9772793-1.902694-.23834-2.842882.476145-.6058151 1.151756-.8645864 1.809036-.842698z" fill="#fff" stroke-width=".256504"/></svg> diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index bdb0c3c493..34079d0a4b 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -181,7 +181,7 @@ Variant EditorScenePostImportPlugin::get_internal_option_update_view_required(In return ret; } -void EditorScenePostImportPlugin::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, RES p_resource, const Dictionary &p_options) { +void EditorScenePostImportPlugin::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) { current_options_dict = &p_options; GDVIRTUAL_CALL(_internal_process, p_category, p_base_scene, p_node, p_resource); current_options_dict = nullptr; @@ -736,7 +736,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< { ObjectID node_id = p_node->get_instance_id(); for (int i = 0; i < post_importer_plugins.size(); i++) { - post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_NODE, p_root, p_node, RES(), node_settings); + post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_NODE, p_root, p_node, Ref<Resource>(), node_settings); if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue break; } @@ -746,7 +746,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< if (Object::cast_to<ImporterMeshInstance3D>(p_node)) { ObjectID node_id = p_node->get_instance_id(); for (int i = 0; i < post_importer_plugins.size(); i++) { - post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, p_root, p_node, RES(), node_settings); + post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, p_root, p_node, Ref<Resource>(), node_settings); if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue break; } @@ -953,7 +953,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< } for (int i = 0; i < post_importer_plugins.size(); i++) { - post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, RES(), node_settings); + post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, Ref<Resource>(), node_settings); } bool use_optimizer = node_settings["optimizer/enabled"]; diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 368f68ae8f..ac72a8f39d 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -119,7 +119,7 @@ protected: GDVIRTUAL1(_get_internal_import_options, int) GDVIRTUAL3RC(Variant, _get_internal_option_visibility, int, bool, String) GDVIRTUAL2RC(Variant, _get_internal_option_update_view_required, int, String) - GDVIRTUAL4(_internal_process, int, Node *, Node *, RES) + GDVIRTUAL4(_internal_process, int, Node *, Node *, Ref<Resource>) GDVIRTUAL1(_get_import_options, String) GDVIRTUAL3RC(Variant, _get_option_visibility, String, bool, String) GDVIRTUAL1(_pre_process, Node *) @@ -136,7 +136,7 @@ public: virtual Variant get_internal_option_visibility(InternalImportCategory p_category, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options) const; virtual Variant get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, RES p_resource, const Dictionary &p_options); + virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options); virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options); virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const Map<StringName, Variant> &p_options) const; diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index b08622b910..8866794505 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -558,6 +558,8 @@ void SceneImportSettings::open_settings(const String &p_path, bool p_for_animati node_map.clear(); defaults.clear(); + mesh_preview->hide(); + selected_id = ""; selected_type = ""; diff --git a/editor/import/scene_import_settings.h b/editor/import/scene_import_settings.h index 55cfba3275..ec24a8a5a5 100644 --- a/editor/import/scene_import_settings.h +++ b/editor/import/scene_import_settings.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENEIMPORTSETTINGS_H -#define SCENEIMPORTSETTINGS_H +#ifndef SCENE_IMPORT_SETTINGS_H +#define SCENE_IMPORT_SETTINGS_H #include "editor/import/resource_importer_scene.h" #include "scene/3d/camera_3d.h" @@ -86,9 +86,9 @@ class SceneImportSettings : public ConfirmationDialog { Ref<StandardMaterial3D> collider_mat; - float cam_rot_x; - float cam_rot_y; - float cam_zoom; + float cam_rot_x = 0.0f; + float cam_rot_y = 0.0f; + float cam_zoom = 0.0f; void _update_scene(); @@ -176,7 +176,7 @@ class SceneImportSettings : public ConfirmationDialog { void _menu_callback(int p_id); void _save_dir_callback(const String &p_path); - int current_action; + int current_action = 0; Vector<TreeItem *> save_path_items; @@ -205,4 +205,4 @@ public: ~SceneImportSettings(); }; -#endif // SCENEIMPORTSETTINGS_H +#endif // SCENE_IMPORT_SETTINGS_H diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index f0fe48f4fc..a62d1af477 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -117,8 +117,8 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { } Variant v = current->get(E->get().name); - REF ref = v; - RES res = ref; + Ref<RefCounted> ref = v; + Ref<Resource> res = ref; if (v.is_ref_counted() && ref.is_valid() && res.is_valid()) { // Valid resource which would be duplicated if action is confirmed. resource_propnames.append(E->get().name); @@ -149,7 +149,7 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { if (current) { List<PropertyInfo> props; current->get_property_list(&props); - Map<RES, RES> duplicates; + Map<Ref<Resource>, Ref<Resource>> duplicates; for (const PropertyInfo &prop_info : props) { if (!(prop_info.usage & PROPERTY_USAGE_STORAGE)) { continue; @@ -157,9 +157,9 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { Variant v = current->get(prop_info.name); if (v.is_ref_counted()) { - REF ref = v; + Ref<RefCounted> ref = v; if (ref.is_valid()) { - RES res = ref; + Ref<Resource> res = ref; if (res.is_valid()) { if (!duplicates.has(res)) { duplicates[res] = res->duplicate(); @@ -231,7 +231,7 @@ void InspectorDock::_load_resource(const String &p_type) { } void InspectorDock::_resource_file_selected(String p_file) { - RES res; + Ref<Resource> res; if (ResourceLoader::exists(p_file, "")) { res = ResourceLoader::load(p_file); } else { @@ -255,7 +255,7 @@ void InspectorDock::_save_resource(bool save_as) { ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); - RES current_res = RES(Object::cast_to<Resource>(current_obj)); + Ref<Resource> current_res = Ref<Resource>(Object::cast_to<Resource>(current_obj)); if (save_as) { EditorNode::get_singleton()->save_resource_as(current_res); @@ -270,7 +270,7 @@ void InspectorDock::_unref_resource() { ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); - RES current_res = RES(Object::cast_to<Resource>(current_obj)); + Ref<Resource> current_res = Ref<Resource>(Object::cast_to<Resource>(current_obj)); current_res->set_path(""); EditorNode::get_singleton()->edit_current(); } @@ -281,20 +281,20 @@ void InspectorDock::_copy_resource() { ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); - RES current_res = RES(Object::cast_to<Resource>(current_obj)); + Ref<Resource> current_res = Ref<Resource>(Object::cast_to<Resource>(current_obj)); EditorSettings::get_singleton()->set_resource_clipboard(current_res); } void InspectorDock::_paste_resource() { - RES r = EditorSettings::get_singleton()->get_resource_clipboard(); + Ref<Resource> r = EditorSettings::get_singleton()->get_resource_clipboard(); if (r.is_valid()) { EditorNode::get_singleton()->push_item(EditorSettings::get_singleton()->get_resource_clipboard().ptr(), String()); } } void InspectorDock::_prepare_resource_extra_popup() { - RES r = EditorSettings::get_singleton()->get_resource_clipboard(); + Ref<Resource> r = EditorSettings::get_singleton()->get_resource_clipboard(); PopupMenu *popup = resource_extra_button->get_popup(); popup->set_item_disabled(popup->get_item_index(RESOURCE_EDIT_CLIPBOARD), r.is_null()); } @@ -370,12 +370,12 @@ void InspectorDock::_resource_created() { EditorNode::get_singleton()->push_item(r); } -void InspectorDock::_resource_selected(const RES &p_res, const String &p_property) { +void InspectorDock::_resource_selected(const Ref<Resource> &p_res, const String &p_property) { if (p_res.is_null()) { return; } - RES r = p_res; + Ref<Resource> r = p_res; EditorNode::get_singleton()->push_item(r.operator->(), p_property); } diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 86733c992d..1f2d8afb7d 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -118,7 +118,7 @@ class InspectorDock : public VBoxContainer { void _warning_pressed(); void _resource_created(); - void _resource_selected(const RES &p_res, const String &p_property); + void _resource_selected(const Ref<Resource> &p_res, const String &p_property); void _edit_forward(); void _edit_back(); void _menu_collapseall(); diff --git a/editor/plugin_config_dialog.h b/editor/plugin_config_dialog.h index 76fec636f3..5c6043da12 100644 --- a/editor/plugin_config_dialog.h +++ b/editor/plugin_config_dialog.h @@ -54,7 +54,7 @@ class PluginConfigDialog : public ConfirmationDialog { TextureRect *subfolder_validation = nullptr; TextureRect *script_validation = nullptr; - bool _edit_mode; + bool _edit_mode = false; void _clear_fields(); void _on_confirmed(); diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 22e0a3dabb..ad6d8e6379 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -703,10 +703,8 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c } AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) { - canvas_item_editor = nullptr; undo_redo = EditorNode::get_undo_redo(); - wip_active = false; edited_point = PosVertex(); wip_destructive = p_wip_destructive; @@ -736,8 +734,6 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) { create_resource = memnew(ConfirmationDialog); add_child(create_resource); create_resource->get_ok_button()->set_text(TTR("Create")); - - mode = MODE_EDIT; } void AbstractPolygon2DEditorPlugin::edit(Object *p_object) { diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index b0483cbb62..696fd7b637 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -80,10 +80,10 @@ class AbstractPolygon2DEditor : public HBoxContainer { Vector<Vector2> pre_move_edit; Vector<Vector2> wip; - bool wip_active; - bool wip_destructive; + bool wip_active = false; + bool wip_destructive = false; - bool _polygon_editing_enabled; + bool _polygon_editing_enabled = false; CanvasItemEditor *canvas_item_editor = nullptr; Panel *panel = nullptr; @@ -97,7 +97,7 @@ protected: MODE_CONT, }; - int mode; + int mode = MODE_EDIT; UndoRedo *undo_redo = nullptr; diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 94882b3464..ae4482155c 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -594,7 +594,6 @@ AnimationNodeBlendSpace1DEditor *AnimationNodeBlendSpace1DEditor::singleton = nu AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { singleton = this; - updating = false; HBoxContainer *top_hb = memnew(HBoxContainer); add_child(top_hb); @@ -745,9 +744,5 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_file_opened)); undo_redo = EditorNode::get_undo_redo(); - selected_point = -1; - dragging_selected = false; - dragging_selected_attempt = false; - set_custom_minimum_size(Size2(0, 150 * EDSCALE)); } diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index 816c2555ca..2f7dee65fc 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -65,14 +65,14 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { SpinBox *edit_value = nullptr; Button *open_editor = nullptr; - int selected_point; + int selected_point = -1; Control *blend_space_draw = nullptr; PanelContainer *error_panel = nullptr; Label *error_label = nullptr; - bool updating; + bool updating = false; UndoRedo *undo_redo = nullptr; @@ -90,11 +90,11 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { PopupMenu *menu = nullptr; PopupMenu *animations_menu = nullptr; Vector<String> animations_to_add; - float add_point_pos; + float add_point_pos = 0.0f; Vector<real_t> points; - bool dragging_selected_attempt; - bool dragging_selected; + bool dragging_selected_attempt = false; + bool dragging_selected = false; Vector2 drag_from; Vector2 drag_ofs; diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 42f17965ce..d3f25d7a85 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -42,6 +42,8 @@ #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" +#include "scene/gui/tree.h" +#include "scene/main/viewport.h" #include "scene/main/window.h" bool AnimationNodeStateMachineEditor::can_edit(const Ref<AnimationNode> &p_node) { @@ -55,7 +57,10 @@ void AnimationNodeStateMachineEditor::edit(const Ref<AnimationNode> &p_node) { if (state_machine.is_valid()) { selected_transition_from = StringName(); selected_transition_to = StringName(); + selected_transition_index = -1; + selected_multi_transition = TransitionLine(); selected_node = StringName(); + selected_nodes.clear(); _update_mode(); _update_graph(); } @@ -69,71 +74,39 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv Ref<InputEventKey> k = p_event; if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_keycode() == Key::KEY_DELETE && !k->is_echo()) { - if (selected_node != StringName() || selected_transition_to != StringName() || selected_transition_from != StringName()) { + if (selected_node != StringName() || !selected_nodes.is_empty() || selected_transition_to != StringName() || selected_transition_from != StringName()) { _erase_selected(); accept_event(); } } - Ref<InputEventMouseButton> mb = p_event; - - //Add new node - if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == MouseButton::LEFT))) { - menu->clear(); - animations_menu->clear(); - animations_to_add.clear(); - List<StringName> classes; - classes.sort_custom<StringName::AlphCompare>(); - - ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); - menu->add_submenu_item(TTR("Add Animation"), "animations"); - - AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_tree(); - ERR_FAIL_COND(!gp); - if (gp && gp->has_node(gp->get_animation_player())) { - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); - if (ap) { - List<StringName> names; - ap->get_animation_list(&names); - for (const StringName &E : names) { - animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E); - animations_to_add.push_back(E); - } - } - } + // Group selected nodes on a state machine + if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->is_ctrl_pressed() && !k->is_shift_pressed() && k->get_keycode() == Key::G && !k->is_echo()) { + _group_selected_nodes(); + } - for (const StringName &E : classes) { - String name = String(E).replace_first("AnimationNode", ""); - if (name == "Animation") { - continue; // nope - } - int idx = menu->get_item_count(); - menu->add_item(vformat(TTR("Add %s"), name), idx); - menu->set_item_metadata(idx, E); - } - Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard(); + // Ungroup state machine + if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->is_ctrl_pressed() && k->is_shift_pressed() && k->get_keycode() == Key::G && !k->is_echo()) { + _ungroup_selected_nodes(); + } - if (clipb.is_valid()) { - menu->add_separator(); - menu->add_item(TTR("Paste"), MENU_PASTE); - } - menu->add_separator(); - menu->add_item(TTR("Load..."), MENU_LOAD_FILE); + Ref<InputEventMouseButton> mb = p_event; - menu->set_position(state_machine_draw->get_screen_position() + mb->get_position()); - menu->reset_size(); - menu->popup(); - add_node_pos = mb->get_position() / EDSCALE + state_machine->get_graph_offset(); + // Add new node + if (mb.is_valid() && mb->is_pressed() && !box_selecting && !connecting && ((tool_select->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == MouseButton::LEFT))) { + connecting_from = StringName(); + _open_menu(mb->get_position()); } - // select node or push a field inside - if (mb.is_valid() && !mb->is_shift_pressed() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { + // Select node or push a field inside + if (mb.is_valid() && !mb->is_shift_pressed() && !mb->is_ctrl_pressed() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { selected_transition_from = StringName(); selected_transition_to = StringName(); + selected_transition_index = -1; + selected_multi_transition = TransitionLine(); selected_node = StringName(); for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order - if (node_rects[i].play.has_point(mb->get_position())) { //edit name if (play_mode->get_selected() == 1 || !playback->is_playing()) { //start @@ -146,8 +119,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv return; } - if (node_rects[i].name.has_point(mb->get_position())) { //edit name - + if (node_rects[i].name.has_point(mb->get_position()) && state_machine->can_edit_node(node_rects[i].node_name)) { // edit name Ref<StyleBox> line_sb = get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")); Rect2 edit_rect = node_rects[i].name; @@ -173,6 +145,12 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected selected_node = node_rects[i].node_name; + if (!selected_nodes.has(selected_node)) { + selected_nodes.clear(); + } + + selected_nodes.insert(selected_node); + Ref<AnimationNode> anode = state_machine->get_node(selected_node); EditorNode::get_singleton()->push_item(anode.ptr(), "", true); state_machine_draw->update(); @@ -209,23 +187,53 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (closest >= 0) { selected_transition_from = transition_lines[closest].from_node; selected_transition_to = transition_lines[closest].to_node; + selected_transition_index = closest; Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(closest); EditorNode::get_singleton()->push_item(tr.ptr(), "", true); + + if (!transition_lines[closest].multi_transitions.is_empty()) { + selected_transition_index = -1; + selected_multi_transition = transition_lines[closest]; + + Ref<EditorAnimationMultiTransitionEdit> multi; + multi.instantiate(); + multi->add_transition(selected_transition_from, selected_transition_to, tr); + + for (int i = 0; i < transition_lines[closest].multi_transitions.size(); i++) { + int index = transition_lines[closest].multi_transitions[i].transition_index; + + Ref<AnimationNodeStateMachineTransition> transition = state_machine->get_transition(index); + StringName from = transition_lines[closest].multi_transitions[i].from_node; + StringName to = transition_lines[closest].multi_transitions[i].to_node; + + multi->add_transition(from, to, transition); + } + EditorNode::get_singleton()->push_item(multi.ptr(), "", true); + } } state_machine_draw->update(); _update_mode(); } - //end moving node + // End moving node if (mb.is_valid() && dragging_selected_attempt && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { if (dragging_selected) { Ref<AnimationNode> an = state_machine->get_node(selected_node); updating = true; + undo_redo->create_action(TTR("Move Node")); - undo_redo->add_do_method(state_machine.ptr(), "set_node_position", selected_node, state_machine->get_node_position(selected_node) + drag_ofs / EDSCALE); - undo_redo->add_undo_method(state_machine.ptr(), "set_node_position", selected_node, state_machine->get_node_position(selected_node)); + + for (int i = 0; i < node_rects.size(); i++) { + if (!selected_nodes.has(node_rects[i].node_name)) { + continue; + } + + undo_redo->add_do_method(state_machine.ptr(), "set_node_position", node_rects[i].node_name, state_machine->get_node_position(node_rects[i].node_name) + drag_ofs / EDSCALE); + undo_redo->add_undo_method(state_machine.ptr(), "set_node_position", node_rects[i].node_name, state_machine->get_node_position(node_rects[i].node_name)); + } + undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -239,7 +247,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv state_machine_draw->update(); } - //connect nodes + // Connect nodes if (mb.is_valid() && ((tool_select->is_pressed() && mb->is_shift_pressed()) || tool_connect->is_pressed()) && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected @@ -252,47 +260,63 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } } - //end connecting nodes + // End connecting nodes if (mb.is_valid() && connecting && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { if (connecting_to_node != StringName()) { - if (state_machine->has_transition(connecting_from, connecting_to_node)) { - EditorNode::get_singleton()->show_warning(TTR("Transition exists!")); + Ref<AnimationNode> node = state_machine->get_node(connecting_to_node); + Ref<AnimationNodeStateMachine> anodesm = node; + Ref<AnimationNodeEndState> end_node = node; + if (state_machine->has_transition(connecting_from, connecting_to_node) && state_machine->can_edit_node(connecting_to_node) && !anodesm.is_valid()) { + EditorNode::get_singleton()->show_warning(TTR("Transition exists!")); + connecting = false; } else { - Ref<AnimationNodeStateMachineTransition> tr; - tr.instantiate(); - tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected())); - - updating = true; - undo_redo->create_action(TTR("Add Transition")); - undo_redo->add_do_method(state_machine.ptr(), "add_transition", connecting_from, connecting_to_node, tr); - undo_redo->add_undo_method(state_machine.ptr(), "remove_transition", connecting_from, connecting_to_node); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - updating = false; - - selected_transition_from = connecting_from; - selected_transition_to = connecting_to_node; - - EditorNode::get_singleton()->push_item(tr.ptr(), "", true); - _update_mode(); + if (anodesm.is_valid() || end_node.is_valid()) { + _open_connect_menu(mb->get_position()); + } else { + _add_transition(); + } } + } else { + _open_menu(mb->get_position()); } connecting_to_node = StringName(); - connecting = false; state_machine_draw->update(); } + // Start box selecting + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && tool_select->is_pressed()) { + box_selecting = true; + box_selecting_from = box_selecting_to = state_machine_draw->get_local_mouse_position(); + box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x), + MIN(box_selecting_from.y, box_selecting_to.y), + ABS(box_selecting_from.x - box_selecting_to.x), + ABS(box_selecting_from.y - box_selecting_to.y)); + + if (mb->is_ctrl_pressed() || mb->is_shift_pressed()) { + previous_selected = selected_nodes; + } else { + selected_nodes.clear(); + previous_selected.clear(); + } + } + + // End box selecting + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed() && box_selecting) { + box_selecting = false; + state_machine_draw->update(); + _update_mode(); + } + Ref<InputEventMouseMotion> mm = p_event; - //pan window + // Pan window if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } - //move mouse while connecting + // Move mouse while connecting if (mm.is_valid() && connecting) { connecting_to = mm->get_position(); connecting_to_node = StringName(); @@ -306,7 +330,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } } - //move mouse while moving a node + // Move mouse while moving a node if (mm.is_valid() && dragging_selected_attempt) { dragging_selected = true; drag_ofs = mm->get_position() - drag_from; @@ -353,6 +377,11 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv int new_over_node_what = -1; if (tool_select->is_pressed()) { for (int i = node_rects.size() - 1; i >= 0; i--) { // Inverse to draw order. + + if (!state_machine->can_edit_node(node_rects[i].node_name)) { + continue; // start/end node can't be edited + } + if (node_rects[i].node.has_point(mm->get_position())) { new_over_node = node_rects[i].node_name; if (node_rects[i].play.has_point(mm->get_position())) { @@ -370,6 +399,43 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv over_node_what = new_over_node_what; state_machine_draw->update(); } + + // set tooltip for transition + if (tool_select->is_pressed()) { + int closest = -1; + float closest_d = 1e20; + for (int i = 0; i < transition_lines.size(); i++) { + Vector2 s[2] = { + transition_lines[i].from, + transition_lines[i].to + }; + Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mm->get_position(), s); + float d = cpoint.distance_to(mm->get_position()); + if (d > transition_lines[i].width) { + continue; + } + + if (d < closest_d) { + closest = i; + closest_d = d; + } + } + + if (closest >= 0) { + String from = String(transition_lines[closest].from_node); + String to = String(transition_lines[closest].to_node); + String tooltip = from + " -> " + to; + + for (int i = 0; i < transition_lines[closest].multi_transitions.size(); i++) { + from = String(transition_lines[closest].multi_transitions[i].from_node); + to = String(transition_lines[closest].multi_transitions[i].to_node); + tooltip += "\n" + from + " -> " + to; + } + state_machine_draw->set_tooltip(tooltip); + } else { + state_machine_draw->set_tooltip(""); + } + } } Ref<InputEventPanGesture> pan_gesture = p_event; @@ -396,6 +462,458 @@ Control::CursorShape AnimationNodeStateMachineEditor::get_cursor_shape(const Poi return cursor_shape; } +void AnimationNodeStateMachineEditor::_group_selected_nodes() { + if (!selected_nodes.is_empty()) { + if (selected_nodes.size() == 1 && (selected_nodes.front()->get() == state_machine->start_node || selected_nodes.front()->get() == state_machine->end_node)) + return; + + Ref<AnimationNodeStateMachine> group_sm = memnew(AnimationNodeStateMachine); + Vector2 group_position; + + Vector<NodeUR> nodes_ur; + Vector<TransitionUR> transitions_ur; + + int base = 1; + String base_name = group_sm->get_caption(); + String group_name = base_name; + + while (state_machine->has_node(group_name) && !selected_nodes.has(group_name)) { + base++; + group_name = base_name + " " + itos(base); + } + + updating = true; + undo_redo->create_action("Group"); + + // Move selected nodes to the new state machine + for (const StringName &E : selected_nodes) { + if (!state_machine->can_edit_node(E)) { + continue; + } + + Ref<AnimationNode> node = state_machine->get_node(E); + Vector2 node_position = state_machine->get_node_position(E); + group_position += node_position; + + NodeUR new_node; + new_node.name = E; + new_node.node = node; + new_node.position = node_position; + + nodes_ur.push_back(new_node); + } + + // Add the transitions to the new state machine + for (int i = 0; i < state_machine->get_transition_count(); i++) { + String from = state_machine->get_transition_from(i); + String to = state_machine->get_transition_to(i); + + String local_from = from.get_slicec('/', 0); + String local_to = to.get_slicec('/', 0); + + String old_from = from; + String old_to = to; + + bool from_selected = false; + bool to_selected = false; + + if (selected_nodes.has(local_from) && local_from != state_machine->start_node) { + from_selected = true; + } + if (selected_nodes.has(local_to) && local_to != state_machine->end_node) { + to_selected = true; + } + if (!from_selected && !to_selected) { + continue; + } + + Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(i); + + if (!from_selected) { + from = "../" + old_from; + } + if (!to_selected) { + to = "../" + old_to; + } + + TransitionUR new_tr; + new_tr.new_from = from; + new_tr.new_to = to; + new_tr.old_from = old_from; + new_tr.old_to = old_to; + new_tr.transition = tr; + + transitions_ur.push_back(new_tr); + } + + for (int i = 0; i < nodes_ur.size(); i++) { + undo_redo->add_do_method(state_machine.ptr(), "remove_node", nodes_ur[i].name); + undo_redo->add_undo_method(group_sm.ptr(), "remove_node", nodes_ur[i].name); + } + + undo_redo->add_do_method(state_machine.ptr(), "add_node", group_name, group_sm, group_position / nodes_ur.size()); + undo_redo->add_undo_method(state_machine.ptr(), "remove_node", group_name); + + for (int i = 0; i < nodes_ur.size(); i++) { + undo_redo->add_do_method(group_sm.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + undo_redo->add_undo_method(state_machine.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + } + + for (int i = 0; i < transitions_ur.size(); i++) { + undo_redo->add_do_method(group_sm.ptr(), "add_transition", transitions_ur[i].new_from, transitions_ur[i].new_to, transitions_ur[i].transition); + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", transitions_ur[i].old_from, transitions_ur[i].old_to, transitions_ur[i].transition); + } + + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + + selected_nodes.clear(); + selected_nodes.insert(group_name); + state_machine_draw->update(); + accept_event(); + _update_mode(); + } +} + +void AnimationNodeStateMachineEditor::_ungroup_selected_nodes() { + bool find = false; + Set<StringName> new_selected_nodes; + + for (const StringName &E : selected_nodes) { + Ref<AnimationNodeStateMachine> group_sm = state_machine->get_node(E); + + if (group_sm.is_valid()) { + find = true; + + Vector2 group_position = state_machine->get_node_position(E); + StringName group_name = E; + + List<AnimationNode::ChildNode> nodes; + group_sm->get_child_nodes(&nodes); + + Vector<NodeUR> nodes_ur; + Vector<TransitionUR> transitions_ur; + + updating = true; + undo_redo->create_action("Ungroup"); + + // Move all child nodes to current state machine + for (int i = 0; i < nodes.size(); i++) { + if (!group_sm->can_edit_node(nodes[i].name)) { + continue; + } + + Vector2 node_position = group_sm->get_node_position(nodes[i].name); + + NodeUR new_node; + new_node.name = nodes[i].name; + new_node.position = node_position; + new_node.node = nodes[i].node; + + nodes_ur.push_back(new_node); + } + + for (int i = 0; i < group_sm->get_transition_count(); i++) { + String from = group_sm->get_transition_from(i); + String to = group_sm->get_transition_to(i); + Ref<AnimationNodeStateMachineTransition> tr = group_sm->get_transition(i); + + TransitionUR new_tr; + new_tr.new_from = from.replace_first("../", ""); + new_tr.new_to = to.replace_first("../", ""); + new_tr.old_from = from; + new_tr.old_to = to; + new_tr.transition = tr; + + transitions_ur.push_back(new_tr); + } + + for (int i = 0; i < nodes_ur.size(); i++) { + undo_redo->add_do_method(group_sm.ptr(), "remove_node", nodes_ur[i].name); + undo_redo->add_undo_method(state_machine.ptr(), "remove_node", nodes_ur[i].name); + } + + undo_redo->add_do_method(state_machine.ptr(), "remove_node", group_name); + undo_redo->add_undo_method(state_machine.ptr(), "add_node", group_name, group_sm, group_position); + + for (int i = 0; i < nodes_ur.size(); i++) { + new_selected_nodes.insert(nodes_ur[i].name); + undo_redo->add_do_method(state_machine.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + undo_redo->add_undo_method(group_sm.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + } + + for (int i = 0; i < transitions_ur.size(); i++) { + if (transitions_ur[i].old_from != state_machine->start_node && transitions_ur[i].old_to != state_machine->end_node) { + undo_redo->add_do_method(state_machine.ptr(), "add_transition", transitions_ur[i].new_from, transitions_ur[i].new_to, transitions_ur[i].transition); + } + + undo_redo->add_undo_method(group_sm.ptr(), "add_transition", transitions_ur[i].old_from, transitions_ur[i].old_to, transitions_ur[i].transition); + } + + for (int i = 0; i < state_machine->get_transition_count(); i++) { + String from = state_machine->get_transition_from(i); + String to = state_machine->get_transition_to(i); + Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(i); + + if (from == group_name || to == group_name) { + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", from, to, tr); + } + } + + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + } + } + + if (find) { + selected_nodes = new_selected_nodes; + selected_node = StringName(); + state_machine_draw->update(); + accept_event(); + _update_mode(); + } +} + +void AnimationNodeStateMachineEditor::_open_menu(const Vector2 &p_position) { + menu->clear(); + animations_menu->clear(); + animations_to_add.clear(); + List<StringName> classes; + classes.sort_custom<StringName::AlphCompare>(); + + ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); + menu->add_submenu_item(TTR("Add Animation"), "animations"); + + AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_tree(); + ERR_FAIL_COND(!gp); + if (gp && gp->has_node(gp->get_animation_player())) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); + if (ap) { + List<StringName> names; + ap->get_animation_list(&names); + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + animations_menu->add_icon_item(get_theme_icon("Animation", "EditorIcons"), E->get()); + animations_to_add.push_back(E->get()); + } + } + } + + for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { + String name = String(E->get()).replace_first("AnimationNode", ""); + if (name == "Animation" || name == "StartState" || name == "EndState") { + continue; // nope + } + int idx = menu->get_item_count(); + menu->add_item(vformat(TTR("Add %s"), name), idx); + menu->set_item_metadata(idx, E->get()); + } + Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard(); + + if (clipb.is_valid()) { + menu->add_separator(); + menu->add_item(TTR("Paste"), MENU_PASTE); + } + menu->add_separator(); + menu->add_item(TTR("Load..."), MENU_LOAD_FILE); + + menu->set_position(state_machine_draw->get_screen_transform().xform(p_position)); + menu->popup(); + add_node_pos = p_position / EDSCALE + state_machine->get_graph_offset(); +} + +void AnimationNodeStateMachineEditor::_open_connect_menu(const Vector2 &p_position) { + ERR_FAIL_COND(connecting_to_node == StringName()); + + Ref<AnimationNode> node = state_machine->get_node(connecting_to_node); + Ref<AnimationNodeStateMachine> anodesm = node; + Ref<AnimationNodeEndState> end_node = node; + ERR_FAIL_COND(!anodesm.is_valid() && !end_node.is_valid()); + + connect_menu->clear(); + state_machine_menu->clear(); + end_menu->clear(); + nodes_to_connect.clear(); + + for (int i = connect_menu->get_child_count() - 1; i >= 0; i--) { + Node *child = connect_menu->get_child(i); + + if (child->is_class("PopupMenu")) { + connect_menu->remove_child(child); + } + } + + connect_menu->reset_size(); + state_machine_menu->reset_size(); + end_menu->reset_size(); + + if (anodesm.is_valid()) { + _create_submenu(connect_menu, anodesm, connecting_to_node, connecting_to_node); + } else { + Ref<AnimationNodeStateMachine> prev = state_machine; + _create_submenu(connect_menu, prev, connecting_to_node, connecting_to_node, true); + } + + connect_menu->add_submenu_item(TTR("To") + " Animation", connecting_to_node); + + if (state_machine_menu->get_item_count() > 0 || !end_node.is_valid()) { + connect_menu->add_submenu_item(TTR("To") + " StateMachine", "state_machines"); + connect_menu->add_child(state_machine_menu); + } + + if (end_node.is_valid()) { + connect_menu->add_submenu_item(TTR("To") + " End", "end_nodes"); + connect_menu->add_child(end_menu); + } else { + state_machine_menu->add_item(connecting_to_node, nodes_to_connect.size()); + } + + nodes_to_connect.push_back(connecting_to_node); + + if (nodes_to_connect.size() == 1) { + _add_transition(); + return; + } + + connect_menu->set_position(state_machine_draw->get_screen_transform().xform(p_position)); + connect_menu->popup(); +} + +bool AnimationNodeStateMachineEditor::_create_submenu(PopupMenu *p_menu, Ref<AnimationNodeStateMachine> p_nodesm, const StringName &p_name, const StringName &p_path, bool from_root, Vector<Ref<AnimationNodeStateMachine>> p_parents) { + String prev_path; + Vector<Ref<AnimationNodeStateMachine>> parents = p_parents; + + if (from_root) { + Ref<AnimationNodeStateMachine> prev = p_nodesm->get_prev_state_machine(); + + while (prev.is_valid()) { + parents.push_back(prev); + p_nodesm = prev; + prev_path += "../"; + prev = prev->get_prev_state_machine(); + } + prev_path.remove_at(prev_path.size() - 1); + } + + List<StringName> nodes; + p_nodesm->get_node_list(&nodes); + + PopupMenu *nodes_menu = memnew(PopupMenu); + nodes_menu->set_name(p_name); + nodes_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + p_menu->add_child(nodes_menu); + + bool node_added = false; + for (const StringName &E : nodes) { + if (p_nodesm->can_edit_node(E)) { + Ref<AnimationNodeStateMachine> ansm = p_nodesm->get_node(E); + + String path; + if (from_root) { + path = prev_path + "/" + E; + } else { + path = String(p_path) + "/" + E; + } + + if (ansm == state_machine) { + end_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(state_machine->end_node); + continue; + } + + if (ansm.is_valid()) { + bool found = false; + + for (int i = 0; i < parents.size(); i++) { + if (parents[i] == ansm) { + path = path.replace_first("/../" + E, ""); + found = true; + break; + } + } + + if (!found) { + state_machine_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(path); + } else { + end_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(path + "/" + state_machine->end_node); + } + + if (_create_submenu(nodes_menu, ansm, E, path, false, parents)) { + nodes_menu->add_submenu_item(E, E); + node_added = true; + } + } else { + nodes_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(path); + node_added = true; + } + } + } + + return node_added; +} + +void AnimationNodeStateMachineEditor::_stop_connecting() { + connecting = false; + state_machine_draw->update(); +} + +void AnimationNodeStateMachineEditor::_delete_selected() { + TreeItem *item = delete_tree->get_next_selected(nullptr); + while (item) { + if (!updating) { + updating = true; + selected_multi_transition = TransitionLine(); + undo_redo->create_action("Transition(s) Removed"); + } + + Vector<String> path = item->get_text(0).split(" -> "); + + selected_transition_from = path[0]; + selected_transition_to = path[1]; + _erase_selected(true); + + item = delete_tree->get_next_selected(item); + } + + if (updating) { + undo_redo->commit_action(); + updating = false; + } +} + +void AnimationNodeStateMachineEditor::_delete_all() { + Vector<TransitionLine> multi_transitions = selected_multi_transition.multi_transitions; + selected_multi_transition = TransitionLine(); + + updating = true; + undo_redo->create_action("Transition(s) Removed"); + _erase_selected(true); + for (int i = 0; i < multi_transitions.size(); i++) { + selected_transition_from = multi_transitions[i].from_node; + selected_transition_to = multi_transitions[i].to_node; + _erase_selected(true); + } + undo_redo->commit_action(); + updating = false; + + delete_window->hide(); +} + +void AnimationNodeStateMachineEditor::_delete_tree_draw() { + TreeItem *item = delete_tree->get_next_selected(nullptr); + while (item) { + delete_window->get_cancel_button()->set_disabled(false); + return; + } + delete_window->get_cancel_button()->set_disabled(true); +} + void AnimationNodeStateMachineEditor::_file_opened(const String &p_file) { file_loaded = ResourceLoader::load(p_file); if (file_loaded.is_valid()) { @@ -456,6 +974,8 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) { undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); + connecting_to_node = name; + _add_transition(true); undo_redo->commit_action(); updating = false; @@ -482,13 +1002,58 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); + connecting_to_node = name; + _add_transition(true); undo_redo->commit_action(); updating = false; state_machine_draw->update(); } -void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance) { +void AnimationNodeStateMachineEditor::_connect_to(int p_index) { + connecting_to_node = nodes_to_connect[p_index]; + _add_transition(); +} + +void AnimationNodeStateMachineEditor::_add_transition(const bool p_nested_action) { + if (connecting_from != StringName() && connecting_to_node != StringName()) { + if (state_machine->has_transition(connecting_from, connecting_to_node)) { + EditorNode::get_singleton()->show_warning("Transition exists!"); + connecting = false; + return; + } + + Ref<AnimationNodeStateMachineTransition> tr; + tr.instantiate(); + tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected())); + + if (!p_nested_action) { + updating = true; + } + + undo_redo->create_action(TTR("Add Transition")); + undo_redo->add_do_method(state_machine.ptr(), "add_transition", connecting_from, connecting_to_node, tr); + undo_redo->add_undo_method(state_machine.ptr(), "remove_transition", connecting_from, connecting_to_node); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + + if (!p_nested_action) { + updating = false; + } + + selected_transition_from = connecting_from; + selected_transition_to = connecting_to_node; + selected_transition_index = transition_lines.size(); + + EditorNode::get_singleton()->push_item(tr.ptr(), "", true); + _update_mode(); + } + + connecting = false; +} + +void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance, bool p_multi_transitions) { Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label")); Color icon_color(1, 1, 1); Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor")); @@ -516,6 +1081,7 @@ void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, co linecolor = accent; linecolor.set_hsv(1.0, linecolor.get_s(), linecolor.get_v()); } + state_machine_draw->draw_line(p_from, p_to, linecolor, 2); Ref<Texture2D> icon = icons[p_mode + (p_auto_advance ? 3 : 0)]; @@ -526,7 +1092,13 @@ void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, co xf.columns[2] = (p_from + p_to) * 0.5 - xf.columns[1] * icon->get_height() * 0.5 - xf.columns[0] * icon->get_height() * 0.5; state_machine_draw->draw_set_transform_matrix(xf); - state_machine_draw->draw_texture(icon, Vector2(), icon_color); + if (p_multi_transitions) { + state_machine_draw->draw_texture(icons[0], Vector2(-icon->get_width(), 0), icon_color); + state_machine_draw->draw_texture(icons[0], Vector2(), icon_color); + state_machine_draw->draw_texture(icons[0], Vector2(icon->get_width(), 0), icon_color); + } else { + state_machine_draw->draw_texture(icon, Vector2(), icon_color); + } state_machine_draw->draw_set_transform_matrix(Transform2D()); } @@ -557,20 +1129,27 @@ void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(const Vector2 &p_fr void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); - Ref<StyleBox> style = get_theme_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode")); - Ref<StyleBox> style_selected = get_theme_stylebox(SNAME("state_machine_selected_frame"), SNAME("GraphNode")); + Ref<StyleBoxFlat> style = get_theme_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode")); + Ref<StyleBoxFlat> style_selected = get_theme_stylebox(SNAME("state_machine_selected_frame"), SNAME("GraphNode")); Ref<Font> font = get_theme_font(SNAME("title_font"), SNAME("GraphNode")); int font_size = get_theme_font_size(SNAME("title_font_size"), SNAME("GraphNode")); Color font_color = get_theme_color(SNAME("title_color"), SNAME("GraphNode")); Ref<Texture2D> play = get_theme_icon(SNAME("Play"), SNAME("EditorIcons")); - Ref<Texture2D> auto_play = get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons")); Ref<Texture2D> edit = get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")); Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor")); Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label")); linecolor.a *= 0.3; Ref<StyleBox> playing_overlay = get_theme_stylebox(SNAME("position"), SNAME("GraphNode")); + Ref<StyleBoxFlat> start_overlay = style->duplicate(); + start_overlay->set_border_width_all(1 * EDSCALE); + start_overlay->set_border_color(Color::html("#80f6cf")); + + Ref<StyleBoxFlat> end_overlay = style->duplicate(); + end_overlay->set_border_width_all(1 * EDSCALE); + end_overlay->set_border_color(Color::html("#f26661")); + bool playing = false; StringName current; StringName blend_from; @@ -612,22 +1191,25 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref<AnimationNode> anode = state_machine->get_node(E); String name = E; bool needs_editor = EditorNode::get_singleton()->item_has_editor(anode.ptr()); - Ref<StyleBox> sb = E == selected_node ? style_selected : style; + Ref<StyleBox> sb = selected_nodes.has(E) ? style_selected : style; Size2 s = sb->get_minimum_size(); int strsize = font->get_string_size(name, font_size).width; s.width += strsize; s.height += MAX(font->get_height(font_size), play->get_height()); s.width += sep + play->get_width(); + if (needs_editor) { s.width += sep + edit->get_width(); } Vector2 offset; offset += state_machine->get_node_position(E) * EDSCALE; - if (selected_node == E && dragging_selected) { + + if (selected_nodes.has(E) && dragging_selected) { offset += drag_ofs; } + offset -= s / 2; offset = offset.floor(); @@ -666,7 +1248,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } } - _connection_draw(from, to, AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected()), true, false, false, false); + _connection_draw(from, to, AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected()), true, false, false, false, false); } Ref<Texture2D> tr_reference_icon = get_theme_icon(SNAME("TransitionImmediateBig"), SNAME("EditorIcons")); @@ -675,13 +1257,18 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { //draw transition lines for (int i = 0; i < state_machine->get_transition_count(); i++) { TransitionLine tl; + tl.transition_index = i; tl.from_node = state_machine->get_transition_from(i); - Vector2 ofs_from = (dragging_selected && tl.from_node == selected_node) ? drag_ofs : Vector2(); - tl.from = (state_machine->get_node_position(tl.from_node) * EDSCALE) + ofs_from - state_machine->get_graph_offset() * EDSCALE; + StringName local_from = String(tl.from_node).get_slicec('/', 0); + local_from = local_from == ".." ? state_machine->start_node : local_from; + Vector2 ofs_from = (dragging_selected && selected_nodes.has(local_from)) ? drag_ofs : Vector2(); + tl.from = (state_machine->get_node_position(local_from) * EDSCALE) + ofs_from - state_machine->get_graph_offset() * EDSCALE; tl.to_node = state_machine->get_transition_to(i); - Vector2 ofs_to = (dragging_selected && tl.to_node == selected_node) ? drag_ofs : Vector2(); - tl.to = (state_machine->get_node_position(tl.to_node) * EDSCALE) + ofs_to - state_machine->get_graph_offset() * EDSCALE; + StringName local_to = String(tl.to_node).get_slicec('/', 0); + local_to = local_to == ".." ? state_machine->end_node : local_to; + Vector2 ofs_to = (dragging_selected && selected_nodes.has(local_to)) ? drag_ofs : Vector2(); + tl.to = (state_machine->get_node_position(local_to) * EDSCALE) + ofs_to - state_machine->get_graph_offset() * EDSCALE; Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(i); tl.disabled = tr->is_disabled(); @@ -690,62 +1277,79 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { tl.advance_condition_state = false; tl.mode = tr->get_switch_mode(); tl.width = tr_bidi_offset; + tl.travel = false; + tl.hidden = false; - if (state_machine->has_transition(tl.to_node, tl.from_node)) { //offset if same exists + if (state_machine->has_local_transition(local_to, local_from)) { //offset if same exists Vector2 offset = -(tl.from - tl.to).normalized().orthogonal() * tr_bidi_offset; tl.from += offset; tl.to += offset; } for (int j = 0; j < node_rects.size(); j++) { - if (node_rects[j].node_name == tl.from_node) { + if (node_rects[j].node_name == local_from) { _clip_src_line_to_rect(tl.from, tl.to, node_rects[j].node); } - if (node_rects[j].node_name == tl.to_node) { + if (node_rects[j].node_name == local_to) { _clip_dst_line_to_rect(tl.from, tl.to, node_rects[j].node); } } - bool selected = selected_transition_from == tl.from_node && selected_transition_to == tl.to_node; - - bool travel = false; + tl.selected = selected_transition_from == tl.from_node && selected_transition_to == tl.to_node; - if (blend_from == tl.from_node && current == tl.to_node) { - travel = true; + if (blend_from == local_from && current == local_to) { + tl.travel = true; } if (travel_path.size()) { - if (current == tl.from_node && travel_path[0] == tl.to_node) { - travel = true; + if (current == local_from && travel_path[0] == local_to) { + tl.travel = true; } else { for (int j = 0; j < travel_path.size() - 1; j++) { - if (travel_path[j] == tl.from_node && travel_path[j + 1] == tl.to_node) { - travel = true; + if (travel_path[j] == local_from && travel_path[j + 1] == local_to) { + tl.travel = true; break; } } } } - bool auto_advance = tl.auto_advance; StringName fullpath = AnimationTreeEditor::get_singleton()->get_base_path() + String(tl.advance_condition_name); if (tl.advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(fullpath))) { tl.advance_condition_state = true; - auto_advance = true; + tl.auto_advance = true; } - _connection_draw(tl.from, tl.to, tl.mode, !tl.disabled, selected, travel, auto_advance); + // check if already have this local transition + for (int j = 0; j < transition_lines.size(); j++) { + StringName from = String(transition_lines[j].from_node).get_slicec('/', 0); + StringName to = String(transition_lines[j].to_node).get_slicec('/', 0); + from = from == ".." ? state_machine->start_node : from; + to = to == ".." ? state_machine->end_node : to; + + if (from == local_from && to == local_to) { + tl.hidden = true; + transition_lines.write[j].disabled = transition_lines[j].disabled && tl.disabled; + transition_lines.write[j].multi_transitions.push_back(tl); + } + } transition_lines.push_back(tl); } + for (int i = 0; i < transition_lines.size(); i++) { + TransitionLine tl = transition_lines[i]; + if (!tl.hidden) { + _connection_draw(tl.from, tl.to, tl.mode, !tl.disabled, tl.selected, tl.travel, tl.auto_advance, !tl.multi_transitions.is_empty()); + } + } + //draw actual nodes for (int i = 0; i < node_rects.size(); i++) { String name = node_rects[i].node_name; Ref<AnimationNode> anode = state_machine->get_node(name); bool needs_editor = AnimationTreeEditor::get_singleton()->can_edit(anode); - Ref<StyleBox> sb = name == selected_node ? style_selected : style; + Ref<StyleBox> sb = selected_nodes.has(name) ? style_selected : style; int strsize = font->get_string_size(name, font_size).width; - NodeRect &nr = node_rects.write[i]; Vector2 offset = nr.node.position; @@ -756,18 +1360,16 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { //now scroll it to draw state_machine_draw->draw_style_box(sb, nr.node); - if (playing && (blend_from == name || current == name || travel_path.has(name))) { - state_machine_draw->draw_style_box(playing_overlay, nr.node); + if (state_machine->start_node == name) { + state_machine_draw->draw_style_box(sb == style_selected ? style_selected : start_overlay, nr.node); } - bool onstart = state_machine->get_start_node() == name; - if (onstart) { - state_machine_draw->draw_string(font, offset + Vector2(0, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("Start"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); + if (state_machine->end_node == name) { + state_machine_draw->draw_style_box(sb == style_selected ? style_selected : end_overlay, nr.node); } - if (state_machine->get_end_node() == name) { - int endofs = nr.node.size.x - font->get_string_size(TTR("End"), font_size).x; - state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("End"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); + if (playing && (blend_from == name || current == name || travel_path.has(name))) { + state_machine_draw->draw_style_box(playing_overlay, nr.node); } offset.x += sb->get_offset().x; @@ -775,13 +1377,14 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { nr.play.position = offset + Vector2(0, (h - play->get_height()) / 2).floor(); nr.play.size = play->get_size(); - Ref<Texture2D> play_tex = onstart ? auto_play : play; + Ref<Texture2D> play_tex = play; if (over_node == name && over_node_what == 0) { state_machine_draw->draw_texture(play_tex, nr.play.position, accent); } else { state_machine_draw->draw_texture(play_tex, nr.play.position); } + offset.x += sep + play->get_width(); nr.name.position = offset + Vector2(0, (h - font->get_height(font_size)) / 2).floor(); @@ -803,6 +1406,11 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } } + //draw box select + if (box_selecting) { + state_machine_draw->draw_rect(box_selecting_rect, Color(0.7, 0.7, 1.0, 0.3)); + } + scroll_range.position -= state_machine_draw->get_size(); scroll_range.size += state_machine_draw->get_size() * 2.0; @@ -829,6 +1437,10 @@ void AnimationNodeStateMachineEditor::_state_machine_pos_draw() { return; } + if (playback->get_current_node() == state_machine->start_node || playback->get_current_node() == state_machine->end_node) { + return; + } + int idx = -1; for (int i = 0; i < node_rects.size(); i++) { if (node_rects[i].node_name == playback->get_current_node()) { @@ -902,8 +1514,8 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionEnd"), SNAME("EditorIcons")), TTR("At End")); tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - tool_autoplay->set_icon(get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons"))); - tool_end->set_icon(get_theme_icon(SNAME("AutoEnd"), SNAME("EditorIcons"))); + tool_group->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons"))); + tool_ungroup->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons"))); play_mode->clear(); play_mode->add_icon_item(get_theme_icon(SNAME("PlayTravel"), SNAME("EditorIcons")), TTR("Travel")); @@ -1109,94 +1721,121 @@ void AnimationNodeStateMachineEditor::_scroll_changed(double) { state_machine_draw->update(); } -void AnimationNodeStateMachineEditor::_erase_selected() { - if (selected_node != StringName() && state_machine->has_node(selected_node)) { - updating = true; +void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action) { + if (!selected_nodes.is_empty()) { + if (!p_nested_action) { + updating = true; + } undo_redo->create_action(TTR("Node Removed")); - undo_redo->add_do_method(state_machine.ptr(), "remove_node", selected_node); - undo_redo->add_undo_method(state_machine.ptr(), "add_node", selected_node, state_machine->get_node(selected_node), state_machine->get_node_position(selected_node)); - for (int i = 0; i < state_machine->get_transition_count(); i++) { - String from = state_machine->get_transition_from(i); - String to = state_machine->get_transition_to(i); - if (from == selected_node || to == selected_node) { - undo_redo->add_undo_method(state_machine.ptr(), "add_transition", from, to, state_machine->get_transition(i)); + + for (int i = 0; i < node_rects.size(); i++) { + if (node_rects[i].node_name == state_machine->start_node || node_rects[i].node_name == state_machine->end_node) { + continue; + } + + if (!selected_nodes.has(node_rects[i].node_name)) { + continue; + } + + undo_redo->add_do_method(state_machine.ptr(), "remove_node", node_rects[i].node_name); + undo_redo->add_undo_method(state_machine.ptr(), "add_node", node_rects[i].node_name, + state_machine->get_node(node_rects[i].node_name), + state_machine->get_node_position(node_rects[i].node_name)); + + for (int j = 0; j < state_machine->get_transition_count(); j++) { + String from = state_machine->get_transition_from(j); + String to = state_machine->get_transition_to(j); + String local_from = from.get_slicec('/', 0); + String local_to = to.get_slicec('/', 0); + + if (local_from == node_rects[i].node_name || local_to == node_rects[i].node_name) { + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", from, to, state_machine->get_transition(j)); + } } } - if (String(state_machine->get_start_node()) == selected_node) { - undo_redo->add_undo_method(state_machine.ptr(), "set_start_node", selected_node); - } + undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); - updating = false; - selected_node = StringName(); + + if (!p_nested_action) { + updating = false; + } + + selected_nodes.clear(); + } + + if (!selected_multi_transition.multi_transitions.is_empty()) { + delete_tree->clear(); + + TreeItem *root = delete_tree->create_item(); + + TreeItem *item = delete_tree->create_item(root); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + item->set_text(0, String(selected_transition_from) + " -> " + selected_transition_to); + item->set_editable(0, true); + + for (int i = 0; i < selected_multi_transition.multi_transitions.size(); i++) { + String from = selected_multi_transition.multi_transitions[i].from_node; + String to = selected_multi_transition.multi_transitions[i].to_node; + + item = delete_tree->create_item(root); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + item->set_text(0, from + " -> " + to); + item->set_editable(0, true); + } + + delete_window->popup_centered(Vector2(400, 200)); + return; } if (selected_transition_to != StringName() && selected_transition_from != StringName() && state_machine->has_transition(selected_transition_from, selected_transition_to)) { Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(state_machine->find_transition(selected_transition_from, selected_transition_to)); - updating = true; + if (!p_nested_action) { + updating = true; + } undo_redo->create_action(TTR("Transition Removed")); undo_redo->add_do_method(state_machine.ptr(), "remove_transition", selected_transition_from, selected_transition_to); undo_redo->add_undo_method(state_machine.ptr(), "add_transition", selected_transition_from, selected_transition_to, tr); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); - updating = false; + if (!p_nested_action) { + updating = false; + } selected_transition_from = StringName(); selected_transition_to = StringName(); + selected_transition_index = -1; + selected_multi_transition = TransitionLine(); } state_machine_draw->update(); } -void AnimationNodeStateMachineEditor::_autoplay_selected() { - if (selected_node != StringName() && state_machine->has_node(selected_node)) { - StringName new_start_node; - if (state_machine->get_start_node() == selected_node) { //toggle it - new_start_node = StringName(); - } else { - new_start_node = selected_node; - } - - updating = true; - undo_redo->create_action(TTR("Set Start Node (Autoplay)")); - undo_redo->add_do_method(state_machine.ptr(), "set_start_node", new_start_node); - undo_redo->add_undo_method(state_machine.ptr(), "set_start_node", state_machine->get_start_node()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - updating = false; - state_machine_draw->update(); - } -} - -void AnimationNodeStateMachineEditor::_end_selected() { - if (selected_node != StringName() && state_machine->has_node(selected_node)) { - StringName new_end_node; - if (state_machine->get_end_node() == selected_node) { //toggle it - new_end_node = StringName(); - } else { - new_end_node = selected_node; - } - - updating = true; - undo_redo->create_action(TTR("Set Start Node (Autoplay)")); - undo_redo->add_do_method(state_machine.ptr(), "set_end_node", new_end_node); - undo_redo->add_undo_method(state_machine.ptr(), "set_end_node", state_machine->get_end_node()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - updating = false; - state_machine_draw->update(); - } -} - void AnimationNodeStateMachineEditor::_update_mode() { if (tool_select->is_pressed()) { tool_erase_hb->show(); - tool_erase->set_disabled(selected_node == StringName() && selected_transition_from == StringName() && selected_transition_to == StringName()); - tool_autoplay->set_disabled(selected_node == StringName()); - tool_end->set_disabled(selected_node == StringName()); + bool nothing_selected = selected_nodes.is_empty() && selected_transition_from == StringName() && selected_transition_to == StringName(); + bool start_end_selected = selected_nodes.size() == 1 && (selected_nodes.front()->get() == state_machine->start_node || selected_nodes.front()->get() == state_machine->end_node); + tool_erase->set_disabled(nothing_selected || start_end_selected); + + if (selected_nodes.is_empty() || start_end_selected) { + tool_group->set_disabled(true); + tool_group->set_visible(true); + tool_ungroup->set_visible(false); + } else { + Ref<AnimationNodeStateMachine> ansm = state_machine->get_node(selected_nodes.front()->get()); + + if (selected_nodes.size() == 1 && ansm.is_valid()) { + tool_group->set_disabled(true); + tool_group->set_visible(false); + tool_ungroup->set_visible(true); + } else { + tool_group->set_disabled(false); + tool_group->set_visible(true); + tool_ungroup->set_visible(false); + } + } } else { tool_erase_hb->hide(); } @@ -1204,17 +1843,19 @@ void AnimationNodeStateMachineEditor::_update_mode() { void AnimationNodeStateMachineEditor::_bind_methods() { ClassDB::bind_method("_update_graph", &AnimationNodeStateMachineEditor::_update_graph); - ClassDB::bind_method("_removed_from_graph", &AnimationNodeStateMachineEditor::_removed_from_graph); - ClassDB::bind_method("_open_editor", &AnimationNodeStateMachineEditor::_open_editor); + ClassDB::bind_method("_connect_to", &AnimationNodeStateMachineEditor::_connect_to); + ClassDB::bind_method("_stop_connecting", &AnimationNodeStateMachineEditor::_stop_connecting); + ClassDB::bind_method("_delete_selected", &AnimationNodeStateMachineEditor::_delete_selected); + ClassDB::bind_method("_delete_all", &AnimationNodeStateMachineEditor::_delete_all); + ClassDB::bind_method("_delete_tree_draw", &AnimationNodeStateMachineEditor::_delete_tree_draw); } AnimationNodeStateMachineEditor *AnimationNodeStateMachineEditor::singleton = nullptr; AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { singleton = this; - updating = false; HBoxContainer *top_hb = memnew(HBoxContainer); add_child(top_hb); @@ -1228,7 +1869,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_select->set_toggle_mode(true); tool_select->set_button_group(bg); tool_select->set_pressed(true); - tool_select->set_tooltip(TTR("Select and move nodes.\nRMB to add new nodes.\nShift+LMB to create connections.")); + tool_select->set_tooltip(TTR("Select and move nodes.\nRMB: Add node at position clicked.\nShift+LMB+Drag: Connects the selected node with another node or creates a new node if you select an area without nodes.")); tool_select->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), varray(), CONNECT_DEFERRED); tool_create = memnew(Button); @@ -1250,28 +1891,27 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_erase_hb = memnew(HBoxContainer); top_hb->add_child(tool_erase_hb); tool_erase_hb->add_child(memnew(VSeparator)); + + tool_group = memnew(Button); + tool_group->set_flat(true); + tool_group->set_tooltip(TTR("Group Selected Node(s)") + " (Ctrl+G)"); + tool_group->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_group_selected_nodes)); + tool_group->set_disabled(true); + tool_erase_hb->add_child(tool_group); + + tool_ungroup = memnew(Button); + tool_ungroup->set_flat(true); + tool_ungroup->set_tooltip(TTR("Ungroup Selected Node") + " (Ctrl+Shift+G)"); + tool_ungroup->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_ungroup_selected_nodes)); + tool_ungroup->set_visible(false); + tool_erase_hb->add_child(tool_ungroup); + tool_erase = memnew(Button); tool_erase->set_flat(true); tool_erase->set_tooltip(TTR("Remove selected node or transition.")); - tool_erase_hb->add_child(tool_erase); - tool_erase->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_erase_selected)); + tool_erase->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_erase_selected), varray(false)); tool_erase->set_disabled(true); - - tool_erase_hb->add_child(memnew(VSeparator)); - - tool_autoplay = memnew(Button); - tool_autoplay->set_flat(true); - tool_autoplay->set_tooltip(TTR("Toggle autoplay this animation on start, restart or seek to zero.")); - tool_erase_hb->add_child(tool_autoplay); - tool_autoplay->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_autoplay_selected)); - tool_autoplay->set_disabled(true); - - tool_end = memnew(Button); - tool_end->set_flat(true); - tool_end->set_tooltip(TTR("Set the end animation. This is useful for sub-transitions.")); - tool_erase_hb->add_child(tool_end); - tool_end->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_end_selected)); - tool_end->set_disabled(true); + tool_erase_hb->add_child(tool_erase); top_hb->add_child(memnew(VSeparator)); top_hb->add_child(memnew(Label(TTR("Transition: ")))); @@ -1327,12 +1967,28 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { menu = memnew(PopupMenu); add_child(menu); menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_add_menu_type)); + menu->connect("popup_hide", callable_mp(this, &AnimationNodeStateMachineEditor::_stop_connecting)); animations_menu = memnew(PopupMenu); menu->add_child(animations_menu); animations_menu->set_name("animations"); animations_menu->connect("index_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_add_animation_type)); + connect_menu = memnew(PopupMenu); + add_child(connect_menu); + connect_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + connect_menu->connect("popup_hide", callable_mp(this, &AnimationNodeStateMachineEditor::_stop_connecting)); + + state_machine_menu = memnew(PopupMenu); + state_machine_menu->set_name("state_machines"); + state_machine_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + connect_menu->add_child(state_machine_menu); + + end_menu = memnew(PopupMenu); + end_menu->set_name("end_nodes"); + end_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + connect_menu->add_child(end_menu); + name_edit_popup = memnew(Popup); add_child(name_edit_popup); name_edit = memnew(LineEdit); @@ -1348,11 +2004,94 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { open_file->connect("file_selected", callable_mp(this, &AnimationNodeStateMachineEditor::_file_opened)); undo_redo = EditorNode::get_undo_redo(); + delete_window = memnew(ConfirmationDialog); + delete_window->set_flag(Window::FLAG_RESIZE_DISABLED, true); + add_child(delete_window); + + delete_tree = memnew(Tree); + delete_tree->set_hide_root(true); + delete_tree->connect("draw", callable_mp(this, &AnimationNodeStateMachineEditor::_delete_tree_draw)); + delete_window->add_child(delete_tree); + + Button *ok = delete_window->get_cancel_button(); + ok->set_text(TTR("Delete Selected")); + ok->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_delete_selected)); + + Button *delete_all = delete_window->add_button(TTR("Delete All"), true); + delete_all->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_delete_all)); + over_node_what = -1; dragging_selected_attempt = false; connecting = false; + selected_transition_index = -1; last_active = false; error_time = 0; } + +void EditorAnimationMultiTransitionEdit::add_transition(const StringName &p_from, const StringName &p_to, Ref<AnimationNodeStateMachineTransition> p_transition) { + Transition tr; + tr.from = p_from; + tr.to = p_to; + tr.transition = p_transition; + transitions.push_back(tr); +} + +bool EditorAnimationMultiTransitionEdit::_set(const StringName &p_name, const Variant &p_property) { + int index = String(p_name).get_slicec('/', 0).to_int(); + StringName prop = String(p_name).get_slicec('/', 1); + + bool found; + transitions.write[index].transition->set(prop, p_property, &found); + if (found) { + return true; + } + + return false; +} + +bool EditorAnimationMultiTransitionEdit::_get(const StringName &p_name, Variant &r_property) const { + int index = String(p_name).get_slicec('/', 0).to_int(); + StringName prop = String(p_name).get_slicec('/', 1); + + if (prop == "transition_path") { + r_property = String(transitions[index].from) + " -> " + transitions[index].to; + return true; + } + + bool found; + r_property = transitions[index].transition->get(prop, &found); + if (found) { + return true; + } + + return false; +} + +void EditorAnimationMultiTransitionEdit::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < transitions.size(); i++) { + List<PropertyInfo> plist; + transitions[i].transition->get_property_list(&plist, true); + + PropertyInfo prop_transition_path; + prop_transition_path.type = Variant::STRING; + prop_transition_path.name = itos(i) + "/" + "transition_path"; + p_list->push_back(prop_transition_path); + + for (List<PropertyInfo>::Element *F = plist.front(); F; F = F->next()) { + if (F->get().name == "script" || F->get().name == "resource_name" || F->get().name == "resource_path" || F->get().name == "resource_local_to_scene") { + continue; + } + + if (F->get().usage != PROPERTY_USAGE_DEFAULT) { + continue; + } + + PropertyInfo prop = F->get(); + prop.name = itos(i) + "/" + prop.name; + + p_list->push_back(prop); + } + } +} diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index fe3f6f370c..1247d99389 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -50,13 +50,13 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { Button *tool_select = nullptr; Button *tool_create = nullptr; Button *tool_connect = nullptr; + Button *tool_group = nullptr; + Button *tool_ungroup = nullptr; Popup *name_edit_popup = nullptr; LineEdit *name_edit = nullptr; HBoxContainer *tool_erase_hb = nullptr; Button *tool_erase = nullptr; - Button *tool_autoplay = nullptr; - Button *tool_end = nullptr; OptionButton *transition_mode = nullptr; OptionButton *play_mode = nullptr; @@ -64,6 +64,7 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { PanelContainer *panel = nullptr; StringName selected_node; + Set<StringName> selected_nodes; HScrollBar *h_scroll = nullptr; VScrollBar *v_scroll = nullptr; @@ -74,39 +75,53 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { PanelContainer *error_panel = nullptr; Label *error_label = nullptr; - bool updating; + bool updating = false; UndoRedo *undo_redo = nullptr; static AnimationNodeStateMachineEditor *singleton; void _state_machine_gui_input(const Ref<InputEvent> &p_event); - void _connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance); + void _connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance, bool p_multi_transitions); void _state_machine_draw(); void _state_machine_pos_draw(); void _update_graph(); PopupMenu *menu = nullptr; + PopupMenu *connect_menu = nullptr; + PopupMenu *state_machine_menu = nullptr; + PopupMenu *end_menu = nullptr; PopupMenu *animations_menu = nullptr; Vector<String> animations_to_add; + Vector<String> nodes_to_connect; Vector2 add_node_pos; - bool dragging_selected_attempt; - bool dragging_selected; + ConfirmationDialog *delete_window; + Tree *delete_tree; + + bool box_selecting = false; + Point2 box_selecting_from; + Point2 box_selecting_to; + Rect2 box_selecting_rect; + Set<StringName> previous_selected; + + bool dragging_selected_attempt = false; + bool dragging_selected = false; Vector2 drag_from; Vector2 drag_ofs; StringName snap_x; StringName snap_y; - bool connecting; + bool connecting = false; StringName connecting_from; Vector2 connecting_to; StringName connecting_to_node; void _add_menu_type(int p_index); void _add_animation_type(int p_index); + void _connect_to(int p_index); void _removed_from_graph(); @@ -131,15 +146,37 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { bool disabled = false; bool auto_advance = false; float width = 0; + bool selected; + bool travel; + bool hidden; + int transition_index; + Vector<TransitionLine> multi_transitions; }; Vector<TransitionLine> transition_lines; + struct NodeUR { + StringName name; + Ref<AnimationNode> node; + Vector2 position; + }; + + struct TransitionUR { + StringName new_from; + StringName new_to; + StringName old_from; + StringName old_to; + Ref<AnimationNodeStateMachineTransition> transition; + }; + StringName selected_transition_from; StringName selected_transition_to; + int selected_transition_index; + TransitionLine selected_multi_transition; + void _add_transition(const bool p_nested_action = false); StringName over_node; - int over_node_what; + int over_node_what = -1; String prev_name; void _name_edited(const String &p_text); @@ -150,20 +187,29 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { void _clip_src_line_to_rect(Vector2 &r_from, const Vector2 &p_to, const Rect2 &p_rect); void _clip_dst_line_to_rect(const Vector2 &p_from, Vector2 &r_to, const Rect2 &p_rect); - void _erase_selected(); + void _erase_selected(const bool p_nested_action = false); void _update_mode(); - void _autoplay_selected(); - void _end_selected(); + void _open_menu(const Vector2 &p_position); + void _open_connect_menu(const Vector2 &p_position); + bool _create_submenu(PopupMenu *p_menu, Ref<AnimationNodeStateMachine> p_nodesm, const StringName &p_name, const StringName &p_path, bool from_root = false, Vector<Ref<AnimationNodeStateMachine>> p_parents = Vector<Ref<AnimationNodeStateMachine>>()); + void _stop_connecting(); + + void _group_selected_nodes(); + void _ungroup_selected_nodes(); - bool last_active; + void _delete_selected(); + void _delete_all(); + void _delete_tree_draw(); + + bool last_active = false; StringName last_blend_from_node; StringName last_current_node; Vector<StringName> last_travel_path; - float last_play_pos; - float play_pos; - float current_length; + float last_play_pos = 0.0f; + float play_pos = 0.0f; + float current_length = 0.0f; - float error_time; + float error_time = 0.0f; String error_text; EditorFileDialog *open_file = nullptr; @@ -188,4 +234,26 @@ public: AnimationNodeStateMachineEditor(); }; +class EditorAnimationMultiTransitionEdit : public RefCounted { + GDCLASS(EditorAnimationMultiTransitionEdit, RefCounted); + + struct Transition { + StringName from; + StringName to; + Ref<AnimationNodeStateMachineTransition> transition; + }; + + Vector<Transition> transitions; + +protected: + bool _set(const StringName &p_name, const Variant &p_property); + bool _get(const StringName &p_name, Variant &r_property) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void add_transition(const StringName &p_from, const StringName &p_to, Ref<AnimationNodeStateMachineTransition> p_transition); + + EditorAnimationMultiTransitionEdit(){}; +}; + #endif // ANIMATION_STATE_MACHINE_EDITOR_H diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index 96830c31fd..65c8398558 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -60,9 +60,9 @@ class EditorAssetLibraryItem : public PanelContainer { TextureRect *stars[5]; Label *price = nullptr; - int asset_id; - int category_id; - int author_id; + int asset_id = 0; + int category_id = 0; + int author_id = 0; void _asset_clicked(); void _category_clicked(); @@ -102,7 +102,7 @@ class EditorAssetLibraryItemDescription : public ConfirmationDialog { void set_image(int p_type, int p_index, const Ref<Texture2D> &p_image); - int asset_id; + int asset_id = 0; String download_url; String title; String sha256; @@ -146,7 +146,7 @@ class EditorAssetLibraryItemDownload : public MarginContainer { int prev_status; - int asset_id; + int asset_id = 0; bool external_install; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index fd2aaec4da..d237697597 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -4888,14 +4888,6 @@ CanvasItemEditor::CanvasItemEditor() { view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH); previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen - grid_offset = Point2(); - grid_step = Point2(8, 8); // A power-of-two value works better as a default - primary_grid_steps = 8; // A power-of-two value works better as a default - grid_step_multiplier = 0; - - snap_rotation_offset = 0; - snap_rotation_step = Math::deg2rad(15.0); - snap_scale_step = 0.1f; snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; @@ -5401,7 +5393,7 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons bool add_preview = false; for (int i = 0; i < files.size(); i++) { String path = files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); ERR_FAIL_COND(res.is_null()); Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res)); Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); @@ -5596,7 +5588,7 @@ void CanvasItemEditorViewport::_perform_drop_data() { for (int i = 0; i < selected_files.size(); i++) { String path = selected_files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { continue; } @@ -5651,7 +5643,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian for (int i = 0; i < files.size(); i++) { // Check if dragged files with texture or scene extension can be created at least once. if (texture_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { - RES res = ResourceLoader::load(files[i]); + Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 26852ea8ed..7a49041131 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -180,7 +180,7 @@ private: GRID_VISIBILITY_HIDE, }; - bool selection_menu_additive_selection; + bool selection_menu_additive_selection = false; Tool tool = TOOL_SELECT; Control *viewport = nullptr; @@ -204,20 +204,20 @@ private: bool show_edit_locks = true; bool show_transformation_gizmos = true; - real_t zoom; + real_t zoom = 1.0; Point2 view_offset; Point2 previous_update_view_offset; bool selected_from_canvas = false; Point2 grid_offset; - Point2 grid_step; - int primary_grid_steps; - int grid_step_multiplier; + Point2 grid_step = Point2(8, 8); // A power-of-two value works better as a default. + int primary_grid_steps = 8; + int grid_step_multiplier = 0; - real_t snap_rotation_step; - real_t snap_rotation_offset; - real_t snap_scale_step; + real_t snap_rotation_step = 0.0; + real_t snap_rotation_offset = Math::deg2rad(15.0); + real_t snap_scale_step = 0.1f; bool smart_snap_active = false; bool grid_snap_active = false; @@ -241,7 +241,7 @@ private: bool pan_pressed = false; bool ruler_tool_active = false; - Point2 ruler_tool_origin = Point2(); + Point2 ruler_tool_origin; Point2 node_create_position; MenuOption last_option; @@ -346,7 +346,7 @@ private: bool is_hovering_h_guide = false; bool is_hovering_v_guide = false; - bool updating_value_dialog; + bool updating_value_dialog = false; Point2 box_selecting_to; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index a160ca463b..80fc1c64d0 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -79,7 +79,7 @@ bool EditorTexturePreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorTexturePreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Image> img; Ref<AtlasTexture> atex = p_from; if (atex.is_valid()) { @@ -145,7 +145,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const { return p_type == "Image"; } -Ref<Texture2D> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorImagePreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Image> img = p_from; if (img.is_null() || img->is_empty()) { @@ -194,7 +194,7 @@ bool EditorBitmapPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "BitMap"); } -Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<BitMap> bm = p_from; if (bm->get_size() == Size2()) { @@ -261,7 +261,7 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "PackedScene"); } -Ref<Texture2D> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorPackedScenePreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { return generate_from_path(p_from->get_path(), p_size); } @@ -316,7 +316,7 @@ bool EditorMaterialPreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Material> material = p_from; ERR_FAIL_COND_V(material.is_null(), Ref<Texture2D>()); @@ -467,7 +467,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Script"); } -Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Script> scr = p_from; if (scr.is_null()) { return Ref<Texture2D>(); @@ -609,7 +609,7 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "AudioStream"); } -Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<AudioStream> stream = p_from; ERR_FAIL_COND_V(stream.is_null(), Ref<Texture2D>()); @@ -703,7 +703,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Mesh"); // Any mesh. } -Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorMeshPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Mesh> mesh = p_from; ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture2D>()); @@ -816,7 +816,7 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const { } Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { - RES res = ResourceLoader::load(p_path); + Ref<Resource> res = ResourceLoader::load(p_path); ERR_FAIL_COND_V(res.is_null(), Ref<Texture2D>()); Ref<Font> sampled_font; if (res->is_class("Font")) { @@ -877,7 +877,7 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, return ptex; } -Ref<Texture2D> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorFontPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { String path = p_from->get_path(); if (!FileAccess::exists(path)) { return Ref<Texture2D>(); @@ -917,7 +917,7 @@ bool EditorGradientPreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture2D> EditorGradientPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorGradientPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Gradient> gradient = p_from; if (gradient.is_valid()) { Ref<GradientTexture1D> ptex; diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 73eb90dd86..f548683b70 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -42,7 +42,7 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorTexturePreviewPlugin(); }; @@ -53,7 +53,7 @@ class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorImagePreviewPlugin(); }; @@ -64,7 +64,7 @@ class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorBitmapPreviewPlugin(); }; @@ -72,7 +72,7 @@ public: class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; virtual Ref<Texture2D> generate_from_path(const String &p_path, const Size2 &p_size) const; EditorPackedScenePreviewPlugin(); @@ -99,7 +99,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorMaterialPreviewPlugin(); ~EditorMaterialPreviewPlugin(); @@ -108,7 +108,7 @@ public: class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; EditorScriptPreviewPlugin(); }; @@ -116,7 +116,7 @@ public: class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; EditorAudioStreamPreviewPlugin(); }; @@ -140,7 +140,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorMeshPreviewPlugin(); ~EditorMeshPreviewPlugin(); @@ -160,7 +160,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; virtual Ref<Texture2D> generate_from_path(const String &p_path, const Size2 &p_size) const override; EditorFontPreviewPlugin(); @@ -177,7 +177,7 @@ class EditorTileMapPatternPreviewPlugin : public EditorResourcePreviewGenerator public: virtual bool handles(const String &p_type) const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorTileMapPatternPreviewPlugin(); ~EditorTileMapPatternPreviewPlugin(); @@ -189,7 +189,7 @@ class EditorGradientPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorGradientPreviewPlugin(); }; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index 4fbc8188b9..e7ef65c32b 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -96,7 +96,7 @@ void LightOccluder2DEditor::_create_resource() { undo_redo->create_action(TTR("Create Occluder Polygon")); undo_redo->add_do_method(node, "set_occluder_polygon", Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D))); - undo_redo->add_undo_method(node, "set_occluder_polygon", Variant(REF())); + undo_redo->add_undo_method(node, "set_occluder_polygon", Variant(Ref<RefCounted>())); undo_redo->commit_action(); _menu_option(MODE_CREATE); diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h index 85ead35534..f4b4288a5f 100644 --- a/editor/plugins/mesh_library_editor_plugin.h +++ b/editor/plugins/mesh_library_editor_plugin.h @@ -47,8 +47,8 @@ class MeshLibraryEditor : public Control { ConfirmationDialog *cd_remove = nullptr; ConfirmationDialog *cd_update = nullptr; EditorFileDialog *file = nullptr; - bool apply_xforms; - int to_erase; + bool apply_xforms = false; + int to_erase = 0; enum { MENU_OPTION_ADD_ITEM, @@ -58,7 +58,7 @@ class MeshLibraryEditor : public Control { MENU_OPTION_IMPORT_FROM_SCENE_APPLY_XFORMS }; - int option; + int option = 0; void _import_scene_cbk(const String &p_str); void _menu_cbk(int p_option); void _menu_remove_confirm(); diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h index 9f5e85216c..5773989d0d 100644 --- a/editor/plugins/multimesh_editor_plugin.h +++ b/editor/plugins/multimesh_editor_plugin.h @@ -46,7 +46,7 @@ class MultiMeshEditor : public Control { AcceptDialog *err_dialog = nullptr; MenuButton *options = nullptr; MultiMeshInstance3D *_last_pp_node = nullptr; - bool browsing_source; + bool browsing_source = false; Panel *panel = nullptr; MultiMeshInstance3D *node = nullptr; diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index 17eaf45bb5..8f3553b8cf 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -106,7 +106,7 @@ void NavigationPolygonEditor::_create_resource() { undo_redo->create_action(TTR("Create Navigation Polygon")); undo_redo->add_do_method(node, "set_navigation_polygon", Ref<NavigationPolygon>(memnew(NavigationPolygon))); - undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(REF())); + undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(Ref<RefCounted>())); undo_redo->commit_action(); _menu_option(MODE_CREATE); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 7e01593bda..344efb4f13 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2990,7 +2990,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { bool current = view_menu->get_popup()->is_item_checked(idx); current = !current; if (current) { - camera->set_environment(RES()); + camera->set_environment(Ref<Resource>()); } else { camera->set_environment(Node3DEditor::get_singleton()->get_viewport_environment()); } @@ -3767,7 +3767,7 @@ Node *Node3DEditorViewport::_sanitize_preview_node(Node *p_node) const { void Node3DEditorViewport::_create_preview(const Vector<String> &files) const { for (int i = 0; i < files.size(); i++) { String path = files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); ERR_CONTINUE(res.is_null()); Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); Ref<Mesh> mesh = Ref<Mesh>(Object::cast_to<Mesh>(*res)); @@ -3818,7 +3818,7 @@ bool Node3DEditorViewport::_cyclical_dependency_exists(const String &p_target_sc } bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) { - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); ERR_FAIL_COND_V(res.is_null(), false); Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); @@ -3908,7 +3908,7 @@ void Node3DEditorViewport::_perform_drop_data() { for (int i = 0; i < selected_files.size(); i++) { String path = selected_files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { continue; } @@ -3951,7 +3951,7 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant for (int i = 0; i < files.size(); i++) { // Check if dragged files with mesh or scene extension can be created at least once. if (mesh_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { - RES res = ResourceLoader::load(files[i]); + Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index d5d50c743c..43efdeec72 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -211,7 +211,7 @@ private: Control *surface = nullptr; SubViewport *viewport = nullptr; Camera3D *camera = nullptr; - bool transforming; + bool transforming = false; bool orthogonal; bool auto_orthogonal; bool lock_rotation; @@ -271,7 +271,7 @@ private: ObjectID clicked; Vector<_RayResult> selection_results; - bool clicked_wants_append; + bool clicked_wants_append = false; bool selection_in_progress = false; PopupMenu *selection_menu = nullptr; @@ -551,12 +551,12 @@ private: RID origin; RID origin_instance; - bool origin_enabled; + bool origin_enabled = false; RID grid[3]; RID grid_instance[3]; bool grid_visible[3]; //currently visible bool grid_enable[3]; //should be always visible if true - bool grid_enabled; + bool grid_enabled = false; bool grid_init_draw = false; Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; Vector3 grid_camera_last_update_position = Vector3(); diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index 9a8584f4a2..8d083d28b2 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -43,7 +43,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, // These properties are translated with the tr() function in the C++ code when being set or updated. Error err; - RES loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + Ref<Resource> loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index ff74aeedf7..720f5c090f 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -82,11 +82,11 @@ class Path2DEditor : public HBoxContainer { }; Action action; - int action_point; + int action_point = 0; Point2 moving_from; Point2 moving_screen_from; - float orig_in_length; - float orig_out_length; + float orig_in_length = 0.0f; + float orig_out_length = 0.0f; Vector2 edge_point; void _mode_selected(int p_mode); diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index 72c24732c0..ee31fcf43d 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -84,7 +84,7 @@ class Path3DEditorPlugin : public EditorPlugin { void _mode_changed(int p_idx); void _close_curve(); void _handle_option_pressed(int p_option); - bool handle_clicked; + bool handle_clicked = false; bool mirror_handle_angle; bool mirror_handle_length; diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 4403d1e9c7..d878d3f9af 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -96,7 +96,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { SpinBox *bone_paint_radius = nullptr; Label *bone_paint_radius_label = nullptr; bool bone_painting; - int bone_painting_bone; + int bone_painting_bone = 0; Vector<float> prev_weights; Vector2 bone_paint_pos; AcceptDialog *grid_settings = nullptr; @@ -110,7 +110,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { Vector<Vector2> uv_create_uv_prev; Vector<Vector2> uv_create_poly_prev; Vector<Color> uv_create_colors_prev; - int uv_create_prev_internal_vertices; + int uv_create_prev_internal_vertices = 0; Array uv_create_bones_prev; Array polygons_prev; diff --git a/editor/plugins/polygon_3d_editor_plugin.h b/editor/plugins/polygon_3d_editor_plugin.h index 3ad7a4df58..e1e1261250 100644 --- a/editor/plugins/polygon_3d_editor_plugin.h +++ b/editor/plugins/polygon_3d_editor_plugin.h @@ -66,14 +66,14 @@ class Polygon3DEditor : public HBoxContainer { MenuButton *options = nullptr; - int edited_point; + int edited_point = 0; Vector2 edited_point_pos; PackedVector2Array pre_move_edit; PackedVector2Array wip; bool wip_active; bool snap_ignore; - float prev_depth; + float prev_depth = 0.0f; void _wip_close(); void _polygon_draw(); diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index eafc53c72b..71d31aa1d7 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -50,7 +50,7 @@ void ResourcePreloaderEditor::_files_load_request(const Vector<String> &p_paths) for (int i = 0; i < p_paths.size(); i++) { String path = p_paths[i]; - RES resource; + Ref<Resource> resource; resource = ResourceLoader::load(path); if (resource.is_null()) { @@ -113,7 +113,7 @@ void ResourcePreloaderEditor::_item_edited() { return; } - RES samp = preloader->get_resource(old_name); + Ref<Resource> samp = preloader->get_resource(old_name); undo_redo->create_action(TTR("Rename Resource")); undo_redo->add_do_method(preloader, "remove_resource", old_name); undo_redo->add_do_method(preloader, "add_resource", new_name, samp); @@ -135,7 +135,7 @@ void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) { } void ResourcePreloaderEditor::_paste_pressed() { - RES r = EditorSettings::get_singleton()->get_resource_clipboard(); + Ref<Resource> r = EditorSettings::get_singleton()->get_resource_clipboard(); if (!r.is_valid()) { dialog->set_text(TTR("Resource clipboard is empty!")); dialog->set_title(TTR("Error!")); @@ -190,7 +190,7 @@ void ResourcePreloaderEditor::_update_library() { ti->set_text(0, E); ti->set_metadata(0, E); - RES r = preloader->get_resource(E); + Ref<Resource> r = preloader->get_resource(E); ERR_CONTINUE(r.is_null()); @@ -222,7 +222,7 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column, EditorInterface::get_singleton()->open_scene_from_path(rpath); } else if (p_id == BUTTON_EDIT_RESOURCE) { - RES r = preloader->get_resource(item->get_text(0)); + Ref<Resource> r = preloader->get_resource(item->get_text(0)); EditorInterface::get_singleton()->edit_resource(r); } else if (p_id == BUTTON_REMOVE) { @@ -249,7 +249,7 @@ Variant ResourcePreloaderEditor::get_drag_data_fw(const Point2 &p_point, Control String name = ti->get_metadata(0); - RES res = preloader->get_resource(name); + Ref<Resource> res = preloader->get_resource(name); if (!res.is_valid()) { return Variant(); } @@ -269,7 +269,7 @@ bool ResourcePreloaderEditor::can_drop_data_fw(const Point2 &p_point, const Vari } if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; return r.is_valid(); } @@ -294,7 +294,7 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant } if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; if (r.is_valid()) { String basename; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index a4bf28625d..0d33a7bdc6 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -232,7 +232,7 @@ void ScriptEditorBase::_bind_methods() { class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache { struct Cache { uint64_t time_loaded = 0; - RES cache; + Ref<Resource> cache; }; Map<String, Cache> cached; @@ -258,7 +258,7 @@ public: } } - virtual RES get_cached_resource(const String &p_path) { + virtual Ref<Resource> get_cached_resource(const String &p_path) { Map<String, Cache>::Element *E = cached.find(p_path); if (!E) { Cache c; @@ -428,7 +428,7 @@ void ScriptEditor::_goto_script_line2(int p_line) { } } -void ScriptEditor::_goto_script_line(REF p_script, int p_line) { +void ScriptEditor::_goto_script_line(Ref<RefCounted> p_script, int p_line) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { if (edit(p_script, p_line, 0)) { @@ -444,7 +444,7 @@ void ScriptEditor::_goto_script_line(REF p_script, int p_line) { } } -void ScriptEditor::_set_execution(REF p_script, int p_line) { +void ScriptEditor::_set_execution(Ref<RefCounted> p_script, int p_line) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { for (int i = 0; i < tab_container->get_tab_count(); i++) { @@ -460,7 +460,7 @@ void ScriptEditor::_set_execution(REF p_script, int p_line) { } } -void ScriptEditor::_clear_execution(REF p_script) { +void ScriptEditor::_clear_execution(Ref<RefCounted> p_script) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { for (int i = 0; i < tab_container->get_tab_count(); i++) { @@ -476,7 +476,7 @@ void ScriptEditor::_clear_execution(REF p_script) { } } -void ScriptEditor::_set_breakpoint(REF p_script, int p_line, bool p_enabled) { +void ScriptEditor::_set_breakpoint(Ref<RefCounted> p_script, int p_line, bool p_enabled) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { // Update if open. @@ -758,7 +758,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tselected); if (current) { - RES file = current->get_edited_resource(); + Ref<Resource> file = current->get_edited_resource(); if (p_save && file.is_valid()) { // Do not try to save internal scripts, but prompt to save in-memory // scripts which are not saved to disk yet (have empty path). @@ -849,7 +849,7 @@ void ScriptEditor::_close_docs_tab() { void ScriptEditor::_copy_script_path() { ScriptEditorBase *se = _get_current_editor(); if (se) { - RES script = se->get_edited_resource(); + Ref<Resource> script = se->get_edited_resource(); DisplayServer::get_singleton()->clipboard_set(script->get_path()); } } @@ -906,7 +906,7 @@ void ScriptEditor::_resave_scripts(const String &p_str) { continue; } - RES script = se->get_edited_resource(); + Ref<Resource> script = se->get_edited_resource(); if (script->is_built_in()) { continue; //internal script, who cares @@ -947,7 +947,7 @@ void ScriptEditor::_reload_scripts() { continue; } - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (edited_res->is_built_in()) { continue; //internal script, who cares @@ -991,7 +991,7 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) { continue; } - RES script = se->get_edited_resource(); + Ref<Resource> script = se->get_edited_resource(); if (script == p_res) { se->tag_saved_version(); @@ -1010,7 +1010,7 @@ void ScriptEditor::_scene_saved_callback(const String &p_path) { continue; } - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (!edited_res->is_built_in()) { continue; // External script, who cares. @@ -1039,7 +1039,7 @@ void ScriptEditor::_live_auto_reload_running_scripts() { EditorDebuggerNode::get_singleton()->reload_scripts(); } -bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) { +bool ScriptEditor::_test_script_times_on_disk(Ref<Resource> p_for_script) { disk_changed_list->clear(); TreeItem *r = disk_changed_list->create_item(); disk_changed_list->set_hide_root(true); @@ -1051,7 +1051,7 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (se) { - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res) { continue; } @@ -1117,7 +1117,7 @@ void ScriptEditor::_file_dialog_action(String p_file) { case FILE_SAVE_AS: { ScriptEditorBase *current = _get_current_editor(); if (current) { - RES resource = current->get_edited_resource(); + Ref<Resource> resource = current->get_edited_resource(); String path = ProjectSettings::get_singleton()->localize_path(p_file); Error err = _save_text_file(resource, path); @@ -1323,7 +1323,7 @@ void ScriptEditor::_menu_option(int p_option) { } } - RES resource = current->get_edited_resource(); + Ref<Resource> resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; Ref<Script> script = resource; @@ -1413,7 +1413,7 @@ void ScriptEditor::_menu_option(int p_option) { _copy_script_path(); } break; case SHOW_IN_FILE_SYSTEM: { - const RES script = current->get_edited_resource(); + const Ref<Resource> script = current->get_edited_resource(); String path = script->get_path(); if (!path.is_empty()) { if (script->is_built_in()) { @@ -2188,7 +2188,7 @@ Ref<TextFile> ScriptEditor::_load_text_file(const String &p_path, Error *r_error Ref<TextFile> text_res(text_file); Error err = text_file->load_text(path); - ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load text file '" + path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Cannot load text file '" + path + "'."); text_file->set_file_path(local_path); text_file->set_path(local_path, true); @@ -2230,7 +2230,7 @@ Error ScriptEditor::_save_text_file(Ref<TextFile> p_text_file, const String &p_p return OK; } -bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus) { +bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, bool p_grab_focus) { if (p_resource.is_null()) { return false; } @@ -2447,7 +2447,7 @@ void ScriptEditor::save_current_script() { } } - RES resource = current->get_edited_resource(); + Ref<Resource> resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; Ref<Script> script = resource; @@ -2516,7 +2516,7 @@ void ScriptEditor::save_all_scripts() { continue; } - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (edited_res.is_valid()) { se->apply_code(); } @@ -2589,14 +2589,14 @@ void ScriptEditor::open_text_file_create_dialog(const String &p_base_path, const open_textfile_after_create = false; } -RES ScriptEditor::open_file(const String &p_file) { +Ref<Resource> ScriptEditor::open_file(const String &p_file) { List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("Script", &extensions); if (extensions.find(p_file.get_extension())) { Ref<Script> scr = ResourceLoader::load(p_file); if (!scr.is_valid()) { EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); - return RES(); + return Ref<Resource>(); } edit(scr); @@ -2607,14 +2607,14 @@ RES ScriptEditor::open_file(const String &p_file) { Ref<TextFile> text_file = _load_text_file(p_file, &error); if (error != OK) { EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); - return RES(); + return Ref<Resource>(); } if (text_file.is_valid()) { edit(text_file); return text_file; } - return RES(); + return Ref<Resource>(); } void ScriptEditor::_editor_stop() { @@ -2980,7 +2980,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co continue; } - RES res = open_file(file); + Ref<Resource> res = open_file(file); if (res.is_valid()) { if (tab_container->get_tab_count() > num_tabs_before) { tab_container->move_child(tab_container->get_tab_control(tab_container->get_tab_count() - 1), new_index); @@ -3533,7 +3533,7 @@ void ScriptEditor::_on_replace_in_files_requested(String text) { void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) { if (ResourceLoader::exists(fpath)) { - RES res = ResourceLoader::load(fpath); + Ref<Resource> res = ResourceLoader::load(fpath); if (fpath.get_extension() == "gdshader") { ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader")); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 7885ffe2c5..41b311f745 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -53,7 +53,7 @@ class EditorSyntaxHighlighter : public SyntaxHighlighter { GDCLASS(EditorSyntaxHighlighter, SyntaxHighlighter) private: - REF edited_resourse; + Ref<RefCounted> edited_resourse; protected: static void _bind_methods(); @@ -65,8 +65,8 @@ public: virtual String _get_name() const; virtual Array _get_supported_languages() const; - void _set_edited_resource(const RES &p_res) { edited_resourse = p_res; } - REF _get_edited_resource() { return edited_resourse; } + void _set_edited_resource(const Ref<Resource> &p_res) { edited_resourse = p_res; } + Ref<RefCounted> _get_edited_resource() { return edited_resourse; } virtual Ref<EditorSyntaxHighlighter> _create() const; }; @@ -136,9 +136,9 @@ public: virtual void set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) = 0; virtual void apply_code() = 0; - virtual RES get_edited_resource() const = 0; + virtual Ref<Resource> get_edited_resource() const = 0; virtual Vector<String> get_functions() = 0; - virtual void set_edited_resource(const RES &p_res) = 0; + virtual void set_edited_resource(const Ref<Resource> &p_res) = 0; virtual void enable_editor() = 0; virtual void reload_text() = 0; virtual String get_name() = 0; @@ -179,7 +179,7 @@ public: ScriptEditorBase() {} }; -typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const RES &p_resource); +typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const Ref<Resource> &p_resource); class EditorScriptCodeCompletionCache; class FindInFilesDialog; @@ -249,7 +249,7 @@ class ScriptEditor : public PanelContainer { MenuButton *debug_menu = nullptr; PopupMenu *context_menu = nullptr; Timer *autosave_timer = nullptr; - uint64_t idle; + uint64_t idle = 0; PopupMenu *recent_scripts = nullptr; PopupMenu *theme_submenu = nullptr; @@ -330,7 +330,7 @@ class ScriptEditor : public PanelContainer { void _resave_scripts(const String &p_str); void _reload_scripts(); - bool _test_script_times_on_disk(RES p_for_script = Ref<Resource>()); + bool _test_script_times_on_disk(Ref<Resource> p_for_script = Ref<Resource>()); void _add_recent_script(String p_path); void _update_recent_scripts(); @@ -377,12 +377,12 @@ class ScriptEditor : public PanelContainer { bool convert_indent_on_save; void _goto_script_line2(int p_line); - void _goto_script_line(REF p_script, int p_line); - void _set_execution(REF p_script, int p_line); - void _clear_execution(REF p_script); + void _goto_script_line(Ref<RefCounted> p_script, int p_line); + void _set_execution(Ref<RefCounted> p_script, int p_line); + void _clear_execution(Ref<RefCounted> p_script); void _breaked(bool p_breaked, bool p_can_debug); void _script_created(Ref<Script> p_script); - void _set_breakpoint(REF p_scrpt, int p_line, bool p_enabled); + void _set_breakpoint(Ref<RefCounted> p_scrpt, int p_line, bool p_enabled); void _clear_breakpoints(); Array _get_cached_breakpoints_for_script(const String &p_path) const; @@ -481,12 +481,12 @@ public: void apply_scripts() const; void open_script_create_dialog(const String &p_base_name, const String &p_base_path); void open_text_file_create_dialog(const String &p_base_path, const String &p_base_name = ""); - RES open_file(const String &p_file); + Ref<Resource> open_file(const String &p_file); void ensure_select_current(); - _FORCE_INLINE_ bool edit(const RES &p_resource, bool p_grab_focus = true) { return edit(p_resource, -1, 0, p_grab_focus); } - bool edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus = true); + _FORCE_INLINE_ bool edit(const Ref<Resource> &p_resource, bool p_grab_focus = true) { return edit(p_resource, -1, 0, p_grab_focus); } + bool edit(const Ref<Resource> &p_resource, int p_line, int p_col, bool p_grab_focus = true); void get_breakpoints(List<String> *p_breakpoints); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 4626f10b8d..981881fb9b 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -133,11 +133,11 @@ void ScriptTextEditor::apply_code() { code_editor->get_text_editor()->get_syntax_highlighter()->update_cache(); } -RES ScriptTextEditor::get_edited_resource() const { +Ref<Resource> ScriptTextEditor::get_edited_resource() const { return script; } -void ScriptTextEditor::set_edited_resource(const RES &p_res) { +void ScriptTextEditor::set_edited_resource(const Ref<Resource> &p_res) { ERR_FAIL_COND(script.is_valid()); ERR_FAIL_COND(p_res.is_null()); @@ -239,6 +239,29 @@ void ScriptTextEditor::_show_warnings_panel(bool p_show) { void ScriptTextEditor::_warning_clicked(Variant p_line) { if (p_line.get_type() == Variant::INT) { goto_line_centered(p_line.operator int64_t()); + } else if (p_line.get_type() == Variant::DICTIONARY) { + Dictionary meta = p_line.operator Dictionary(); + const int line = meta["line"].operator int64_t() - 1; + + CodeEdit *text_editor = code_editor->get_text_editor(); + String prev_line = line > 0 ? text_editor->get_line(line - 1) : ""; + if (prev_line.contains("@warning_ignore")) { + const int closing_bracket_idx = prev_line.find(")"); + const String text_to_insert = ", " + meta["code"].operator String(); + prev_line = prev_line.insert(closing_bracket_idx, text_to_insert); + text_editor->set_line(line - 1, prev_line); + } else { + const int indent = text_editor->get_indent_level(line) / text_editor->get_indent_size(); + String annotation_indent; + if (!text_editor->is_indent_using_spaces()) { + annotation_indent = String("\t").repeat(indent); + } else { + annotation_indent = String(" ").repeat(text_editor->get_indent_size() * indent); + } + text_editor->insert_line_at(line, annotation_indent + "@warning_ignore(" + meta["code"].operator String() + ")"); + } + + _validate_script(); } } @@ -482,8 +505,20 @@ void ScriptTextEditor::_update_warnings() { } // Add script warnings. - warnings_panel->push_table(2); + warnings_panel->push_table(3); for (const ScriptLanguage::Warning &w : warnings) { + Dictionary ignore_meta; + ignore_meta["line"] = w.start_line; + ignore_meta["code"] = w.string_code.to_lower(); + warnings_panel->push_cell(); + warnings_panel->push_meta(ignore_meta); + warnings_panel->push_color( + warnings_panel->get_theme_color(SNAME("accent_color"), SNAME("Editor")).lerp(warnings_panel->get_theme_color(SNAME("mono_color"), SNAME("Editor")), 0.5f)); + warnings_panel->add_text(TTR("[Ignore]")); + warnings_panel->pop(); // Color. + warnings_panel->pop(); // Meta ignore. + warnings_panel->pop(); // Cell. + warnings_panel->push_cell(); warnings_panel->push_meta(w.start_line - 1); warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); @@ -1963,7 +1998,7 @@ ScriptTextEditor::~ScriptTextEditor() { } } -static ScriptEditorBase *create_editor(const RES &p_resource) { +static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) { if (Object::cast_to<Script>(*p_resource)) { return memnew(ScriptTextEditor); } diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index c1c4b0af54..b3e0c28bb1 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -205,8 +205,8 @@ public: void update_toggle_scripts_button() override; virtual void apply_code() override; - virtual RES get_edited_resource() const override; - virtual void set_edited_resource(const RES &p_res) override; + virtual Ref<Resource> get_edited_resource() const override; + virtual void set_edited_resource(const Ref<Resource> &p_res) override; virtual void enable_editor() override; virtual Vector<String> get_functions() override; virtual void reload_text() override; diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index 067711c75c..bd0c2db824 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -114,7 +114,7 @@ class ShaderEditor : public PanelContainer { MenuButton *help_menu = nullptr; PopupMenu *context_menu = nullptr; RichTextLabel *warnings_panel = nullptr; - uint64_t idle; + uint64_t idle = 0; GotoLineDialog *goto_line_dialog = nullptr; ConfirmationDialog *erase_tab_confirm = nullptr; diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 911e39a34f..f4a82225f2 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -131,7 +131,7 @@ class Skeleton3DEditor : public VBoxContainer { EditorFileDialog *file_dialog = nullptr; - bool keyable; + bool keyable = false; static Skeleton3DEditor *singleton; diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 29beb8be84..7b6aeb3679 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -1012,7 +1012,7 @@ Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f return Variant(); } - RES frame = frames->get_frame(edited_anim, idx); + Ref<Resource> frame = frames->get_frame(edited_anim, idx); if (frame.is_null()) { return Variant(); @@ -1036,7 +1036,7 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant & } if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; Ref<Texture2D> texture = r; @@ -1080,7 +1080,7 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da int at_pos = tree->get_item_at_position(p_point, true); if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; Ref<Texture2D> texture = r; diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index d31ce84d09..3230228fdd 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -105,7 +105,7 @@ class SpriteFramesEditor : public HSplitContainer { EditorFileDialog *file_split_sheet = nullptr; Set<int> frames_selected; Set<int> frames_toggled_by_mouse_hover; - int last_frame_selected; + int last_frame_selected = 0; float scale_ratio; int thumbnail_default_size; diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 34f3ec73c0..97ecc234e6 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -89,11 +89,11 @@ Ref<Texture2D> TextEditor::get_theme_icon() { return EditorNode::get_singleton()->get_object_icon(text_file.ptr(), ""); } -RES TextEditor::get_edited_resource() const { +Ref<Resource> TextEditor::get_edited_resource() const { return text_file; } -void TextEditor::set_edited_resource(const RES &p_res) { +void TextEditor::set_edited_resource(const Ref<Resource> &p_res) { ERR_FAIL_COND(text_file.is_valid()); ERR_FAIL_COND(p_res.is_null()); @@ -412,7 +412,7 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) { code_editor->convert_case(p_case); } -static ScriptEditorBase *create_editor(const RES &p_resource) { +static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) { if (Object::cast_to<TextFile>(*p_resource)) { return memnew(TextEditor); } diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index d03385d79e..9b6d568382 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -109,8 +109,8 @@ public: virtual String get_name() override; virtual Ref<Texture2D> get_theme_icon() override; - virtual RES get_edited_resource() const override; - virtual void set_edited_resource(const RES &p_res) override; + virtual Ref<Resource> get_edited_resource() const override; + virtual void set_edited_resource(const Ref<Resource> &p_res) override; virtual void enable_editor() override; virtual void reload_text() override; virtual void apply_code() override; diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index 1e1cc2b7b2..2493446303 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -87,14 +87,14 @@ class TextureRegionEditor : public VBoxContainer { Rect2 rect; Rect2 rect_prev; - float prev_margin; + float prev_margin = 0.0f; int edited_margin; Map<RID, List<Rect2>> cache_map; List<Rect2> autoslice_cache; bool autoslice_is_dirty; bool drag; - bool creating; + bool creating = false; Vector2 drag_from; int drag_index; diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index e17bea0f2a..87f8c4b165 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -2537,7 +2537,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_font(E.key(), edited_type)) { item_editor->set_edited_resource(edited_theme->get_font(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_font_item_changed), varray(E.key())); @@ -2545,7 +2545,7 @@ void ThemeTypeEditor::_update_type_items() { if (Theme::get_default()->has_font(E.key(), edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_font(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->set_editable(false); } @@ -2608,7 +2608,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_icon(E.key(), edited_type)) { item_editor->set_edited_resource(edited_theme->get_icon(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_icon_item_changed), varray(E.key())); @@ -2616,7 +2616,7 @@ void ThemeTypeEditor::_update_type_items() { if (Theme::get_default()->has_icon(E.key(), edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_icon(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->set_editable(false); } @@ -2655,7 +2655,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_stylebox(leading_stylebox.item_name, edited_type)) { item_editor->set_edited_resource(leading_stylebox.stylebox); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(leading_stylebox.item_name)); @@ -2680,7 +2680,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_stylebox(E.key(), edited_type)) { item_editor->set_edited_resource(edited_theme->get_stylebox(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(E.key())); @@ -2696,7 +2696,7 @@ void ThemeTypeEditor::_update_type_items() { if (Theme::get_default()->has_stylebox(E.key(), edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_stylebox(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->set_editable(false); } @@ -3065,7 +3065,7 @@ void ThemeTypeEditor::_font_size_item_changed(float p_value, String p_item_name) ur->commit_action(); } -void ThemeTypeEditor::_edit_resource_item(RES p_resource, bool p_edit) { +void ThemeTypeEditor::_edit_resource_item(Ref<Resource> p_resource, bool p_edit) { EditorNode::get_singleton()->edit_resource(p_resource); } @@ -3131,7 +3131,7 @@ void ThemeTypeEditor::_change_pinned_stylebox() { Ref<StyleBox> new_stylebox = edited_theme->get_stylebox(leading_stylebox.item_name, edited_type); leading_stylebox.stylebox = new_stylebox; - leading_stylebox.ref_stylebox = (new_stylebox.is_valid() ? new_stylebox->duplicate() : RES()); + leading_stylebox.ref_stylebox = (new_stylebox.is_valid() ? new_stylebox->duplicate() : Ref<Resource>()); if (leading_stylebox.stylebox.is_valid()) { new_stylebox->connect("changed", callable_mp(this, &ThemeTypeEditor::_update_stylebox_from_leading)); @@ -3169,7 +3169,7 @@ void ThemeTypeEditor::_pin_leading_stylebox(String p_item_name, Ref<StyleBox> p_ leader.pinned = true; leader.item_name = p_item_name; leader.stylebox = p_stylebox; - leader.ref_stylebox = (p_stylebox.is_valid() ? p_stylebox->duplicate() : RES()); + leader.ref_stylebox = (p_stylebox.is_valid() ? p_stylebox->duplicate() : Ref<Resource>()); leading_stylebox = leader; if (p_stylebox.is_valid()) { diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 4b49fbb186..3894ca31e5 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -384,7 +384,7 @@ class ThemeTypeEditor : public MarginContainer { void _color_item_changed(Color p_value, String p_item_name); void _constant_item_changed(float p_value, String p_item_name); void _font_size_item_changed(float p_value, String p_item_name); - void _edit_resource_item(RES p_resource, bool p_edit); + void _edit_resource_item(Ref<Resource> p_resource, bool p_edit); void _font_item_changed(Ref<Font> p_value, String p_item_name); void _icon_item_changed(Ref<Texture2D> p_value, String p_item_name); void _stylebox_item_changed(Ref<StyleBox> p_value, String p_item_name); diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h index 3ac9eacb05..2c849637f0 100644 --- a/editor/plugins/tiles/tile_data_editors.h +++ b/editor/plugins/tiles/tile_data_editors.h @@ -108,8 +108,8 @@ private: DRAG_TYPE_PAN, }; DragType drag_type = DRAG_TYPE_NONE; - int drag_polygon_index; - int drag_point_index; + int drag_polygon_index = 0; + int drag_point_index = 0; Vector2 drag_last_pos; PackedVector2Array drag_old_polygon; @@ -132,9 +132,9 @@ private: Ref<Texture2D> background_texture; Rect2 background_region; Vector2 background_offset; - bool background_h_flip; - bool background_v_flip; - bool background_transpose; + bool background_h_flip = false; + bool background_v_flip = false; + bool background_transpose = false; Color background_modulate; Color polygon_color = Color(1.0, 0.0, 0.0); diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index c1a95c11f6..ba87eba9e0 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -76,7 +76,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { picker_button->show(); erase_button->show(); tools_settings_vsep_2->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } else if (tool_buttons_group->get_pressed_button() == line_tool_button) { @@ -84,7 +84,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { picker_button->show(); erase_button->show(); tools_settings_vsep_2->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } else if (tool_buttons_group->get_pressed_button() == rect_tool_button) { @@ -92,7 +92,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { picker_button->show(); erase_button->show(); tools_settings_vsep_2->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } else if (tool_buttons_group->get_pressed_button() == bucket_tool_button) { @@ -101,7 +101,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { erase_button->show(); tools_settings_vsep_2->show(); bucket_contiguous_checkbox->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } @@ -461,6 +461,7 @@ void TileMapEditorTilesPlugin::_update_theme() { picker_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons"))); erase_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Eraser"), SNAME("EditorIcons"))); + random_tile_toggle->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("RandomNumberGenerator"), SNAME("EditorIcons"))); missing_atlas_texture_icon = tiles_bottom_panel->get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons")); } @@ -870,7 +871,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over Transform2D tile_xform; tile_xform.set_origin(tile_map->map_to_world(E.key)); tile_xform.set_scale(tile_set->get_tile_size()); - if (!(drag_erasing || erase_button->is_pressed()) && random_tile_checkbox->is_pressed()) { + if (!(drag_erasing || erase_button->is_pressed()) && random_tile_toggle->is_pressed()) { tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); } else { if (tile_set->has_source(E.value.source_id)) { @@ -1001,7 +1002,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_start_ Map<Vector2i, TileMapCell> output; if (!pattern->is_empty()) { // Paint the tiles on the tile map. - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(p_from_mouse_pos), tile_map->world_to_map(p_to_mouse_pos)); for (int i = 0; i < line.size(); i++) { @@ -1061,7 +1062,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_rect(Vector2i p_start Map<Vector2i, TileMapCell> output; if (!pattern->is_empty()) { - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. for (int x = 0; x < rect.size.x; x++) { for (int y = 0; y < rect.size.y; y++) { @@ -1134,7 +1135,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i source_cell.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) && source_cell.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) && (source_cell.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) { - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. output.insert(coords, _pick_random_tile(pattern)); } else { @@ -1180,7 +1181,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i source_cell.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) && source_cell.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) && (source_cell.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) { - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. output.insert(coords, _pick_random_tile(pattern)); } else { @@ -2103,11 +2104,12 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { tools_settings->add_child(bucket_contiguous_checkbox); // Random tile checkbox. - random_tile_checkbox = memnew(CheckBox); - random_tile_checkbox->set_flat(true); - random_tile_checkbox->set_text(TTR("Place Random Tile")); - random_tile_checkbox->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled)); - tools_settings->add_child(random_tile_checkbox); + random_tile_toggle = memnew(Button); + random_tile_toggle->set_flat(true); + random_tile_toggle->set_toggle_mode(true); + random_tile_toggle->set_tooltip(TTR("Place Random Tile")); + random_tile_toggle->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled)); + tools_settings->add_child(random_tile_toggle); // Random tile scattering. scatter_label = memnew(Label); diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index 3a0293f48f..ec32c83d10 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -92,7 +92,7 @@ private: VSeparator *tools_settings_vsep_2 = nullptr; CheckBox *bucket_contiguous_checkbox = nullptr; - CheckBox *random_tile_checkbox = nullptr; + Button *random_tile_toggle = nullptr; float scattering = 0.0; Label *scatter_label = nullptr; SpinBox *scatter_spinbox = nullptr; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index dc07ac7c39..f184049d41 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5864,7 +5864,7 @@ public: class VisualShaderNodePluginDefaultEditor : public VBoxContainer { GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer); Ref<Resource> parent_resource; - int node_id; + int node_id = 0; VisualShader::Type shader_type; public: @@ -5881,18 +5881,18 @@ public: undo_redo->add_undo_property(node.ptr(), p_property, node->get(p_property)); if (p_value.get_type() == Variant::OBJECT) { - RES prev_res = node->get(p_property); - RES curr_res = p_value; + Ref<Resource> prev_res = node->get(p_property); + Ref<Resource> curr_res = p_value; if (curr_res.is_null()) { - undo_redo->add_do_method(this, "_open_inspector", (RES)parent_resource.ptr()); + undo_redo->add_do_method(this, "_open_inspector", (Ref<Resource>)parent_resource.ptr()); } else { - undo_redo->add_do_method(this, "_open_inspector", (RES)curr_res.ptr()); + undo_redo->add_do_method(this, "_open_inspector", (Ref<Resource>)curr_res.ptr()); } if (!prev_res.is_null()) { - undo_redo->add_undo_method(this, "_open_inspector", (RES)prev_res.ptr()); + undo_redo->add_undo_method(this, "_open_inspector", (Ref<Resource>)prev_res.ptr()); } else { - undo_redo->add_undo_method(this, "_open_inspector", (RES)parent_resource.ptr()); + undo_redo->add_undo_method(this, "_open_inspector", (Ref<Resource>)parent_resource.ptr()); } } if (p_property != "constant") { @@ -5919,15 +5919,15 @@ public: } } - void _resource_selected(const String &p_path, RES p_resource) { + void _resource_selected(const String &p_path, Ref<Resource> p_resource) { _open_inspector(p_resource); } - void _open_inspector(RES p_resource) { + void _open_inspector(Ref<Resource> p_resource) { InspectorDock::get_inspector_singleton()->edit(p_resource.ptr()); } - bool updating; + bool updating = false; Ref<VisualShaderNode> node; Vector<EditorProperty *> properties; Vector<Label *> prop_names; diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 8db2cf07f9..540cb709b3 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -48,7 +48,7 @@ class VisualShaderNodePlugin : public RefCounted { protected: static void _bind_methods(); - GDVIRTUAL2RC(Object *, _create_editor, RES, Ref<VisualShaderNode>) + GDVIRTUAL2RC(Object *, _create_editor, Ref<Resource>, Ref<VisualShaderNode>) public: virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node); diff --git a/editor/progress_dialog.h b/editor/progress_dialog.h index f395750165..23a77ea201 100644 --- a/editor/progress_dialog.h +++ b/editor/progress_dialog.h @@ -85,7 +85,7 @@ class ProgressDialog : public PopupPanel { void _popup(); void _cancel_pressed(); - bool cancelled; + bool cancelled = false; protected: void _notification(int p_what); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index adbaad9d7c..5effdf0b36 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -85,7 +85,7 @@ bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) co } Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const { - RES ret; + Ref<Resource> ret; if (GDVIRTUAL_CALL(_convert, p_resource, ret)) { return ret; } @@ -151,7 +151,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { } break; case OBJ_MENU_EDIT: { - REF r = v; + Ref<RefCounted> r = v; if (!r.is_null()) { emit_signal(SNAME("resource_edit_request")); @@ -223,7 +223,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { } break; case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { - RES r = v; + Ref<Resource> r = v; FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); file_system_dock->navigate_to_path(r->get_path()); // Ensure that the FileSystem dock is visible. @@ -234,7 +234,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { if (p_which >= CONVERT_BASE_ID) { int to_type = p_which - CONVERT_BASE_ID; - Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v)); + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(Ref<Resource>(v)); ERR_FAIL_INDEX(to_type, conversions.size()); @@ -928,19 +928,19 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: menu->add_item(TTR("Load"), OBJ_MENU_LOAD); - if (!RES(v).is_null()) { + if (!Ref<Resource>(v).is_null()) { menu->add_item(TTR("Edit"), OBJ_MENU_EDIT); menu->add_item(TTR("Clear"), OBJ_MENU_CLEAR); menu->add_item(TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); - RES r = v; + Ref<Resource> r = v; if (r.is_valid() && r->get_path().is_resource_file()) { menu->add_separator(); menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM); } } - RES cb = EditorSettings::get_singleton()->get_resource_clipboard(); + Ref<Resource> cb = EditorSettings::get_singleton()->get_resource_clipboard(); bool paste_valid = false; if (cb.is_valid()) { if (hint_text.is_empty()) { @@ -955,10 +955,10 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } } - if (!RES(v).is_null() || paste_valid) { + if (!Ref<Resource>(v).is_null() || paste_valid) { menu->add_separator(); - if (!RES(v).is_null()) { + if (!Ref<Resource>(v).is_null()) { menu->add_item(TTR("Copy"), OBJ_MENU_COPY); } @@ -967,8 +967,8 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } } - if (!RES(v).is_null()) { - Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v)); + if (!Ref<Resource>(v).is_null()) { + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(Ref<Resource>(v)); if (conversions.size()) { menu->add_separator(); } @@ -1029,7 +1029,7 @@ void CustomPropertyEditor::_file_selected(String p_file) { case Variant::OBJECT: { String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String(); - RES res = ResourceLoader::load(p_file, type); + Ref<Resource> res = ResourceLoader::load(p_file, type); if (res.is_null()) { error->set_text(TTR("Error loading file: Not a resource!")); error->popup_centered(); @@ -1312,7 +1312,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { file->popup_file_dialog(); } else if (p_which == 2) { - RES r = v; + Ref<Resource> r = v; if (!r.is_null()) { emit_signal(SNAME("resource_edit_request")); diff --git a/editor/property_editor.h b/editor/property_editor.h index 1a4d88f7fa..3230834d00 100644 --- a/editor/property_editor.h +++ b/editor/property_editor.h @@ -58,8 +58,8 @@ protected: static void _bind_methods(); GDVIRTUAL0RC(String, _converts_to) - GDVIRTUAL1RC(bool, _handles, RES) - GDVIRTUAL1RC(RES, _convert, RES) + GDVIRTUAL1RC(bool, _handles, Ref<Resource>) + GDVIRTUAL1RC(Ref<Resource>, _convert, Ref<Resource>) public: virtual String converts_to() const; @@ -104,7 +104,7 @@ class CustomPropertyEditor : public PopupPanel { Variant::Type type; Variant v; List<String> field_names; - int hint; + int hint = 0; String hint_text; HBoxContainer *value_hboxes[MAX_VALUE_EDITORS / 4]; VBoxContainer *value_vbox = nullptr; @@ -120,7 +120,7 @@ class CustomPropertyEditor : public PopupPanel { ColorPicker *color_picker = nullptr; TextEdit *text_edit = nullptr; bool read_only = false; - bool picking_viewport; + bool picking_viewport = false; GridContainer *checks20gc = nullptr; CheckBox *checks20[20]; SpinBox *spinbox = nullptr; diff --git a/editor/property_selector.h b/editor/property_selector.h index 597804da31..f42f5daa3f 100644 --- a/editor/property_selector.h +++ b/editor/property_selector.h @@ -50,7 +50,7 @@ class PropertySelector : public ConfirmationDialog { EditorHelpBit *help_bit = nullptr; - bool properties; + bool properties = false; String selected; Variant::Type type; String base_type; diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index d05e80fc04..f3a850045e 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -64,7 +64,7 @@ class RenameDialog : public ConfirmationDialog { SceneTreeEditor *scene_tree_editor = nullptr; UndoRedo *undo_redo = nullptr; - int global_count; + int global_count = 0; LineEdit *lne_search = nullptr; LineEdit *lne_replace = nullptr; @@ -97,9 +97,9 @@ class RenameDialog : public ConfirmationDialog { List<Pair<NodePath, String>> to_rename; Node *preview_node = nullptr; - bool lock_preview_update; + bool lock_preview_update = false; ErrorHandlerList eh; - bool has_errors; + bool has_errors = false; protected: static void _bind_methods(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 3e8eb6b4ee..0ddcb1788a 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1153,7 +1153,7 @@ void SceneTreeDock::_property_selected(int p_idx) { property_drop_node = nullptr; } -void SceneTreeDock::_perform_property_drop(Node *p_node, String p_property, RES p_res) { +void SceneTreeDock::_perform_property_drop(Node *p_node, String p_property, Ref<Resource> p_res) { editor_data->get_undo_redo().create_action(vformat(TTR("Set %s"), p_property)); editor_data->get_undo_redo().add_do_property(p_node, p_property, p_res); editor_data->get_undo_redo().add_undo_property(p_node, p_property, p_node->get(p_property)); @@ -3056,14 +3056,14 @@ List<Node *> SceneTreeDock::paste_nodes() { ur.create_action(TTR("Paste Node(s)")); ur.add_do_method(editor_selection, "clear"); - Map<RES, RES> resource_remap; + Map<Ref<Resource>, Ref<Resource>> resource_remap; String target_scene; if (edited_scene) { target_scene = edited_scene->get_scene_file_path(); } if (target_scene != clipboard_source_scene) { if (!clipboard_resource_remap.has(target_scene)) { - Map<RES, RES> remap; + Map<Ref<Resource>, Ref<Resource>> remap; for (Node *E : node_clipboard) { _create_remap_for_node(E, remap); } @@ -3259,7 +3259,7 @@ void SceneTreeDock::_clear_clipboard() { clipboard_resource_remap.clear(); } -void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) { +void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<Ref<Resource>, Ref<Resource>> &r_remap) { List<PropertyInfo> props; p_node->get_property_list(&props); @@ -3273,7 +3273,7 @@ void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) Variant v = p_node->get(E.name); if (v.is_ref_counted()) { - RES res = v; + Ref<Resource> res = v; if (res.is_valid()) { if (!states_stack_ready) { states_stack = PropertyUtils::get_node_states_stack(p_node); @@ -3298,7 +3298,7 @@ void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) } } -void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_remap) { +void SceneTreeDock::_create_remap_for_resource(Ref<Resource> p_resource, Map<Ref<Resource>, Ref<Resource>> &r_remap) { r_remap[p_resource] = p_resource->duplicate(); List<PropertyInfo> props; @@ -3311,7 +3311,7 @@ void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_ Variant v = p_resource->get(E.name); if (v.is_ref_counted()) { - RES res = v; + Ref<Resource> res = v; if (res.is_valid()) { if (res->is_built_in() && !r_remap.has(res)) { _create_remap_for_resource(res, r_remap); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 77e727b2c8..a1d300d3d6 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -108,7 +108,7 @@ class SceneTreeDock : public VBoxContainer { bool restore_script_editor_on_drag = false; bool reset_create_dialog = false; - int current_option; + int current_option = 0; CreateDialog *create_dialog = nullptr; #ifdef MODULE_REGEX_ENABLED RenameDialog *rename_dialog = nullptr; @@ -138,14 +138,14 @@ class SceneTreeDock : public VBoxContainer { Node *property_drop_node = nullptr; String resource_drop_path; - void _perform_property_drop(Node *p_node, String p_property, RES p_res); + void _perform_property_drop(Node *p_node, String p_property, Ref<Resource> p_res); EditorData *editor_data = nullptr; EditorSelection *editor_selection = nullptr; List<Node *> node_clipboard; String clipboard_source_scene; - HashMap<String, Map<RES, RES>> clipboard_resource_remap; + HashMap<String, Map<Ref<Resource>, Ref<Resource>>> clipboard_resource_remap; ScriptCreateDialog *script_create_dialog = nullptr; ShaderCreateDialog *shader_create_dialog = nullptr; @@ -258,8 +258,8 @@ class SceneTreeDock : public VBoxContainer { void _feature_profile_changed(); void _clear_clipboard(); - void _create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap); - void _create_remap_for_resource(RES p_resource, Map<RES, RES> &r_remap); + void _create_remap_for_node(Node *p_node, Map<Ref<Resource>, Ref<Resource>> &r_remap); + void _create_remap_for_resource(Ref<Resource> p_resource, Map<Ref<Resource>, Ref<Resource>> &r_remap); bool profile_allow_editing = true; bool profile_allow_script_editing = true; diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 7d063e13f9..9530a58eb2 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -398,7 +398,7 @@ void ScriptCreateDialog::_create_new() { void ScriptCreateDialog::_load_exist() { String path = file_path->get_text(); - RES p_script = ResourceLoader::load(path, "Script"); + Ref<Resource> p_script = ResourceLoader::load(path, "Script"); if (p_script.is_null()) { alert->set_text(vformat(TTR("Error loading script from %s"), path)); alert->popup_centered(); diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index f07ec161c2..3a2c4fb17b 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -135,7 +135,7 @@ void ShaderCreateDialog::ok_pressed() { } void ShaderCreateDialog::_create_new() { - RES shader; + Ref<Resource> shader; if (language_menu->get_selected() == int(SHADER_TYPE_TEXT)) { Ref<Shader> text_shader; @@ -205,7 +205,7 @@ void ShaderCreateDialog::_create_new() { void ShaderCreateDialog::_load_exist() { String path = file_path->get_text(); - RES p_shader = ResourceLoader::load(path, "Shader"); + Ref<Resource> p_shader = ResourceLoader::load(path, "Shader"); if (p_shader.is_null()) { alert->set_text(vformat(TTR("Error loading shader from %s"), path)); alert->popup_centered(); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index 81e672c5c3..bfabf269bf 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -94,7 +94,7 @@ protected: Dictionary gv; gv["type"] = global_var_type_names[type]; if (type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { - RES res = p_value; + Ref<Resource> res = p_value; if (res.is_valid()) { gv["value"] = res->get_path(); } else { diff --git a/main/main.cpp b/main/main.cpp index 755924929c..bc07aad1a7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2324,7 +2324,7 @@ bool Main::start() { for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { const ProjectSettings::AutoloadInfo &info = E.get(); - RES res = ResourceLoader::load(info.path); + Ref<Resource> res = ResourceLoader::load(info.path); ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path); Node *n = nullptr; Ref<PackedScene> scn = res; diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index d18340a2c8..a7cfcaa262 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -46,7 +46,7 @@ struct CVTTCompressionJobParams { }; struct CVTTCompressionRowTask { - const uint8_t *in_mm_bytes; + const uint8_t *in_mm_bytes = nullptr; uint8_t *out_mm_bytes = nullptr; int y_start = 0; int width = 0; @@ -55,7 +55,7 @@ struct CVTTCompressionRowTask { struct CVTTCompressionJobQueue { CVTTCompressionJobParams job_params; - const CVTTCompressionRowTask *job_tasks; + const CVTTCompressionRowTask *job_tasks = nullptr; uint32_t num_tasks = 0; SafeNumeric<uint32_t> current_task; }; diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index 58e5e31f46..2c0e604e66 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -68,7 +68,7 @@ enum DDSFormat { }; struct DDSFormatInfo { - const char *name; + const char *name = nullptr; bool compressed = false; bool palette = false; uint32_t divisor = 0; @@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 } }; -RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -102,7 +102,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error err; Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err); if (f.is_null()) { - return RES(); + return Ref<Resource>(); } Ref<FileAccess> fref(f); @@ -110,7 +110,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, *r_error = ERR_FILE_CORRUPT; } - ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open DDS texture file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Unable to open DDS texture file '" + p_path + "'."); uint32_t magic = f->get_32(); uint32_t hsize = f->get_32(); @@ -131,7 +131,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, // We don't check DDSD_CAPS or DDSD_PIXELFORMAT, as they're mandatory when writing, // but non-mandatory when reading (as some writers don't set them)... if (magic != DDS_MAGIC || hsize != 124) { - ERR_FAIL_V_MSG(RES(), "Invalid or unsupported DDS texture file '" + p_path + "'."); + ERR_FAIL_V_MSG(Ref<Resource>(), "Invalid or unsupported DDS texture file '" + p_path + "'."); } /* uint32_t format_size = */ f->get_32(); @@ -204,7 +204,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, dds_format = DDS_BGR565; } else { printf("unrecognized fourcc %x format_flags: %x - rgbbits %i - red_mask %x green mask %x blue mask %x alpha mask %x\n", format_fourcc, format_flags, format_rgb_bits, format_red_mask, format_green_mask, format_blue_mask, format_alpha_mask); - ERR_FAIL_V_MSG(RES(), "Unrecognized or unsupported color layout in DDS '" + p_path + "'."); + ERR_FAIL_V_MSG(Ref<Resource>(), "Unrecognized or unsupported color layout in DDS '" + p_path + "'."); } if (!(flags & DDSD_MIPMAPCOUNT)) { @@ -221,8 +221,8 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, //compressed bc uint32_t size = MAX(info.divisor, w) / info.divisor * MAX(info.divisor, h) / info.divisor * info.block_size; - ERR_FAIL_COND_V(size != pitch, RES()); - ERR_FAIL_COND_V(!(flags & DDSD_LINEARSIZE), RES()); + ERR_FAIL_COND_V(size != pitch, Ref<Resource>()); + ERR_FAIL_COND_V(!(flags & DDSD_LINEARSIZE), Ref<Resource>()); for (uint32_t i = 1; i < mipmaps; i++) { w = MAX(1u, w >> 1); @@ -238,11 +238,11 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, } else if (info.palette) { //indexed - ERR_FAIL_COND_V(!(flags & DDSD_PITCH), RES()); - ERR_FAIL_COND_V(format_rgb_bits != 8, RES()); + ERR_FAIL_COND_V(!(flags & DDSD_PITCH), Ref<Resource>()); + ERR_FAIL_COND_V(format_rgb_bits != 8, Ref<Resource>()); uint32_t size = pitch * height; - ERR_FAIL_COND_V(size != width * height * info.block_size, RES()); + ERR_FAIL_COND_V(size != width * height * info.block_size, Ref<Resource>()); uint8_t palette[256 * 4]; f->get_buffer(palette, 256 * 4); diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h index 25ded4e168..701f8f4a13 100644 --- a/modules/dds/texture_loader_dds.h +++ b/modules/dds/texture_loader_dds.h @@ -36,7 +36,7 @@ class ResourceFormatDDS : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp index a8f4483cf4..9b540b16f2 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp @@ -44,7 +44,7 @@ Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Ve // Search strings in AssignmentNode -> text = "__", hint_tooltip = "__" etc. Error err; - RES loaded_res = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + Ref<Resource> loaded_res = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 55c7ace938..1b4711804c 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -82,7 +82,7 @@ Variant GDScriptNativeClass::_new() { RefCounted *rc = Object::cast_to<RefCounted>(o); if (rc) { - return REF(rc); + return Ref<RefCounted>(rc); } else { return o; } @@ -195,7 +195,7 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallErr } r_error.error = Callable::CallError::CALL_OK; - REF ref; + Ref<RefCounted> ref; Object *owner = nullptr; GDScript *_baseptr = this; @@ -213,7 +213,7 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallErr RefCounted *r = Object::cast_to<RefCounted>(owner); if (r) { - ref = REF(r); + ref = Ref<RefCounted>(r); } GDScriptInstance *instance = _create_instance(p_args, p_argcount, owner, r != nullptr, r_error); @@ -2292,7 +2292,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na /*************** RESOURCE ***************/ -RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -2353,7 +2353,7 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S } } -Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverGDScript::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { Ref<GDScript> sqscr = p_resource; ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER); @@ -2378,12 +2378,12 @@ Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resou return OK; } -void ResourceFormatSaverGDScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceFormatSaverGDScript::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { if (Object::cast_to<GDScript>(*p_resource)) { p_extensions->push_back("gd"); } } -bool ResourceFormatSaverGDScript::recognize(const RES &p_resource) const { +bool ResourceFormatSaverGDScript::recognize(const Ref<Resource> &p_resource) const { return Object::cast_to<GDScript>(*p_resource) != nullptr; } diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index caca7d8ca5..a20f3b2fca 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -512,7 +512,7 @@ public: class ResourceFormatLoaderGDScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -521,9 +521,9 @@ public: class ResourceFormatSaverGDScript : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; - virtual bool recognize(const RES &p_resource) const; + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; + virtual bool recognize(const Ref<Resource> &p_resource) const; }; #endif // GDSCRIPT_H diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 225c2d0d45..37a988ee4c 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -356,7 +356,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code class_node = class_node->outer; } - RES res; + Ref<Resource> res; if (class_node->identifier && class_node->identifier->name == identifier) { res = Ref<GDScript>(main_script); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index b3f9914b7d..0197bf9ea3 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -3106,7 +3106,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co } Variant v; - REF v_ref; + Ref<RefCounted> v_ref; if (base_type.builtin_type == Variant::OBJECT) { v_ref.instantiate(); v = v_ref; diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index 89d94d8635..a914374985 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -545,7 +545,7 @@ struct GDScriptUtilityFunctionsDefinitions { }; struct GDScriptUtilityFunctionInfo { - GDScriptUtilityFunctions::FunctionPtr function; + GDScriptUtilityFunctions::FunctionPtr function = nullptr; MethodInfo info; bool is_constant = false; }; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index 4c4e810370..5516f59fe9 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -212,7 +212,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p const Variant &default_value = m.constant->initializer->reduced_value; String value_text; if (default_value.get_type() == Variant::OBJECT) { - RES res = default_value; + Ref<Resource> res = default_value; if (res.is_valid() && !res->get_path().is_empty()) { value_text = "preload(\"" + res->get_path() + "\")"; if (symbol.documentation.is_empty()) { diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 229c322f26..89ee6b35e5 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -560,7 +560,7 @@ Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) { for (int i = 0; i < owners.size(); i++) { NodePath owner_path = owners[i]; - RES owner_res = ResourceLoader::load(owner_path); + Ref<Resource> owner_res = ResourceLoader::load(owner_path); if (Object::cast_to<PackedScene>(owner_res.ptr())) { Ref<PackedScene> owner_packed_scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*owner_res)); owner_scene_node = owner_packed_scene->instantiate(); diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index e78517a708..ea51990237 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -70,7 +70,7 @@ void init_autoloads() { continue; } - RES res = ResourceLoader::load(info.path); + Ref<Resource> res = ResourceLoader::load(info.path); ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path); Node *n = nullptr; Ref<PackedScene> scn = res; diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 02fe4d93de..3c7bd5eb70 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -797,7 +797,7 @@ void GridMap::clear() { clear_baked_meshes(); } -void GridMap::resource_changed(const RES &p_res) { +void GridMap::resource_changed(const Ref<Resource> &p_res) { _recreate_octant_data(); } diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index b09cabfe25..5e367e149d 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -181,7 +181,7 @@ class GridMap : public Node3D { void _queue_octants_dirty(); void _update_octants_callback(); - void resource_changed(const RES &p_res); + void resource_changed(const Ref<Resource> &p_res); void _clear_internal(); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 02aebb3805..5875a0fbd4 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -924,7 +924,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { for (Ref<CSharpScript> &script : scripts) { while (script->instances.front()) { Object *obj = script->instances.front()->get(); - obj->set_script(REF()); // Remove script and existing script instances (placeholder are not removed before domain reload) + obj->set_script(Ref<RefCounted>()); // Remove script and existing script instances (placeholder are not removed before domain reload) } script->_clear(); @@ -3221,10 +3221,10 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Callable::Cal Object *owner = ClassDB::instantiate(NATIVE_GDMONOCLASS_NAME(native)); - REF ref; + Ref<RefCounted> ref; RefCounted *r = Object::cast_to<RefCounted>(owner); if (r) { - ref = REF(r); + ref = Ref<RefCounted>(r); } CSharpInstance *instance = _create_instance(p_args, p_argcount, owner, r != nullptr, r_error); @@ -3586,7 +3586,7 @@ void CSharpScript::get_members(Set<StringName> *p_members) { /*************** RESOURCE ***************/ -RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -3599,7 +3599,7 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p #if defined(DEBUG_ENABLED) || defined(TOOLS_ENABLED) Error err = script->load_source_code(p_path); - ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load C# script file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Cannot load C# script file '" + p_path + "'."); #endif script->set_path(p_original_path); @@ -3625,7 +3625,7 @@ String ResourceFormatLoaderCSharpScript::get_resource_type(const String &p_path) return p_path.get_extension().to_lower() == "cs" ? CSharpLanguage::get_singleton()->get_type() : ""; } -Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverCSharpScript::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { Ref<CSharpScript> sqscr = p_resource; ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER); @@ -3662,13 +3662,13 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r return OK; } -void ResourceFormatSaverCSharpScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceFormatSaverCSharpScript::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { if (Object::cast_to<CSharpScript>(p_resource.ptr())) { p_extensions->push_back("cs"); } } -bool ResourceFormatSaverCSharpScript::recognize(const RES &p_resource) const { +bool ResourceFormatSaverCSharpScript::recognize(const Ref<Resource> &p_resource) const { return Object::cast_to<CSharpScript>(p_resource.ptr()) != nullptr; } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 1e5f218c95..41b54248a3 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -534,7 +534,7 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; + Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; void get_recognized_extensions(List<String> *p_extensions) const override; bool handles_type(const String &p_type) const override; String get_resource_type(const String &p_path) const override; @@ -542,9 +542,9 @@ public: class ResourceFormatSaverCSharpScript : public ResourceFormatSaver { public: - Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0) override; - void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const override; - bool recognize(const RES &p_resource) const override; + Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0) override; + void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override; + bool recognize(const Ref<Resource> &p_resource) const override; }; #endif // CSHARP_SCRIPT_H diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index b5f2c98af5..b10d78c593 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -148,7 +148,7 @@ MonoObject *godot_icall_Object_weakref(Object *p_ptr) { RefCounted *rc = Object::cast_to<RefCounted>(p_ptr); if (rc) { - REF r = rc; + Ref<RefCounted> r = rc; if (!r.is_valid()) { return nullptr; } diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 9e2daf3a99..2d6c78f704 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -34,7 +34,6 @@ #include "core/math/convex_hull.h" #include "core/os/thread.h" -#include "scene/3d/collision_shape_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" @@ -202,14 +201,17 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans StaticBody3D *static_body = Object::cast_to<StaticBody3D>(p_node); if (static_body->get_collision_layer() & p_collision_mask) { - for (int i = 0; i < p_node->get_child_count(); ++i) { - Node *child = p_node->get_child(i); - if (Object::cast_to<CollisionShape3D>(child)) { - CollisionShape3D *col_shape = Object::cast_to<CollisionShape3D>(child); - - Transform3D transform = p_navmesh_transform * static_body->get_global_transform() * col_shape->get_transform(); + List<uint32_t> shape_owners; + static_body->get_shape_owners(&shape_owners); + for (uint32_t shape_owner : shape_owners) { + const int shape_count = static_body->shape_owner_get_shape_count(shape_owner); + for (int i = 0; i < shape_count; i++) { + Ref<Shape3D> s = static_body->shape_owner_get_shape(shape_owner, i); + if (s.is_null()) { + continue; + } - Ref<Shape3D> s = col_shape->get_shape(); + const Transform3D transform = p_navmesh_transform * static_body->get_global_transform() * static_body->shape_owner_get_transform(shape_owner); BoxShape3D *box = Object::cast_to<BoxShape3D>(*s); if (box) { diff --git a/modules/noise/noise.cpp b/modules/noise/noise.cpp index ad3df0a016..d14b63f7c8 100644 --- a/modules/noise/noise.cpp +++ b/modules/noise/noise.cpp @@ -31,6 +31,8 @@ #include "noise.h" Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, real_t p_blend_skirt) const { + ERR_FAIL_COND_V(p_width <= 0 || p_height <= 0, Ref<Image>()); + int skirt_width = p_width * p_blend_skirt; int skirt_height = p_height * p_blend_skirt; int src_width = p_width + skirt_width; @@ -55,6 +57,8 @@ uint8_t Noise::_alpha_blend<uint8_t>(uint8_t p_bg, uint8_t p_fg, int p_alpha) co } Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space) const { + ERR_FAIL_COND_V(p_width <= 0 || p_height <= 0, Ref<Image>()); + Vector<uint8_t> data; data.resize(p_width * p_height); diff --git a/modules/openxr/extensions/openxr_vulkan_extension.h b/modules/openxr/extensions/openxr_vulkan_extension.h index cf55ae264f..1e34fe1f80 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.h +++ b/modules/openxr/extensions/openxr_vulkan_extension.h @@ -78,11 +78,11 @@ private: bool check_graphics_api_support(XrVersion p_desired_version); - VkInstance vulkan_instance; - VkPhysicalDevice vulkan_physical_device; - VkDevice vulkan_device; - uint32_t vulkan_queue_family_index; - uint32_t vulkan_queue_index; + VkInstance vulkan_instance = nullptr; + VkPhysicalDevice vulkan_physical_device = nullptr; + VkDevice vulkan_device = nullptr; + uint32_t vulkan_queue_family_index = 0; + uint32_t vulkan_queue_index = 0; XrResult xrGetVulkanGraphicsRequirements2KHR(XrInstance p_instance, XrSystemId p_system_id, XrGraphicsRequirementsVulkanKHR *p_graphics_requirements); XrResult xrCreateVulkanInstanceKHR(XrInstance p_instance, const XrVulkanInstanceCreateInfoKHR *p_create_info, VkInstance *r_vulkan_instance, VkResult *r_vulkan_result); diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index 57475944c0..702f6b9b1d 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -104,9 +104,9 @@ private: // state XrInstance instance = XR_NULL_HANDLE; - XrSystemId system_id; + XrSystemId system_id = 0; String system_name; - uint32_t vendor_id; + uint32_t vendor_id = 0; XrSystemTrackingProperties tracking_properties; XrSession session = XR_NULL_HANDLE; XrSessionState session_state = XR_SESSION_STATE_UNKNOWN; diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 62f11df4b7..ba249aff7a 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -878,8 +878,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_ struct MSContext { msdfgen::Point2 position; - msdfgen::Shape *shape; - msdfgen::Contour *contour; + msdfgen::Shape *shape = nullptr; + msdfgen::Contour *contour = nullptr; }; class DistancePixelConversion { diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index d84e9e581a..8ae56aa64d 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -322,8 +322,8 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ struct MSContext { msdfgen::Point2 position; - msdfgen::Shape *shape; - msdfgen::Contour *contour; + msdfgen::Shape *shape = nullptr; + msdfgen::Contour *contour = nullptr; }; class DistancePixelConversion { diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 3f5140cc8c..77e370849f 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -669,13 +669,13 @@ void VideoStreamTheora::_bind_methods() { //////////// -RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); if (f.is_null()) { if (r_error) { *r_error = ERR_CANT_OPEN; } - return RES(); + return Ref<Resource>(); } VideoStreamTheora *stream = memnew(VideoStreamTheora); diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index 6fa7313fad..8940ed6aff 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -99,7 +99,7 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { Ref<ImageTexture> texture; - AudioMixCallback mix_callback; + AudioMixCallback mix_callback = nullptr; void *mix_udata = nullptr; bool paused = false; @@ -186,7 +186,7 @@ public: class ResourceFormatLoaderTheora : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 06fa90eb29..3e6680d8d8 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -2611,11 +2611,11 @@ void VisualScriptEditor::_button_resource_previewed(const String &p_path, const void VisualScriptEditor::apply_code() { } -RES VisualScriptEditor::get_edited_resource() const { +Ref<Resource> VisualScriptEditor::get_edited_resource() const { return script; } -void VisualScriptEditor::set_edited_resource(const RES &p_res) { +void VisualScriptEditor::set_edited_resource(const Ref<Resource> &p_res) { ERR_FAIL_COND(script.is_valid()); ERR_FAIL_COND(p_res.is_null()); script = p_res; @@ -4795,7 +4795,7 @@ VisualScriptEditor::~VisualScriptEditor() { memdelete(variable_editor); } -static ScriptEditorBase *create_editor(const RES &p_resource) { +static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) { if (Object::cast_to<VisualScript>(*p_resource)) { return memnew(VisualScriptEditor); } @@ -4839,7 +4839,7 @@ Ref<VisualScriptNode> VisualScriptCustomNodes::create_node_custom(const String & } VisualScriptCustomNodes *VisualScriptCustomNodes::singleton = nullptr; -Map<String, REF> VisualScriptCustomNodes::custom_nodes; +Map<String, Ref<RefCounted>> VisualScriptCustomNodes::custom_nodes; VisualScriptCustomNodes::VisualScriptCustomNodes() { singleton = this; diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index fcfd44cecd..e63539ac5b 100644 --- a/modules/visual_script/editor/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -303,8 +303,8 @@ public: virtual void set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) override; virtual void apply_code() override; - virtual RES get_edited_resource() const override; - virtual void set_edited_resource(const RES &p_res) override; + virtual Ref<Resource> get_edited_resource() const override; + virtual void set_edited_resource(const Ref<Resource> &p_res) override; virtual void enable_editor() override; virtual Vector<String> get_functions() override; virtual void reload_text() override; @@ -359,7 +359,7 @@ protected: static void _bind_methods(); static VisualScriptCustomNodes *singleton; - static Map<String, REF> custom_nodes; + static Map<String, Ref<RefCounted>> custom_nodes; static Ref<VisualScriptNode> create_node_custom(const String &p_name); public: diff --git a/modules/visual_script/editor/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h index 1b32ee2967..90a6265ab7 100644 --- a/modules/visual_script/editor/visual_script_property_selector.h +++ b/modules/visual_script/editor/visual_script_property_selector.h @@ -173,8 +173,8 @@ class VisualScriptPropertySelector::SearchRunner : public RefCounted { Control *ui_service = nullptr; Tree *results_tree = nullptr; String term; - int search_flags; - int scope_flags; + int search_flags = 0; + int scope_flags = 0; Ref<Texture2D> empty_icon; Color disabled_color; diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 7e2df23618..44e792869d 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -989,7 +989,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in } if (p_inputs[0]->is_ref_counted()) { - REF r = *p_inputs[0]; + Ref<RefCounted> r = *p_inputs[0]; if (!r.is_valid()) { return; } @@ -1180,8 +1180,8 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in class VisualScriptNodeInstanceBuiltinFunc : public VisualScriptNodeInstance { public: - VisualScriptBuiltinFunc *node; - VisualScriptInstance *instance; + VisualScriptBuiltinFunc *node = nullptr; + VisualScriptInstance *instance = nullptr; VisualScriptBuiltinFunc::BuiltinFunc func; diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index bd36a9ceec..e0f6436094 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -1299,8 +1299,8 @@ bool VisualScriptExpression::_compile_expression() { class VisualScriptNodeInstanceExpression : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; - VisualScriptExpression *expression; + VisualScriptInstance *instance = nullptr; + VisualScriptExpression *expression = nullptr; //virtual int get_working_memory_size() const override { return 0; } //execute by parsing the tree directly diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index 7946d96b29..0e63753720 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -119,9 +119,9 @@ void VisualScriptReturn::_bind_methods() { class VisualScriptNodeInstanceReturn : public VisualScriptNodeInstance { public: - VisualScriptReturn *node; - VisualScriptInstance *instance; - bool with_value; + VisualScriptReturn *node = nullptr; + VisualScriptInstance *instance = nullptr; + bool with_value = false; virtual int get_working_memory_size() const override { return 1; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -213,8 +213,8 @@ void VisualScriptCondition::_bind_methods() { class VisualScriptNodeInstanceCondition : public VisualScriptNodeInstance { public: - VisualScriptCondition *node; - VisualScriptInstance *instance; + VisualScriptCondition *node = nullptr; + VisualScriptInstance *instance = nullptr; //virtual int get_working_memory_size() const override { return 1; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -293,8 +293,8 @@ void VisualScriptWhile::_bind_methods() { class VisualScriptNodeInstanceWhile : public VisualScriptNodeInstance { public: - VisualScriptWhile *node; - VisualScriptInstance *instance; + VisualScriptWhile *node = nullptr; + VisualScriptInstance *instance = nullptr; //virtual int get_working_memory_size() const override { return 1; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -376,8 +376,8 @@ void VisualScriptIterator::_bind_methods() { class VisualScriptNodeInstanceIterator : public VisualScriptNodeInstance { public: - VisualScriptIterator *node; - VisualScriptInstance *instance; + VisualScriptIterator *node = nullptr; + VisualScriptInstance *instance = nullptr; virtual int get_working_memory_size() const override { return 2; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -508,9 +508,9 @@ void VisualScriptSequence::_bind_methods() { class VisualScriptNodeInstanceSequence : public VisualScriptNodeInstance { public: - VisualScriptSequence *node; - VisualScriptInstance *instance; - int steps; + VisualScriptSequence *node = nullptr; + VisualScriptInstance *instance = nullptr; + int steps = 0; virtual int get_working_memory_size() const override { return 1; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -596,8 +596,8 @@ String VisualScriptSwitch::get_text() const { class VisualScriptNodeInstanceSwitch : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; - int case_count; + VisualScriptInstance *instance = nullptr; + int case_count = 0; //virtual int get_working_memory_size() const override { return 0; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -774,7 +774,7 @@ VisualScriptTypeCast::TypeGuess VisualScriptTypeCast::guess_output_type(TypeGues class VisualScriptNodeInstanceTypeCast : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; StringName base_type; String script; diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 5cc9236a9a..483fc8b6c3 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -720,15 +720,15 @@ class VisualScriptNodeInstanceFunctionCall : public VisualScriptNodeInstance { public: VisualScriptFunctionCall::CallMode call_mode; NodePath node_path; - int input_args; - bool validate; - int returns; + int input_args = 0; + bool validate = false; + int returns = 0; VisualScriptFunctionCall::RPCCallMode rpc_mode; StringName function; StringName singleton; - VisualScriptFunctionCall *node; - VisualScriptInstance *instance; + VisualScriptFunctionCall *node = nullptr; + VisualScriptInstance *instance = nullptr; //virtual int get_working_memory_size() const override { return 0; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -1462,11 +1462,11 @@ public: NodePath node_path; StringName property; - VisualScriptPropertySet *node; - VisualScriptInstance *instance; + VisualScriptPropertySet *node = nullptr; + VisualScriptInstance *instance = nullptr; VisualScriptPropertySet::AssignOp assign_op; StringName index; - bool needs_get; + bool needs_get = false; //virtual int get_working_memory_size() const override { return 0; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -2152,8 +2152,8 @@ public: StringName property; StringName index; - VisualScriptPropertyGet *node; - VisualScriptInstance *instance; + VisualScriptPropertyGet *node = nullptr; + VisualScriptInstance *instance = nullptr; virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { switch (call_mode) { @@ -2362,9 +2362,9 @@ void VisualScriptEmitSignal::_bind_methods() { class VisualScriptNodeInstanceEmitSignal : public VisualScriptNodeInstance { public: - VisualScriptEmitSignal *node; - VisualScriptInstance *instance; - int argcount; + VisualScriptEmitSignal *node = nullptr; + VisualScriptInstance *instance = nullptr; + int argcount = 0; StringName name; //virtual int get_working_memory_size() const override { return 0; } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 6e10b72013..dbbe74f3d5 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -271,8 +271,8 @@ Multiplayer::RPCMode VisualScriptFunction::get_rpc_mode() const { class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance { public: - VisualScriptFunction *node; - VisualScriptInstance *instance; + VisualScriptFunction *node = nullptr; + VisualScriptInstance *instance = nullptr; //virtual int get_working_memory_size() const override { return 0; } @@ -1097,7 +1097,7 @@ void VisualScriptOperator::_bind_methods() { class VisualScriptNodeInstanceOperator : public VisualScriptNodeInstance { public: - bool unary; + bool unary = false; Variant::Operator op; //virtual int get_working_memory_size() const override { return 0; } @@ -1328,8 +1328,8 @@ void VisualScriptVariableGet::_bind_methods() { class VisualScriptNodeInstanceVariableGet : public VisualScriptNodeInstance { public: - VisualScriptVariableGet *node; - VisualScriptInstance *instance; + VisualScriptVariableGet *node = nullptr; + VisualScriptInstance *instance = nullptr; StringName variable; virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { @@ -1438,8 +1438,8 @@ void VisualScriptVariableSet::_bind_methods() { class VisualScriptNodeInstanceVariableSet : public VisualScriptNodeInstance { public: - VisualScriptVariableSet *node; - VisualScriptInstance *instance; + VisualScriptVariableSet *node = nullptr; + VisualScriptInstance *instance = nullptr; StringName variable; //virtual int get_working_memory_size() const override { return 0; } @@ -1851,8 +1851,7 @@ int VisualScriptGlobalConstant::get_global_constant() { class VisualScriptNodeInstanceGlobalConstant : public VisualScriptNodeInstance { public: - int index; - //virtual int get_working_memory_size() const override { return 0; } + int index = 0; virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { *p_outputs[0] = CoreConstants::get_global_constant_value(index); @@ -1963,9 +1962,8 @@ StringName VisualScriptClassConstant::get_base_type() { class VisualScriptNodeInstanceClassConstant : public VisualScriptNodeInstance { public: - int value; - bool valid; - //virtual int get_working_memory_size() const override { return 0; } + int value = 0; + bool valid = false; virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { if (!valid) { @@ -2098,8 +2096,7 @@ Variant::Type VisualScriptBasicTypeConstant::get_basic_type() const { class VisualScriptNodeInstanceBasicTypeConstant : public VisualScriptNodeInstance { public: Variant value; - bool valid; - //virtual int get_working_memory_size() const override { return 0; } + bool valid = false; virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { if (!valid) { @@ -2227,8 +2224,7 @@ VisualScriptMathConstant::MathConstant VisualScriptMathConstant::get_math_consta class VisualScriptNodeInstanceMathConstant : public VisualScriptNodeInstance { public: - float value; - //virtual int get_working_memory_size() const override { return 0; } + float value = 0.0f; virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { *p_outputs[0] = value; @@ -2320,7 +2316,7 @@ String VisualScriptEngineSingleton::get_singleton() { class VisualScriptNodeInstanceEngineSingleton : public VisualScriptNodeInstance { public: - Object *singleton; + Object *singleton = nullptr; //virtual int get_working_memory_size() const override { return 0; } @@ -2429,8 +2425,8 @@ NodePath VisualScriptSceneNode::get_node_path() { class VisualScriptNodeInstanceSceneNode : public VisualScriptNodeInstance { public: - VisualScriptSceneNode *node; - VisualScriptInstance *instance; + VisualScriptSceneNode *node = nullptr; + VisualScriptInstance *instance = nullptr; NodePath path; //virtual int get_working_memory_size() const override { return 0; } @@ -2610,8 +2606,8 @@ String VisualScriptSceneTree::get_caption() const { class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance { public: - VisualScriptSceneTree *node; - VisualScriptInstance *instance; + VisualScriptSceneTree *node = nullptr; + VisualScriptInstance *instance = nullptr; //virtual int get_working_memory_size() const override { return 0; } @@ -2779,7 +2775,7 @@ String VisualScriptSelf::get_caption() const { class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; //virtual int get_working_memory_size() const override { return 0; } @@ -2965,11 +2961,11 @@ String VisualScriptCustomNode::get_category() const { class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; - VisualScriptCustomNode *node; - int in_count; - int out_count; - int work_mem_size; + VisualScriptInstance *instance = nullptr; + VisualScriptCustomNode *node = nullptr; + int in_count = 0; + int out_count = 0; + int work_mem_size = 0; virtual int get_working_memory_size() const override { return work_mem_size; } virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { @@ -3161,10 +3157,10 @@ String VisualScriptSubCall::get_category() const { class VisualScriptNodeInstanceSubCall : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; - VisualScriptSubCall *subcall; - int input_args; - bool valid; + VisualScriptInstance *instance = nullptr; + VisualScriptSubCall *subcall = nullptr; + int input_args = 0; + bool valid = false; //virtual int get_working_memory_size() const override { return 0; } @@ -3281,7 +3277,7 @@ String VisualScriptComment::get_category() const { class VisualScriptNodeInstanceComment : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; //virtual int get_working_memory_size() const override { return 0; } @@ -3380,9 +3376,9 @@ Dictionary VisualScriptConstructor::get_constructor() const { class VisualScriptNodeInstanceConstructor : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; Variant::Type type; - int argcount; + int argcount = 0; //virtual int get_working_memory_size() const override { return 0; } @@ -3497,7 +3493,7 @@ Variant::Type VisualScriptLocalVar::get_var_type() const { class VisualScriptNodeInstanceLocalVar : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; StringName name; virtual int get_working_memory_size() const override { return 1; } @@ -3604,7 +3600,7 @@ Variant::Type VisualScriptLocalVarSet::get_var_type() const { class VisualScriptNodeInstanceLocalVarSet : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; StringName name; virtual int get_working_memory_size() const override { return 1; } @@ -3728,7 +3724,7 @@ VisualScriptInputAction::Mode VisualScriptInputAction::get_action_mode() const { class VisualScriptNodeInstanceInputAction : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; StringName action; VisualScriptInputAction::Mode mode; @@ -3906,7 +3902,7 @@ Array VisualScriptDeconstruct::_get_elem_cache() const { class VisualScriptNodeInstanceDeconstruct : public VisualScriptNodeInstance { public: - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; Vector<StringName> outputs; //virtual int get_working_memory_size() const override { return 0; } diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index e6e7f79d1f..96e91a0baf 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -93,7 +93,7 @@ String VisualScriptYield::get_text() const { class VisualScriptNodeInstanceYield : public VisualScriptNodeInstance { public: VisualScriptYield::YieldMode mode; - double wait_time; + double wait_time = 0.0; virtual int get_working_memory_size() const override { return 1; } //yield needs at least 1 //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } @@ -500,11 +500,11 @@ class VisualScriptNodeInstanceYieldSignal : public VisualScriptNodeInstance { public: VisualScriptYieldSignal::CallMode call_mode; NodePath node_path; - int output_args; + int output_args = 0; StringName signal; - VisualScriptYieldSignal *node; - VisualScriptInstance *instance; + VisualScriptYieldSignal *node = nullptr; + VisualScriptInstance *instance = nullptr; virtual int get_working_memory_size() const override { return 1; } //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 58c329f043..6f0b726f5c 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -103,13 +103,14 @@ bool WSLClient::_verify_headers(String &r_protocol) { String s = (char *)_resp_buf; Vector<String> psa = s.split("\r\n"); int len = psa.size(); - ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4."); + ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers. Got: " + itos(len) + ", expected >= 4."); Vector<String> req = psa[0].split(" ", false); - ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code."); + ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code. Got '" + psa[0] + "', expected 'HTTP/1.1 101'."); // Wrong protocol - ERR_FAIL_COND_V_MSG(req[0] != "HTTP/1.1" || req[1] != "101", false, "Invalid protocol or status code."); + ERR_FAIL_COND_V_MSG(req[0] != "HTTP/1.1", false, "Invalid protocol. Got: '" + req[0] + "', expected 'HTTP/1.1'."); + ERR_FAIL_COND_V_MSG(req[1] != "101", false, "Invalid status code. Got: '" + req[1] + "', expected '101'."); Map<String, String> headers; for (int i = 1; i < len; i++) { @@ -137,9 +138,11 @@ bool WSLClient::_verify_headers(String &r_protocol) { #undef WSL_CHECK if (_protocols.size() == 0) { // We didn't request a custom protocol - ERR_FAIL_COND_V(headers.has("sec-websocket-protocol"), false); + ERR_FAIL_COND_V_MSG(headers.has("sec-websocket-protocol"), false, "Received unrequested sub-protocol -> " + headers["sec-websocket-protocol"]); } else { - ERR_FAIL_COND_V(!headers.has("sec-websocket-protocol"), false); + // We requested at least one custom protocol but didn't receive one + ERR_FAIL_COND_V_MSG(!headers.has("sec-websocket-protocol"), false, "Requested sub-protocol(s) but received none."); + // Check received sub-protocol was one of those requested. r_protocol = headers["sec-websocket-protocol"]; bool valid = false; for (int i = 0; i < _protocols.size(); i++) { @@ -150,6 +153,7 @@ bool WSLClient::_verify_headers(String &r_protocol) { break; } if (!valid) { + ERR_FAIL_V_MSG(false, "Received unrequested sub-protocol -> " + r_protocol); return false; } } diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 22b3a4f373..04af83f28c 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -63,7 +63,7 @@ private: String _key; String _host; - uint16_t _port; + uint16_t _port = 0; Array _ip_candidates; Vector<String> _protocols; bool _use_ssl = false; diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 2eb7056a36..d414ea5824 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -136,6 +136,18 @@ bool DisplayServerAndroid::clipboard_has() const { } } +Array DisplayServerAndroid::get_display_cutouts() const { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_NULL_V(godot_io_java, Array()); + return godot_io_java->get_display_cutouts(); +} + +Rect2i DisplayServerAndroid::get_display_safe_area() const { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_NULL_V(godot_io_java, Rect2i()); + return godot_io_java->get_display_safe_area(); +} + void DisplayServerAndroid::screen_set_keep_on(bool p_enable) { GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); ERR_FAIL_COND(!godot_java); @@ -177,11 +189,8 @@ Size2i DisplayServerAndroid::screen_get_size(int p_screen) const { } Rect2i DisplayServerAndroid::screen_get_usable_rect(int p_screen) const { - GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); - ERR_FAIL_COND_V(!godot_io_java, Rect2i()); - int xywh[4]; - godot_io_java->screen_get_usable_rect(xywh); - return Rect2i(xywh[0], xywh[1], xywh[2], xywh[3]); + Size2i display_size = OS_Android::get_singleton()->get_display_size(); + return Rect2i(0, 0, display_size.width, display_size.height); } int DisplayServerAndroid::screen_get_dpi(int p_screen) const { diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 2604214ac0..65bf2ec1a8 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -104,6 +104,9 @@ public: virtual String clipboard_get() const override; virtual bool clipboard_has() const override; + virtual Array get_display_cutouts() const override; + virtual Rect2i get_display_safe_area() const override; + virtual void screen_set_keep_on(bool p_enable) override; virtual bool screen_is_kept_on() const override; diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 8cfa3a67b9..d357cd586e 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1000,16 +1000,23 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p } } - if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") { - if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) { + // Hand tracking related configurations + if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) { + if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") { string_table.write[attr_value] = "com.oculus.handtracking.frequency"; } - } - if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_metadata_value") { - if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) { + if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_metadata_value") { string_table.write[attr_value] = (hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH"); } + + if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_version_name") { + string_table.write[attr_value] = "com.oculus.handtracking.version"; + } + + if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_version_value") { + string_table.write[attr_value] = "V2.0"; + } } iofs += 20; diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp index 173bb8bcb7..d9574a1a52 100644 --- a/platform/android/export/gradle_export_util.cpp +++ b/platform/android/export/gradle_export_util.cpp @@ -279,6 +279,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ " android:requestLegacyExternalStorage=\"%s\"\n" " tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n" " tools:ignore=\"GoogleAppIndexingWarning\">\n\n" + " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_version_name\" />\n" " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_metadata_name\" />\n", bool_to_string(p_preset->get("user_data_backup/allow")), bool_to_string(p_preset->get("package/classify_as_game")), @@ -293,6 +294,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ manifest_application_text += vformat( " <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.frequency\" android:value=\"%s\" />\n", hand_tracking_frequency); + manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.version\" android:value=\"V2.0\" />\n"; } } else { manifest_application_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.supportedDevices\" />\n"; diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 4c4501729d..c98e8f1d55 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -40,6 +40,13 @@ android:name="xr_hand_tracking_metadata_name" android:value="xr_hand_tracking_metadata_value"/> + <!-- XR hand tracking version --> + <!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> + <!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. --> + <meta-data + android:name="xr_hand_tracking_version_name" + android:value="xr_hand_tracking_version_value"/> + <!-- Supported Meta devices --> <!-- This is removed by the exporter if the xr mode is not VR. --> <meta-data diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index e8e292df5d..b69d25dd8b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -38,6 +38,7 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.AssetManager; import android.graphics.Point; +import android.graphics.Rect; import android.net.Uri; import android.os.Build; import android.os.Environment; @@ -51,6 +52,7 @@ import android.view.DisplayCutout; import android.view.WindowInsets; import java.io.IOException; +import java.util.List; import java.util.Locale; // Wrapper for native library @@ -238,7 +240,7 @@ public class GodotIO { return fallback; } - public int[] screenGetUsableRect() { + public int[] getDisplaySafeArea() { DisplayMetrics metrics = activity.getResources().getDisplayMetrics(); Display display = activity.getWindowManager().getDefaultDisplay(); Point size = new Point(); @@ -260,6 +262,25 @@ public class GodotIO { return result; } + public int[] getDisplayCutouts() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) + return new int[0]; + DisplayCutout cutout = activity.getWindow().getDecorView().getRootWindowInsets().getDisplayCutout(); + if (cutout == null) + return new int[0]; + List<Rect> rects = cutout.getBoundingRects(); + int cutouts = rects.size(); + int[] result = new int[cutouts * 4]; + int index = 0; + for (Rect rect : rects) { + result[index++] = rect.left; + result[index++] = rect.top; + result[index++] = rect.width(); + result[index++] = rect.height(); + } + return result; + } + public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { if (edit != null) edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end); diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index 5b21e696c3..7ae3a65105 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -31,6 +31,8 @@ #include "java_godot_io_wrapper.h" #include "core/error/error_list.h" +#include "core/math/rect2.h" +#include "core/variant/variant.h" // JNIEnv is only valid within the thread it belongs to, in a multi threading environment // we can't cache it. @@ -51,12 +53,13 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc _open_URI = p_env->GetMethodID(cls, "openURI", "(Ljava/lang/String;)I"); _get_cache_dir = p_env->GetMethodID(cls, "getCacheDir", "()Ljava/lang/String;"); _get_data_dir = p_env->GetMethodID(cls, "getDataDir", "()Ljava/lang/String;"); + _get_display_cutouts = p_env->GetMethodID(cls, "getDisplayCutouts", "()[I"), + _get_display_safe_area = p_env->GetMethodID(cls, "getDisplaySafeArea", "()[I"), _get_locale = p_env->GetMethodID(cls, "getLocale", "()Ljava/lang/String;"); _get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;"); _get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I"); _get_scaled_density = p_env->GetMethodID(cls, "getScaledDensity", "()F"); _get_screen_refresh_rate = p_env->GetMethodID(cls, "getScreenRefreshRate", "(D)D"); - _screen_get_usable_rect = p_env->GetMethodID(cls, "screenGetUsableRect", "()[I"), _get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;"); _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;ZIII)V"); _hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V"); @@ -162,18 +165,38 @@ float GodotIOJavaWrapper::get_screen_refresh_rate(float fallback) { return fallback; } -void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) { - if (_screen_get_usable_rect) { - JNIEnv *env = get_jni_env(); - ERR_FAIL_COND(env == nullptr); - jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _screen_get_usable_rect); - ERR_FAIL_COND(env->GetArrayLength(returnArray) != 4); - jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE); - for (int i = 0; i < 4; i++) { - p_rect_xywh[i] = arrayBody[i]; - } - env->ReleaseIntArrayElements(returnArray, arrayBody, 0); +Array GodotIOJavaWrapper::get_display_cutouts() { + Array result; + ERR_FAIL_NULL_V(_get_display_cutouts, result); + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL_V(env, result); + jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _get_display_cutouts); + jint arrayLength = env->GetArrayLength(returnArray); + jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE); + int cutouts = arrayLength / 4; + for (int i = 0; i < cutouts; i++) { + int x = arrayBody[i * 4]; + int y = arrayBody[i * 4 + 1]; + int width = arrayBody[i * 4 + 2]; + int height = arrayBody[i * 4 + 3]; + Rect2 cutout(x, y, width, height); + result.append(cutout); } + env->ReleaseIntArrayElements(returnArray, arrayBody, 0); + return result; +} + +Rect2i GodotIOJavaWrapper::get_display_safe_area() { + Rect2i result; + ERR_FAIL_NULL_V(_get_display_safe_area, result); + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL_V(env, result); + jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _get_display_safe_area); + ERR_FAIL_COND_V(env->GetArrayLength(returnArray) != 4, result); + jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE); + result = Rect2i(arrayBody[0], arrayBody[1], arrayBody[2], arrayBody[3]); + env->ReleaseIntArrayElements(returnArray, arrayBody, 0); + return result; } String GodotIOJavaWrapper::get_unique_id() { diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index 08e3092afd..02c57130ab 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -37,6 +37,8 @@ #include <android/log.h> #include <jni.h> +#include "core/math/rect2i.h" +#include "core/variant/array.h" #include "string_android.h" // Class that makes functions in java/src/org/godotengine/godot/GodotIO.java callable from C++ @@ -48,12 +50,13 @@ private: jmethodID _open_URI = 0; jmethodID _get_cache_dir = 0; jmethodID _get_data_dir = 0; + jmethodID _get_display_cutouts = 0; + jmethodID _get_display_safe_area = 0; jmethodID _get_locale = 0; jmethodID _get_model = 0; jmethodID _get_screen_DPI = 0; jmethodID _get_scaled_density = 0; jmethodID _get_screen_refresh_rate = 0; - jmethodID _screen_get_usable_rect = 0; jmethodID _get_unique_id = 0; jmethodID _show_keyboard = 0; jmethodID _hide_keyboard = 0; @@ -75,7 +78,8 @@ public: int get_screen_dpi(); float get_scaled_density(); float get_screen_refresh_rate(float fallback); - void screen_get_usable_rect(int (&p_rect_xywh)[4]); + Array get_display_cutouts(); + Rect2i get_display_safe_area(); String get_unique_id(); bool has_vk(); void show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index fc46005b41..25daf1ca90 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -162,9 +162,14 @@ Vector<String> OS_Android::get_granted_permissions() const { return godot_java->get_granted_permissions(); } -Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { +Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW); ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + "."); + + if (r_resolved_path != nullptr) { + *r_resolved_path = p_path; + } + return OK; } diff --git a/platform/android/os_android.h b/platform/android/os_android.h index a40e17dc2c..f86c5b5212 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -90,7 +90,7 @@ public: virtual void alert(const String &p_alert, const String &p_title) override; - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual String get_name() const override; virtual MainLoop *get_main_loop() const override; diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h index 6ae190b81a..7af222e3f8 100644 --- a/platform/iphone/display_server_iphone.h +++ b/platform/iphone/display_server_iphone.h @@ -134,6 +134,8 @@ public: virtual void tts_resume() override; virtual void tts_stop() override; + virtual Rect2i get_display_safe_area() const override; + virtual int get_screen_count() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm index ec58ab195a..573ee9b7a8 100644 --- a/platform/iphone/display_server_iphone.mm +++ b/platform/iphone/display_server_iphone.mm @@ -360,6 +360,22 @@ void DisplayServerIPhone::tts_stop() { [tts stopSpeaking]; } +Rect2i DisplayServerIPhone::get_display_safe_area() const { + if (@available(iOS 11, *)) { + UIEdgeInsets insets = UIEdgeInsetsZero; + UIView *view = AppDelegate.viewController.godotView; + if ([view respondsToSelector:@selector(safeAreaInsets)]) { + insets = [view safeAreaInsets]; + } + float scale = screen_get_scale(); + Size2i insets_position = Size2i(insets.left, insets.top) * scale; + Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale; + return Rect2i(screen_get_position() + insets_position, screen_get_size() - insets_size); + } else { + return Rect2i(screen_get_position(), screen_get_size()); + } +} + int DisplayServerIPhone::get_screen_count() const { return 1; } @@ -379,22 +395,7 @@ Size2i DisplayServerIPhone::screen_get_size(int p_screen) const { } Rect2i DisplayServerIPhone::screen_get_usable_rect(int p_screen) const { - if (@available(iOS 11, *)) { - UIEdgeInsets insets = UIEdgeInsetsZero; - UIView *view = AppDelegate.viewController.godotView; - - if ([view respondsToSelector:@selector(safeAreaInsets)]) { - insets = [view safeAreaInsets]; - } - - float scale = screen_get_scale(p_screen); - Size2i insets_position = Size2i(insets.left, insets.top) * scale; - Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale; - - return Rect2i(screen_get_position(p_screen) + insets_position, screen_get_size(p_screen) - insets_size); - } else { - return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen)); - } + return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen)); } int DisplayServerIPhone::screen_get_dpi(int p_screen) const { diff --git a/platform/iphone/export/export_plugin.h b/platform/iphone/export/export_plugin.h index 3831f3bff2..2c6faed691 100644 --- a/platform/iphone/export/export_plugin.h +++ b/platform/iphone/export/export_plugin.h @@ -53,8 +53,6 @@ class EditorExportPlatformIOS : public EditorExportPlatform { GDCLASS(EditorExportPlatformIOS, EditorExportPlatform); - int version_code; - Ref<ImageTexture> logo; // Plugins diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/iphone/godot_view_gesture_recognizer.mm index c8137f35ff..49a92add5e 100644 --- a/platform/iphone/godot_view_gesture_recognizer.mm +++ b/platform/iphone/godot_view_gesture_recognizer.mm @@ -70,6 +70,7 @@ const CGFloat kGLGestureMovementDistance = 0.5; self.cancelsTouchesInView = YES; self.delaysTouchesBegan = YES; self.delaysTouchesEnded = YES; + self.requiresExclusiveTouchType = NO; self.delayTimeInterval = GLOBAL_GET("input_devices/pointing/ios/touch_delay"); diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 6a61f3a910..d03403bbb4 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -92,7 +92,7 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index f7974c4b3d..95b06b728e 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -204,12 +204,17 @@ void OSIPhone::finalize() { // MARK: Dynamic Libraries -Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { +Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { if (p_path.length() == 0) { p_library_handle = RTLD_SELF; + + if (r_resolved_path != nullptr) { + *r_resolved_path = p_path; + } + return OK; } - return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path); + return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path, r_resolved_path); } Error OSIPhone::close_dynamic_library(void *p_library_handle) { diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index cc77c8fcd5..312707c3b5 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -371,7 +371,7 @@ DisplayServer::CursorShape DisplayServerJavaScript::cursor_get_shape() const { return cursor_shape; } -void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void DisplayServerJavaScript::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (p_cursor.is_valid()) { Ref<Texture2D> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index bbd0206087..623546bbd0 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -134,7 +134,7 @@ public: // cursor virtual void cursor_set_shape(CursorShape p_shape) override; virtual CursorShape cursor_get_shape() const override; - virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; + virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; // mouse virtual void mouse_set_mode(MouseMode p_mode) override; diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index c946302862..32bdfed4c7 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -76,7 +76,7 @@ void HTTPClientJavaScript::set_connection(const Ref<StreamPeer> &p_connection) { } Ref<StreamPeer> HTTPClientJavaScript::get_connection() const { - ERR_FAIL_V_MSG(REF(), "Accessing an HTTPClientJavaScript's StreamPeer is not supported for the HTML5 platform."); + ERR_FAIL_V_MSG(Ref<RefCounted>(), "Accessing an HTTPClientJavaScript's StreamPeer is not supported for the HTML5 platform."); } Error HTTPClientJavaScript::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len) { diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index da88ea18b0..79c2b2fefb 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -221,10 +221,15 @@ bool OS_JavaScript::is_userfs_persistent() const { return idb_available; } -Error OS_JavaScript::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { +Error OS_JavaScript::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { String path = p_path.get_file(); p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror()); + + if (r_resolved_path != nullptr) { + *r_resolved_path = path; + } + return OK; } diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 9e272f9aa1..09497ebc5d 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -99,7 +99,7 @@ public: void alert(const String &p_alert, const String &p_title = "ALERT!") override; - Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) override; + Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; void resume_audio(); diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp index 63531d33fa..42b7f68a5e 100644 --- a/platform/linuxbsd/detect_prime_x11.cpp +++ b/platform/linuxbsd/detect_prime_x11.cpp @@ -55,7 +55,7 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *); struct vendor { - const char *glxvendor; + const char *glxvendor = nullptr; int priority = 0; }; diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 027f8562eb..b35f0daec6 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2356,7 +2356,7 @@ DisplayServerX11::CursorShape DisplayServerX11::cursor_get_shape() const { return current_cursor; } -void DisplayServerX11::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { _THREAD_SAFE_METHOD_ if (p_cursor.is_valid()) { @@ -4531,24 +4531,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode r_error = OK; - current_cursor = CURSOR_ARROW; - mouse_mode = MOUSE_MODE_VISIBLE; - for (int i = 0; i < CURSOR_MAX; i++) { cursors[i] = None; img[i] = nullptr; } - xmbstring = nullptr; - - last_click_ms = 0; - last_click_button_index = MouseButton::NONE; - last_click_pos = Point2i(-100, -100); - - last_timestamp = 0; - last_mouse_pos_valid = false; - last_keyrelease_time = 0; - XInitThreads(); //always use threads /** XLIB INITIALIZATION **/ @@ -4583,8 +4570,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } const char *err; - xrr_get_monitors = nullptr; - xrr_free_monitors = nullptr; int xrandr_major = 0; int xrandr_minor = 0; int event_base, error_base; @@ -4660,11 +4645,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode XFree(imvalret); } - /* Atorm internment */ + /* Atom internment */ wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true); - //Set Xdnd (drag & drop) support + // Set Xdnd (drag & drop) support. xdnd_aware = XInternAtom(x11_display, "XdndAware", False); - xdnd_version = 5; xdnd_enter = XInternAtom(x11_display, "XdndEnter", False); xdnd_position = XInternAtom(x11_display, "XdndPosition", False); xdnd_status = XInternAtom(x11_display, "XdndStatus", False); @@ -4751,11 +4735,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } driver_found = true; - // gl_manager->set_use_vsync(current_videomode.use_vsync); - if (true) { - // if (RasterizerGLES3::is_viable() == OK) { - // RasterizerGLES3::register_config(); RasterizerGLES3::make_current(); } else { memdelete(gl_manager); @@ -4930,12 +4910,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } cursor_set_shape(CURSOR_BUSY); - requested = None; - - /*if (p_desired.layered) { - set_window_per_pixel_transparency_enabled(true); - }*/ - XEvent xevent; while (XPending(x11_display) > 0) { XNextEvent(x11_display, &xevent); diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 3d49886b94..ee47d1a12c 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -100,8 +100,8 @@ class DisplayServerX11 : public DisplayServer { Atom xdnd_finished; Atom xdnd_selection; Atom xdnd_aware; - Atom requested; - int xdnd_version; + Atom requested = None; + int xdnd_version = 5; #if defined(GLES3_ENABLED) GLManager_X11 *gl_manager = nullptr; @@ -174,21 +174,21 @@ class DisplayServerX11 : public DisplayServer { String internal_clipboard; String internal_clipboard_primary; - Window xdnd_source_window; + Window xdnd_source_window = 0; ::Display *x11_display; char *xmbstring = nullptr; - int xmblen; - unsigned long last_timestamp; - ::Time last_keyrelease_time; + int xmblen = 0; + unsigned long last_timestamp = 0; + ::Time last_keyrelease_time = 0; ::XIM xim; ::XIMStyle xim_style; static void _xim_destroy_callback(::XIM im, ::XPointer client_data, ::XPointer call_data); Point2i last_mouse_pos; - bool last_mouse_pos_valid; - Point2i last_click_pos; - uint64_t last_click_ms; + bool last_mouse_pos_valid = false; + Point2i last_click_pos = Point2i(-100, -100); + uint64_t last_click_ms = 0; MouseButton last_click_button_index = MouseButton::NONE; MouseButton last_button_state = MouseButton::NONE; bool app_focused = false; @@ -221,7 +221,7 @@ class DisplayServerX11 : public DisplayServer { void _get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state); void _flush_mouse_motion(); - MouseMode mouse_mode; + MouseMode mouse_mode = MOUSE_MODE_VISIBLE; Point2i center; void _handle_key_event(WindowID p_window, XKeyEvent *p_event, LocalVector<XEvent> &p_events, uint32_t &p_event_index, bool p_echo = false); @@ -233,30 +233,26 @@ class DisplayServerX11 : public DisplayServer { String _clipboard_get(Atom p_source, Window x11_window) const; void _clipboard_transfer_ownership(Atom p_source, Window x11_window) const; - //bool minimized; - //bool window_has_focus; - bool do_mouse_warp; + bool do_mouse_warp = false; - const char *cursor_theme; - int cursor_size; + const char *cursor_theme = nullptr; + int cursor_size = 0; XcursorImage *img[CURSOR_MAX]; Cursor cursors[CURSOR_MAX]; Cursor null_cursor; - CursorShape current_cursor; + CursorShape current_cursor = CURSOR_ARROW; Map<CursorShape, Vector<Variant>> cursors_cache; - bool layered_window; + bool layered_window = false; String rendering_driver; - //bool window_focused; - //void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); void set_wm_above(bool p_enabled); typedef xrr_monitor_info *(*xrr_get_monitors_t)(Display *dpy, Window window, Bool get_active, int *nmonitors); typedef void (*xrr_free_monitors_t)(xrr_monitor_info *monitors); - xrr_get_monitors_t xrr_get_monitors; - xrr_free_monitors_t xrr_free_monitors; + xrr_get_monitors_t xrr_get_monitors = nullptr; + xrr_free_monitors_t xrr_free_monitors = nullptr; void *xrandr_handle = nullptr; Bool xrandr_ext_ok; @@ -411,7 +407,7 @@ public: virtual void cursor_set_shape(CursorShape p_shape) override; virtual CursorShape cursor_get_shape() const override; - virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override; + virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override; virtual int keyboard_get_layout_count() const override; virtual int keyboard_get_current_layout() const override; diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index fcb3a62bec..e1e5aea715 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -372,7 +372,7 @@ public: void cursor_update_shape(); virtual void cursor_set_shape(CursorShape p_shape) override; virtual CursorShape cursor_get_shape() const override; - virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; + virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; virtual bool get_swap_cancel_ok() override; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 17a44a3fbd..548acba923 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -2674,7 +2674,7 @@ DisplayServerOSX::CursorShape DisplayServerOSX::cursor_get_shape() const { return cursor_shape; } -void DisplayServerOSX::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void DisplayServerOSX::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { _THREAD_SAFE_METHOD_ if (p_cursor.is_valid()) { diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 53c5c8bd90..e4ec411c96 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -80,7 +80,7 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual MainLoop *get_main_loop() const override; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 33fee01c08..a8fa56e34b 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -150,7 +150,7 @@ void OS_OSX::alert(const String &p_alert, const String &p_title) { } } -Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { +Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { String path = get_framework_executable(p_path); if (!FileAccess::exists(path)) { @@ -165,6 +165,11 @@ Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + "."); + + if (r_resolved_path != nullptr) { + *r_resolved_path = path; + } + return OK; } diff --git a/platform/uwp/export/app_packager.h b/platform/uwp/export/app_packager.h index a32b78bf04..ea42e9bdfe 100644 --- a/platform/uwp/export/app_packager.h +++ b/platform/uwp/export/app_packager.h @@ -93,8 +93,8 @@ class AppxPackager { Vector<FileMeta> file_metadata; - ZPOS64_T central_dir_offset; - ZPOS64_T end_of_central_dir_offset; + ZPOS64_T central_dir_offset = 0; + ZPOS64_T end_of_central_dir_offset = 0; Vector<uint8_t> central_dir_data; String hash_block(const uint8_t *p_block_data, size_t p_block_len); diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 22a54911f9..f002e47f2d 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -631,7 +631,7 @@ OS::CursorShape OS_UWP::get_cursor_shape() const { return cursor_shape; } -void OS_UWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void OS_UWP::set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { // TODO } @@ -733,10 +733,15 @@ static String format_error_message(DWORD id) { return msg; } -Error OS_UWP::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { +Error OS_UWP::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { String full_path = "game/" + p_path; p_library_handle = (void *)LoadPackagedLibrary((LPCWSTR)(full_path.utf16().get_data()), 0); ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + full_path + ", error: " + format_error_message(GetLastError()) + "."); + + if (r_resolved_path != nullptr) { + *r_resolved_path = full_path; + } + return OK; } diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index f955be1da9..bde65257be 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -208,7 +208,7 @@ public: void set_cursor_shape(CursorShape p_shape); CursorShape get_cursor_shape() const; - virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); + virtual void set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); void set_icon(const Ref<Image> &p_icon); virtual String get_executable_path() const; @@ -233,7 +233,7 @@ public: virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1); virtual void hide_virtual_keyboard(); - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr); virtual Error close_dynamic_library(void *p_library_handle); virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 0412eb2d9c..b548277f95 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1490,7 +1490,7 @@ void DisplayServerWindows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTra DeleteDC(hMainDC); } -void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void DisplayServerWindows::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { _THREAD_SAFE_METHOD_ if (p_cursor.is_valid()) { diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 80faf71bd4..c039b29c54 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -561,7 +561,7 @@ public: virtual void cursor_set_shape(CursorShape p_shape) override; virtual CursorShape cursor_get_shape() const override; - virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; + virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; virtual bool get_swap_cancel_ok() override; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 8755bc65dc..6b4e455197 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -202,7 +202,7 @@ Error OS_Windows::get_entropy(uint8_t *r_buffer, int p_bytes) { return OK; } -Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { +Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { String path = p_path.replace("/", "\\"); if (!FileAccess::exists(path)) { @@ -230,6 +230,10 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han remove_dll_directory(cookie); } + if (r_resolved_path != nullptr) { + *r_resolved_path = path; + } + return OK; } diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 370cb77fde..81cc7c3fc1 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -108,7 +108,7 @@ public: virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) override; - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 68047ccebf..a42e7722b0 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -49,7 +49,7 @@ public: private: SpaceOverride gravity_space_override = SPACE_OVERRIDE_DISABLED; Vector2 gravity_vec; - real_t gravity; + real_t gravity = 0.0; bool gravity_is_point = false; real_t gravity_distance_scale = 0.0; diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 7ae51e3966..51d58723b4 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -137,7 +137,7 @@ private: real_t randomness_ratio = 0.0; double lifetime_randomness = 0.0; double speed_scale = 1.0; - bool local_coords; + bool local_coords = false; int fixed_fps = 0; bool fractional_delta = true; diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 04518dff97..35f1ae5421 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -666,9 +666,6 @@ GPUParticles2D::GPUParticles2D() { set_speed_scale(1); set_fixed_fps(30); set_collision_base_size(collision_base_size); -#ifdef TOOLS_ENABLED - show_visibility_rect = false; -#endif } GPUParticles2D::~GPUParticles2D() { diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index 852270dd3c..3c7f4cd9b5 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -47,20 +47,20 @@ public: private: RID particles; - bool one_shot; - int amount; - double lifetime; - double pre_process_time; - real_t explosiveness_ratio; - real_t randomness_ratio; - double speed_scale; + bool one_shot = false; + int amount = 0; + double lifetime = 0.0; + double pre_process_time = 0.0; + real_t explosiveness_ratio = 0.0; + real_t randomness_ratio = 0.0; + double speed_scale = 0.0; Rect2 visibility_rect; - bool local_coords; - int fixed_fps; - bool fractional_delta; + bool local_coords = false; + int fixed_fps = 0; + bool fractional_delta = false; bool interpolate = true; #ifdef TOOLS_ENABLED - bool show_visibility_rect; + bool show_visibility_rect = false; #endif Ref<Material> process_material; diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index c4e57b375d..14188d7120 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -285,7 +285,6 @@ void LightOccluder2D::_bind_methods() { LightOccluder2D::LightOccluder2D() { occluder = RS::get_singleton()->canvas_light_occluder_create(); - mask = 1; set_notify_transform(true); set_as_sdf_collision(true); diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 4f8c6d20df..4acfeaf781 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -81,10 +81,9 @@ class LightOccluder2D : public Node2D { GDCLASS(LightOccluder2D, Node2D); RID occluder; - bool enabled; - int mask; + int mask = 1; Ref<OccluderPolygon2D> occluder_polygon; - bool sdf_collision; + bool sdf_collision = false; void _poly_changed(); protected: diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 2fb6fab91c..1447e25e8c 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -45,17 +45,17 @@ class NavigationAgent2D : public Node { uint32_t navigable_layers = 1; real_t target_desired_distance = 1.0; - real_t radius; - real_t neighbor_dist; - int max_neighbors; - real_t time_horizon; - real_t max_speed; + real_t radius = 0.0; + real_t neighbor_dist = 0.0; + int max_neighbors = 0; + real_t time_horizon = 0.0; + real_t max_speed = 0.0; real_t path_max_distance = 3.0; Vector2 target_location; Vector<Vector2> navigation_path; - int nav_path_index; + int nav_path_index = 0; bool velocity_submitted = false; Vector2 prev_safe_velocity; /// The submitted target velocity @@ -63,7 +63,7 @@ class NavigationAgent2D : public Node { bool target_reached = false; bool navigation_finished = true; // No initialized on purpose - uint32_t update_frame_id; + uint32_t update_frame_id = 0; protected: static void _bind_methods(); diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 261d371dc4..3cc9f3f2c4 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -387,6 +387,10 @@ uint32_t NavigationRegion2D::get_layers() const { return NavigationServer2D::get_singleton()->region_get_layers(region); } +RID NavigationRegion2D::get_region_rid() const { + return region; +} + ///////////////////////////// #ifdef TOOLS_ENABLED Rect2 NavigationRegion2D::_edit_get_rect() const { @@ -534,6 +538,8 @@ void NavigationRegion2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion2D::set_layers); ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion2D::get_layers); + ClassDB::bind_method(D_METHOD("get_region_rid"), &NavigationRegion2D::get_region_rid); + ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon"); diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 487a578401..3c4a4e81d9 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -117,6 +117,8 @@ public: void set_layers(uint32_t p_layers); uint32_t get_layers() const; + RID get_region_rid() const; + void set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly); Ref<NavigationPolygon> get_navigation_polygon() const; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 074924ef90..88f68e4142 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1257,7 +1257,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo set_global_transform(gt); } // Determines if you are on the ground. - _snap_on_floor(true, false); + _snap_on_floor(true, false, true); velocity = Vector2(); last_motion = Vector2(); motion = Vector2(); @@ -1396,8 +1396,8 @@ void CharacterBody2D::_move_and_slide_floating(double p_delta) { } } -void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up) { - if (on_floor || !was_on_floor || vel_dir_facing_up) { +void CharacterBody2D::_snap_on_floor(bool p_was_on_floor, bool p_vel_dir_facing_up, bool p_wall_as_floor) { + if (on_floor || !p_was_on_floor || p_vel_dir_facing_up) { return; } @@ -1409,7 +1409,8 @@ void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up) PhysicsServer2D::MotionResult result; if (move_and_collide(parameters, result, true, false)) { - if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { + if ((result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) || + (p_wall_as_floor && result.get_angle(-up_direction) > floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { on_floor = true; floor_normal = result.collision_normal; _set_platform_data(result); @@ -1430,8 +1431,8 @@ void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up) } } -bool CharacterBody2D::_on_floor_if_snapped(bool was_on_floor, bool vel_dir_facing_up) { - if (up_direction == Vector2() || on_floor || !was_on_floor || vel_dir_facing_up) { +bool CharacterBody2D::_on_floor_if_snapped(bool p_was_on_floor, bool p_vel_dir_facing_up) { + if (up_direction == Vector2() || on_floor || !p_was_on_floor || p_vel_dir_facing_up) { return false; } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 8d9e31d4dd..1e4483b4d0 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -441,11 +441,11 @@ private: Ref<KinematicCollision2D> _get_slide_collision(int p_bounce); Ref<KinematicCollision2D> _get_last_slide_collision(); const Vector2 &get_up_direction() const; - bool _on_floor_if_snapped(bool was_on_floor, bool vel_dir_facing_up); + bool _on_floor_if_snapped(bool p_was_on_floor, bool p_vel_dir_facing_up); void set_up_direction(const Vector2 &p_up_direction); void _set_collision_direction(const PhysicsServer2D::MotionResult &p_result); void _set_platform_data(const PhysicsServer2D::MotionResult &p_result); - void _snap_on_floor(bool was_on_floor, bool vel_dir_facing_up); + void _snap_on_floor(bool p_was_on_floor, bool p_vel_dir_facing_up, bool p_wall_as_floor = false); protected: void _notification(int p_what); diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index c2399985ff..31ded00fb7 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -49,7 +49,7 @@ public: private: SpaceOverride gravity_space_override = SPACE_OVERRIDE_DISABLED; Vector3 gravity_vec; - real_t gravity; + real_t gravity = 0.0; bool gravity_is_point = false; real_t gravity_distance_scale = 0.0; @@ -228,4 +228,4 @@ public: VARIANT_ENUM_CAST(Area3D::SpaceOverride); -#endif // AREA__H +#endif // AREA_3D_H diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index d28e11a2e9..759997de7b 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -110,7 +110,7 @@ void CollisionShape3D::_notification(int p_what) { } } -void CollisionShape3D::resource_changed(RES res) { +void CollisionShape3D::resource_changed(Ref<Resource> res) { update_gizmos(); } diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index fbcabf6529..5c32230942 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -43,7 +43,7 @@ class CollisionShape3D : public Node3D { uint32_t owner_id = 0; CollisionObject3D *parent = nullptr; - void resource_changed(RES res); + void resource_changed(Ref<Resource> res); bool disabled = false; protected: diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 521b6c615e..7f225ee98d 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -174,9 +174,9 @@ private: Vector<Color> emission_colors; int emission_point_count = 0; Vector3 emission_ring_axis; - real_t emission_ring_height; - real_t emission_ring_radius; - real_t emission_ring_inner_radius; + real_t emission_ring_height = 0.0; + real_t emission_ring_radius = 0.0; + real_t emission_ring_inner_radius = 0.0; Ref<Curve> scale_curve_x; Ref<Curve> scale_curve_y; diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index f3eb52d124..adce45a0a9 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -61,16 +61,16 @@ private: RID particles; bool one_shot; - int amount; - double lifetime; - double pre_process_time; - real_t explosiveness_ratio; - real_t randomness_ratio; - double speed_scale; + int amount = 0; + double lifetime = 0.0; + double pre_process_time = 0.0; + real_t explosiveness_ratio = 0.0; + real_t randomness_ratio = 0.0; + double speed_scale = 0.0; AABB visibility_aabb; - bool local_coords; - int fixed_fps; - bool fractional_delta; + bool local_coords = false; + int fixed_fps = 0; + bool fractional_delta = false; bool interpolate = true; NodePath sub_emitter; real_t collision_base_size = 0.01; diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index 3750249d59..9375190151 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -69,6 +69,12 @@ void Label3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_uppercase", "enable"), &Label3D::set_uppercase); ClassDB::bind_method(D_METHOD("is_uppercase"), &Label3D::is_uppercase); + ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Label3D::set_render_priority); + ClassDB::bind_method(D_METHOD("get_render_priority"), &Label3D::get_render_priority); + + ClassDB::bind_method(D_METHOD("set_outline_render_priority", "priority"), &Label3D::set_outline_render_priority); + ClassDB::bind_method(D_METHOD("get_outline_render_priority"), &Label3D::get_outline_render_priority); + ClassDB::bind_method(D_METHOD("set_font", "font"), &Label3D::set_font); ClassDB::bind_method(D_METHOD("get_font"), &Label3D::get_font); @@ -126,6 +132,8 @@ void Label3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_outline_render_priority", "get_outline_render_priority"); ADD_GROUP("Text", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); @@ -580,13 +588,13 @@ void Label3D::_shape() { // Outline surfaces. Vector2 ol_offset = offset; for (int j = 0; j < gl_size; j++) { - _generate_glyph_surfaces(glyphs[j], ol_offset, outline_modulate, -1, outline_size); + _generate_glyph_surfaces(glyphs[j], ol_offset, outline_modulate, outline_render_priority, outline_size); } } // Main text surfaces. for (int j = 0; j < gl_size; j++) { - _generate_glyph_surfaces(glyphs[j], offset, modulate, 0); + _generate_glyph_surfaces(glyphs[j], offset, modulate, render_priority); } offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing + font->get_spacing(TextServer::SPACING_BOTTOM)) * pixel_size; } @@ -732,6 +740,30 @@ bool Label3D::is_uppercase() const { return uppercase; } +void Label3D::set_render_priority(int p_priority) { + ERR_FAIL_COND(p_priority < RS::MATERIAL_RENDER_PRIORITY_MIN || p_priority > RS::MATERIAL_RENDER_PRIORITY_MAX); + if (render_priority != p_priority) { + render_priority = p_priority; + _queue_update(); + } +} + +int Label3D::get_render_priority() const { + return render_priority; +} + +void Label3D::set_outline_render_priority(int p_priority) { + ERR_FAIL_COND(p_priority < RS::MATERIAL_RENDER_PRIORITY_MIN || p_priority > RS::MATERIAL_RENDER_PRIORITY_MAX); + if (outline_render_priority != p_priority) { + outline_render_priority = p_priority; + _queue_update(); + } +} + +int Label3D::get_outline_render_priority() const { + return outline_render_priority; +} + void Label3D::_font_changed() { dirty_font = true; _queue_update(); diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h index 22a99987ef..86b8faa617 100644 --- a/scene/3d/label_3d.h +++ b/scene/3d/label_3d.h @@ -98,6 +98,8 @@ private: Ref<Font> font_override; Color modulate = Color(1, 1, 1, 1); Point2 lbl_offset; + int outline_render_priority = -1; + int render_priority = 0; int outline_size = 0; Color outline_modulate = Color(0, 0, 0, 1); @@ -150,6 +152,12 @@ public: void set_vertical_alignment(VerticalAlignment p_alignment); VerticalAlignment get_vertical_alignment() const; + void set_render_priority(int p_priority); + int get_render_priority() const; + + void set_outline_render_priority(int p_priority); + int get_outline_render_priority() const; + void set_text(const String &p_string); String get_text() const; diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index f4afebb36e..283b99a24f 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -45,19 +45,19 @@ class NavigationAgent3D : public Node { uint32_t navigable_layers = 1; real_t target_desired_distance = 1.0; - real_t radius; + real_t radius = 0.0; real_t navigation_height_offset = 0.0; - bool ignore_y; - real_t neighbor_dist; - int max_neighbors; - real_t time_horizon; - real_t max_speed; + bool ignore_y = false; + real_t neighbor_dist = 0.0; + int max_neighbors = 0; + real_t time_horizon = 0.0; + real_t max_speed = 0.0; real_t path_max_distance = 3.0; Vector3 target_location; Vector<Vector3> navigation_path; - int nav_path_index; + int nav_path_index = 0; bool velocity_submitted = false; Vector3 prev_safe_velocity; /// The submitted target velocity @@ -65,7 +65,7 @@ class NavigationAgent3D : public Node { bool target_reached = false; bool navigation_finished = true; // No initialized on purpose - uint32_t update_frame_id; + uint32_t update_frame_id = 0; protected: static void _bind_methods(); diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 215e18869a..7f6ecbebb7 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -73,6 +73,10 @@ uint32_t NavigationRegion3D::get_layers() const { return NavigationServer3D::get_singleton()->region_get_layers(region); } +RID NavigationRegion3D::get_region_rid() const { + return region; +} + ///////////////////////////// void NavigationRegion3D::_notification(int p_what) { @@ -198,6 +202,8 @@ void NavigationRegion3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion3D::set_layers); ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion3D::get_layers); + ClassDB::bind_method(D_METHOD("get_region_rid"), &NavigationRegion3D::get_region_rid); + ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion3D::bake_navigation_mesh); ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion3D::_bake_finished); diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index 1a50bb5f64..1c559bc31a 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -57,6 +57,8 @@ public: void set_layers(uint32_t p_layers); uint32_t get_layers() const; + RID get_region_rid() const; + void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh); Ref<NavigationMesh> get_navigation_mesh() const; diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index ecc00fe765..989b2cbec6 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -1565,8 +1565,8 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) { } } -void CharacterBody3D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up) { - if (collision_state.floor || !was_on_floor || vel_dir_facing_up) { +void CharacterBody3D::_snap_on_floor(bool p_was_on_floor, bool p_vel_dir_facing_up) { + if (collision_state.floor || !p_was_on_floor || p_vel_dir_facing_up) { return; } @@ -1600,8 +1600,8 @@ void CharacterBody3D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up) } } -bool CharacterBody3D::_on_floor_if_snapped(bool was_on_floor, bool vel_dir_facing_up) { - if (up_direction == Vector3() || collision_state.floor || !was_on_floor || vel_dir_facing_up) { +bool CharacterBody3D::_on_floor_if_snapped(bool p_was_on_floor, bool p_vel_dir_facing_up) { + if (up_direction == Vector3() || collision_state.floor || !p_was_on_floor || p_vel_dir_facing_up) { return false; } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 6ace681021..e64987b73e 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -474,11 +474,11 @@ private: Ref<KinematicCollision3D> _get_slide_collision(int p_bounce); Ref<KinematicCollision3D> _get_last_slide_collision(); const Vector3 &get_up_direction() const; - bool _on_floor_if_snapped(bool was_on_floor, bool vel_dir_facing_up); + bool _on_floor_if_snapped(bool p_was_on_floor, bool p_vel_dir_facing_up); void set_up_direction(const Vector3 &p_up_direction); void _set_collision_direction(const PhysicsServer3D::MotionResult &p_result, CollisionState &r_state, CollisionState p_apply_state = CollisionState(true, true, true)); void _set_platform_data(const PhysicsServer3D::MotionCollision &p_collision); - void _snap_on_floor(bool was_on_floor, bool vel_dir_facing_up); + void _snap_on_floor(bool p_was_on_floor, bool p_vel_dir_facing_up); protected: void _notification(int p_what); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index f8c9fa2c96..ca706bea98 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -137,7 +137,7 @@ private: bool animate_physical_bones = true; Vector<Bone> bones; - bool process_order_dirty; + bool process_order_dirty = false; Vector<int> parentless_bones; diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 6a8fa9327c..223da13b71 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -134,6 +134,16 @@ Color SpriteBase3D::get_modulate() const { return modulate; } +void SpriteBase3D::set_render_priority(int p_priority) { + ERR_FAIL_COND(p_priority < RS::MATERIAL_RENDER_PRIORITY_MIN || p_priority > RS::MATERIAL_RENDER_PRIORITY_MAX); + render_priority = p_priority; + _queue_update(); +} + +int SpriteBase3D::get_render_priority() const { + return render_priority; +} + void SpriteBase3D::set_pixel_size(real_t p_amount) { pixel_size = p_amount; _queue_update(); @@ -295,6 +305,9 @@ void SpriteBase3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &SpriteBase3D::set_modulate); ClassDB::bind_method(D_METHOD("get_modulate"), &SpriteBase3D::get_modulate); + ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &SpriteBase3D::set_render_priority); + ClassDB::bind_method(D_METHOD("get_render_priority"), &SpriteBase3D::get_render_priority); + ClassDB::bind_method(D_METHOD("set_pixel_size", "pixel_size"), &SpriteBase3D::set_pixel_size); ClassDB::bind_method(D_METHOD("get_pixel_size"), &SpriteBase3D::get_pixel_size); @@ -335,6 +348,7 @@ void SpriteBase3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_draw_flag", "get_draw_flag", FLAG_FIXED_SIZE); ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); BIND_ENUM_CONSTANT(FLAG_TRANSPARENT); BIND_ENUM_CONSTANT(FLAG_SHADED); @@ -614,6 +628,10 @@ void Sprite3D::_draw() { RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid()); last_texture = texture->get_rid(); } + if (get_alpha_cut_mode() == ALPHA_CUT_DISABLED) { + RS::get_singleton()->material_set_render_priority(get_material(), get_render_priority()); + RS::get_singleton()->mesh_surface_set_material(mesh, 0, get_material()); + } } void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) { @@ -976,6 +994,10 @@ void AnimatedSprite3D::_draw() { RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid()); last_texture = texture->get_rid(); } + if (get_alpha_cut_mode() == ALPHA_CUT_DISABLED) { + RS::get_singleton()->material_set_render_priority(get_material(), get_render_priority()); + RS::get_singleton()->mesh_surface_set_material(mesh, 0, get_material()); + } } void AnimatedSprite3D::_validate_property(PropertyInfo &property) const { diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 047ed5a40d..028720a783 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -71,6 +71,7 @@ private: bool vflip = false; Color modulate = Color(1, 1, 1, 1); + int render_priority = 0; Vector3::Axis axis = Vector3::AXIS_Z; real_t pixel_size = 0.01; @@ -100,10 +101,10 @@ protected: uint32_t mesh_surface_offsets[RS::ARRAY_MAX]; PackedByteArray vertex_buffer; PackedByteArray attribute_buffer; - uint32_t vertex_stride; - uint32_t attrib_stride; - uint32_t skin_stride; - uint32_t mesh_surface_format; + uint32_t vertex_stride = 0; + uint32_t attrib_stride = 0; + uint32_t skin_stride = 0; + uint32_t mesh_surface_format = 0; void _queue_update(); @@ -120,6 +121,9 @@ public: void set_flip_v(bool p_flip); bool is_flipped_v() const; + void set_render_priority(int p_priority); + int get_render_priority() const; + void set_modulate(const Color &p_color); Color get_modulate() const; diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index f5a451ca04..675cd1b172 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -40,7 +40,7 @@ public: Vector3 m_0MinvJt; Vector3 m_1MinvJt; //Optimization: can be stored in the w/last component of one of the vectors - real_t m_Adiag; + real_t m_Adiag = 0.0; real_t getDiagonal() const { return m_Adiag; } diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 4f94ec3584..b3cae4f5b5 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -194,16 +194,20 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta //build open list for (int i = 0; i < p_state_machine->transitions.size(); i++) { - if (p_state_machine->transitions[i].from == current) { + if (p_state_machine->transitions[i].transition->is_disabled()) { + continue; + } + + if (p_state_machine->transitions[i].local_from == current) { open_list.push_back(i); - float cost = p_state_machine->states[p_state_machine->transitions[i].to].position.distance_to(current_pos); + float cost = p_state_machine->states[p_state_machine->transitions[i].local_to].position.distance_to(current_pos); cost *= p_state_machine->transitions[i].transition->get_priority(); AStarCost ap; ap.prev = current; ap.distance = cost; - cost_map[p_state_machine->transitions[i].to] = ap; + cost_map[p_state_machine->transitions[i].local_to] = ap; - if (p_state_machine->transitions[i].to == p_travel) { //prematurely found it! :D + if (p_state_machine->transitions[i].local_to == p_travel) { //prematurely found it! :D path.push_back(p_travel); return true; } @@ -222,8 +226,8 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta float least_cost = 1e20; for (List<int>::Element *E = open_list.front(); E; E = E->next()) { - float cost = cost_map[p_state_machine->transitions[E->get()].to].distance; - cost += p_state_machine->states[p_state_machine->transitions[E->get()].to].position.distance_to(target_pos); + float cost = cost_map[p_state_machine->transitions[E->get()].local_to].distance; + cost += p_state_machine->states[p_state_machine->transitions[E->get()].local_to].position.distance_to(target_pos); if (cost < least_cost) { least_cost_transition = E; @@ -231,34 +235,38 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta } } - StringName transition_prev = p_state_machine->transitions[least_cost_transition->get()].from; - StringName transition = p_state_machine->transitions[least_cost_transition->get()].to; + StringName transition_prev = p_state_machine->transitions[least_cost_transition->get()].local_from; + StringName transition = p_state_machine->transitions[least_cost_transition->get()].local_to; for (int i = 0; i < p_state_machine->transitions.size(); i++) { - if (p_state_machine->transitions[i].from != transition || p_state_machine->transitions[i].to == transition_prev) { + if (p_state_machine->transitions[i].transition->is_disabled()) { + continue; + } + + if (p_state_machine->transitions[i].local_from != transition || p_state_machine->transitions[i].local_to == transition_prev) { continue; //not interested on those } - float distance = p_state_machine->states[p_state_machine->transitions[i].from].position.distance_to(p_state_machine->states[p_state_machine->transitions[i].to].position); + float distance = p_state_machine->states[p_state_machine->transitions[i].local_from].position.distance_to(p_state_machine->states[p_state_machine->transitions[i].local_to].position); distance *= p_state_machine->transitions[i].transition->get_priority(); - distance += cost_map[p_state_machine->transitions[i].from].distance; + distance += cost_map[p_state_machine->transitions[i].local_from].distance; - if (cost_map.has(p_state_machine->transitions[i].to)) { + if (cost_map.has(p_state_machine->transitions[i].local_to)) { //oh this was visited already, can we win the cost? - if (distance < cost_map[p_state_machine->transitions[i].to].distance) { - cost_map[p_state_machine->transitions[i].to].distance = distance; - cost_map[p_state_machine->transitions[i].to].prev = p_state_machine->transitions[i].from; + if (distance < cost_map[p_state_machine->transitions[i].local_to].distance) { + cost_map[p_state_machine->transitions[i].local_to].distance = distance; + cost_map[p_state_machine->transitions[i].local_to].prev = p_state_machine->transitions[i].local_from; } } else { //add to open list AStarCost ac; - ac.prev = p_state_machine->transitions[i].from; + ac.prev = p_state_machine->transitions[i].local_from; ac.distance = distance; - cost_map[p_state_machine->transitions[i].to] = ac; + cost_map[p_state_machine->transitions[i].local_to] = ac; open_list.push_back(i); - if (p_state_machine->transitions[i].to == p_travel) { + if (p_state_machine->transitions[i].local_to == p_travel) { found_route = true; break; } @@ -397,7 +405,11 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s if (path.size()) { for (int i = 0; i < p_state_machine->transitions.size(); i++) { - if (p_state_machine->transitions[i].from == current && p_state_machine->transitions[i].to == path[0]) { + if (p_state_machine->transitions[i].transition->is_disabled()) { + continue; + } + + if (p_state_machine->transitions[i].local_from == current && p_state_machine->transitions[i].local_to == path[0]) { next_xfade = p_state_machine->transitions[i].transition->get_xfade_time(); switch_mode = p_state_machine->transitions[i].transition->get_switch_mode(); next = path[0]; @@ -406,17 +418,39 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s } else { float priority_best = 1e20; int auto_advance_to = -1; + for (int i = 0; i < p_state_machine->transitions.size(); i++) { - bool auto_advance = false; - if (p_state_machine->transitions[i].transition->has_auto_advance()) { - auto_advance = true; + if (p_state_machine->transitions[i].transition->is_disabled()) { + continue; } - StringName advance_condition_name = p_state_machine->transitions[i].transition->get_advance_condition_name(); - if (advance_condition_name != StringName() && bool(p_state_machine->get_parameter(advance_condition_name))) { - auto_advance = true; + + // handles end_node: when end_node is reached in a sub state machine, find and activate the current_transition + if (force_auto_advance) { + if (p_state_machine->transitions[i].from == current_transition.from && p_state_machine->transitions[i].to == current_transition.to) { + auto_advance_to = i; + force_auto_advance = false; + break; + } } - if (p_state_machine->transitions[i].from == current && auto_advance) { + // handles start_node: if previous state machine is pointing to a node inside the current state machine, starts the current machine from start_node to prev_local_to + if (p_state_machine->start_node == current && p_state_machine->transitions[i].local_from == current) { + if (p_state_machine->prev_state_machine.is_valid()) { + Ref<AnimationNodeStateMachinePlayback> prev_playback = p_state_machine->prev_state_machine->get_parameter("playback"); + + if (prev_playback.is_valid()) { + StringName prev_local_to = String(prev_playback->current_transition.next).replace_first(String(p_state_machine->state_machine_name) + "/", ""); + + if (p_state_machine->transitions[i].to == prev_local_to) { + auto_advance_to = i; + prev_playback->current_transition.next = StringName(); + break; + } + } + } + } + + if (p_state_machine->transitions[i].from == current && _check_advance_condition(p_state_machine, p_state_machine->transitions[i].transition)) { if (p_state_machine->transitions[i].transition->get_priority() <= priority_best) { priority_best = p_state_machine->transitions[i].transition->get_priority(); auto_advance_to = i; @@ -425,12 +459,55 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s } if (auto_advance_to != -1) { - next = p_state_machine->transitions[auto_advance_to].to; + next = p_state_machine->transitions[auto_advance_to].local_to; + Transition tr; + tr.from = String(p_state_machine->state_machine_name) + "/" + String(p_state_machine->transitions[auto_advance_to].from); + tr.to = String(p_state_machine->transitions[auto_advance_to].to).replace_first("../", ""); + tr.next = p_state_machine->transitions[auto_advance_to].to; + current_transition = tr; next_xfade = p_state_machine->transitions[auto_advance_to].transition->get_xfade_time(); switch_mode = p_state_machine->transitions[auto_advance_to].transition->get_switch_mode(); } } + if (next == p_state_machine->end_node) { + Ref<AnimationNodeStateMachine> prev_state_machine = p_state_machine->prev_state_machine; + + if (prev_state_machine.is_valid()) { + Ref<AnimationNodeStateMachinePlayback> prev_playback = prev_state_machine->get_parameter("playback"); + + if (prev_playback.is_valid()) { + if (next_xfade) { + prev_playback->current_transition = current_transition; + prev_playback->force_auto_advance = true; + + return rem; + } + float priority_best = 1e20; + int auto_advance_to = -1; + + for (int i = 0; i < prev_state_machine->transitions.size(); i++) { + if (prev_state_machine->transitions[i].transition->is_disabled()) { + continue; + } + + if (current_transition.next == prev_state_machine->end_node && _check_advance_condition(prev_state_machine, prev_state_machine->transitions[i].transition)) { + if (prev_state_machine->transitions[i].transition->get_priority() <= priority_best) { + priority_best = prev_state_machine->transitions[i].transition->get_priority(); + auto_advance_to = i; + } + } + } + + if (auto_advance_to != -1) { + if (prev_state_machine->transitions[auto_advance_to].transition->get_xfade_time()) { + return rem; + } + } + } + } + } + //if next, see when to transition if (next != StringName()) { bool goto_next = false; @@ -474,14 +551,35 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s } } - //compute time left for transitions by using the end node - if (p_state_machine->end_node != StringName() && p_state_machine->end_node != current) { - rem = p_state_machine->blend_node(p_state_machine->end_node, p_state_machine->states[p_state_machine->end_node].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false); + // time left must always be 1 because the end node don't lenght to compute + if (p_state_machine->end_node != current) { + rem = 1; + } else { + Ref<AnimationNodeStateMachinePlayback> prev_playback = p_state_machine->prev_state_machine->get_parameter("playback"); + + if (prev_playback.is_valid()) { + prev_playback->current_transition = current_transition; + prev_playback->force_auto_advance = true; + } } return rem; } +bool AnimationNodeStateMachinePlayback::_check_advance_condition(const Ref<AnimationNodeStateMachine> state_machine, const Ref<AnimationNodeStateMachineTransition> transition) const { + if (transition->has_auto_advance()) { + return true; + } + + StringName advance_condition_name = transition->get_advance_condition_name(); + + if (advance_condition_name != StringName() && bool(state_machine->get_parameter(advance_condition_name))) { + return true; + } + + return false; +} + void AnimationNodeStateMachinePlayback::_bind_methods() { ClassDB::bind_method(D_METHOD("travel", "to_node"), &AnimationNodeStateMachinePlayback::travel); ClassDB::bind_method(D_METHOD("start", "node"), &AnimationNodeStateMachinePlayback::start); @@ -513,6 +611,23 @@ void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) c for (const StringName &E : advance_conditions) { r_list->push_back(PropertyInfo(Variant::BOOL, E)); } + + // for (const KeyValue<StringName, State> &E : states) { + // if (E->node == ansm) { + // for (int i = 0; i < E->node->transitions.size(); i++) { + // StringName ac = E->node->transitions[i].transition->get_advance_condition_name(); + // if (ac != StringName() && advance_conditions.find(ac) == nullptr) { + // advance_conditions.push_back(ac); + // } + // } + + // advance_conditions.sort_custom<StringName::AlphCompare>(); + + // for (const StringName &E : advance_conditions) { + // r_list->push_back(PropertyInfo(Variant::BOOL, E)); + // } + // } + // } } Variant AnimationNodeStateMachine::get_parameter_default_value(const StringName &p_parameter) const { @@ -536,6 +651,13 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation states[p_name] = state; + Ref<AnimationNodeStateMachine> anodesm = p_node; + + if (anodesm.is_valid()) { + anodesm->state_machine_name = p_name; + anodesm->prev_state_machine = (Ref<AnimationNodeStateMachine>)this; + } + emit_changed(); emit_signal(SNAME("tree_changed")); @@ -562,6 +684,14 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); } +bool AnimationNodeStateMachine::can_edit_node(const StringName &p_name) const { + if (states.has(p_name)) { + return !(states[p_name].node->is_class("AnimationNodeStartState") || states[p_name].node->is_class("AnimationNodeEndState")); + } + + return true; +} + Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const { ERR_FAIL_COND_V(!states.has(p_name), Ref<AnimationNode>()); @@ -602,36 +732,24 @@ bool AnimationNodeStateMachine::has_node(const StringName &p_name) const { void AnimationNodeStateMachine::remove_node(const StringName &p_name) { ERR_FAIL_COND(!states.has(p_name)); - { - Ref<AnimationNode> node = states[p_name].node; - - ERR_FAIL_COND(node.is_null()); - - node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); + if (!can_edit_node(p_name)) { + return; } - states.erase(p_name); - //path.erase(p_name); - for (int i = 0; i < transitions.size(); i++) { - if (transitions[i].from == p_name || transitions[i].to == p_name) { - transitions.write[i].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); - transitions.remove_at(i); + if (transitions[i].local_from == p_name || transitions[i].local_to == p_name) { + remove_transition_by_index(i); i--; } } - if (start_node == p_name) { - start_node = StringName(); - } - - if (end_node == p_name) { - end_node = StringName(); + { + Ref<AnimationNode> node = states[p_name].node; + ERR_FAIL_COND(node.is_null()); + node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); } - /*if (playing && current == p_name) { - stop(); - }*/ + states.erase(p_name); emit_changed(); emit_signal(SNAME("tree_changed")); @@ -640,39 +758,73 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) { void AnimationNodeStateMachine::rename_node(const StringName &p_name, const StringName &p_new_name) { ERR_FAIL_COND(!states.has(p_name)); ERR_FAIL_COND(states.has(p_new_name)); + ERR_FAIL_COND(!can_edit_node(p_name)); states[p_new_name] = states[p_name]; states.erase(p_name); + Ref<AnimationNodeStateMachine> anodesm = states[p_new_name].node; + if (anodesm.is_valid()) { + anodesm->state_machine_name = p_new_name; + } + for (int i = 0; i < transitions.size(); i++) { - if (transitions[i].from == p_name) { - transitions.write[i].from = p_new_name; + if (transitions[i].local_from == p_name) { + _rename_transition(transitions[i].from, String(transitions[i].from).replace_first(p_name, p_new_name)); } - if (transitions[i].to == p_name) { - transitions.write[i].to = p_new_name; + if (transitions[i].local_to == p_name) { + _rename_transition(transitions[i].to, String(transitions[i].to).replace_first(p_name, p_new_name)); } } - if (start_node == p_name) { - start_node = p_new_name; - } + emit_signal("tree_changed"); +} - if (end_node == p_name) { - end_node = p_new_name; +void AnimationNodeStateMachine::_rename_transition(const StringName &p_name, const StringName &p_new_name) { + if (updating_transitions) { + return; } - /*if (playing && current == p_name) { - current = p_new_name; - }*/ + updating_transitions = true; + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == p_name) { + Vector<String> path = String(transitions[i].to).split("/"); + if (path.size() > 1) { + if (path[0] == "..") { + prev_state_machine->_rename_transition(String(state_machine_name) + "/" + p_name, String(state_machine_name) + "/" + p_new_name); + } else { + ((Ref<AnimationNodeStateMachine>)states[transitions[i].local_to].node)->_rename_transition("../" + p_name, "../" + p_new_name); + } + } + + transitions.write[i].from = p_new_name; + } - //path.clear(); //clear path - emit_signal(SNAME("tree_changed")); + if (transitions[i].to == p_name) { + Vector<String> path = String(transitions[i].from).split("/"); + if (path.size() > 1) { + if (path[0] == "..") { + prev_state_machine->_rename_transition(String(state_machine_name) + "/" + p_name, String(state_machine_name) + "/" + p_new_name); + } else { + ((Ref<AnimationNodeStateMachine>)states[transitions[i].local_from].node)->_rename_transition("../" + p_name, "../" + p_new_name); + } + } + + transitions.write[i].to = p_new_name; + } + + updating_transitions = false; + } } void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const { List<StringName> nodes; for (const KeyValue<StringName, State> &E : states) { + if (E.key == end_node && !prev_state_machine.is_valid()) { + continue; + } + nodes.push_back(E.key); } nodes.sort_custom<StringName::AlphCompare>(); @@ -682,9 +834,16 @@ void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const { } } +Ref<AnimationNodeStateMachine> AnimationNodeStateMachine::get_prev_state_machine() const { + return prev_state_machine; +} + bool AnimationNodeStateMachine::has_transition(const StringName &p_from, const StringName &p_to) const { + StringName from = _get_shortest_path(p_from); + StringName to = _get_shortest_path(p_to); + for (int i = 0; i < transitions.size(); i++) { - if (transitions[i].from == p_from && transitions[i].to == p_to) { + if (transitions[i].from == from && transitions[i].to == to) { return true; } } @@ -692,32 +851,148 @@ bool AnimationNodeStateMachine::has_transition(const StringName &p_from, const S } int AnimationNodeStateMachine::find_transition(const StringName &p_from, const StringName &p_to) const { + StringName from = _get_shortest_path(p_from); + StringName to = _get_shortest_path(p_to); + for (int i = 0; i < transitions.size(); i++) { - if (transitions[i].from == p_from && transitions[i].to == p_to) { + if (transitions[i].from == from && transitions[i].to == to) { return i; } } return -1; } +bool AnimationNodeStateMachine::_can_connect(const StringName &p_name, Vector<Ref<AnimationNodeStateMachine>> p_parents) const { + if (p_parents.is_empty()) { + Ref<AnimationNodeStateMachine> prev = (Ref<AnimationNodeStateMachine>)this; + while (prev.is_valid()) { + p_parents.push_back(prev); + prev = prev->prev_state_machine; + } + } + + if (states.has(p_name)) { + Ref<AnimationNodeStateMachine> anodesm = states[p_name].node; + + if (anodesm.is_valid() && p_parents.find(anodesm) != -1) { + return false; + } + + return true; + } + + String name = p_name; + Vector<String> path = name.split("/"); + + if (path.size() < 2) { + return false; + } + + if (path[0] == "..") { + if (prev_state_machine.is_valid()) { + return prev_state_machine->_can_connect(name.replace_first("../", ""), p_parents); + } + } else if (states.has(path[0])) { + Ref<AnimationNodeStateMachine> anodesm = states[path[0]].node; + if (anodesm.is_valid()) { + return anodesm->_can_connect(name.replace_first(path[0] + "/", ""), p_parents); + } + } + + return false; +} + +StringName AnimationNodeStateMachine::_get_shortest_path(const StringName &p_path) const { + // If p_path is something like StateMachine/../StateMachine2/State1, + // the result will be StateMachine2/State1. This avoid duplicate + // transitions when using add_transition. eg, this two calls is the same: + // + // add_transition("State1", "StateMachine/../State2", tr) + // add_transition("State1", "State2", tr) + // + // but the second call must be invalid because the transition already exists + + Vector<String> path = String(p_path).split("/"); + Vector<String> new_path; + + for (int i = 0; i < path.size(); i++) { + if (i > 0 && path[i] == ".." && new_path[i - 1] != "..") { + new_path.remove_at(i - 1); + } else { + new_path.push_back(path[i]); + } + } + + String result; + for (int i = 0; i < new_path.size(); i++) { + result += new_path[i] + "/"; + } + result.remove_at(result.length() - 1); + + return result; +} + void AnimationNodeStateMachine::add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition) { - ERR_FAIL_COND(p_from == p_to); - ERR_FAIL_COND(!states.has(p_from)); - ERR_FAIL_COND(!states.has(p_to)); + if (updating_transitions) { + return; + } + + StringName from = _get_shortest_path(p_from); + StringName to = _get_shortest_path(p_to); + Vector<String> path_from = String(from).split("/"); + Vector<String> path_to = String(to).split("/"); + + ERR_FAIL_COND(from == end_node || to == start_node); + ERR_FAIL_COND(from == to); + ERR_FAIL_COND(!_can_connect(from)); + ERR_FAIL_COND(!_can_connect(to)); ERR_FAIL_COND(p_transition.is_null()); for (int i = 0; i < transitions.size(); i++) { - ERR_FAIL_COND(transitions[i].from == p_from && transitions[i].to == p_to); + ERR_FAIL_COND(transitions[i].from == from && transitions[i].to == to); } + if (path_from.size() > 1 || path_to.size() > 1) { + ERR_FAIL_COND(path_from[0] == path_to[0]); + } + + updating_transitions = true; + + StringName local_from = String(from).get_slicec('/', 0); + StringName local_to = String(to).get_slicec('/', 0); + local_from = local_from == ".." ? "Start" : local_from; + local_to = local_to == ".." ? "End" : local_to; + Transition tr; - tr.from = p_from; - tr.to = p_to; + tr.from = from; + tr.to = to; + tr.local_from = local_from; + tr.local_to = local_to; tr.transition = p_transition; tr.transition->connect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); transitions.push_back(tr); + + // do recursive + if (path_from.size() > 1) { + StringName local_path = String(from).replace_first(path_from[0] + "/", ""); + if (path_from[0] == "..") { + prev_state_machine->add_transition(local_path, String(state_machine_name) + "/" + to, p_transition); + } else { + ((Ref<AnimationNodeStateMachine>)states[path_from[0]].node)->add_transition(local_path, "../" + to, p_transition); + } + } + if (path_to.size() > 1) { + StringName local_path = String(to).replace_first(path_to[0] + "/", ""); + if (path_to[0] == "..") { + prev_state_machine->add_transition(String(state_machine_name) + "/" + from, local_path, p_transition); + } else { + ((Ref<AnimationNodeStateMachine>)states[path_to[0]].node)->add_transition("../" + from, local_path, p_transition); + } + } + + updating_transitions = false; } Ref<AnimationNodeStateMachineTransition> AnimationNodeStateMachine::get_transition(int p_transition) const { @@ -740,44 +1015,52 @@ int AnimationNodeStateMachine::get_transition_count() const { } void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) { + StringName from = _get_shortest_path(p_from); + StringName to = _get_shortest_path(p_to); + for (int i = 0; i < transitions.size(); i++) { - if (transitions[i].from == p_from && transitions[i].to == p_to) { - transitions.write[i].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); - transitions.remove_at(i); + if (transitions[i].from == from && transitions[i].to == to) { + remove_transition_by_index(i); return; } } - - /*if (playing) { - path.clear(); - }*/ } -void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) { +void AnimationNodeStateMachine::remove_transition_by_index(const int p_transition) { ERR_FAIL_INDEX(p_transition, transitions.size()); + Transition tr = transitions[p_transition]; transitions.write[p_transition].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); transitions.remove_at(p_transition); - /*if (playing) { - path.clear(); - }*/ -} -void AnimationNodeStateMachine::set_start_node(const StringName &p_node) { - ERR_FAIL_COND(p_node != StringName() && !states.has(p_node)); - start_node = p_node; -} + Vector<String> path_from = String(tr.from).split("/"); + Vector<String> path_to = String(tr.to).split("/"); -String AnimationNodeStateMachine::get_start_node() const { - return start_node; -} + List<Vector<String>> paths; + paths.push_back(path_from); + paths.push_back(path_to); -void AnimationNodeStateMachine::set_end_node(const StringName &p_node) { - ERR_FAIL_COND(p_node != StringName() && !states.has(p_node)); - end_node = p_node; + for (List<Vector<String>>::Element *E = paths.front(); E; E = E->next()) { + if (E->get()[0].size() > 1) { + if (E->get()[0] == "..") { + prev_state_machine->_remove_transition(tr.transition); + } else if (states.has(E->get()[0])) { + Ref<AnimationNodeStateMachine> anodesm = states[E->get()[0]].node; + + if (anodesm.is_valid()) { + anodesm->_remove_transition(tr.transition); + } + } + } + } } -String AnimationNodeStateMachine::get_end_node() const { - return end_node; +void AnimationNodeStateMachine::_remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition) { + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].transition == p_transition) { + remove_transition_by_index(i); + return; + } + } } void AnimationNodeStateMachine::set_graph_offset(const Vector2 &p_offset) { @@ -799,6 +1082,18 @@ String AnimationNodeStateMachine::get_caption() const { return "StateMachine"; } +bool AnimationNodeStateMachine::has_local_transition(const StringName &p_from, const StringName &p_to) const { + StringName from = _get_shortest_path(p_from); + StringName to = _get_shortest_path(p_to); + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].local_from == from && transitions[i].local_to == to) { + return true; + } + } + return false; +} + Ref<AnimationNode> AnimationNodeStateMachine::get_child_by_name(const StringName &p_name) { return get_node(p_name); } @@ -831,12 +1126,6 @@ bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_ add_transition(trans[i], trans[i + 1], trans[i + 2]); } return true; - } else if (name == "start_node") { - set_start_node(p_value); - return true; - } else if (name == "end_node") { - set_end_node(p_value); - return true; } else if (name == "graph_offset") { set_graph_offset(p_value); return true; @@ -852,7 +1141,7 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c String what = name.get_slicec('/', 2); if (what == "node") { - if (states.has(node_name)) { + if (states.has(node_name) && can_edit_node(node_name)) { r_ret = states[node_name].node; return true; } @@ -866,22 +1155,21 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c } } else if (name == "transitions") { Array trans; - trans.resize(transitions.size() * 3); - for (int i = 0; i < transitions.size(); i++) { - trans[i * 3 + 0] = transitions[i].from; - trans[i * 3 + 1] = transitions[i].to; - trans[i * 3 + 2] = transitions[i].transition; + String from = transitions[i].from; + String to = transitions[i].to; + + if (from.get_slicec('/', 0) == ".." || to.get_slicec('/', 0) == "..") { + continue; + } + + trans.push_back(from); + trans.push_back(to); + trans.push_back(transitions[i].transition); } r_ret = trans; return true; - } else if (name == "start_node") { - r_ret = get_start_node(); - return true; - } else if (name == "end_node") { - r_ret = get_end_node(); - return true; } else if (name == "graph_offset") { r_ret = get_graph_offset(); return true; @@ -903,8 +1191,6 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c } p_list->push_back(PropertyInfo(Variant::ARRAY, "transitions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::STRING_NAME, "start_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::STRING_NAME, "end_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); } @@ -912,10 +1198,24 @@ void AnimationNodeStateMachine::reset_state() { states.clear(); transitions.clear(); playback = "playback"; - start_node = StringName(); - end_node = StringName(); + start_node = "Start"; + end_node = "End"; graph_offset = Vector2(); + Ref<AnimationNodeStartState> s; + s.instantiate(); + State start; + start.node = s; + start.position = Vector2(200, 100); + states[start_node] = start; + + Ref<AnimationNodeEndState> e; + e.instantiate(); + State end; + end.node = e; + end.position = Vector2(900, 100); + states[end_node] = end; + emit_changed(); emit_signal(SNAME("tree_changed")); } @@ -955,15 +1255,22 @@ void AnimationNodeStateMachine::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_transition_by_index", "idx"), &AnimationNodeStateMachine::remove_transition_by_index); ClassDB::bind_method(D_METHOD("remove_transition", "from", "to"), &AnimationNodeStateMachine::remove_transition); - ClassDB::bind_method(D_METHOD("set_start_node", "name"), &AnimationNodeStateMachine::set_start_node); - ClassDB::bind_method(D_METHOD("get_start_node"), &AnimationNodeStateMachine::get_start_node); - - ClassDB::bind_method(D_METHOD("set_end_node", "name"), &AnimationNodeStateMachine::set_end_node); - ClassDB::bind_method(D_METHOD("get_end_node"), &AnimationNodeStateMachine::get_end_node); - ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeStateMachine::set_graph_offset); ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset); } AnimationNodeStateMachine::AnimationNodeStateMachine() { + Ref<AnimationNodeStartState> s; + s.instantiate(); + State start; + start.node = s; + start.position = Vector2(200, 100); + states[start_node] = start; + + Ref<AnimationNodeEndState> e; + e.instantiate(); + State end; + end.node = e; + end.position = Vector2(900, 100); + states[end_node] = end; } diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index 96add7f538..39a84358fb 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -93,13 +93,19 @@ class AnimationNodeStateMachinePlayback : public Resource { StringName prev; }; - float len_total = 0.0; + struct Transition { + StringName from; + StringName to; + StringName next; + }; float len_current = 0.0; float pos_current = 0.0; bool end_loop = false; StringName current; + Transition current_transition; + bool force_auto_advance = false; StringName fading_from; float fading_time = 0.0; @@ -116,6 +122,8 @@ class AnimationNodeStateMachinePlayback : public Resource { double process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek); + bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const; + protected: static void _bind_methods(); @@ -149,19 +157,25 @@ private: struct Transition { StringName from; StringName to; + StringName local_from; + StringName local_to; Ref<AnimationNodeStateMachineTransition> transition; }; Vector<Transition> transitions; StringName playback = "playback"; - - StringName start_node; - StringName end_node; + StringName state_machine_name; + Ref<AnimationNodeStateMachine> prev_state_machine; + bool updating_transitions = false; Vector2 graph_offset; void _tree_changed(); + void _remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition); + void _rename_transition(const StringName &p_name, const StringName &p_new_name); + bool _can_connect(const StringName &p_name, const Vector<Ref<AnimationNodeStateMachine>> p_parents = Vector<Ref<AnimationNodeStateMachine>>()) const; + StringName _get_shortest_path(const StringName &p_path) const; protected: static void _bind_methods(); @@ -169,10 +183,14 @@ protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const; virtual void reset_state() override; public: + StringName start_node = "Start"; + StringName end_node = "End"; + virtual void get_parameter_list(List<PropertyInfo> *r_list) const override; virtual Variant get_parameter_default_value(const StringName &p_parameter) const override; @@ -191,20 +209,19 @@ public: virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override; bool has_transition(const StringName &p_from, const StringName &p_to) const; + bool has_local_transition(const StringName &p_from, const StringName &p_to) const; int find_transition(const StringName &p_from, const StringName &p_to) const; void add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition); Ref<AnimationNodeStateMachineTransition> get_transition(int p_transition) const; StringName get_transition_from(int p_transition) const; StringName get_transition_to(int p_transition) const; int get_transition_count() const; - void remove_transition_by_index(int p_transition); + void remove_transition_by_index(const int p_transition); void remove_transition(const StringName &p_from, const StringName &p_to); - void set_start_node(const StringName &p_node); - String get_start_node() const; + bool can_edit_node(const StringName &p_name) const; - void set_end_node(const StringName &p_node); - String get_end_node() const; + Ref<AnimationNodeStateMachine> get_prev_state_machine() const; void set_graph_offset(const Vector2 &p_offset); Vector2 get_graph_offset() const; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 6949e3681c..081e6e809a 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -284,7 +284,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov for (int i = 0; i < a->get_track_count(); i++) { p_anim->node_cache.write[i] = nullptr; - RES resource; + Ref<Resource> resource; Vector<StringName> leftover_path; Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path); ERR_CONTINUE_MSG(!child, "On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'."); // couldn't find the child node diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 1d450175ad..8c2f0e390b 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -94,7 +94,7 @@ private: struct TrackNodeCache { NodePath path; uint32_t id = 0; - RES resource; + Ref<Resource> resource; Node *node = nullptr; Node2D *node_2d = nullptr; #ifndef _3D_DISABLED diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 424716e002..b0590bc2bd 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -570,7 +570,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { } if (!track) { - RES resource; + Ref<Resource> resource; Vector<StringName> leftover_path; Node *child = parent->get_node_and_resource(path, resource, leftover_path); diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index e61a297b04..3f09bf7f4b 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -37,6 +37,8 @@ #include "scene/resources/animation.h" class AnimationNodeBlendTree; +class AnimationNodeStartState; +class AnimationNodeEndState; class AnimationPlayer; class AnimationTree; @@ -164,6 +166,14 @@ public: AnimationRootNode() {} }; +class AnimationNodeStartState : public AnimationRootNode { + GDCLASS(AnimationNodeStartState, AnimationRootNode); +}; + +class AnimationNodeEndState : public AnimationRootNode { + GDCLASS(AnimationNodeEndState, AnimationRootNode); +}; + class AnimationTree : public Node { GDCLASS(AnimationTree, Node); diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 66cfb4c17e..a52902f8c6 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -278,14 +278,15 @@ bool Tween::step(float p_delta) { bool step_active = false; total_time += rem_delta; +#ifdef DEBUG_ENABLED + float initial_delta = rem_delta; + bool potential_infinite = false; +#endif + while (rem_delta > 0 && running) { float step_delta = rem_delta; step_active = false; -#ifdef DEBUG_ENABLED - float prev_delta = rem_delta; -#endif - for (Ref<Tweener> &tweener : tweeners.write[current_step]) { // Modified inside Tweener.step(). float temp_delta = rem_delta; @@ -310,17 +311,21 @@ bool Tween::step(float p_delta) { emit_signal(SNAME("loop_finished"), loops_done); current_step = 0; start_tweeners(); +#ifdef DEBUG_ENABLED + if (loops <= 0 && Math::is_equal_approx(rem_delta, initial_delta)) { + if (!potential_infinite) { + potential_infinite = true; + } else { + // Looped twice without using any time, this is 100% certain infinite loop. + ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info."); + } + } +#endif } } else { start_tweeners(); } } - -#ifdef DEBUG_ENABLED - if (Math::is_equal_approx(rem_delta, prev_delta) && running && loops <= 0) { - ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info."); - } -#endif } return true; @@ -850,7 +855,7 @@ bool CallbackTweener::step(float &r_delta) { Callable::CallError ce; callback.call(nullptr, 0, result, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(false, "Error calling method from CallbackTweener: " + Variant::get_call_error_text(callback.get_object(), callback.get_method(), nullptr, 0, ce)); + ERR_FAIL_V_MSG(false, "Error calling method from CallbackTweener: " + Variant::get_callable_error_text(callback, nullptr, 0, ce)); } finished = true; @@ -921,7 +926,7 @@ bool MethodTweener::step(float &r_delta) { Callable::CallError ce; callback.call(argptr, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(false, "Error calling method from MethodTweener: " + Variant::get_call_error_text(callback.get_object(), callback.get_method(), argptr, 1, ce)); + ERR_FAIL_V_MSG(false, "Error calling method from MethodTweener: " + Variant::get_callable_error_text(callback, argptr, 1, ce)); } if (time < duration) { diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 5c1567d510..40268405cf 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -116,6 +116,9 @@ private: bool valid = false; bool default_parallel = false; bool parallel_enabled = false; +#ifdef DEBUG_ENABLED + bool is_infinite = false; +#endif typedef real_t (*interpolater)(real_t t, real_t b, real_t c, real_t d); static interpolater interpolaters[TRANS_MAX][EASE_MAX]; diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index ac0d017a23..77c1c20499 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -467,7 +467,7 @@ void SceneDebuggerObject::serialize(Array &r_arr, int p_max_size) { const PropertyInfo &pi = properties[i].first; Variant &var = properties[i].second; - RES res = var; + Ref<Resource> res = var; Array prop; prop.push_back(pi.name); @@ -529,7 +529,7 @@ void SceneDebuggerObject::deserialize(const Array &p_arr) { if (pinfo.type == Variant::OBJECT) { if (var.is_zero()) { - var = RES(); + var = Ref<Resource>(); } else if (var.get_type() == Variant::OBJECT) { if (((Object *)var)->is_class("EncodedObjectAsID")) { var = Object::cast_to<EncodedObjectAsID>(var)->get_object_id(); @@ -646,7 +646,7 @@ void LiveEditor::_node_set_func(int p_id, const StringName &p_prop, const Varian } void LiveEditor::_node_set_res_func(int p_id, const StringName &p_prop, const String &p_value) { - RES r = ResourceLoader::load(p_value); + Ref<Resource> r = ResourceLoader::load(p_value); if (!r.is_valid()) { return; } @@ -701,7 +701,7 @@ void LiveEditor::_res_set_func(int p_id, const StringName &p_prop, const Variant return; } - RES r = ResourceCache::get(resp); + Ref<Resource> r = ResourceCache::get(resp); if (!r.is_valid()) { return; } @@ -710,7 +710,7 @@ void LiveEditor::_res_set_func(int p_id, const StringName &p_prop, const Variant } void LiveEditor::_res_set_res_func(int p_id, const StringName &p_prop, const String &p_value) { - RES r = ResourceLoader::load(p_value); + Ref<Resource> r = ResourceLoader::load(p_value); if (!r.is_valid()) { return; } @@ -728,7 +728,7 @@ void LiveEditor::_res_call_func(int p_id, const StringName &p_method, const Vari return; } - RES r = ResourceCache::get(resp); + Ref<Resource> r = ResourceCache::get(resp); if (!r.is_valid()) { return; } diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index fdcd7116f3..05bb30f7e0 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -1818,7 +1818,7 @@ void CodeEdit::request_code_completion(bool p_force) { } } -void CodeEdit::add_code_completion_option(CodeCompletionKind p_type, const String &p_display_text, const String &p_insert_text, const Color &p_text_color, const RES &p_icon, const Variant &p_value) { +void CodeEdit::add_code_completion_option(CodeCompletionKind p_type, const String &p_display_text, const String &p_insert_text, const Color &p_text_color, const Ref<Resource> &p_icon, const Variant &p_value) { ScriptLanguage::CodeCompletionOption completion_option; completion_option.kind = (ScriptLanguage::CodeCompletionKind)p_type; completion_option.display = p_display_text; @@ -2196,7 +2196,7 @@ void CodeEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_text_for_code_completion"), &CodeEdit::get_text_for_code_completion); ClassDB::bind_method(D_METHOD("request_code_completion", "force"), &CodeEdit::request_code_completion, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("add_code_completion_option", "type", "display_text", "insert_text", "text_color", "icon", "value"), &CodeEdit::add_code_completion_option, DEFVAL(Color(1, 1, 1)), DEFVAL(RES()), DEFVAL(Variant::NIL)); + ClassDB::bind_method(D_METHOD("add_code_completion_option", "type", "display_text", "insert_text", "text_color", "icon", "value"), &CodeEdit::add_code_completion_option, DEFVAL(Color(1, 1, 1)), DEFVAL(Ref<Resource>()), DEFVAL(Variant::NIL)); ClassDB::bind_method(D_METHOD("update_code_completion_options", "force"), &CodeEdit::update_code_completion_options); ClassDB::bind_method(D_METHOD("get_code_completion_options"), &CodeEdit::get_code_completion_options); ClassDB::bind_method(D_METHOD("get_code_completion_option", "index"), &CodeEdit::get_code_completion_option); diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index 596a065f12..135dd32780 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -398,7 +398,7 @@ public: void request_code_completion(bool p_force = false); - void add_code_completion_option(CodeCompletionKind p_type, const String &p_display_text, const String &p_insert_text, const Color &p_text_color = Color(1, 1, 1), const RES &p_icon = RES(), const Variant &p_value = Variant::NIL); + void add_code_completion_option(CodeCompletionKind p_type, const String &p_display_text, const String &p_insert_text, const Color &p_text_color = Color(1, 1, 1), const Ref<Resource> &p_icon = Ref<Resource>(), const Variant &p_value = Variant::NIL); void update_code_completion_options(bool p_forced = false); TypedArray<Dictionary> get_code_completion_options() const; diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 18b9eeebd4..f556fcdd23 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -125,7 +125,7 @@ private: VScrollBar *v_scroll = nullptr; float port_grab_distance_horizontal = 0.0; - float port_grab_distance_vertical; + float port_grab_distance_vertical = 0.0; Ref<ViewPanner> panner; bool warped_panning = true; @@ -142,7 +142,7 @@ private: bool connecting_target = false; Vector2 connecting_to; String connecting_target_to; - int connecting_target_index; + int connecting_target_index = 0; bool just_disconnected = false; bool connecting_valid = false; Vector2 click_pos; @@ -155,8 +155,9 @@ private: float zoom = 1.0; float zoom_step = 1.2; - float zoom_min; - float zoom_max; + // Proper values set in constructor. + float zoom_min = 0.0; + float zoom_max = 0.0; void _zoom_minus(); void _zoom_reset(); @@ -206,7 +207,7 @@ private: Array _get_connection_list() const; - bool lines_on_bg; + bool lines_on_bg = false; struct ConnType { union { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index f1c0260dd5..f549b3dde2 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2288,10 +2288,10 @@ Node *Node::duplicate(int p_flags) const { #ifdef TOOLS_ENABLED Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { - return duplicate_from_editor(r_duplimap, Map<RES, RES>()); + return duplicate_from_editor(r_duplimap, Map<Ref<Resource>, Ref<Resource>>()); } -Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const { +Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<Ref<Resource>, Ref<Resource>> &p_resource_remap) const { Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap); // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated. @@ -2307,7 +2307,7 @@ Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const M return dupe; } -void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const { +void Node::remap_node_resources(Node *p_node, const Map<Ref<Resource>, Ref<Resource>> &p_resource_remap) const { List<PropertyInfo> props; p_node->get_property_list(&props); @@ -2318,7 +2318,7 @@ void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_re Variant v = p_node->get(E.name); if (v.is_ref_counted()) { - RES res = v; + Ref<Resource> res = v; if (res.is_valid()) { if (p_resource_remap.has(res)) { p_node->set(E.name, p_resource_remap[res]); @@ -2333,7 +2333,7 @@ void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_re } } -void Node::remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const { +void Node::remap_nested_resources(Ref<Resource> p_resource, const Map<Ref<Resource>, Ref<Resource>> &p_resource_remap) const { List<PropertyInfo> props; p_resource->get_property_list(&props); @@ -2344,7 +2344,7 @@ void Node::remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resourc Variant v = p_resource->get(E.name); if (v.is_ref_counted()) { - RES res = v; + Ref<Resource> res = v; if (res.is_valid()) { if (p_resource_remap.has(res)) { p_resource->set(E.name, p_resource_remap[res]); @@ -2493,7 +2493,7 @@ bool Node::has_node_and_resource(const NodePath &p_path) const { if (!has_node(p_path)) { return false; } - RES res; + Ref<Resource> res; Vector<StringName> leftover_path; Node *node = get_node_and_resource(p_path, res, leftover_path, false); @@ -2501,7 +2501,7 @@ bool Node::has_node_and_resource(const NodePath &p_path) const { } Array Node::_get_node_and_resource(const NodePath &p_path) { - RES res; + Ref<Resource> res; Vector<StringName> leftover_path; Node *node = get_node_and_resource(p_path, res, leftover_path, false); Array result; @@ -2523,9 +2523,9 @@ Array Node::_get_node_and_resource(const NodePath &p_path) { return result; } -Node *Node::get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property) const { +Node *Node::get_node_and_resource(const NodePath &p_path, Ref<Resource> &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property) const { Node *node = get_node(p_path); - r_res = RES(); + r_res = Ref<Resource>(); r_leftover_subpath = Vector<StringName>(); if (!node) { return nullptr; @@ -2541,7 +2541,7 @@ Node *Node::get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<Str return nullptr; } - RES new_res = new_res_v; + Ref<Resource> new_res = new_res_v; if (new_res.is_null()) { // No longer a resource, assume property break; diff --git a/scene/main/node.h b/scene/main/node.h index fb84aabb62..72f340bbc3 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -313,7 +313,7 @@ public: Node *find_child(const String &p_pattern, bool p_recursive = true, bool p_owned = true) const; TypedArray<Node> find_children(const String &p_pattern, const String &p_type = "", bool p_recursive = true, bool p_owned = true) const; bool has_node_and_resource(const NodePath &p_path) const; - Node *get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const; + Node *get_node_and_resource(const NodePath &p_path, Ref<Resource> &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const; Node *get_parent() const; Node *find_parent(const String &p_pattern) const; @@ -421,9 +421,9 @@ public: Node *duplicate(int p_flags = DUPLICATE_GROUPS | DUPLICATE_SIGNALS | DUPLICATE_SCRIPTS) const; #ifdef TOOLS_ENABLED Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const; - Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const; - void remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const; - void remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const; + Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<Ref<Resource>, Ref<Resource>> &p_resource_remap) const; + void remap_node_resources(Node *p_node, const Map<Ref<Resource>, Ref<Resource>> &p_resource_remap) const; + void remap_nested_resources(Ref<Resource> p_resource, const Map<Ref<Resource>, Ref<Resource>> &p_resource_remap) const; #endif // used by editors, to save what has changed only diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp index 49010095ff..8fb7456335 100644 --- a/scene/main/resource_preloader.cpp +++ b/scene/main/resource_preloader.cpp @@ -41,7 +41,7 @@ void ResourcePreloader::_set_resources(const Array &p_data) { for (int i = 0; i < resdata.size(); i++) { String name = names[i]; - RES resource = resdata[i]; + Ref<Resource> resource = resdata[i]; ERR_CONTINUE(!resource.is_valid()); resources[name] = resource; @@ -57,7 +57,7 @@ Array ResourcePreloader::_get_resources() const { Set<String> sorted_names; - for (const KeyValue<StringName, RES> &E : resources) { + for (const KeyValue<StringName, Ref<Resource>> &E : resources) { sorted_names.insert(E.key); } @@ -74,7 +74,7 @@ Array ResourcePreloader::_get_resources() const { return res; } -void ResourcePreloader::add_resource(const StringName &p_name, const RES &p_resource) { +void ResourcePreloader::add_resource(const StringName &p_name, const Ref<Resource> &p_resource) { ERR_FAIL_COND(p_resource.is_null()); if (resources.has(p_name)) { StringName new_name; @@ -104,7 +104,7 @@ void ResourcePreloader::remove_resource(const StringName &p_name) { void ResourcePreloader::rename_resource(const StringName &p_from_name, const StringName &p_to_name) { ERR_FAIL_COND(!resources.has(p_from_name)); - RES res = resources[p_from_name]; + Ref<Resource> res = resources[p_from_name]; resources.erase(p_from_name); add_resource(p_to_name, res); @@ -114,8 +114,8 @@ bool ResourcePreloader::has_resource(const StringName &p_name) const { return resources.has(p_name); } -RES ResourcePreloader::get_resource(const StringName &p_name) const { - ERR_FAIL_COND_V(!resources.has(p_name), RES()); +Ref<Resource> ResourcePreloader::get_resource(const StringName &p_name) const { + ERR_FAIL_COND_V(!resources.has(p_name), Ref<Resource>()); return resources[p_name]; } @@ -123,7 +123,7 @@ Vector<String> ResourcePreloader::_get_resource_list() const { Vector<String> res; res.resize(resources.size()); int i = 0; - for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next(), i++) { + for (Map<StringName, Ref<Resource>>::Element *E = resources.front(); E; E = E->next(), i++) { res.set(i, E->key()); } @@ -131,7 +131,7 @@ Vector<String> ResourcePreloader::_get_resource_list() const { } void ResourcePreloader::get_resource_list(List<StringName> *p_list) { - for (const KeyValue<StringName, RES> &E : resources) { + for (const KeyValue<StringName, Ref<Resource>> &E : resources) { p_list->push_back(E.key); } } diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h index aabb109d56..2df8b5cda7 100644 --- a/scene/main/resource_preloader.h +++ b/scene/main/resource_preloader.h @@ -36,7 +36,7 @@ class ResourcePreloader : public Node { GDCLASS(ResourcePreloader, Node); - Map<StringName, RES> resources; + Map<StringName, Ref<Resource>> resources; void _set_resources(const Array &p_data); Array _get_resources() const; @@ -46,11 +46,11 @@ protected: static void _bind_methods(); public: - void add_resource(const StringName &p_name, const RES &p_resource); + void add_resource(const StringName &p_name, const Ref<Resource> &p_resource); void remove_resource(const StringName &p_name); void rename_resource(const StringName &p_from_name, const StringName &p_to_name); bool has_resource(const StringName &p_name) const; - RES get_resource(const StringName &p_name) const; + Ref<Resource> get_resource(const StringName &p_name) const; void get_resource_list(List<StringName> *p_list); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 82f18d1a42..a151d3cb33 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -981,12 +981,12 @@ bool SceneTree::has_group(const StringName &p_identifier) const { Node *SceneTree::get_first_node_in_group(const StringName &p_group) { Map<StringName, Group>::Element *E = group_map.find(p_group); if (!E) { - return nullptr; //no group + return nullptr; // No group. } - _update_group_order(E->get()); //update order just in case + _update_group_order(E->get()); // Update order just in case. - if (E->get().nodes.size() == 0) { + if (E->get().nodes.is_empty()) { return nullptr; } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 32882fbb68..c1e71c69a3 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -230,7 +230,6 @@ private: Rect2 last_vp_rect; bool transparent_bg = false; - bool filter; bool gen_mipmaps = false; bool snap_controls_to_pixels = true; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index e045a379d2..a26aa10f42 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -3455,7 +3455,7 @@ real_t Animation::bezier_track_interpolate(int p_track, double p_time) const { return low_pos.lerp(high_pos, c).y; } -int Animation::audio_track_insert_key(int p_track, double p_time, const RES &p_stream, real_t p_start_offset, real_t p_end_offset) { +int Animation::audio_track_insert_key(int p_track, double p_time, const Ref<Resource> &p_stream, real_t p_start_offset, real_t p_end_offset) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_AUDIO, -1); @@ -3481,7 +3481,7 @@ int Animation::audio_track_insert_key(int p_track, double p_time, const RES &p_s return key; } -void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_stream) { +void Animation::audio_track_set_key_stream(int p_track, int p_key, const Ref<Resource> &p_stream) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_AUDIO); @@ -3531,14 +3531,14 @@ void Animation::audio_track_set_key_end_offset(int p_track, int p_key, real_t p_ emit_changed(); } -RES Animation::audio_track_get_key_stream(int p_track, int p_key) const { - ERR_FAIL_INDEX_V(p_track, tracks.size(), RES()); +Ref<Resource> Animation::audio_track_get_key_stream(int p_track, int p_key) const { + ERR_FAIL_INDEX_V(p_track, tracks.size(), Ref<Resource>()); const Track *t = tracks[p_track]; - ERR_FAIL_COND_V(t->type != TYPE_AUDIO, RES()); + ERR_FAIL_COND_V(t->type != TYPE_AUDIO, Ref<Resource>()); const AudioTrack *at = static_cast<const AudioTrack *>(t); - ERR_FAIL_INDEX_V(p_key, at->values.size(), RES()); + ERR_FAIL_INDEX_V(p_key, at->values.size(), Ref<Resource>()); return at->values[p_key].value.stream; } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index f9a33da428..b4528ccd3a 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -180,7 +180,7 @@ private: /* AUDIO TRACK */ struct AudioKey { - RES stream; + Ref<Resource> stream; real_t start_offset = 0.0; //offset from start real_t end_offset = 0.0; //offset from end, if 0 then full length or infinite AudioKey() { @@ -436,11 +436,11 @@ public: real_t bezier_track_interpolate(int p_track, double p_time) const; - int audio_track_insert_key(int p_track, double p_time, const RES &p_stream, real_t p_start_offset = 0, real_t p_end_offset = 0); - void audio_track_set_key_stream(int p_track, int p_key, const RES &p_stream); + int audio_track_insert_key(int p_track, double p_time, const Ref<Resource> &p_stream, real_t p_start_offset = 0, real_t p_end_offset = 0); + void audio_track_set_key_stream(int p_track, int p_key, const Ref<Resource> &p_stream); void audio_track_set_key_start_offset(int p_track, int p_key, real_t p_offset); void audio_track_set_key_end_offset(int p_track, int p_key, real_t p_offset); - RES audio_track_get_key_stream(int p_track, int p_key) const; + Ref<Resource> audio_track_get_key_stream(int p_track, int p_key) const; real_t audio_track_get_key_start_offset(int p_track, int p_key) const; real_t audio_track_get_key_end_offset(int p_track, int p_key) const; diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h index e40e4392cb..b097d174f0 100644 --- a/scene/resources/canvas_item_material.h +++ b/scene/resources/canvas_item_material.h @@ -107,10 +107,10 @@ private: LightMode light_mode = LIGHT_MODE_NORMAL; bool particles_animation = false; - // Initialized in the constructor. - int particles_anim_h_frames; - int particles_anim_v_frames; - bool particles_anim_loop; + // Proper values set in constructor. + int particles_anim_h_frames = 0; + int particles_anim_v_frames = 0; + bool particles_anim_loop = false; protected: static void _bind_methods(); diff --git a/scene/resources/material.h b/scene/resources/material.h index 99e125f5b0..71150c2d23 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -449,36 +449,36 @@ private: bool orm; Color albedo; - float specular; - float metallic; - float roughness; + float specular = 0.0f; + float metallic = 0.0f; + float roughness = 0.0f; Color emission; - float emission_energy; - float normal_scale; - float rim; - float rim_tint; - float clearcoat; - float clearcoat_roughness; - float anisotropy; - float heightmap_scale; - float subsurface_scattering_strength; - float transmittance_amount; + float emission_energy = 0.0f; + float normal_scale = 0.0f; + float rim = 0.0f; + float rim_tint = 0.0f; + float clearcoat = 0.0f; + float clearcoat_roughness = 0.0f; + float anisotropy = 0.0f; + float heightmap_scale = 0.0f; + float subsurface_scattering_strength = 0.0f; + float transmittance_amount = 0.0f; Color transmittance_color; - float transmittance_depth; - float transmittance_boost; + float transmittance_depth = 0.0f; + float transmittance_boost = 0.0f; Color backlight; - float refraction; - float point_size; - float alpha_scissor_threshold; - float alpha_hash_scale; - float alpha_antialiasing_edge; + float refraction = 0.0f; + float point_size = 0.0f; + float alpha_scissor_threshold = 0.0f; + float alpha_hash_scale = 0.0f; + float alpha_antialiasing_edge = 0.0f; bool grow_enabled = false; - float ao_light_affect; - float grow; - int particles_anim_h_frames; - int particles_anim_v_frames; - bool particles_anim_loop; + float ao_light_affect = 0.0f; + float grow = 0.0f; + int particles_anim_h_frames = 0; + int particles_anim_v_frames = 0; + bool particles_anim_loop = false; Transparency transparency = TRANSPARENCY_DISABLED; ShadingMode shading_mode = SHADING_MODE_PER_PIXEL; @@ -486,29 +486,29 @@ private: Vector3 uv1_scale; Vector3 uv1_offset; - float uv1_triplanar_sharpness; + float uv1_triplanar_sharpness = 0.0f; Vector3 uv2_scale; Vector3 uv2_offset; - float uv2_triplanar_sharpness; + float uv2_triplanar_sharpness = 0.0f; DetailUV detail_uv = DETAIL_UV_1; bool deep_parallax = false; - int deep_parallax_min_layers; - int deep_parallax_max_layers; + int deep_parallax_min_layers = 0; + int deep_parallax_max_layers = 0; bool heightmap_parallax_flip_tangent = false; bool heightmap_parallax_flip_binormal = false; bool proximity_fade_enabled = false; - float proximity_fade_distance; + float proximity_fade_distance = 0.0f; float msdf_pixel_range = 4.f; float msdf_outline_size = 0.f; DistanceFadeMode distance_fade = DISTANCE_FADE_DISABLED; - float distance_fade_max_distance; - float distance_fade_min_distance; + float distance_fade_max_distance = 0.0f; + float distance_fade_min_distance = 0.0f; BlendMode blend_mode = BLEND_MODE_MIX; BlendMode detail_blend_mode = BLEND_MODE_MIX; diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 57da344ce0..4c3a3ba16c 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -230,8 +230,8 @@ private: bool is_initialized = false; Vector3 direction; - float spread; - float flatness; + float spread = 0.0f; + float flatness = 0.0f; float params_min[PARAM_MAX]; float params_max[PARAM_MAX]; @@ -244,34 +244,34 @@ private: bool particle_flags[PARTICLE_FLAG_MAX]; EmissionShape emission_shape; - float emission_sphere_radius; + float emission_sphere_radius = 0.0f; Vector3 emission_box_extents; Ref<Texture2D> emission_point_texture; Ref<Texture2D> emission_normal_texture; Ref<Texture2D> emission_color_texture; Vector3 emission_ring_axis; - real_t emission_ring_height; - real_t emission_ring_radius; - real_t emission_ring_inner_radius; + real_t emission_ring_height = 0.0f; + real_t emission_ring_radius = 0.0f; + real_t emission_ring_inner_radius = 0.0f; int emission_point_count = 1; - bool anim_loop; + bool anim_loop = false; Vector3 gravity; - double lifetime_randomness; + double lifetime_randomness = 0.0; SubEmitterMode sub_emitter_mode; - double sub_emitter_frequency; - int sub_emitter_amount_at_end; - bool sub_emitter_keep_velocity; + double sub_emitter_frequency = 0.0; + int sub_emitter_amount_at_end = 0; + bool sub_emitter_keep_velocity = false; //do not save emission points here - bool attractor_interaction_enabled; - bool collision_enabled; - bool collision_scale; - float collision_friction; - float collision_bounce; + bool attractor_interaction_enabled = false; + bool collision_enabled = false; + bool collision_scale = false; + float collision_friction = 0.0f; + float collision_bounce = 0.0f; protected: static void _bind_methods(); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 40edc5f198..c9a890194d 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -314,7 +314,7 @@ void CapsuleMesh::create_mesh_array(Array &p_arr, const float radius, const floa Vector3 p = Vector3(x * radius * w, y, -z * radius * w); points.push_back(p + Vector3(0.0, 0.5 * height - radius, 0.0)); normals.push_back(p.normalized()); - ADD_TANGENT(z, 0.0, x, 1.0) + ADD_TANGENT(-z, 0.0, -x, 1.0) uvs.push_back(Vector2(u, v * onethird)); point++; @@ -353,7 +353,7 @@ void CapsuleMesh::create_mesh_array(Array &p_arr, const float radius, const floa Vector3 p = Vector3(x * radius, y, -z * radius); points.push_back(p); normals.push_back(Vector3(x, 0.0, -z)); - ADD_TANGENT(z, 0.0, x, 1.0) + ADD_TANGENT(-z, 0.0, -x, 1.0) uvs.push_back(Vector2(u, onethird + (v * onethird))); point++; @@ -393,7 +393,7 @@ void CapsuleMesh::create_mesh_array(Array &p_arr, const float radius, const floa Vector3 p = Vector3(x * radius * w, y, -z * radius * w); points.push_back(p + Vector3(0.0, -0.5 * height + radius, 0.0)); normals.push_back(p.normalized()); - ADD_TANGENT(z, 0.0, x, 1.0) + ADD_TANGENT(-z, 0.0, -x, 1.0) uvs.push_back(Vector2(u2, twothirds + ((v - 1.0) * onethird))); point++; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index b18456d464..04a6ad7675 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -150,7 +150,7 @@ Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, R if (ext_resources[id].cache.is_valid()) { r_res = ext_resources[id].cache; } else if (use_sub_threads) { - RES res = ResourceLoader::load_threaded_get(path); + Ref<Resource> res = ResourceLoader::load_threaded_get(path); if (res.is_null()) { if (ResourceLoader::get_abort_on_missing_resources()) { error = ERR_FILE_MISSING_DEPENDENCIES; @@ -171,7 +171,7 @@ Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, R return error; } } else { - r_res = RES(); + r_res = Ref<Resource>(); } VariantParser::get_token(p_stream, token, line, r_err_str); @@ -460,7 +460,7 @@ Error ResourceLoaderText::load() { } } else { - RES res = ResourceLoader::load(path, type); + Ref<Resource> res = ResourceLoader::load(path, type); if (res.is_null()) { if (ResourceLoader::get_abort_on_missing_resources()) { @@ -890,7 +890,6 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String fw->store_8(c); c = f->get_8(); } - f.unref(); bool all_ok = fw->get_error() == OK; @@ -898,12 +897,6 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String return ERR_CANT_CREATE; } - fw.unref(); - - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - da->remove(p_path); - da->rename(p_path + ".depren", p_path); - return OK; } @@ -1334,7 +1327,7 @@ ResourceUID::ID ResourceLoaderText::get_uid(Ref<FileAccess> p_f) { ///////////////////// -RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -1343,7 +1336,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Cannot open file '" + p_path + "'."); ResourceLoaderText loader; String path = !p_original_path.is_empty() ? p_original_path : p_path; @@ -1360,7 +1353,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina if (err == OK) { return loader.get_resource(); } else { - return RES(); + return Ref<Resource>(); } } @@ -1370,9 +1363,12 @@ void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String & return; } - if (p_type == "PackedScene") { + if (ClassDB::is_parent_class("PackedScene", p_type)) { p_extensions->push_back("tscn"); - } else { + } + + // Don't allow .tres for PackedScenes. + if (p_type != "PackedScene") { p_extensions->push_back("tres"); } } @@ -1439,15 +1435,26 @@ void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<Strin } Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { - Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - if (f.is_null()) { - ERR_FAIL_V(ERR_CANT_OPEN); + Error err = OK; + { + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + if (f.is_null()) { + ERR_FAIL_V(ERR_CANT_OPEN); + } + + ResourceLoaderText loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + err = loader.rename_dependencies(f, p_path, p_map); } - ResourceLoaderText loader; - loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); - loader.res_path = loader.local_path; - return loader.rename_dependencies(f, p_path, p_map); + if (err == OK) { + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + da->remove(p_path); + da->rename(p_path + ".depren", p_path); + } + + return err; } ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = nullptr; @@ -1477,12 +1484,12 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, /*****************************************************************************************************/ /*****************************************************************************************************/ -String ResourceFormatSaverTextInstance::_write_resources(void *ud, const RES &p_resource) { +String ResourceFormatSaverTextInstance::_write_resources(void *ud, const Ref<Resource> &p_resource) { ResourceFormatSaverTextInstance *rsi = static_cast<ResourceFormatSaverTextInstance *>(ud); return rsi->_write_resource(p_resource); } -String ResourceFormatSaverTextInstance::_write_resource(const RES &res) { +String ResourceFormatSaverTextInstance::_write_resource(const Ref<Resource> &res) { if (external_resources.has(res)) { return "ExtResource( \"" + external_resources[res] + "\" )"; } else { @@ -1505,7 +1512,7 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) { void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, bool p_main) { switch (p_variant.get_type()) { case Variant::OBJECT: { - RES res = p_variant; + Ref<Resource> res = p_variant; if (res.is_null() || external_resources.has(res)) { return; @@ -1542,7 +1549,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, Variant v = res->get(I->get().name); if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { - RES sres = v; + Ref<Resource> sres = v; if (sres.is_valid()) { NonPersistentKey npk; npk.base = res; @@ -1586,7 +1593,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, } } -Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { if (p_path.ends_with(".tscn")) { packed_scene = p_resource; } @@ -1649,7 +1656,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r #ifdef TOOLS_ENABLED // Keep order from cached ids. Set<String> cached_ids_found; - for (KeyValue<RES, String> &E : external_resources) { + for (KeyValue<Ref<Resource>, String> &E : external_resources) { String cached_id = E.key->get_id_for_path(local_path); if (cached_id.is_empty() || cached_ids_found.has(cached_id)) { int sep_pos = E.value.find("_"); @@ -1665,7 +1672,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } } // Create IDs for non cached resources. - for (KeyValue<RES, String> &E : external_resources) { + for (KeyValue<Ref<Resource>, String> &E : external_resources) { if (cached_ids_found.has(E.value)) { // Already cached, go on. continue; } @@ -1687,14 +1694,14 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r #else // Make sure to start from one, as it makes format more readable. int counter = 1; - for (KeyValue<RES, String> &E : external_resources) { + for (KeyValue<Ref<Resource>, String> &E : external_resources) { E.value = itos(counter++); } #endif Vector<ResourceSort> sorted_er; - for (const KeyValue<RES, String> &E : external_resources) { + for (const KeyValue<Ref<Resource>, String> &E : external_resources) { ResourceSort rs; rs.resource = E.key; rs.id = E.value; @@ -1722,8 +1729,8 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r Set<String> used_unique_ids; - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { - RES res = E->get(); + for (List<Ref<Resource>>::Element *E = saved_resources.front(); E; E = E->next()) { + Ref<Resource> res = E->get(); if (E->next() && res->is_built_in()) { if (!res->get_scene_unique_id().is_empty()) { if (used_unique_ids.has(res->get_scene_unique_id())) { @@ -1735,8 +1742,8 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } } - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { - RES res = E->get(); + for (List<Ref<Resource>>::Element *E = saved_resources.front(); E; E = E->next()) { + Ref<Resource> res = E->get(); ERR_CONTINUE(!resource_set.has(res)); bool main = (E->next() == nullptr); @@ -1937,7 +1944,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r return OK; } -Error ResourceFormatSaverText::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverText::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { if (p_path.ends_with(".tscn") && !Ref<PackedScene>(p_resource).is_valid()) { return ERR_FILE_UNRECOGNIZED; } @@ -1946,11 +1953,11 @@ Error ResourceFormatSaverText::save(const String &p_path, const RES &p_resource, return saver.save(p_path, p_resource, p_flags); } -bool ResourceFormatSaverText::recognize(const RES &p_resource) const { +bool ResourceFormatSaverText::recognize(const Ref<Resource> &p_resource) const { return true; // All resources recognized! } -void ResourceFormatSaverText::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceFormatSaverText::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { if (Ref<PackedScene>(p_resource).is_valid()) { p_extensions->push_back("tscn"); // Text scene. } else { diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index c6543e616d..e67df72d7e 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -48,7 +48,7 @@ class ResourceLoaderText { VariantParser::StreamFile stream; struct ExtResource { - RES cache; + Ref<Resource> cache; String path; String type; }; @@ -59,7 +59,7 @@ class ResourceLoaderText { bool ignore_resource_parsing = false; Map<String, ExtResource> ext_resources; - Map<String, RES> int_resources; + Map<String, Ref<Resource>> int_resources; int resources_total = 0; int resource_current = 0; @@ -90,10 +90,10 @@ class ResourceLoaderText { }; struct DummyReadData { - Map<RES, int> external_resources; - Map<String, RES> rev_external_resources; - Map<RES, int> resource_index_map; - Map<String, RES> resource_map; + Map<Ref<Resource>, int> external_resources; + Map<String, Ref<Resource>> rev_external_resources; + Map<Ref<Resource>, int> resource_index_map; + Map<String, Ref<Resource>> resource_map; }; static Error _parse_sub_resource_dummys(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return _parse_sub_resource_dummy(static_cast<DummyReadData *>(p_self), p_stream, r_res, line, r_err_str); } @@ -108,7 +108,7 @@ class ResourceLoaderText { Error error = OK; - RES resource; + Ref<Resource> resource; Ref<PackedScene> _parse_node_tag(VariantParser::ResourceParser &parser); @@ -133,7 +133,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: static ResourceFormatLoaderText *singleton; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; @@ -158,20 +158,20 @@ class ResourceFormatSaverTextInstance { bool skip_editor = false; struct NonPersistentKey { //for resource properties generated on the fly - RES base; + Ref<Resource> base; StringName property; bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; } }; - Map<NonPersistentKey, RES> non_persistent_map; + Map<NonPersistentKey, Ref<Resource>> non_persistent_map; - Set<RES> resource_set; - List<RES> saved_resources; - Map<RES, String> external_resources; - Map<RES, String> internal_resources; + Set<Ref<Resource>> resource_set; + List<Ref<Resource>> saved_resources; + Map<Ref<Resource>, String> external_resources; + Map<Ref<Resource>, String> internal_resources; struct ResourceSort { - RES resource; + Ref<Resource> resource; String id; bool operator<(const ResourceSort &p_right) const { return id.naturalnocasecmp_to(p_right.id) < 0; @@ -180,19 +180,19 @@ class ResourceFormatSaverTextInstance { void _find_resources(const Variant &p_variant, bool p_main = false); - static String _write_resources(void *ud, const RES &p_resource); - String _write_resource(const RES &res); + static String _write_resources(void *ud, const Ref<Resource> &p_resource); + String _write_resource(const Ref<Resource> &res); public: - Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); + Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); }; class ResourceFormatSaverText : public ResourceFormatSaver { public: static ResourceFormatSaverText *singleton; - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual bool recognize(const RES &p_resource) const; - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual bool recognize(const Ref<Resource> &p_resource) const; + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; ResourceFormatSaverText(); }; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 25a9278e66..6b1f89454f 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -172,7 +172,7 @@ Shader::~Shader() { //////////// -RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -210,7 +210,7 @@ String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const return ""; } -Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverShader::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { Ref<Shader> shader = p_resource; ERR_FAIL_COND_V(shader.is_null(), ERR_INVALID_PARAMETER); @@ -229,7 +229,7 @@ Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resourc return OK; } -void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { +void ResourceFormatSaverShader::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { if (const Shader *shader = Object::cast_to<Shader>(*p_resource)) { if (shader->is_text_shader()) { p_extensions->push_back("gdshader"); @@ -237,6 +237,6 @@ void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, } } -bool ResourceFormatSaverShader::recognize(const RES &p_resource) const { +bool ResourceFormatSaverShader::recognize(const Ref<Resource> &p_resource) const { return p_resource->get_class_name() == "Shader"; //only shader, not inherited } diff --git a/scene/resources/shader.h b/scene/resources/shader.h index d05ec06819..3212dcd287 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -103,7 +103,7 @@ VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -111,9 +111,9 @@ public: class ResourceFormatSaverShader : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; - virtual bool recognize(const RES &p_resource) const; + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; + virtual bool recognize(const Ref<Resource> &p_resource) const; }; #endif // SHADER_H diff --git a/scene/resources/skeleton_modification_2d_physicalbones.h b/scene/resources/skeleton_modification_2d_physicalbones.h index d53102fa5e..373ff666ee 100644 --- a/scene/resources/skeleton_modification_2d_physicalbones.h +++ b/scene/resources/skeleton_modification_2d_physicalbones.h @@ -52,7 +52,7 @@ private: bool _simulation_state_dirty = false; TypedArray<StringName> _simulation_state_dirty_names; - bool _simulation_state_dirty_process; + bool _simulation_state_dirty_process = false; void _update_simulation_state(); protected: diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 4681d3d6e3..7874d77298 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -144,6 +144,15 @@ float ProceduralSkyMaterial::get_sun_curve() const { return sun_curve; } +void ProceduralSkyMaterial::set_dither_strength(float p_dither_strength) { + dither_strength = p_dither_strength; + RS::get_singleton()->material_set_param(_get_material(), "dither_strength", dither_strength); +} + +float ProceduralSkyMaterial::get_dither_strength() const { + return dither_strength; +} + Shader::Mode ProceduralSkyMaterial::get_shader_mode() const { return Shader::MODE_SKY; } @@ -199,6 +208,9 @@ void ProceduralSkyMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSkyMaterial::set_sun_curve); ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSkyMaterial::get_sun_curve); + ClassDB::bind_method(D_METHOD("set_dither_strength", "strength"), &ProceduralSkyMaterial::set_dither_strength); + ClassDB::bind_method(D_METHOD("get_dither_strength"), &ProceduralSkyMaterial::get_dither_strength); + ADD_GROUP("Sky", "sky_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_sky_top_color", "get_sky_top_color"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_sky_horizon_color", "get_sky_horizon_color"); @@ -216,6 +228,9 @@ void ProceduralSkyMaterial::_bind_methods() { ADD_GROUP("Sun", "sun_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve"); + + ADD_GROUP("", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dither_strength", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_dither_strength", "get_dither_strength"); } void ProceduralSkyMaterial::cleanup_shader() { @@ -247,6 +262,14 @@ uniform float ground_curve : hint_range(0, 1) = 0.02; uniform float ground_energy = 1.0; uniform float sun_angle_max = 30.0; uniform float sun_curve : hint_range(0, 1) = 0.15; +uniform float dither_strength : hint_range(0, 10) = 1.0; + +// From: https://www.shadertoy.com/view/4sfGzS credit to iq +float hash(vec3 p) { + p = fract( p * 0.3183099 + 0.1 ); + p *= 17.0; + return fract(p.x * p.y * p.z * (p.x + p.y + p.z)); +} void sky() { float v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0)); @@ -302,6 +325,9 @@ void sky() { ground *= ground_energy; COLOR = mix(ground, sky, step(0.0, EYEDIR.y)); + + // Make optional, eliminates banding. + COLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength; } )"); } @@ -322,6 +348,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { set_sun_angle_max(30.0); set_sun_curve(0.15); + set_dither_strength(1.0); } ProceduralSkyMaterial::~ProceduralSkyMaterial() { diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 5c791a185a..8163a42519 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -40,18 +40,19 @@ class ProceduralSkyMaterial : public Material { private: Color sky_top_color; Color sky_horizon_color; - float sky_curve; - float sky_energy; + float sky_curve = 0.0f; + float sky_energy = 0.0f; Ref<Texture2D> sky_cover; Color sky_cover_modulate; Color ground_bottom_color; Color ground_horizon_color; - float ground_curve; - float ground_energy; + float ground_curve = 0.0f; + float ground_energy = 0.0f; - float sun_angle_max; - float sun_curve; + float sun_angle_max = 0.0f; + float sun_curve = 0.0f; + float dither_strength = 0.0f; static Mutex shader_mutex; static RID shader; @@ -98,6 +99,9 @@ public: void set_sun_curve(float p_curve); float get_sun_curve() const; + void set_dither_strength(float p_dither_strength); + float get_dither_strength() const; + virtual Shader::Mode get_shader_mode() const override; virtual RID get_shader_rid() const override; virtual RID get_rid() const override; @@ -154,16 +158,16 @@ private: static Mutex shader_mutex; static RID shader; - float rayleigh; + float rayleigh = 0.0f; Color rayleigh_color; - float mie; - float mie_eccentricity; + float mie = 0.0f; + float mie_eccentricity = 0.0f; Color mie_color; - float turbidity; - float sun_disk_scale; + float turbidity = 0.0f; + float sun_disk_scale = 0.0f; Color ground_color; - float exposure; - float dither_strength; + float exposure = 0.0f; + float dither_strength = 0.0f; Ref<Texture2D> night_sky; static void _update_shader(); mutable bool shader_set = false; diff --git a/scene/resources/sphere_shape_3d.h b/scene/resources/sphere_shape_3d.h index ff6d883940..20887dd092 100644 --- a/scene/resources/sphere_shape_3d.h +++ b/scene/resources/sphere_shape_3d.h @@ -35,7 +35,7 @@ class SphereShape3D : public Shape3D { GDCLASS(SphereShape3D, Shape3D); - float radius; + float radius = 1.0f; protected: static void _bind_methods(); diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index ece126791e..ff5a85392c 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -195,7 +195,7 @@ void SpriteFrames::_set_animations(const Array &p_animations) { anim.loop = d["loop"]; Array frames = d["frames"]; for (int j = 0; j < frames.size(); j++) { - RES res = frames[j]; + Ref<Resource> res = frames[j]; anim.frames.push_back(res); } diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 24ba4d2651..72a4324b68 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1058,7 +1058,7 @@ CompressedTexture2D::~CompressedTexture2D() { } } -RES ResourceFormatLoaderCompressedTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderCompressedTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<CompressedTexture2D> st; st.instantiate(); Error err = st->load(p_path); @@ -1066,7 +1066,7 @@ RES ResourceFormatLoaderCompressedTexture2D::load(const String &p_path, const St *r_error = err; } if (err != OK) { - return RES(); + return Ref<Resource>(); } return st; @@ -1416,7 +1416,7 @@ CompressedTexture3D::~CompressedTexture3D() { ///////////////////////////// -RES ResourceFormatLoaderCompressedTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderCompressedTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<CompressedTexture3D> st; st.instantiate(); Error err = st->load(p_path); @@ -1424,7 +1424,7 @@ RES ResourceFormatLoaderCompressedTexture3D::load(const String &p_path, const St *r_error = err; } if (err != OK) { - return RES(); + return Ref<Resource>(); } return st; @@ -3243,7 +3243,7 @@ CompressedTextureLayered::~CompressedTextureLayered() { ///////////////////////////////////////////////// -RES ResourceFormatLoaderCompressedTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { +Ref<Resource> ResourceFormatLoaderCompressedTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<CompressedTextureLayered> ct; if (p_path.get_extension().to_lower() == "ctexarray") { Ref<CompressedTexture2DArray> c; @@ -3261,14 +3261,14 @@ RES ResourceFormatLoaderCompressedTextureLayered::load(const String &p_path, con if (r_error) { *r_error = ERR_FILE_UNRECOGNIZED; } - return RES(); + return Ref<Resource>(); } Error err = ct->load(p_path); if (r_error) { *r_error = err; } if (err != OK) { - return RES(); + return Ref<Resource>(); } return ct; diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 525e3ff979..4107bd9abb 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -287,7 +287,7 @@ public: class ResourceFormatLoaderCompressedTexture2D : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -552,7 +552,7 @@ public: class ResourceFormatLoaderCompressedTextureLayered : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -673,7 +673,7 @@ public: class ResourceFormatLoaderCompressedTexture3D : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 373fbb94ea..be54c309c8 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -261,6 +261,27 @@ int Theme::get_fallback_font_size() { return fallback_font_size; } +bool Theme::is_valid_type_name(const String &p_name) { + for (int i = 0; i < p_name.length(); i++) { + if (!is_ascii_identifier_char(p_name[i])) { + return false; + } + } + return true; +} + +bool Theme::is_valid_item_name(const String &p_name) { + if (p_name.is_empty()) { + return false; + } + for (int i = 0; i < p_name.length(); i++) { + if (!is_ascii_identifier_char(p_name[i])) { + return false; + } + } + return true; +} + // Fallback values for theme item types, configurable per theme. void Theme::set_default_base_scale(float p_base_scale) { if (default_base_scale == p_base_scale) { @@ -326,6 +347,9 @@ bool Theme::has_default_font_size() const { // Icons. void Theme::set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = false; if (icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) { existing = true; @@ -358,6 +382,8 @@ bool Theme::has_icon_nocheck(const StringName &p_name, const StringName &p_theme } void Theme::rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!icon_map.has(p_theme_type), "Cannot rename the icon '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(icon_map[p_theme_type].has(p_name), "Cannot rename the icon '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!icon_map[p_theme_type].has(p_old_name), "Cannot rename the icon '" + String(p_old_name) + "' because it does not exist."); @@ -396,6 +422,8 @@ void Theme::get_icon_list(StringName p_theme_type, List<StringName> *p_list) con } void Theme::add_icon_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (icon_map.has(p_theme_type)) { return; } @@ -433,6 +461,9 @@ void Theme::get_icon_type_list(List<StringName> *p_list) const { // Styleboxes. void Theme::set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = false; if (style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) { existing = true; @@ -465,6 +496,8 @@ bool Theme::has_stylebox_nocheck(const StringName &p_name, const StringName &p_t } void Theme::rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!style_map.has(p_theme_type), "Cannot rename the stylebox '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(style_map[p_theme_type].has(p_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!style_map[p_theme_type].has(p_old_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because it does not exist."); @@ -503,6 +536,8 @@ void Theme::get_stylebox_list(StringName p_theme_type, List<StringName> *p_list) } void Theme::add_stylebox_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (style_map.has(p_theme_type)) { return; } @@ -540,6 +575,9 @@ void Theme::get_stylebox_type_list(List<StringName> *p_list) const { // Fonts. void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = false; if (font_map[p_theme_type][p_name].is_valid()) { existing = true; @@ -574,6 +612,8 @@ bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme } void Theme::rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!font_map.has(p_theme_type), "Cannot rename the font '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(font_map[p_theme_type].has(p_name), "Cannot rename the font '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!font_map[p_theme_type].has(p_old_name), "Cannot rename the font '" + String(p_old_name) + "' because it does not exist."); @@ -612,6 +652,8 @@ void Theme::get_font_list(StringName p_theme_type, List<StringName> *p_list) con } void Theme::add_font_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (font_map.has(p_theme_type)) { return; } @@ -649,6 +691,9 @@ void Theme::get_font_type_list(List<StringName> *p_list) const { // Font sizes. void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = has_font_size_nocheck(p_name, p_theme_type); font_size_map[p_theme_type][p_name] = p_font_size; @@ -674,6 +719,8 @@ bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_ } void Theme::rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!font_size_map.has(p_theme_type), "Cannot rename the font size '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(font_size_map[p_theme_type].has(p_name), "Cannot rename the font size '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!font_size_map[p_theme_type].has(p_old_name), "Cannot rename the font size '" + String(p_old_name) + "' because it does not exist."); @@ -708,6 +755,8 @@ void Theme::get_font_size_list(StringName p_theme_type, List<StringName> *p_list } void Theme::add_font_size_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (font_size_map.has(p_theme_type)) { return; } @@ -733,6 +782,9 @@ void Theme::get_font_size_type_list(List<StringName> *p_list) const { // Colors. void Theme::set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = has_color_nocheck(p_name, p_theme_type); color_map[p_theme_type][p_name] = p_color; @@ -756,6 +808,8 @@ bool Theme::has_color_nocheck(const StringName &p_name, const StringName &p_them } void Theme::rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!color_map.has(p_theme_type), "Cannot rename the color '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(color_map[p_theme_type].has(p_name), "Cannot rename the color '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!color_map[p_theme_type].has(p_old_name), "Cannot rename the color '" + String(p_old_name) + "' because it does not exist."); @@ -790,6 +844,8 @@ void Theme::get_color_list(StringName p_theme_type, List<StringName> *p_list) co } void Theme::add_color_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (color_map.has(p_theme_type)) { return; } @@ -815,6 +871,9 @@ void Theme::get_color_type_list(List<StringName> *p_list) const { // Theme constants. void Theme::set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = has_constant_nocheck(p_name, p_theme_type); constant_map[p_theme_type][p_name] = p_constant; @@ -838,6 +897,8 @@ bool Theme::has_constant_nocheck(const StringName &p_name, const StringName &p_t } void Theme::rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!constant_map.has(p_theme_type), "Cannot rename the constant '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(constant_map[p_theme_type].has(p_name), "Cannot rename the constant '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!constant_map[p_theme_type].has(p_old_name), "Cannot rename the constant '" + String(p_old_name) + "' because it does not exist."); @@ -872,6 +933,8 @@ void Theme::get_constant_list(StringName p_theme_type, List<StringName> *p_list) } void Theme::add_constant_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (constant_map.has(p_theme_type)) { return; } @@ -1154,6 +1217,8 @@ void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_l // Theme type variations. void Theme::set_type_variation(const StringName &p_theme_type, const StringName &p_base_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_base_type), vformat("Invalid type name: '%s'", p_base_type)); ERR_FAIL_COND_MSG(p_theme_type == StringName(), "An empty theme type cannot be marked as a variation of another type."); ERR_FAIL_COND_MSG(ClassDB::class_exists(p_theme_type), "A type associated with a built-in class cannot be marked as a variation of another type."); ERR_FAIL_COND_MSG(p_base_type == StringName(), "An empty theme type cannot be the base type of a variation. Use clear_type_variation() instead if you want to unmark '" + String(p_theme_type) + "' as a variation."); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 9afe05007d..f8f1e95634 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -137,6 +137,9 @@ public: static Ref<Font> get_fallback_font(); static int get_fallback_font_size(); + static bool is_valid_type_name(const String &p_name); + static bool is_valid_item_name(const String &p_name); + void set_default_base_scale(float p_base_scale); float get_default_base_scale() const; bool has_default_base_scale() const; diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp index 082931647a..003275f302 100644 --- a/servers/audio/audio_filter_sw.cpp +++ b/servers/audio/audio_filter_sw.cpp @@ -211,15 +211,6 @@ float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) { return H; } -AudioFilterSW::AudioFilterSW() { - sampling_rate = 44100; - resonance = 0.5; - cutoff = 5000; - gain = 1.0; - mode = LOWPASS; - stages = 1; -} - AudioFilterSW::Processor::Processor() { set_filter(nullptr); } diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h index 1ec1abd4d5..e3f8188997 100644 --- a/servers/audio/audio_filter_sw.h +++ b/servers/audio/audio_filter_sw.h @@ -36,11 +36,11 @@ class AudioFilterSW { public: struct Coeffs { - float a1, a2; - float b0, b1, b2; - - //bool operator==(const Coeffs &p_rv) { return (FLOATS_EQ(a1,p_rv.a1) && FLOATS_EQ(a2,p_rv.a2) && FLOATS_EQ(b1,p_rv.b1) && FLOATS_EQ(b2,p_rv.b2) && FLOATS_EQ(b0,p_rv.b0) ); } - Coeffs() { a1 = a2 = b0 = b1 = b2 = 0.0; } + float a1 = 0.0f; + float a2 = 0.0f; + float b0 = 0.0f; + float b1 = 0.0f; + float b2 = 0.0f; }; enum Mode { @@ -52,14 +52,16 @@ public: BANDLIMIT, LOWSHELF, HIGHSHELF - }; - class Processor { // simple filter processor - + class Processor { // Simple filter processor. AudioFilterSW *filter = nullptr; Coeffs coeffs; - float ha1, ha2, hb1, hb2; //history + // History. + float ha1 = 0.0f; + float ha2 = 0.0f; + float hb1 = 0.0f; + float hb2 = 0.0f; Coeffs incr_coeffs; public: @@ -73,12 +75,12 @@ public: }; private: - float cutoff; - float resonance; - float gain; - float sampling_rate; - int stages; - Mode mode; + float cutoff = 5000.0f; + float resonance = 0.5f; + float gain = 1.0f; + float sampling_rate = 44100.0f; + int stages = 1; + Mode mode = LOWPASS; public: float get_response(float p_freq, Coeffs *p_coeffs); @@ -92,7 +94,7 @@ public: void prepare_coefficients(Coeffs *p_coeffs); - AudioFilterSW(); + AudioFilterSW() {} }; /* inline methods */ diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 1ebd57fa7f..9a9b9815ae 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -709,10 +709,7 @@ void AudioStreamRandomizer::_bind_methods() { BIND_ENUM_CONSTANT(PLAYBACK_SEQUENTIAL); } -AudioStreamRandomizer::AudioStreamRandomizer() { - random_pitch_scale = 1.1; - random_volume_offset_db = 5; -} +AudioStreamRandomizer::AudioStreamRandomizer() {} void AudioStreamPlaybackRandomizer::start(float p_from_pos) { playing = playback; diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 55031dec2c..9800707849 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -78,7 +78,7 @@ class AudioStreamPlaybackResampled : public AudioStreamPlayback { AudioFrame internal_buffer[INTERNAL_BUFFER_LEN + CUBIC_INTERP_HISTORY]; unsigned int internal_buffer_end = -1; - uint64_t mix_offset; + uint64_t mix_offset = 0; protected: void begin_resample(); @@ -145,8 +145,8 @@ class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled { GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlaybackResampled); friend class AudioStreamMicrophone; - bool active; - unsigned int input_ofs; + bool active = false; + unsigned int input_ofs = 0; Ref<AudioStreamMicrophone> microphone; @@ -194,8 +194,8 @@ private: Set<AudioStreamPlaybackRandomizer *> playbacks; Vector<PoolEntry> audio_stream_pool; - float random_pitch_scale; - float random_volume_offset_db; + float random_pitch_scale = 1.1f; + float random_volume_offset_db = 5.0f; Ref<AudioStreamPlayback> instance_playback_random(); Ref<AudioStreamPlayback> instance_playback_no_repeats(); diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp index c81efc55e2..7bb62bcbed 100644 --- a/servers/audio/effects/audio_effect_stereo_enhance.cpp +++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp @@ -29,7 +29,9 @@ /*************************************************************************/ #include "audio_effect_stereo_enhance.h" + #include "servers/audio_server.h" + void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { float intensity = base->pan_pullout; bool surround_mode = base->surround > 0; @@ -140,8 +142,4 @@ void AudioEffectStereoEnhance::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "surround", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_surround", "get_surround"); } -AudioEffectStereoEnhance::AudioEffectStereoEnhance() { - pan_pullout = 1; - time_pullout = 0; - surround = 0; -} +AudioEffectStereoEnhance::AudioEffectStereoEnhance() {} diff --git a/servers/audio/effects/audio_effect_stereo_enhance.h b/servers/audio/effects/audio_effect_stereo_enhance.h index 1f93d1cf9f..30ea11f625 100644 --- a/servers/audio/effects/audio_effect_stereo_enhance.h +++ b/servers/audio/effects/audio_effect_stereo_enhance.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTSTEREOENHANCE_H -#define AUDIOEFFECTSTEREOENHANCE_H +#ifndef AUDIO_EFFECT_STEREO_ENHANCE_H +#define AUDIO_EFFECT_STEREO_ENHANCE_H #include "servers/audio/audio_effect.h" @@ -45,8 +45,8 @@ class AudioEffectStereoEnhanceInstance : public AudioEffectInstance { }; float *delay_ringbuff = nullptr; - unsigned int ringbuff_pos; - unsigned int ringbuff_mask; + unsigned int ringbuff_pos = 0; + unsigned int ringbuff_mask = 0; public: virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) override; @@ -58,11 +58,11 @@ class AudioEffectStereoEnhance : public AudioEffect { GDCLASS(AudioEffectStereoEnhance, AudioEffect); friend class AudioEffectStereoEnhanceInstance; - float volume_db; + float volume_db = 0.0f; - float pan_pullout; - float time_pullout; - float surround; + float pan_pullout = 1.0f; + float time_pullout = 0.0f; + float surround = 0.0f; protected: static void _bind_methods(); @@ -82,4 +82,4 @@ public: AudioEffectStereoEnhance(); }; -#endif // AUDIOEFFECTSTEREOENHANCE_H +#endif // AUDIO_EFFECT_STEREO_ENHANCE_H diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp index 4b5b9ab79f..adfd648514 100644 --- a/servers/audio/effects/reverb.cpp +++ b/servers/audio/effects/reverb.cpp @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2006 - #include "reverb.h" #include "core/math/math_funcs.h" diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h index de25e8c52b..c9602c5b5a 100644 --- a/servers/audio/effects/reverb.h +++ b/servers/audio/effects/reverb.h @@ -77,10 +77,11 @@ private: AllPass allpass[MAX_ALLPASS]; float *input_buffer = nullptr; float *echo_buffer = nullptr; - int echo_buffer_size; - int echo_buffer_pos; + int echo_buffer_size = 0; + int echo_buffer_pos = 0; - float hpf_h1, hpf_h2 = 0; + float hpf_h1 = 0.0f; + float hpf_h2 = 0.0f; struct Parameters { float room_size; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 777bebcf60..c8f48207e4 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -164,17 +164,6 @@ Array AudioDriver::capture_get_device_list() { return list; } -AudioDriver::AudioDriver() { - _last_mix_time = 0; - _last_mix_frames = 0; - input_position = 0; - input_size = 0; - -#ifdef DEBUG_ENABLED - prof_time = 0; -#endif -} - AudioDriverDummy AudioDriverManager::dummy_driver; AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS] = { &AudioDriverManager::dummy_driver, @@ -1748,15 +1737,6 @@ void AudioServer::_bind_methods() { AudioServer::AudioServer() { singleton = this; - mix_frames = 0; - channel_count = 0; - to_mix = 0; -#ifdef DEBUG_ENABLED - prof_time = 0; -#endif - mix_time = 0; - mix_size = 0; - playback_speed_scale = 1; } AudioServer::~AudioServer() { diff --git a/servers/audio_server.h b/servers/audio_server.h index 5563d60e4a..3d8755071a 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -48,18 +48,18 @@ class AudioStreamPlayback; class AudioDriver { static AudioDriver *singleton; - uint64_t _last_mix_time; - uint64_t _last_mix_frames; + uint64_t _last_mix_time = 0; + uint64_t _last_mix_frames = 0; #ifdef DEBUG_ENABLED - uint64_t prof_ticks; - uint64_t prof_time; + uint64_t prof_ticks = 0; + uint64_t prof_time = 0; #endif protected: Vector<int32_t> input_buffer; - unsigned int input_position; - unsigned int input_size; + unsigned int input_position = 0; + unsigned int input_size = 0; void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true); void update_mix_time(int p_frames); @@ -121,7 +121,7 @@ public: void reset_profiling_time() { prof_time = 0; } #endif - AudioDriver(); + AudioDriver() {} virtual ~AudioDriver() {} }; @@ -169,66 +169,61 @@ public: typedef void (*AudioCallback)(void *p_userdata); private: - uint64_t mix_time; - int mix_size; + uint64_t mix_time = 0; + int mix_size = 0; - uint32_t buffer_size; - uint64_t mix_count; - uint64_t mix_frames; + uint32_t buffer_size = 0; + uint64_t mix_count = 0; + uint64_t mix_frames = 0; #ifdef DEBUG_ENABLED - uint64_t prof_time; + uint64_t prof_time = 0; #endif - float channel_disable_threshold_db; - uint32_t channel_disable_frames; + float channel_disable_threshold_db = 0.0f; + uint32_t channel_disable_frames = 0; - int channel_count; - int to_mix; + int channel_count = 0; + int to_mix = 0; - float playback_speed_scale; + float playback_speed_scale = 1.0f; struct Bus { StringName name; - bool solo; - bool mute; - bool bypass; + bool solo = false; + bool mute = false; + bool bypass = false; - bool soloed; + bool soloed = false; - //Each channel is a stereo pair. + // Each channel is a stereo pair. struct Channel { - bool used; - bool active; - AudioFrame peak_volume; + bool used = false; + bool active = false; + AudioFrame peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB); Vector<AudioFrame> buffer; Vector<Ref<AudioEffectInstance>> effect_instances; - uint64_t last_mix_with_audio; - Channel() { - last_mix_with_audio = 0; - used = false; - active = false; - peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB); - } + uint64_t last_mix_with_audio = 0; + Channel() {} }; Vector<Channel> channels; struct Effect { Ref<AudioEffect> effect; - bool enabled; + bool enabled = false; #ifdef DEBUG_ENABLED - uint64_t prof_time; + uint64_t prof_time = 0; #endif }; Vector<Effect> effects; - float volume_db; + float volume_db = 0.0f; StringName send; - int index_cache; + int index_cache = 0; }; struct AudioStreamPlaybackBusDetails { - bool bus_active[MAX_BUSES_PER_PLAYBACK] = { false, false, false, false, false, false }; + bool bus_active[MAX_BUSES_PER_PLAYBACK] = {}; StringName bus[MAX_BUSES_PER_PLAYBACK]; AudioFrame volume[MAX_BUSES_PER_PLAYBACK][MAX_CHANNELS_PER_BUS]; }; @@ -312,7 +307,7 @@ public: ERR_FAIL_V(1); } - //do not use from outside audio thread + // Do not use from outside audio thread. bool thread_has_channel_mix_buffer(int p_bus, int p_buffer) const; AudioFrame *thread_get_channel_mix_buffer(int p_bus, int p_buffer); int thread_get_mix_buffer_size() const; @@ -442,26 +437,21 @@ class AudioBusLayout : public Resource { struct Bus { StringName name; - bool solo; - bool mute; - bool bypass; + bool solo = false; + bool mute = false; + bool bypass = false; struct Effect { Ref<AudioEffect> effect; - bool enabled; + bool enabled = false; }; Vector<Effect> effects; - float volume_db; + float volume_db = 0.0f; StringName send; - Bus() { - solo = false; - mute = false; - bypass = false; - volume_db = 0; - } + Bus() {} }; Vector<Bus> buses; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 8d97cd2543..59f88844e9 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -421,7 +421,7 @@ DisplayServer::CursorShape DisplayServer::cursor_get_shape() const { return CURSOR_ARROW; } -void DisplayServer::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void DisplayServer::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { WARN_PRINT("Custom cursor shape not supported by this display server."); } @@ -579,6 +579,9 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("clipboard_set_primary", "clipboard_primary"), &DisplayServer::clipboard_set_primary); ClassDB::bind_method(D_METHOD("clipboard_get_primary"), &DisplayServer::clipboard_get_primary); + ClassDB::bind_method(D_METHOD("get_display_cutouts"), &DisplayServer::get_display_cutouts); + ClassDB::bind_method(D_METHOD("get_display_safe_area"), &DisplayServer::get_display_safe_area); + ClassDB::bind_method(D_METHOD("get_screen_count"), &DisplayServer::get_screen_count); ClassDB::bind_method(D_METHOD("screen_get_position", "screen"), &DisplayServer::screen_get_position, DEFVAL(SCREEN_OF_MAIN_WINDOW)); ClassDB::bind_method(D_METHOD("screen_get_size", "screen"), &DisplayServer::screen_get_size, DEFVAL(SCREEN_OF_MAIN_WINDOW)); @@ -830,7 +833,7 @@ Input::CursorShape DisplayServer::_input_get_current_cursor_shape() { return (Input::CursorShape)singleton->cursor_get_shape(); } -void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, Input::CursorShape p_shape, const Vector2 &p_hostspot) { +void DisplayServer::_input_set_custom_mouse_cursor_func(const Ref<Resource> &p_image, Input::CursorShape p_shape, const Vector2 &p_hostspot) { singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot); } diff --git a/servers/display_server.h b/servers/display_server.h index 19efcbd3dd..7a15df2f92 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -80,7 +80,7 @@ private: static Input::MouseMode _input_get_mouse_mode(); static void _input_warp(const Vector2 &p_to_pos); static Input::CursorShape _input_get_current_cursor_shape(); - static void _input_set_custom_mouse_cursor_func(const RES &, Input::CursorShape, const Vector2 &p_hostspot); + static void _input_set_custom_mouse_cursor_func(const Ref<Resource> &, Input::CursorShape, const Vector2 &p_hostspot); protected: static void _bind_methods(); @@ -228,6 +228,9 @@ public: virtual void clipboard_set_primary(const String &p_text); virtual String clipboard_get_primary() const; + virtual Array get_display_cutouts() const { return Array(); } + virtual Rect2i get_display_safe_area() const { return screen_get_usable_rect(); } + enum { SCREEN_OF_MAIN_WINDOW = -1 }; @@ -407,7 +410,7 @@ public: }; virtual void cursor_set_shape(CursorShape p_shape); virtual CursorShape cursor_get_shape() const; - virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()); + virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()); virtual bool get_swap_cancel_ok(); diff --git a/servers/physics_2d/godot_collision_solver_2d.cpp b/servers/physics_2d/godot_collision_solver_2d.cpp index 9f83cea858..0d7b42b80d 100644 --- a/servers/physics_2d/godot_collision_solver_2d.cpp +++ b/servers/physics_2d/godot_collision_solver_2d.cpp @@ -140,7 +140,7 @@ struct _ConcaveCollisionInfo2D { Vector2 motion_B; real_t margin_A = 0.0; real_t margin_B = 0.0; - GodotCollisionSolver2D::CallbackResult result_callback; + GodotCollisionSolver2D::CallbackResult result_callback = nullptr; void *userdata = nullptr; bool swap_result = false; bool collided = false; diff --git a/servers/physics_2d/godot_collision_solver_2d_sat.cpp b/servers/physics_2d/godot_collision_solver_2d_sat.cpp index 414967a052..77186d3810 100644 --- a/servers/physics_2d/godot_collision_solver_2d_sat.cpp +++ b/servers/physics_2d/godot_collision_solver_2d_sat.cpp @@ -33,7 +33,7 @@ #include "core/math/geometry_2d.h" struct _CollectorCallback2D { - GodotCollisionSolver2D::CallbackResult callback; + GodotCollisionSolver2D::CallbackResult callback = nullptr; void *userdata = nullptr; bool swap = false; bool collided = false; diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index 23c8079538..ba362740b2 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -113,7 +113,7 @@ struct MinkowskiDiff { real_t margin_A = 0.0; real_t margin_B = 0.0; - Vector3 (*get_support)(const GodotShape3D*, const Vector3&, real_t); + Vector3 (*get_support)(const GodotShape3D*, const Vector3&, real_t) = nullptr; void Initialize(const GodotShape3D* shape0, const Transform3D& wtrs0, const real_t margin0, const GodotShape3D* shape1, const Transform3D& wtrs1, const real_t margin1) { @@ -191,13 +191,13 @@ struct GJK /* Fields */ tShape m_shape; Vector3 m_ray; - real_t m_distance; + real_t m_distance = 0.0f; sSimplex m_simplices[2]; sSV m_store[4]; sSV* m_free[4]; - U m_nfree; - U m_current; - sSimplex* m_simplex; + U m_nfree = 0; + U m_current = 0; + sSimplex* m_simplex = nullptr; eStatus::_ m_status; /* Methods */ GJK() @@ -548,12 +548,12 @@ struct GJK struct sFace { Vector3 n; - real_t d; + real_t d = 0.0f; sSV* c[3]; sFace* f[3]; sFace* l[2]; U1 e[3]; - U1 pass; + U1 pass = 0; }; struct sList { @@ -583,10 +583,10 @@ struct GJK eStatus::_ m_status; GJK::sSimplex m_result; Vector3 m_normal; - real_t m_depth; + real_t m_depth = 0.0f; sSV m_sv_store[EPA_MAX_VERTICES]; sFace m_fc_store[EPA_MAX_FACES]; - U m_nextsv; + U m_nextsv = 0; sList m_hull; sList m_stock; /* Methods */ diff --git a/servers/physics_3d/godot_collision_solver_3d.cpp b/servers/physics_3d/godot_collision_solver_3d.cpp index 0adfabef78..afc74df166 100644 --- a/servers/physics_3d/godot_collision_solver_3d.cpp +++ b/servers/physics_3d/godot_collision_solver_3d.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "godot_collision_solver_3d.h" + #include "godot_collision_solver_3d_sat.h" #include "godot_soft_body_3d.h" @@ -276,19 +277,20 @@ bool GodotCollisionSolver3D::solve_soft_body(const GodotShape3D *p_shape_A, cons } struct _ConcaveCollisionInfo { - const Transform3D *transform_A; - const GodotShape3D *shape_A; - const Transform3D *transform_B; - GodotCollisionSolver3D::CallbackResult result_callback; - void *userdata; - bool swap_result; - bool collided; - int aabb_tests; - int collisions; - bool tested; - real_t margin_A; - real_t margin_B; - Vector3 close_A, close_B; + const Transform3D *transform_A = nullptr; + const GodotShape3D *shape_A = nullptr; + const Transform3D *transform_B = nullptr; + GodotCollisionSolver3D::CallbackResult result_callback = nullptr; + void *userdata = nullptr; + bool swap_result = false; + bool collided = false; + int aabb_tests = 0; + int collisions = 0; + bool tested = false; + real_t margin_A = 0.0f; + real_t margin_B = 0.0f; + Vector3 close_A; + Vector3 close_B; }; bool GodotCollisionSolver3D::concave_callback(void *p_userdata, GodotShape3D *p_convex) { diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/servers/physics_3d/godot_collision_solver_3d_sat.cpp index ca429040f5..7b7a09f31d 100644 --- a/servers/physics_3d/godot_collision_solver_3d_sat.cpp +++ b/servers/physics_3d/godot_collision_solver_3d_sat.cpp @@ -68,7 +68,7 @@ *************************************************************************/ struct _CollectorCallback { - GodotCollisionSolver3D::CallbackResult callback; + GodotCollisionSolver3D::CallbackResult callback = nullptr; void *userdata = nullptr; bool swap = false; bool collided = false; diff --git a/servers/physics_3d/godot_shape_3d.cpp b/servers/physics_3d/godot_shape_3d.cpp index 21595c9612..63ba28258f 100644 --- a/servers/physics_3d/godot_shape_3d.cpp +++ b/servers/physics_3d/godot_shape_3d.cpp @@ -1438,7 +1438,7 @@ Vector3 GodotConcavePolygonShape3D::get_moment_of_inertia(real_t p_mass) const { struct _Volume_BVH_Element { AABB aabb; Vector3 center; - int face_index; + int face_index = 0; }; struct _Volume_BVH_CompareX { @@ -1461,10 +1461,10 @@ struct _Volume_BVH_CompareZ { struct _Volume_BVH { AABB aabb; - _Volume_BVH *left; - _Volume_BVH *right; + _Volume_BVH *left = nullptr; + _Volume_BVH *right = nullptr; - int face_index; + int face_index = 0; }; _Volume_BVH *_volume_build_bvh(_Volume_BVH_Element *p_elements, int p_size, int &count) { diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 45816e3244..d6d23f8310 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -243,7 +243,7 @@ void PhysicsPointQueryParameters2D::_bind_methods() { /////////////////////////////////////////////////////// -void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape_ref) { +void PhysicsShapeQueryParameters2D::set_shape(const Ref<Resource> &p_shape_ref) { ERR_FAIL_COND(p_shape_ref.is_null()); shape_ref = p_shape_ref; parameters.shape_rid = p_shape_ref->get_rid(); @@ -251,7 +251,7 @@ void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape_ref) { void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) { if (parameters.shape_rid != p_shape) { - shape_ref = RES(); + shape_ref = Ref<Resource>(); parameters.shape_rid = p_shape; } } diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index e9faf0a3bf..2f70b88e30 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -663,7 +663,7 @@ class PhysicsShapeQueryParameters2D : public RefCounted { PhysicsDirectSpaceState2D::ShapeParameters parameters; - RES shape_ref; + Ref<Resource> shape_ref; protected: static void _bind_methods(); @@ -671,8 +671,8 @@ protected: public: const PhysicsDirectSpaceState2D::ShapeParameters &get_parameters() const { return parameters; } - void set_shape(const RES &p_shape_ref); - RES get_shape() const { return shape_ref; } + void set_shape(const Ref<Resource> &p_shape_ref); + Ref<Resource> get_shape() const { return shape_ref; } void set_shape_rid(const RID &p_shape); RID get_shape_rid() const { return parameters.shape_rid; } diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 17c94978d1..bfe93f0dfb 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -262,7 +262,7 @@ void PhysicsPointQueryParameters3D::_bind_methods() { /////////////////////////////////////////////////////// -void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape_ref) { +void PhysicsShapeQueryParameters3D::set_shape(const Ref<Resource> &p_shape_ref) { ERR_FAIL_COND(p_shape_ref.is_null()); shape_ref = p_shape_ref; parameters.shape_rid = p_shape_ref->get_rid(); @@ -270,7 +270,7 @@ void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape_ref) { void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) { if (parameters.shape_rid != p_shape) { - shape_ref = RES(); + shape_ref = Ref<Resource>(); parameters.shape_rid = p_shape; } } diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 4811f7a039..47f3fc2027 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -874,7 +874,7 @@ class PhysicsShapeQueryParameters3D : public RefCounted { PhysicsDirectSpaceState3D::ShapeParameters parameters; - RES shape_ref; + Ref<Resource> shape_ref; protected: static void _bind_methods(); @@ -882,8 +882,8 @@ protected: public: const PhysicsDirectSpaceState3D::ShapeParameters &get_parameters() const { return parameters; } - void set_shape(const RES &p_shape_ref); - RES get_shape() const { return shape_ref; } + void set_shape(const Ref<Resource> &p_shape_ref); + Ref<Resource> get_shape() const { return shape_ref; } void set_shape_rid(const RID &p_shape); RID get_shape_rid() const { return parameters.shape_rid; } diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.cpp b/servers/rendering/renderer_rd/effects/tone_mapper.cpp index 7eb15f418b..e5642116bb 100644 --- a/servers/rendering/renderer_rd/effects/tone_mapper.cpp +++ b/servers/rendering/renderer_rd/effects/tone_mapper.cpp @@ -151,37 +151,37 @@ void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Ton mode += 6; } - RID default_shader = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - RID default_mipmap_shader = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); RD::Uniform u_source_color; u_source_color.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_source_color.binding = 0; - u_source_color.append_id(default_shader); + u_source_color.append_id(default_sampler); u_source_color.append_id(p_source_color); RD::Uniform u_exposure_texture; u_exposure_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_exposure_texture.binding = 0; - u_exposure_texture.append_id(default_shader); + u_exposure_texture.append_id(default_sampler); u_exposure_texture.append_id(p_settings.exposure_texture); RD::Uniform u_glow_texture; u_glow_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_glow_texture.binding = 0; - u_glow_texture.append_id(default_mipmap_shader); + u_glow_texture.append_id(default_mipmap_sampler); u_glow_texture.append_id(p_settings.glow_texture); RD::Uniform u_glow_map; u_glow_map.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_glow_map.binding = 1; - u_glow_map.append_id(default_mipmap_shader); + u_glow_map.append_id(default_mipmap_sampler); u_glow_map.append_id(p_settings.glow_map); RD::Uniform u_color_correction_texture; u_color_correction_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_color_correction_texture.binding = 0; - u_color_correction_texture.append_id(default_shader); + u_color_correction_texture.append_id(default_sampler); u_color_correction_texture.append_id(p_settings.color_correction_texture); RID shader = tonemap.shader.version_get_shader(tonemap.shader_version, mode); @@ -233,8 +233,8 @@ void ToneMapper::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_col tonemap.push_constant.use_debanding = p_settings.use_debanding; tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier; - RID default_shader = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - RID default_mipmap_shader = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); RD::Uniform u_source_color; u_source_color.uniform_type = RD::UNIFORM_TYPE_INPUT_ATTACHMENT; @@ -244,25 +244,25 @@ void ToneMapper::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_col RD::Uniform u_exposure_texture; u_exposure_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_exposure_texture.binding = 0; - u_exposure_texture.append_id(default_shader); + u_exposure_texture.append_id(default_sampler); u_exposure_texture.append_id(p_settings.exposure_texture); RD::Uniform u_glow_texture; u_glow_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_glow_texture.binding = 0; - u_glow_texture.append_id(default_mipmap_shader); + u_glow_texture.append_id(default_mipmap_sampler); u_glow_texture.append_id(p_settings.glow_texture); RD::Uniform u_glow_map; u_glow_map.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_glow_map.binding = 1; - u_glow_map.append_id(default_mipmap_shader); + u_glow_map.append_id(default_mipmap_sampler); u_glow_map.append_id(p_settings.glow_map); RD::Uniform u_color_correction_texture; u_color_correction_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_color_correction_texture.binding = 0; - u_color_correction_texture.append_id(default_shader); + u_color_correction_texture.append_id(default_sampler); u_color_correction_texture.append_id(p_settings.color_correction_texture); RID shader = tonemap.shader.version_get_shader(tonemap.shader_version, mode); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 3c115c942b..e60651f092 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -452,8 +452,6 @@ RS::ShaderNativeSourceCode SceneShaderForwardClustered::ShaderData::get_native_s SceneShaderForwardClustered::ShaderData::ShaderData() : shader_list_element(this) { - valid = false; - uses_screen_texture = false; } SceneShaderForwardClustered::ShaderData::~ShaderData() { diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 6185fa7413..0b2df983ff 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -130,9 +130,9 @@ public: ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE }; - bool valid; + bool valid = false; RID version; - uint32_t vertex_input_mask; + uint32_t vertex_input_mask = 0; PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_VERSION_MAX]; PipelineCacheRD color_pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_COLOR_PASS_FLAG_COUNT]; @@ -142,7 +142,7 @@ public: Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; - uint32_t ubo_size; + uint32_t ubo_size = 0; String code; Map<StringName, Map<int, RID>> default_texture_params; @@ -150,28 +150,28 @@ public: DepthDraw depth_draw; DepthTest depth_test; - bool uses_point_size; - bool uses_alpha; - bool uses_blend_alpha; - bool uses_alpha_clip; - bool uses_depth_pre_pass; - bool uses_discard; - bool uses_roughness; - bool uses_normal; - bool uses_particle_trails; - - bool unshaded; - bool uses_vertex; - bool uses_position; - bool uses_sss; - bool uses_transmittance; - bool uses_screen_texture; - bool uses_depth_texture; - bool uses_normal_texture; - bool uses_time; - bool writes_modelview_or_projection; - bool uses_world_coordinates; - Cull cull_mode; + bool uses_point_size = false; + bool uses_alpha = false; + bool uses_blend_alpha = false; + bool uses_alpha_clip = false; + bool uses_depth_pre_pass = false; + bool uses_discard = false; + bool uses_roughness = false; + bool uses_normal = false; + bool uses_particle_trails = false; + + bool unshaded = false; + bool uses_vertex = false; + bool uses_position = false; + bool uses_sss = false; + bool uses_transmittance = false; + bool uses_screen_texture = false; + bool uses_depth_texture = false; + bool uses_normal_texture = false; + bool uses_time = false; + bool writes_modelview_or_projection = false; + bool uses_world_coordinates = false; + Cull cull_mode = CULL_DISABLED; uint64_t last_pass = 0; uint32_t index = 0; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 60badbdfee..cdddc35579 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -415,8 +415,6 @@ RS::ShaderNativeSourceCode SceneShaderForwardMobile::ShaderData::get_native_sour SceneShaderForwardMobile::ShaderData::ShaderData() : shader_list_element(this) { - valid = false; - uses_screen_texture = false; } SceneShaderForwardMobile::ShaderData::~ShaderData() { diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index b89fe908d3..50b5fb26ec 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -97,9 +97,9 @@ public: ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE }; - bool valid; + bool valid = false; RID version; - uint32_t vertex_input_mask; + uint32_t vertex_input_mask = 0; PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX]; String path; @@ -108,7 +108,7 @@ public: Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; - uint32_t ubo_size; + uint32_t ubo_size = 0; String code; Map<StringName, Map<int, RID>> default_texture_params; @@ -116,26 +116,26 @@ public: DepthDraw depth_draw; DepthTest depth_test; - bool uses_point_size; - bool uses_alpha; - bool uses_blend_alpha; - bool uses_alpha_clip; - bool uses_depth_pre_pass; - bool uses_discard; - bool uses_roughness; - bool uses_normal; - bool uses_particle_trails; - - bool unshaded; - bool uses_vertex; - bool uses_sss; - bool uses_transmittance; - bool uses_screen_texture; - bool uses_depth_texture; - bool uses_normal_texture; - bool uses_time; - bool writes_modelview_or_projection; - bool uses_world_coordinates; + bool uses_point_size = false; + bool uses_alpha = false; + bool uses_blend_alpha = false; + bool uses_alpha_clip = false; + bool uses_depth_pre_pass = false; + bool uses_discard = false; + bool uses_roughness = false; + bool uses_normal = false; + bool uses_particle_trails = false; + + bool unshaded = false; + bool uses_vertex = false; + bool uses_sss = false; + bool uses_transmittance = false; + bool uses_screen_texture = false; + bool uses_depth_texture = false; + bool uses_normal_texture = false; + bool uses_time = false; + bool writes_modelview_or_projection = false; + bool uses_world_coordinates = false; uint64_t last_pass = 0; uint32_t index = 0; diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h index 1e80381d88..ad83fc76b7 100644 --- a/servers/rendering/renderer_rd/pipeline_cache_rd.h +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h @@ -45,7 +45,7 @@ class PipelineCacheRD { RD::PipelineMultisampleState multisample_state; RD::PipelineDepthStencilState depth_stencil_state; RD::PipelineColorBlendState blend_state; - int dynamic_state_flags; + int dynamic_state_flags = 0; Vector<RD::PipelineSpecializationConstant> base_specialization_constants; struct Version { diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 38eb8b8c41..386bc18fcd 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2232,12 +2232,6 @@ RS::ShaderNativeSourceCode RendererCanvasRenderRD::CanvasShaderData::get_native_ return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version); } -RendererCanvasRenderRD::CanvasShaderData::CanvasShaderData() { - valid = false; - uses_screen_texture = false; - uses_sdf = false; -} - RendererCanvasRenderRD::CanvasShaderData::~CanvasShaderData() { RendererCanvasRenderRD *canvas_singleton = static_cast<RendererCanvasRenderRD *>(RendererCanvasRender::singleton); ERR_FAIL_COND(!canvas_singleton); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 6448e1a664..06970acca6 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -161,7 +161,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { BLEND_MODE_DISABLED, }; - bool valid; + bool valid = false; RID version; PipelineVariants pipeline_variants; String path; @@ -170,7 +170,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; - uint32_t ubo_size; + uint32_t ubo_size = 0; String code; Map<StringName, Map<int, RID>> default_texture_params; @@ -190,7 +190,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; - CanvasShaderData(); + CanvasShaderData() {} virtual ~CanvasShaderData(); }; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index fd56de845f..759b8690eb 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -286,7 +286,6 @@ RendererCompositorRD::RendererCompositorRD() { } singleton = this; - time = 0; texture_storage = memnew(RendererRD::TextureStorage); material_storage = memnew(RendererRD::MaterialStorage); diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 768e9e0947..26bd28286b 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -50,11 +50,11 @@ class RendererCompositorRD : public RendererCompositor { protected: UniformSetCacheRD *uniform_set_cache = nullptr; RendererCanvasRenderRD *canvas = nullptr; - RendererRD::LightStorage *light_storage; - RendererRD::MaterialStorage *material_storage; - RendererRD::MeshStorage *mesh_storage; - RendererRD::ParticlesStorage *particles_storage; - RendererRD::TextureStorage *texture_storage; + RendererRD::LightStorage *light_storage = nullptr; + RendererRD::MaterialStorage *material_storage = nullptr; + RendererRD::MeshStorage *mesh_storage = nullptr; + RendererRD::ParticlesStorage *particles_storage = nullptr; + RendererRD::TextureStorage *texture_storage = nullptr; RendererStorageRD *storage = nullptr; RendererSceneRenderRD *scene = nullptr; @@ -92,8 +92,8 @@ protected: Map<RID, RID> render_target_descriptors; - double time; - double delta; + double time = 0.0; + double delta = 0.0; static uint64_t frame; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 26365aafc4..3bfcf18f12 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3976,10 +3976,6 @@ RS::ShaderNativeSourceCode RendererSceneRenderRD::FogShaderData::get_native_sour return scene_singleton->volumetric_fog.shader.version_get_native_source_code(version); } -RendererSceneRenderRD::FogShaderData::FogShaderData() { - valid = false; -} - RendererSceneRenderRD::FogShaderData::~FogShaderData() { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); ERR_FAIL_COND(!scene_singleton); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 2b79d8997f..6bf3a95dd0 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -47,10 +47,10 @@ #include "servers/rendering/rendering_device.h" struct RenderDataRD { - RID render_buffers = RID(); + RID render_buffers; - Transform3D cam_transform = Transform3D(); - CameraMatrix cam_projection = CameraMatrix(); + Transform3D cam_transform; + CameraMatrix cam_projection; bool cam_orthogonal = false; // For stereo rendering @@ -67,18 +67,18 @@ struct RenderDataRD { const PagedArray<RID> *decals = nullptr; const PagedArray<RID> *lightmaps = nullptr; const PagedArray<RID> *fog_volumes = nullptr; - RID environment = RID(); - RID camera_effects = RID(); - RID shadow_atlas = RID(); - RID reflection_atlas = RID(); - RID reflection_probe = RID(); + RID environment; + RID camera_effects; + RID shadow_atlas; + RID reflection_atlas; + RID reflection_probe; int reflection_probe_pass = 0; float lod_distance_multiplier = 0.0; - Plane lod_camera_plane = Plane(); + Plane lod_camera_plane; float screen_mesh_lod_threshold = 0.0; - RID cluster_buffer = RID(); + RID cluster_buffer; uint32_t cluster_size = 0; uint32_t cluster_max_elements = 0; @@ -95,8 +95,8 @@ class RendererSceneRenderRD : public RendererSceneRender { protected: RendererStorageRD *storage = nullptr; RendererRD::ToneMapper *tone_mapper = nullptr; - double time; - double time_step = 0; + double time = 0.0; + double time_step = 0.0; struct RenderBufferData { virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) = 0; @@ -236,7 +236,7 @@ private: struct DecalInstance { RID decal; Transform3D transform; - uint32_t cull_mask; + uint32_t cull_mask = 0; ForwardID forward_id = -1; }; @@ -256,7 +256,7 @@ private: struct ShadowShrinkStage { RID texture; RID filter_texture; - uint32_t size; + uint32_t size = 0; }; struct ShadowAtlas { @@ -268,27 +268,20 @@ private: }; struct Quadrant { - uint32_t subdivision; + uint32_t subdivision = 0; struct Shadow { RID owner; - uint64_t version; - uint64_t fog_version; // used for fog - uint64_t alloc_tick; - - Shadow() { - version = 0; - fog_version = 0; - alloc_tick = 0; - } + uint64_t version = 0; + uint64_t fog_version = 0; // used for fog + uint64_t alloc_tick = 0; + + Shadow() {} }; Vector<Shadow> shadows; - Quadrant() { - subdivision = 0; //not in use - } - + Quadrant() {} } quadrants[4]; int size_order[4] = { 0, 1, 2, 3 }; @@ -337,7 +330,6 @@ private: int size = 0; bool use_16_bits = true; int current_light = 0; - } directional_shadow; void _update_directional_shadow_atlas(); @@ -910,7 +902,7 @@ private: void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); struct FogShaderData : public RendererRD::ShaderData { - bool valid; + bool valid = false; RID version; RID pipeline; @@ -918,13 +910,13 @@ private: Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; - uint32_t ubo_size; + uint32_t ubo_size = 0; String path; String code; Map<StringName, Map<int, RID>> default_texture_params; - bool uses_time; + bool uses_time = false; virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); @@ -935,7 +927,8 @@ private: virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; - FogShaderData(); + + FogShaderData() {} virtual ~FogShaderData(); }; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 74bba0d4da..51cf0e952b 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -224,10 +224,6 @@ RS::ShaderNativeSourceCode RendererSceneSkyRD::SkyShaderData::get_native_source_ return scene_singleton->sky.sky_shader.shader.version_get_native_source_code(version); } -RendererSceneSkyRD::SkyShaderData::SkyShaderData() { - valid = false; -} - RendererSceneSkyRD::SkyShaderData::~SkyShaderData() { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); ERR_FAIL_COND(!scene_singleton); diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h index 010e2178a9..497d27ec26 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h @@ -106,7 +106,7 @@ private: }; struct SkyShaderData : public RendererRD::ShaderData { - bool valid; + bool valid = false; RID version; PipelineCacheRD pipelines[SKY_VERSION_MAX]; @@ -114,17 +114,17 @@ private: Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; - uint32_t ubo_size; + uint32_t ubo_size = 0; String path; String code; Map<StringName, Map<int, RID>> default_texture_params; - bool uses_time; - bool uses_position; - bool uses_half_res; - bool uses_quarter_res; - bool uses_light; + bool uses_time = false; + bool uses_position = false; + bool uses_half_res = false; + bool uses_quarter_res = false; + bool uses_light = false; virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); @@ -135,7 +135,8 @@ private: virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; - SkyShaderData(); + + SkyShaderData() {} virtual ~SkyShaderData(); }; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 28ac42457a..9ca2973fd4 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -388,26 +388,60 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy float *gui = reinterpret_cast<float *>(data); if (p_array_size > 0) { - const PackedVector3Array &a = value; - int s = a.size(); + if (value.get_type() == Variant::PACKED_COLOR_ARRAY) { + const PackedColorArray &a = value; + int s = a.size(); - for (int i = 0, j = 0; i < p_array_size; i++, j += 4) { - if (i < s) { - gui[j] = a[i].x; - gui[j + 1] = a[i].y; - gui[j + 2] = a[i].z; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + for (int i = 0, j = 0; i < p_array_size; i++, j += 4) { + if (i < s) { + Color color = a[i]; + if (p_linear_color) { + color = color.srgb_to_linear(); + } + gui[j] = color.r; + gui[j + 1] = color.g; + gui[j + 2] = color.b; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored + } + } else { + const PackedVector3Array &a = value; + int s = a.size(); + + for (int i = 0, j = 0; i < p_array_size; i++, j += 4) { + if (i < s) { + gui[j] = a[i].x; + gui[j + 1] = a[i].y; + gui[j + 2] = a[i].z; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored } - gui[j + 3] = 0; // ignored } } else { - Vector3 v = value; - gui[0] = v.x; - gui[1] = v.y; - gui[2] = v.z; + if (value.get_type() == Variant::COLOR) { + Color v = value; + + if (p_linear_color) { + v = v.srgb_to_linear(); + } + + gui[0] = v.r; + gui[1] = v.g; + gui[2] = v.b; + } else { + Vector3 v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + } } } break; case ShaderLanguage::TYPE_VEC4: { @@ -921,7 +955,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S //value=E.value.default_value; } else { //zero because it was not provided - if (E.value.type == ShaderLanguage::TYPE_VEC4 && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { //colors must be set as black, with alpha as 1.0 _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color); } else { @@ -2057,7 +2091,7 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { } String path = value; - RES resource = ResourceLoader::load(path); + Ref<Resource> resource = ResourceLoader::load(path); ERR_CONTINUE(resource.is_null()); value = resource; } diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 78d7c1e979..094120f908 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -1664,10 +1664,6 @@ RS::ShaderNativeSourceCode ParticlesStorage::ParticlesShaderData::get_native_sou return ParticlesStorage::get_singleton()->particles_shader.shader.version_get_native_source_code(version); } -ParticlesStorage::ParticlesShaderData::ParticlesShaderData() { - valid = false; -} - ParticlesStorage::ParticlesShaderData::~ParticlesShaderData() { //pipeline variants will clear themselves if shader is gone if (version.is_valid()) { diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 7764af08f2..c6480794c1 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -341,16 +341,15 @@ private: /* Particle Shader */ struct ParticlesShaderData : public ShaderData { - bool valid; + bool valid = false; RID version; bool uses_collision = false; - //PipelineCacheRD pipelines[SKY_VERSION_MAX]; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; - uint32_t ubo_size; + uint32_t ubo_size = 0; String path; String code; @@ -373,7 +372,7 @@ private: virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; - ParticlesShaderData(); + ParticlesShaderData() {} virtual ~ParticlesShaderData(); }; diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 5f71250ced..b5e8cf702f 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -921,7 +921,7 @@ public: RID_Owner<Instance, true> instance_owner; - uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecessary on clustered + uint32_t geometry_instance_pair_mask = 0; // used in traditional forward, unnecessary on clustered virtual RID instance_allocate(); virtual void instance_initialize(RID p_rid); diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 4da50d8822..7e18eac6ae 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -195,8 +195,6 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { } } - Color bgcolor = RSG::storage->get_default_clear_color(); - if (!p_viewport->disable_2d && !p_viewport->disable_environment && RSG::scene->is_scenario(p_viewport->scenario)) { RID environment = RSG::scene->scenario_get_environment(p_viewport->scenario); if (RSG::scene->is_environment(environment)) { @@ -207,15 +205,6 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { bool can_draw_3d = RSG::scene->is_camera(p_viewport->camera) && !p_viewport->disable_3d; - if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) { - if (p_viewport->transparent_bg) { - bgcolor = Color(0, 0, 0, 0); - } - if (p_viewport->clear_mode == RS::VIEWPORT_CLEAR_ONLY_NEXT_FRAME) { - p_viewport->clear_mode = RS::VIEWPORT_CLEAR_NEVER; - } - } - if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) { //wants to draw 3D but there is no render buffer, create p_viewport->render_buffers = RSG::scene->render_buffers_create(); @@ -223,7 +212,14 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { _configure_3d_render_buffers(p_viewport); } - RSG::texture_storage->render_target_request_clear(p_viewport->render_target, bgcolor); + Color bgcolor = p_viewport->transparent_bg ? Color(0, 0, 0, 0) : RSG::storage->get_default_clear_color(); + + if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) { + RSG::texture_storage->render_target_request_clear(p_viewport->render_target, bgcolor); + if (p_viewport->clear_mode == RS::VIEWPORT_CLEAR_ONLY_NEXT_FRAME) { + p_viewport->clear_mode = RS::VIEWPORT_CLEAR_NEVER; + } + } if (!scenario_draw_canvas_bg && can_draw_3d) { _draw_3d(p_viewport); diff --git a/servers/rendering/shader_compiler.h b/servers/rendering/shader_compiler.h index 8f0ee664ac..347ecf2988 100644 --- a/servers/rendering/shader_compiler.h +++ b/servers/rendering/shader_compiler.h @@ -106,8 +106,8 @@ private: void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added); String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_scope = true); - const ShaderLanguage::ShaderNode *shader; - const ShaderLanguage::FunctionNode *function; + const ShaderLanguage::ShaderNode *shader = nullptr; + const ShaderLanguage::FunctionNode *function = nullptr; StringName current_func_name; StringName time_name; Set<StringName> texture_functions; diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 54d1a6fd8d..1fd7062d6e 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -3548,13 +3548,25 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 3; - PackedVector3Array array = PackedVector3Array(); - for (int i = 0; i < array_size; i += 3) { - array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real)); + if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + PackedColorArray array = PackedColorArray(); + for (int i = 0; i < array_size; i += 3) { + array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real)); + } + value = Variant(array); + } else { + PackedVector3Array array = PackedVector3Array(); + for (int i = 0; i < array_size; i += 3) { + array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real)); + } + value = Variant(array); } - value = Variant(array); } else { - value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real)); + if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real)); + } else { + value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real)); + } } break; case ShaderLanguage::TYPE_VEC4: @@ -3760,9 +3772,19 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform break; case ShaderLanguage::TYPE_VEC3: if (p_uniform.array_size > 0) { - pi.type = Variant::PACKED_VECTOR3_ARRAY; + if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA; + pi.type = Variant::PACKED_COLOR_ARRAY; + } else { + pi.type = Variant::PACKED_VECTOR3_ARRAY; + } } else { - pi.type = Variant::VECTOR3; + if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA; + pi.type = Variant::COLOR; + } else { + pi.type = Variant::VECTOR3; + } } break; case ShaderLanguage::TYPE_VEC4: { @@ -8001,8 +8023,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } else if (tk.type == TK_HINT_BLACK_ALBEDO_TEXTURE) { uniform2.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO; } else if (tk.type == TK_HINT_COLOR) { - if (type != TYPE_VEC4) { - _set_error(vformat(RTR("Color hint is for '%s' only."), "vec4")); + if (type != TYPE_VEC3 && type != TYPE_VEC4) { + _set_error(vformat(RTR("Color hint is for '%s' or '%s' only."), "vec3", "vec4")); return ERR_PARSE_ERROR; } uniform2.hint = ShaderNode::Uniform::HINT_COLOR; @@ -9514,7 +9536,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ } break; case COMPLETION_HINT: { - if (completion_base == DataType::TYPE_VEC4) { + if (completion_base == DataType::TYPE_VEC3 || completion_base == DataType::TYPE_VEC4) { ScriptLanguage::CodeCompletionOption option("hint_color", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); r_options->push_back(option); } else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) { diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index de6d912a4f..c707d09f29 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -874,11 +874,11 @@ private: static const KeyWord keyword_list[]; - GlobalVariableGetTypeFunc global_var_get_type_func; + GlobalVariableGetTypeFunc global_var_get_type_func = nullptr; - bool error_set; + bool error_set = false; String error_str; - int error_line; + int error_line = 0; #ifdef DEBUG_ENABLED struct Usage { @@ -902,7 +902,7 @@ private: List<ShaderWarning> warnings; bool check_warnings = false; - uint32_t warning_flags; + uint32_t warning_flags = 0; void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()) { warnings.push_back(ShaderWarning(p_code, tk_line, p_subject, p_extra_args)); @@ -917,8 +917,8 @@ private: #endif // DEBUG_ENABLED String code; - int char_idx; - int tk_line; + int char_idx = 0; + int tk_line = 0; StringName current_function; bool last_const = false; @@ -1020,14 +1020,14 @@ private: }; CompletionType completion_type; - int completion_line; + int completion_line = 0; BlockNode *completion_block = nullptr; DataType completion_base; - bool completion_base_array; + bool completion_base_array = false; SubClassTag completion_class; StringName completion_function; StringName completion_struct; - int completion_argument; + int completion_argument = 0; const Map<StringName, FunctionInfo> *stages = nullptr; diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 71896e9d11..2db384f7df 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -47,7 +47,7 @@ class RenderingServer : public Object { static RenderingServer *singleton; - int mm_policy; + int mm_policy = 0; bool render_loop_enabled = true; Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const; diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 87016dddf6..58372a0ed6 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -636,6 +636,38 @@ TEST_CASE("[String] sprintf") { REQUIRE(error == false); CHECK(output == String("fish -5 frog")); + // Negative int left padded with spaces. + format = "fish %5d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -5 frog")); + + // Negative int left padded with zeros. + format = "fish %05d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -0005 frog")); + + // Negative int right padded with spaces. + format = "fish %-5d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -5 frog")); + + // Negative int right padded with zeros. (0 ignored) + format = "fish %-05d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -5 frog")); + // Hex (lower) format = "fish %x frog"; args.clear(); @@ -726,6 +758,14 @@ TEST_CASE("[String] sprintf") { REQUIRE(error == false); CHECK(output == String("fish 100 frog")); + // Negative real right padded with zeros. (0 ignored) + format = "fish %-011f frog"; + args.clear(); + args.push_back(-99.99); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -99.990000 frog")); + /////// Strings. // String diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index 62931cd4dd..d28380d056 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -2961,7 +2961,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") { /* also does not work on col 0 */ code_edit->insert_text_at_caret("i"); code_edit->update_code_completion_options(); - code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), RES(), Color(1, 0, 0)); + code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), Ref<Resource>(), Color(1, 0, 0)); code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_1.", "item_1"); code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_2.", "item_2"); @@ -2989,7 +2989,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") { CHECK(option["display_text"] == "item_0."); CHECK(option["insert_text"] == "item_0"); CHECK(option["font_color"] == Color(1, 0, 0)); - CHECK(option["icon"] == RES()); + CHECK(option["icon"] == Ref<Resource>()); CHECK(option["default_value"] == Color(1, 0, 0)); /* Set size for mouse input. */ diff --git a/tests/scene/test_theme.h b/tests/scene/test_theme.h new file mode 100644 index 0000000000..fedffc8449 --- /dev/null +++ b/tests/scene/test_theme.h @@ -0,0 +1,257 @@ +/*************************************************************************/ +/* test_theme.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_THEME_H +#define TEST_THEME_H + +#include "scene/resources/theme.h" +#include "tests/test_tools.h" + +#include "thirdparty/doctest/doctest.h" + +namespace TestTheme { + +class Fixture { +public: + struct DataEntry { + Theme::DataType type; + Variant value; + } const valid_data[Theme::DATA_TYPE_MAX] = { + { Theme::DATA_TYPE_COLOR, Color() }, + { Theme::DATA_TYPE_CONSTANT, 42 }, + { Theme::DATA_TYPE_FONT, Ref<Font>(memnew(Font)) }, + { Theme::DATA_TYPE_FONT_SIZE, 42 }, + { Theme::DATA_TYPE_ICON, Ref<Texture>(memnew(ImageTexture)) }, + { Theme::DATA_TYPE_STYLEBOX, Ref<StyleBox>(memnew(StyleBoxFlat)) }, + }; + + const StringName valid_item_name = "valid_item_name"; + const StringName valid_type_name = "ValidTypeName"; +}; + +TEST_CASE_FIXTURE(Fixture, "[Theme] Good theme type names") { + StringName names[] = { + "", // Empty name. + "CapitalizedName", + "snake_cased_name", + "42", + "_Underscore_", + }; + + SUBCASE("add_type") { + for (const StringName &name : names) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->add_type(name); + CHECK_FALSE(ed.has_error); + } + } + + SUBCASE("set_theme_item") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_theme_item(entry.type, valid_item_name, name, entry.value); + CHECK_FALSE(ed.has_error); + } + } + } + + SUBCASE("add_theme_item_type") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->add_theme_item_type(entry.type, name); + CHECK_FALSE(ed.has_error); + } + } + } + + SUBCASE("set_type_variation") { + for (const StringName &name : names) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_type_variation(valid_type_name, name); + CHECK(ed.has_error == (name == StringName())); + } + for (const StringName &name : names) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_type_variation(name, valid_type_name); + CHECK(ed.has_error == (name == StringName())); + } + } +} + +TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme type names") { + StringName names[] = { + "With/Slash", + "With Space", + "With@various$symbols!", + String::utf8("contains_汉字"), + }; + + SUBCASE("add_type") { + for (const StringName &name : names) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->add_type(name); + CHECK(ed.has_error); + } + } + + SUBCASE("set_theme_item") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_theme_item(entry.type, valid_item_name, name, entry.value); + CHECK(ed.has_error); + } + } + } + + SUBCASE("add_theme_item_type") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->add_theme_item_type(entry.type, name); + CHECK(ed.has_error); + } + } + } + + SUBCASE("set_type_variation") { + for (const StringName &name : names) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_type_variation(valid_type_name, name); + CHECK(ed.has_error); + } + for (const StringName &name : names) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_type_variation(name, valid_type_name); + CHECK(ed.has_error); + } + } +} + +TEST_CASE_FIXTURE(Fixture, "[Theme] Good theme item names") { + StringName names[] = { + "CapitalizedName", + "snake_cased_name", + "42", + "_Underscore_", + }; + + SUBCASE("set_theme_item") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_theme_item(entry.type, name, valid_type_name, entry.value); + CHECK_FALSE(ed.has_error); + CHECK(theme->has_theme_item(entry.type, name, valid_type_name)); + } + } + } + + SUBCASE("rename_theme_item") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + theme->set_theme_item(entry.type, valid_item_name, valid_type_name, entry.value); + + ErrorDetector ed; + theme->rename_theme_item(entry.type, valid_item_name, name, valid_type_name); + CHECK_FALSE(ed.has_error); + CHECK_FALSE(theme->has_theme_item(entry.type, valid_item_name, valid_type_name)); + CHECK(theme->has_theme_item(entry.type, name, valid_type_name)); + } + } + } +} + +TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme item names") { + StringName names[] = { + "", // Empty name. + "With/Slash", + "With Space", + "With@various$symbols!", + String::utf8("contains_汉字"), + }; + + SUBCASE("set_theme_item") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + + ErrorDetector ed; + theme->set_theme_item(entry.type, name, valid_type_name, entry.value); + CHECK(ed.has_error); + CHECK_FALSE(theme->has_theme_item(entry.type, name, valid_type_name)); + } + } + } + + SUBCASE("rename_theme_item") { + for (const StringName &name : names) { + for (const DataEntry &entry : valid_data) { + Ref<Theme> theme = memnew(Theme); + theme->set_theme_item(entry.type, valid_item_name, valid_type_name, entry.value); + + ErrorDetector ed; + theme->rename_theme_item(entry.type, valid_item_name, name, valid_type_name); + CHECK(ed.has_error); + CHECK(theme->has_theme_item(entry.type, valid_item_name, valid_type_name)); + CHECK_FALSE(theme->has_theme_item(entry.type, name, valid_type_name)); + } + } + } +} + +} // namespace TestTheme + +#endif // TEST_THEME_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index a059949105..be51afd83c 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -77,6 +77,7 @@ #include "tests/scene/test_gradient.h" #include "tests/scene/test_path_3d.h" #include "tests/scene/test_text_edit.h" +#include "tests/scene/test_theme.h" #include "tests/servers/test_text_server.h" #include "tests/test_validate_testing.h" diff --git a/thirdparty/noise/FastNoiseLite.h b/thirdparty/noise/FastNoiseLite.h index 8015bf636a..a213f0888e 100644 --- a/thirdparty/noise/FastNoiseLite.h +++ b/thirdparty/noise/FastNoiseLite.h @@ -1611,6 +1611,12 @@ private: } } +// GCC raises warnings when integer overflows occur, which are needed for hashing here. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Waggressive-loop-optimizations" +#endif + template <typename FNfloat> float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z) const { @@ -1765,6 +1771,9 @@ private: } } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif // Perlin Noise diff --git a/thirdparty/noise/patches/FastNoiseLite.patch b/thirdparty/noise/patches/FastNoiseLite.patch index 41ec943077..3c835c7b06 100644 --- a/thirdparty/noise/patches/FastNoiseLite.patch +++ b/thirdparty/noise/patches/FastNoiseLite.patch @@ -430,3 +430,26 @@ { x *= frequency; y *= frequency; +@@ -1611,6 +1611,12 @@ private: + } + } + ++// GCC raises warnings when integer overflows occur, which are needed for hashing here. ++#if defined(__GNUC__) && !defined(__clang__) ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Waggressive-loop-optimizations" ++#endif ++ + template <typename FNfloat> + float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z) const + { +@@ -1765,6 +1771,9 @@ private: + } + } + ++#if defined(__GNUC__) && !defined(__clang__) ++#pragma GCC diagnostic pop ++#endif + + // Perlin Noise +
\ No newline at end of file |