diff options
127 files changed, 1555 insertions, 864 deletions
diff --git a/SConstruct b/SConstruct index cfedcc84ed..f7c40416c7 100644 --- a/SConstruct +++ b/SConstruct @@ -300,12 +300,10 @@ if env["import_env_vars"]: # Platform selection: validate input, and add options. -selected_platform = env["platform"] +if env.scons_version < (4, 3) and not env["platform"]: + env["platform"] = env["p"] -if env.scons_version < (4, 3) and not selected_platform: - selected_platform = env["p"] - -if selected_platform == "": +if env["platform"] == "": # Missing `platform` argument, try to detect platform automatically if ( sys.platform.startswith("linux") @@ -314,62 +312,57 @@ if selected_platform == "": or sys.platform.startswith("netbsd") or sys.platform.startswith("openbsd") ): - selected_platform = "linuxbsd" + env["platform"] = "linuxbsd" elif sys.platform == "darwin": - selected_platform = "macos" + env["platform"] = "macos" elif sys.platform == "win32": - selected_platform = "windows" + env["platform"] = "windows" - if selected_platform != "": - print(f"Automatically detected platform: {selected_platform}") + if env["platform"] != "": + print(f'Automatically detected platform: {env["platform"]}') -if selected_platform == "osx": +if env["platform"] == "osx": # Deprecated alias kept for compatibility. print_warning('Platform "osx" has been renamed to "macos" in Godot 4. Building for platform "macos".') - selected_platform = "macos" + env["platform"] = "macos" -if selected_platform == "iphone": +if env["platform"] == "iphone": # Deprecated alias kept for compatibility. print_warning('Platform "iphone" has been renamed to "ios" in Godot 4. Building for platform "ios".') - selected_platform = "ios" + env["platform"] = "ios" -if selected_platform in ["linux", "bsd", "x11"]: - if selected_platform == "x11": +if env["platform"] in ["linux", "bsd", "x11"]: + if env["platform"] == "x11": # Deprecated alias kept for compatibility. print_warning('Platform "x11" has been renamed to "linuxbsd" in Godot 4. Building for platform "linuxbsd".') # Alias for convenience. - selected_platform = "linuxbsd" + env["platform"] = "linuxbsd" -if selected_platform == "javascript": +if env["platform"] == "javascript": # Deprecated alias kept for compatibility. print_warning('Platform "javascript" has been renamed to "web" in Godot 4. Building for platform "web".') - selected_platform = "web" + env["platform"] = "web" -if selected_platform not in platform_list: +if env["platform"] not in platform_list: text = "The following platforms are available:\n\t{}\n".format("\n\t".join(platform_list)) text += "Please run SCons again and select a valid platform: platform=<string>." - if selected_platform == "list": + if env["platform"] == "list": print(text) - elif selected_platform == "": + elif env["platform"] == "": print_error("Could not detect platform automatically.\n" + text) else: - print_error(f'Invalid target platform "{selected_platform}".\n' + text) - - Exit(0 if selected_platform == "list" else 255) + print_error(f'Invalid target platform "{env["platform"]}".\n' + text) -# Make sure to update this to the found, valid platform as it's used through the buildsystem as the reference. -# It should always be re-set after calling `opts.Update()` otherwise it uses the original input value. -env["platform"] = selected_platform + Exit(0 if env["platform"] == "list" else 255) # Add platform-specific options. -if selected_platform in platform_opts: - for opt in platform_opts[selected_platform]: +if env["platform"] in platform_opts: + for opt in platform_opts[env["platform"]]: opts.Add(opt) # Update the environment to take platform-specific options into account. -opts.Update(env) -env["platform"] = selected_platform # Must always be re-set after calling opts.Update(). +opts.Update(env, {**ARGUMENTS, **env}) # Detect modules. modules_detected = OrderedDict() @@ -418,7 +411,7 @@ for name, path in modules_detected.items(): # Add module-specific options. try: - for opt in config.get_opts(selected_platform): + for opt in config.get_opts(env["platform"]): opts.Add(opt) except AttributeError: pass @@ -429,8 +422,7 @@ for name, path in modules_detected.items(): env.modules_detected = modules_detected # Update the environment again after all the module options are added. -opts.Update(env) -env["platform"] = selected_platform # Must always be re-set after calling opts.Update(). +opts.Update(env, {**ARGUMENTS, **env}) Help(opts.GenerateHelpText(env)) # add default include paths @@ -492,14 +484,15 @@ if methods.get_cmdline_bool("fast_unsafe", env.dev_build): if env["use_precise_math_checks"]: env.Append(CPPDEFINES=["PRECISE_MATH_CHECKS"]) -if env.editor_build and env["engine_update_check"]: - env.Append(CPPDEFINES=["ENGINE_UPDATE_CHECK_ENABLED"]) +if env.editor_build: + if env["engine_update_check"]: + env.Append(CPPDEFINES=["ENGINE_UPDATE_CHECK_ENABLED"]) -if not env.File("#main/splash_editor.png").exists(): - # Force disabling editor splash if missing. - env["no_editor_splash"] = True -if env["no_editor_splash"]: - env.Append(CPPDEFINES=["NO_EDITOR_SPLASH"]) + if not env.File("#main/splash_editor.png").exists(): + # Force disabling editor splash if missing. + env["no_editor_splash"] = True + if env["no_editor_splash"]: + env.Append(CPPDEFINES=["NO_EDITOR_SPLASH"]) if not env["deprecated"]: env.Append(CPPDEFINES=["DISABLE_DEPRECATED"]) @@ -507,7 +500,7 @@ if not env["deprecated"]: if env["precision"] == "double": env.Append(CPPDEFINES=["REAL_T_IS_DOUBLE"]) -tmppath = "./platform/" + selected_platform +tmppath = "./platform/" + env["platform"] sys.path.insert(0, tmppath) import detect @@ -561,7 +554,7 @@ if env["build_profile"] != "": # Platform specific flags. # These can sometimes override default options. -flag_list = platform_flags[selected_platform] +flag_list = platform_flags[env["platform"]] for f in flag_list: if not (f[0] in ARGUMENTS) or ARGUMENTS[f[0]] == "auto": # Allow command line to override platform flags env[f[0]] = f[1] @@ -598,7 +591,7 @@ if env["scu_build"]: # are actually handled to change compile options, etc. detect.configure(env) -print(f'Building for platform "{selected_platform}", architecture "{env["arch"]}", target "{env["target"]}".') +print(f'Building for platform "{env["platform"]}", architecture "{env["arch"]}", target "{env["target"]}".') if env.dev_build: print("NOTE: Developer build, with debug optimization level and debug symbols (unless overridden).") @@ -854,7 +847,7 @@ else: # GCC, Clang if hasattr(detect, "get_program_suffix"): suffix = "." + detect.get_program_suffix() else: - suffix = "." + selected_platform + suffix = "." + env["platform"] suffix += "." + env["target"] if env.dev_build: @@ -885,7 +878,7 @@ for name, path in modules_detected.items(): env.current_module = name import config - if config.can_build(env, selected_platform): + if config.can_build(env, env["platform"]): # Disable it if a required dependency is missing. if not env.module_check_dependencies(name): continue @@ -1037,7 +1030,7 @@ if env["tests"]: SConscript("tests/SCsub") SConscript("main/SCsub") -SConscript("platform/" + selected_platform + "/SCsub") # Build selected platform. +SConscript("platform/" + env["platform"] + "/SCsub") # Build selected platform. # Microsoft Visual Studio Project Generation if env["vsproj"]: diff --git a/core/SCsub b/core/SCsub index 640c6de6a1..a61c0b5fc2 100644 --- a/core/SCsub +++ b/core/SCsub @@ -166,7 +166,7 @@ def disabled_class_builder(target, source, env): for c in source[0].read(): cs = c.strip() if cs != "": - file.write(f"#define ClassDB_Disable_{cs} 1") + file.write(f"#define ClassDB_Disable_{cs} 1\n") env.CommandNoCache("disabled_classes.gen.h", env.Value(env.disabled_classes), env.Run(disabled_class_builder)) diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index a0412e91ff..a116c9c270 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -291,7 +291,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { } } } else { - if (p_name == CoreStringNames::get_singleton()->_custom_features) { + if (p_name == CoreStringName(_custom_features)) { Vector<String> custom_feature_array = String(p_value).split(","); for (int i = 0; i < custom_feature_array.size(); i++) { custom_features.insert(custom_feature_array[i]); @@ -875,7 +875,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const RBMap<S if (!p_custom_features.is_empty()) { // Store how many properties are saved, add one for custom features, which must always go first. file->store_32(count + 1); - String key = CoreStringNames::get_singleton()->_custom_features; + String key = CoreStringName(_custom_features); file->store_pascal_string(key); int len; diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp index 21645e5efc..1ffe76495d 100644 --- a/core/core_string_names.cpp +++ b/core/core_string_names.cpp @@ -33,12 +33,10 @@ CoreStringNames *CoreStringNames::singleton = nullptr; CoreStringNames::CoreStringNames() : - _free(StaticCString::create("free")), + free_(StaticCString::create("free")), changed(StaticCString::create("changed")), - _script(StaticCString::create("script")), + script(StaticCString::create("script")), script_changed(StaticCString::create("script_changed")), - ___pdcdata(StaticCString::create("___pdcdata")), - __getvar(StaticCString::create("__getvar")), _iter_init(StaticCString::create("_iter_init")), _iter_next(StaticCString::create("_iter_next")), _iter_get(StaticCString::create("_iter_get")), diff --git a/core/core_string_names.h b/core/core_string_names.h index 1c77cef567..d7ddc39f5e 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -50,12 +50,10 @@ public: static CoreStringNames *singleton; - StringName _free; + StringName free_; // "free", conflict with C++ keyword. StringName changed; - StringName _script; + StringName script; StringName script_changed; - StringName ___pdcdata; - StringName __getvar; StringName _iter_init; StringName _iter_next; StringName _iter_get; @@ -98,4 +96,6 @@ public: StringName property_list_changed; }; +#define CoreStringName(m_name) CoreStringNames::get_singleton()->m_name + #endif // CORE_STRING_NAMES_H diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 2cdfacae17..1928f86d6a 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -1696,7 +1696,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo Variant value; - if (E.name == CoreStringNames::get_singleton()->_script) { + if (E.name == CoreStringName(script)) { Ref<Script> script = obj->get_script(); if (script.is_valid()) { String path = script->get_path(); diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 4c3cfeaa58..24ff0e83d2 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -43,9 +43,9 @@ void Resource::emit_changed() { if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) { // Let the connection happen on the main thread, later, since signals are not thread-safe. - call_deferred("emit_signal", CoreStringNames::get_singleton()->changed); + call_deferred("emit_signal", CoreStringName(changed)); } else { - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } } @@ -172,8 +172,8 @@ void Resource::connect_changed(const Callable &p_callable, uint32_t p_flags) { callable_mp(this, &Resource::connect_changed).call_deferred(p_callable, p_flags); return; } - if (!is_connected(CoreStringNames::get_singleton()->changed, p_callable) || p_flags & CONNECT_REFERENCE_COUNTED) { - connect(CoreStringNames::get_singleton()->changed, p_callable, p_flags); + if (!is_connected(CoreStringName(changed), p_callable) || p_flags & CONNECT_REFERENCE_COUNTED) { + connect(CoreStringName(changed), p_callable, p_flags); } } @@ -183,8 +183,8 @@ void Resource::disconnect_changed(const Callable &p_callable) { callable_mp(this, &Resource::disconnect_changed).call_deferred(p_callable); return; } - if (is_connected(CoreStringNames::get_singleton()->changed, p_callable)) { - disconnect(CoreStringNames::get_singleton()->changed, p_callable); + if (is_connected(CoreStringName(changed), p_callable)) { + disconnect(CoreStringName(changed), p_callable); } } diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 6b84dfcee9..7ea26c3fc5 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -1554,7 +1554,7 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia } // The "free()" method is special, so we assume it exists and return a Callable. - if (p_property == CoreStringNames::get_singleton()->_free) { + if (p_property == CoreStringName(free_)) { r_value = Callable(p_object, p_property); return true; } diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp index 90536e58ff..9351253c6f 100644 --- a/core/object/message_queue.cpp +++ b/core/object/message_queue.cpp @@ -197,7 +197,7 @@ Error CallQueue::push_notification(ObjectID p_id, int p_notification) { Message *msg = memnew_placement(buffer_end, Message); msg->type = TYPE_NOTIFICATION; - msg->callable = Callable(p_id, CoreStringNames::get_singleton()->notification); //name is meaningless but callable needs it + msg->callable = Callable(p_id, CoreStringName(notification)); //name is meaningless but callable needs it //msg->target; msg->notification = p_notification; @@ -224,64 +224,7 @@ void CallQueue::_call_function(const Callable &p_callable, const Variant *p_args } } -Error CallQueue::_transfer_messages_to_main_queue() { - if (pages.size() == 0) { - return OK; - } - - CallQueue *mq = MessageQueue::main_singleton; - DEV_ASSERT(!mq->allocator_is_custom && !allocator_is_custom); // Transferring pages is only safe if using the same alloator parameters. - - mq->mutex.lock(); - - // Here we're transferring the data from this queue to the main one. - // However, it's very unlikely big amounts of messages will be queued here, - // so PagedArray/Pool would be overkill. Also, in most cases the data will fit - // an already existing page of the main queue. - - // Let's see if our first (likely only) page fits the current target queue page. - uint32_t src_page = 0; - { - if (mq->pages_used) { - uint32_t dst_page = mq->pages_used - 1; - uint32_t dst_offset = mq->page_bytes[dst_page]; - if (dst_offset + page_bytes[0] < uint32_t(PAGE_SIZE_BYTES)) { - memcpy(mq->pages[dst_page]->data + dst_offset, pages[0]->data, page_bytes[0]); - mq->page_bytes[dst_page] += page_bytes[0]; - src_page++; - } - } - } - - // Any other possibly existing source page needs to be added. - - if (mq->pages_used + (pages_used - src_page) > mq->max_pages) { - fprintf(stderr, "Failed appending thread queue. Message queue out of memory. %s\n", mq->error_text.utf8().get_data()); - mq->statistics(); - mq->mutex.unlock(); - return ERR_OUT_OF_MEMORY; - } - - for (; src_page < pages_used; src_page++) { - mq->_add_page(); - memcpy(mq->pages[mq->pages_used - 1]->data, pages[src_page]->data, page_bytes[src_page]); - mq->page_bytes[mq->pages_used - 1] = page_bytes[src_page]; - } - - mq->mutex.unlock(); - - page_bytes[0] = 0; - pages_used = 1; - - return OK; -} - Error CallQueue::flush() { - // Thread overrides are not meant to be flushed, but appended to the main one. - if (unlikely(this == MessageQueue::thread_singleton)) { - return _transfer_messages_to_main_queue(); - } - LOCK_MUTEX; if (pages.size() == 0) { diff --git a/core/object/message_queue.h b/core/object/message_queue.h index c2f4ad1643..9f567e4dd0 100644 --- a/core/object/message_queue.h +++ b/core/object/message_queue.h @@ -98,8 +98,6 @@ private: } } - Error _transfer_messages_to_main_queue(); - void _add_page(); void _call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error); diff --git a/core/object/object.cpp b/core/object/object.cpp index 5125ab8a6e..57f8766509 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -260,7 +260,7 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid } } - if (p_name == CoreStringNames::get_singleton()->_script) { + if (p_name == CoreStringName(script)) { set_script(p_value); if (r_valid) { *r_valid = true; @@ -351,7 +351,7 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { } } - if (p_name == CoreStringNames::get_singleton()->_script) { + if (p_name == CoreStringName(script)) { ret = get_script(); if (r_valid) { *r_valid = true; @@ -672,7 +672,7 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Call } bool Object::has_method(const StringName &p_method) const { - if (p_method == CoreStringNames::get_singleton()->_free) { + if (p_method == CoreStringName(free_)) { return true; } @@ -698,7 +698,7 @@ int Object::_get_method_argument_count_bind(const StringName &p_method) const { } int Object::get_method_argument_count(const StringName &p_method, bool *r_is_valid) const { - if (p_method == CoreStringNames::get_singleton()->_free) { + if (p_method == CoreStringName(free_)) { if (r_is_valid) { *r_is_valid = true; } @@ -787,7 +787,7 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) { Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { r_error.error = Callable::CallError::CALL_OK; - if (p_method == CoreStringNames::get_singleton()->_free) { + if (p_method == CoreStringName(free_)) { //free must be here, before anything, always ready #ifdef DEBUG_ENABLED if (p_argcount != 0) { @@ -850,7 +850,7 @@ Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_ Variant Object::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { r_error.error = Callable::CallError::CALL_OK; - if (p_method == CoreStringNames::get_singleton()->_free) { + if (p_method == CoreStringName(free_)) { // Free is not const, so fail. r_error.error = Callable::CallError::CALL_ERROR_METHOD_NOT_CONST; return Variant(); @@ -979,7 +979,7 @@ void Object::set_script(const Variant &p_script) { } notify_property_list_changed(); //scripts may add variables, so refresh is desired - emit_signal(CoreStringNames::get_singleton()->script_changed); + emit_signal(CoreStringName(script_changed)); } void Object::set_script_instance(ScriptInstance *p_instance) { @@ -1654,7 +1654,7 @@ void Object::clear_internal_resource_paths() { } void Object::notify_property_list_changed() { - emit_signal(CoreStringNames::get_singleton()->property_list_changed); + emit_signal(CoreStringName(property_list_changed)); } void Object::_bind_methods() { diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 3a499a2bcd..8be00b1358 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -2121,7 +2121,7 @@ Variant::operator ::RID() const { } #endif Callable::CallError ce; - Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); + Variant ret = _get_obj().obj->callp(CoreStringName(get_rid), nullptr, 0, ce); if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::RID) { return ret; } diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 96c52260d9..48176163a1 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -1384,7 +1384,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { ref.push_back(r_iter); Variant vref = ref; const Variant *refp[] = { &vref }; - Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce); + Variant ret = _get_obj().obj->callp(CoreStringName(_iter_init), refp, 1, ce); if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { valid = false; @@ -1619,7 +1619,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { ref.push_back(r_iter); Variant vref = ref; const Variant *refp[] = { &vref }; - Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce); + Variant ret = _get_obj().obj->callp(CoreStringName(_iter_next), refp, 1, ce); if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { valid = false; @@ -1811,7 +1811,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { Callable::CallError ce; ce.error = Callable::CallError::CALL_OK; const Variant *refp[] = { &r_iter }; - Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce); + Variant ret = _get_obj().obj->callp(CoreStringName(_iter_get), refp, 1, ce); if (ce.error != Callable::CallError::CALL_OK) { r_valid = false; diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index bf53cb2e14..207045b065 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -84,6 +84,7 @@ Draws a circle. See also [method draw_arc], [method draw_polyline], and [method draw_polygon]. If [param filled] is [code]true[/code], the circle will be filled with the [param color] specified. If [param filled] is [code]false[/code], the circle will be drawn as a stroke with the [param color] and [param width] specified. If [param width] is negative, then two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the lines will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code]. + If [param antialiased] is [code]true[/code], half transparent "feathers" will be attached to the boundary, making outlines smooth. [b]Note:[/b] [param width] is only effective if [param filled] is [code]false[/code]. </description> </method> @@ -105,9 +106,12 @@ <param index="3" name="width" type="float" default="-1.0" /> <param index="4" name="dash" type="float" default="2.0" /> <param index="5" name="aligned" type="bool" default="true" /> + <param index="6" name="antialiased" type="bool" default="false" /> <description> Draws a dashed line from a 2D point to another, with a given color and width. See also [method draw_multiline] and [method draw_polyline]. If [param width] is negative, then a two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the line parts will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code]. + If [param antialiased] is [code]true[/code], half transparent "feathers" will be attached to the boundary, making outlines smooth. + [b]Note:[/b] [param antialiased] is only effective if [param width] is greater than [code]0.0[/code]. </description> </method> <method name="draw_end_animation"> @@ -175,9 +179,11 @@ <param index="0" name="points" type="PackedVector2Array" /> <param index="1" name="color" type="Color" /> <param index="2" name="width" type="float" default="-1.0" /> + <param index="3" name="antialiased" type="bool" default="false" /> <description> Draws multiple disconnected lines with a uniform [param width] and [param color]. Each line is defined by two consecutive points from [param points] array, i.e. i-th segment consists of [code]points[2 * i][/code], [code]points[2 * i + 1][/code] endpoints. When drawing large amounts of lines, this is faster than using individual [method draw_line] calls. To draw interconnected lines, use [method draw_polyline] instead. If [param width] is negative, then two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the lines will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code]. + [b]Note:[/b] [param antialiased] is only effective if [param width] is greater than [code]0.0[/code]. </description> </method> <method name="draw_multiline_colors"> @@ -185,9 +191,11 @@ <param index="0" name="points" type="PackedVector2Array" /> <param index="1" name="colors" type="PackedColorArray" /> <param index="2" name="width" type="float" default="-1.0" /> + <param index="3" name="antialiased" type="bool" default="false" /> <description> Draws multiple disconnected lines with a uniform [param width] and segment-by-segment coloring. Each segment is defined by two consecutive points from [param points] array and a corresponding color from [param colors] array, i.e. i-th segment consists of [code]points[2 * i][/code], [code]points[2 * i + 1][/code] endpoints and has [code]colors[i][/code] color. When drawing large amounts of lines, this is faster than using individual [method draw_line] calls. To draw interconnected lines, use [method draw_polyline_colors] instead. If [param width] is negative, then two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the lines will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code]. + [b]Note:[/b] [param antialiased] is only effective if [param width] is greater than [code]0.0[/code]. </description> </method> <method name="draw_multiline_string" qualifiers="const"> @@ -283,9 +291,11 @@ <param index="1" name="color" type="Color" /> <param index="2" name="filled" type="bool" default="true" /> <param index="3" name="width" type="float" default="-1.0" /> + <param index="4" name="antialiased" type="bool" default="false" /> <description> Draws a rectangle. If [param filled] is [code]true[/code], the rectangle will be filled with the [param color] specified. If [param filled] is [code]false[/code], the rectangle will be drawn as a stroke with the [param color] and [param width] specified. See also [method draw_texture_rect]. If [param width] is negative, then two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the lines will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code]. + If [param antialiased] is [code]true[/code], half transparent "feathers" will be attached to the boundary, making outlines smooth. [b]Note:[/b] [param width] is only effective if [param filled] is [code]false[/code]. [b]Note:[/b] Unfilled rectangles drawn with a negative [param width] may not display perfectly. For example, corners may be missing or brighter due to overlapping lines (for a translucent [param color]). </description> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index ad1028d7f4..cc3acad6d6 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -267,6 +267,9 @@ </method> </methods> <members> + <member name="ignore_invalid_connection_type" type="bool" setter="set_ignore_invalid_connection_type" getter="is_ignoring_valid_connection_type" default="false"> + If [code]true[/code], you can connect ports with different types, even if the connection was not explicitly allowed in the parent [GraphEdit]. + </member> <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="0" /> <member name="title" type="String" setter="set_title" getter="get_title" default=""""> The text displayed in the GraphNode's title bar. diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 110bc133ef..3ddc0d8f7b 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -214,6 +214,7 @@ <param index="1" name="pos" type="Vector2" /> <param index="2" name="radius" type="float" /> <param index="3" name="color" type="Color" /> + <param index="4" name="antialiased" type="bool" default="false" /> <description> Draws a circle on the [CanvasItem] pointed to by the [param item] [RID]. See also [method CanvasItem.draw_circle]. </description> @@ -280,6 +281,7 @@ <param index="1" name="points" type="PackedVector2Array" /> <param index="2" name="colors" type="PackedColorArray" /> <param index="3" name="width" type="float" default="-1.0" /> + <param index="4" name="antialiased" type="bool" default="false" /> <description> Draws a 2D multiline on the [CanvasItem] pointed to by the [param item] [RID]. See also [method CanvasItem.draw_multiline] and [method CanvasItem.draw_multiline_colors]. </description> @@ -356,6 +358,7 @@ <param index="0" name="item" type="RID" /> <param index="1" name="rect" type="Rect2" /> <param index="2" name="color" type="Color" /> + <param index="3" name="antialiased" type="bool" default="false" /> <description> Draws a rectangle on the [CanvasItem] pointed to by the [param item] [RID]. See also [method CanvasItem.draw_rect]. </description> diff --git a/doc/classes/VisualShaderNodeReroute.xml b/doc/classes/VisualShaderNodeReroute.xml new file mode 100644 index 0000000000..1baaa7bbb6 --- /dev/null +++ b/doc/classes/VisualShaderNodeReroute.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeReroute" inherits="VisualShaderNode" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + A node that allows rerouting a connection within the visual shader graph. + </brief_description> + <description> + Automatically adapts its port type to the type of the incoming connection and ensures valid connections. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_port_type" qualifiers="const"> + <return type="int" enum="VisualShaderNode.PortType" /> + <description> + Returns the port type of the reroute node. + </description> + </method> + </methods> +</class> diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index 7856d454d0..a949899ac4 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -547,8 +547,8 @@ ActionMapEditor::ActionMapEditor() { action_list_search_by_event->set_h_size_flags(Control::SIZE_EXPAND_FILL); action_list_search_by_event->set_stretch_ratio(0.75); action_list_search_by_event->connect("event_changed", callable_mp(this, &ActionMapEditor::_search_by_event)); - action_list_search_by_event->connect(SceneStringNames::get_singleton()->focus_entered, callable_mp(this, &ActionMapEditor::_on_filter_focused)); - action_list_search_by_event->connect(SceneStringNames::get_singleton()->focus_exited, callable_mp(this, &ActionMapEditor::_on_filter_unfocused)); + action_list_search_by_event->connect(SceneStringName(focus_entered), callable_mp(this, &ActionMapEditor::_on_filter_focused)); + action_list_search_by_event->connect(SceneStringName(focus_exited), callable_mp(this, &ActionMapEditor::_on_filter_unfocused)); top_hbox->add_child(action_list_search_by_event); Button *clear_all_search = memnew(Button); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index f21a0816ca..28aef2789b 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -2932,7 +2932,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } if (selected || editor->is_selection_active()) { AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (!player->has_animation(SceneStringNames::get_singleton()->RESET) || animation != player->get_animation(SceneStringNames::get_singleton()->RESET)) { + if (!player->has_animation(SceneStringName(RESET)) || animation != player->get_animation(SceneStringName(RESET))) { menu->add_icon_item(get_editor_theme_icon(SNAME("Reload")), TTR("Add RESET Value(s)"), MENU_KEY_ADD_RESET); } @@ -3691,8 +3691,8 @@ void AnimationTrackEditor::_animation_track_remove_request(int p_track, Ref<Anim // Remove corresponding reset tracks if they are no longer needed. AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (player->has_animation(SceneStringNames::get_singleton()->RESET)) { - Ref<Animation> reset = player->get_animation(SceneStringNames::get_singleton()->RESET); + if (player->has_animation(SceneStringName(RESET))) { + Ref<Animation> reset = player->get_animation(SceneStringName(RESET)); if (reset != p_from_animation) { for (int i = 0; i < reset->get_track_count(); i++) { if (reset->track_get_path(i) == p_from_animation->track_get_path(p_track)) { @@ -3798,7 +3798,7 @@ void AnimationTrackEditor::make_insert_queue() { void AnimationTrackEditor::commit_insert_queue() { bool reset_allowed = true; AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (player->has_animation(SceneStringNames::get_singleton()->RESET) && player->get_animation(SceneStringNames::get_singleton()->RESET) == animation) { + if (player->has_animation(SceneStringName(RESET)) && player->get_animation(SceneStringName(RESET)) == animation) { // Avoid messing with the reset animation itself. reset_allowed = false; } else { @@ -4207,8 +4207,8 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() { AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (player->has_animation(SceneStringNames::get_singleton()->RESET)) { - return player->get_animation(SceneStringNames::get_singleton()->RESET); + if (player->has_animation(SceneStringName(RESET))) { + return player->get_animation(SceneStringName(RESET)); } else { Ref<AnimationLibrary> al; AnimationMixer *mixer = AnimationPlayerEditor::get_singleton()->fetch_mixer_for_library(); @@ -4224,9 +4224,9 @@ Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() { reset_anim.instantiate(); reset_anim->set_length(ANIM_MIN_LENGTH); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->add_do_method(al.ptr(), "add_animation", SceneStringNames::get_singleton()->RESET, reset_anim); + undo_redo->add_do_method(al.ptr(), "add_animation", SceneStringName(RESET), reset_anim); undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player); - undo_redo->add_undo_method(al.ptr(), "remove_animation", SceneStringNames::get_singleton()->RESET); + undo_redo->add_undo_method(al.ptr(), "remove_animation", SceneStringName(RESET)); undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player); return reset_anim; } @@ -5024,8 +5024,8 @@ void AnimationTrackEditor::_add_track(int p_type) { void AnimationTrackEditor::_fetch_value_track_options(const NodePath &p_path, Animation::UpdateMode *r_update_mode, Animation::InterpolationType *r_interpolation_type, bool *r_loop_wrap) { AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (player->has_animation(SceneStringNames::get_singleton()->RESET)) { - Ref<Animation> reset_anim = player->get_animation(SceneStringNames::get_singleton()->RESET); + if (player->has_animation(SceneStringName(RESET))) { + Ref<Animation> reset_anim = player->get_animation(SceneStringName(RESET)); int rt = reset_anim->find_track(p_path, Animation::TrackType::TYPE_VALUE); if (rt >= 0) { *r_update_mode = reset_anim->value_track_get_update_mode(rt); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index d0ad0e8b11..fd728dc393 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -3760,6 +3760,14 @@ EditorHelpBit::EditorHelpBit(const String &p_symbol) { /// EditorHelpBitTooltip /// +void EditorHelpBitTooltip::_safe_queue_free() { + if (_pushing_input > 0) { + _need_free = true; + } else { + queue_free(); + } +} + void EditorHelpBitTooltip::_notification(int p_what) { switch (p_what) { case NOTIFICATION_WM_MOUSE_ENTER: @@ -3778,7 +3786,13 @@ void EditorHelpBitTooltip::_input_from_window(const Ref<InputEvent> &p_event) { } else { const Ref<InputEventMouse> mouse_event = p_event; if (mouse_event.is_null()) { + // GH-91652. Prevents use-after-free since `ProgressDialog` calls `Main::iteration()`. + _pushing_input++; get_parent_viewport()->push_input(p_event); + _pushing_input--; + if (_pushing_input <= 0 && _need_free) { + queue_free(); + } } } } @@ -3839,7 +3853,7 @@ EditorHelpBitTooltip::EditorHelpBitTooltip(Control *p_target) { timer = memnew(Timer); timer->set_wait_time(0.2); - timer->connect("timeout", callable_mp(static_cast<Node *>(this), &Node::queue_free)); + timer->connect("timeout", callable_mp(this, &EditorHelpBitTooltip::_safe_queue_free)); add_child(timer); ERR_FAIL_NULL(p_target); diff --git a/editor/editor_help.h b/editor/editor_help.h index ca3a05275f..76f9e71931 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -325,6 +325,10 @@ class EditorHelpBitTooltip : public PopupPanel { GDCLASS(EditorHelpBitTooltip, PopupPanel); Timer *timer = nullptr; + int _pushing_input = 0; + bool _need_free = false; + + void _safe_queue_free(); protected: void _notification(int p_what); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 266901c938..a9c5586ba2 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -50,6 +50,7 @@ #include "scene/property_utils.h" #include "scene/resources/packed_scene.h" #include "scene/resources/style_box_flat.h" +#include "scene/scene_string_names.h" bool EditorInspector::_property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) { if (p_property_path.containsn(p_filter)) { @@ -390,6 +391,17 @@ void EditorProperty::_notification(int p_what) { delete_rect = Rect2(); } } break; + case NOTIFICATION_ENTER_TREE: { + if (has_borders) { + get_parent()->connect(SceneStringName(theme_changed), callable_mp(this, &EditorProperty::_update_property_bg)); + _update_property_bg(); + } + } break; + case NOTIFICATION_EXIT_TREE: { + if (has_borders) { + get_parent()->disconnect(SceneStringName(theme_changed), callable_mp(this, &EditorProperty::_update_property_bg)); + } + } } } @@ -810,6 +822,9 @@ void EditorProperty::set_label_reference(Control *p_control) { void EditorProperty::set_bottom_editor(Control *p_control) { bottom_editor = p_control; + if (has_borders) { + _update_property_bg(); + } } Variant EditorProperty::_get_cache_value(const StringName &p_prop, bool &r_valid) const { @@ -4087,6 +4102,9 @@ void EditorInspector::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { bool needs_update = false; + if (EditorThemeManager::is_generated_theme_outdated() && !sub_inspector) { + add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree"))); + } if (use_settings_name_style && EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/localize_settings")) { EditorPropertyNameProcessor::Style style = EditorPropertyNameProcessor::get_settings_style(); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index b052693524..8fe690fddf 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -136,6 +136,8 @@ private: void _update_pin_flags(); protected: + bool has_borders = false; + void _notification(int p_what); static void _bind_methods(); virtual void _set_read_only(bool p_read_only); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index d7f197b569..e8a0b77184 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -4073,11 +4073,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b EditorDebuggerNode::get_singleton()->update_live_edit_root(); - // Tell everything to edit this object, unless we're in the process of restoring scenes. - // If we are, we'll edit it after the restoration is done. - if (!restoring_scenes) { - push_item(new_scene); - } else { + if (restoring_scenes) { // Initialize history for restored scenes. ObjectID id = new_scene->get_instance_id(); if (id != editor_history.get_current()) { diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 816d3d7778..c73bdafb1a 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -3141,7 +3141,7 @@ void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) // Changing the value of Script-type exported variables of the main script should not trigger saving/reloading properties. bool is_script = false; Ref<Script> s = p_resource; - if (get_edited_object() && s.is_valid() && get_edited_property() == CoreStringNames::get_singleton()->_script) { + if (get_edited_object() && s.is_valid() && get_edited_property() == CoreStringName(script)) { is_script = true; InspectorDock::get_singleton()->store_script_properties(get_edited_object()); s->call("set_instance_base_type", get_edited_object()->get_class()); @@ -3364,8 +3364,6 @@ void EditorPropertyResource::update_property() { EditorNode::get_singleton()->hide_unused_editors(); opened_editor = false; } - - _update_property_bg(); } } } @@ -3422,12 +3420,6 @@ bool EditorPropertyResource::is_colored(ColorationMode p_mode) { void EditorPropertyResource::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_THEME_CHANGED: { - if (EditorThemeManager::is_generated_theme_outdated()) { - _update_property_bg(); - } - } break; - case NOTIFICATION_EXIT_TREE: { const EditorInspector *ei = get_parent_inspector(); if (ei && !ei->is_main_editor_inspector()) { @@ -3439,6 +3431,7 @@ void EditorPropertyResource::_notification(int p_what) { EditorPropertyResource::EditorPropertyResource() { use_sub_inspector = bool(EDITOR_GET("interface/inspector/open_resources_in_current_inspector")); + has_borders = true; } ////////////// DEFAULT PLUGIN ////////////////////// diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index c3142b4cd0..e338c5c8bd 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -391,8 +391,6 @@ void EditorPropertyArray::update_property() { paginator->connect("page_changed", callable_mp(this, &EditorPropertyArray::_page_changed)); vbox->add_child(paginator); - _update_property_bg(); - for (int i = 0; i < page_length; i++) { _create_new_property_slot(); } @@ -454,7 +452,6 @@ void EditorPropertyArray::update_property() { memdelete(container); button_add_item = nullptr; container = nullptr; - _update_property_bg(); slots.clear(); } } @@ -628,10 +625,6 @@ Node *EditorPropertyArray::get_base_node() { void EditorPropertyArray::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: - if (EditorThemeManager::is_generated_theme_outdated()) { - _update_property_bg(); - } - [[fallthrough]]; case NOTIFICATION_ENTER_TREE: { change_type->clear(); for (int i = 0; i < Variant::VARIANT_MAX; i++) { @@ -851,6 +844,7 @@ EditorPropertyArray::EditorPropertyArray() { subtype = Variant::NIL; subtype_hint = PROPERTY_HINT_NONE; subtype_hint_string = ""; + has_borders = true; } ///////////////////// DICTIONARY /////////////////////////// @@ -1000,7 +994,6 @@ void EditorPropertyDictionary::update_property() { paginator = memnew(EditorPaginator); paginator->connect("page_changed", callable_mp(this, &EditorPropertyDictionary::_page_changed)); vbox->add_child(paginator); - _update_property_bg(); for (int i = 0; i < page_length; i++) { _create_new_property_slot(slots.size()); @@ -1075,7 +1068,6 @@ void EditorPropertyDictionary::update_property() { memdelete(container); button_add_item = nullptr; container = nullptr; - _update_property_bg(); add_panel = nullptr; slots.clear(); } @@ -1089,10 +1081,6 @@ void EditorPropertyDictionary::_object_id_selected(const StringName &p_property, void EditorPropertyDictionary::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: - if (EditorThemeManager::is_generated_theme_outdated()) { - _update_property_bg(); - } - [[fallthrough]]; case NOTIFICATION_ENTER_TREE: { change_type->clear(); for (int i = 0; i < Variant::VARIANT_MAX; i++) { @@ -1109,6 +1097,7 @@ void EditorPropertyDictionary::_notification(int p_what) { if (button_add_item) { button_add_item->set_icon(get_editor_theme_icon(SNAME("Add"))); + add_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("DictionaryAddItem"))); } } break; } @@ -1166,6 +1155,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() { add_child(change_type); change_type->connect("id_pressed", callable_mp(this, &EditorPropertyDictionary::_change_type_menu)); changing_type_index = -1; + has_borders = true; } ///////////////////// LOCALIZABLE STRING /////////////////////////// diff --git a/editor/gui/editor_scene_tabs.cpp b/editor/gui/editor_scene_tabs.cpp index 94fac59b9b..b824a90170 100644 --- a/editor/gui/editor_scene_tabs.cpp +++ b/editor/gui/editor_scene_tabs.cpp @@ -63,6 +63,7 @@ void EditorSceneTabs::_notification(int p_what) { if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/scene_tabs")) { scene_tabs->set_tab_close_display_policy((TabBar::CloseButtonDisplayPolicy)EDITOR_GET("interface/scene_tabs/display_close_button").operator int()); scene_tabs->set_max_tab_width(int(EDITOR_GET("interface/scene_tabs/maximum_width")) * EDSCALE); + _scene_tabs_resized(); } } break; } diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp index 5f42bb828f..c454ebc6eb 100644 --- a/editor/import/resource_importer_imagefont.cpp +++ b/editor/import/resource_importer_imagefont.cpp @@ -62,8 +62,8 @@ bool ResourceImporterImageFont::get_option_visibility(const String &p_path, cons void ResourceImporterImageFont::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "character_ranges"), Vector<String>())); r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "kerning_pairs"), Vector<String>())); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "columns"), 1)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "rows"), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "columns", PROPERTY_HINT_RANGE, "1,1024,1,or_greater"), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "rows", PROPERTY_HINT_RANGE, "1,1024,1,or_greater"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::RECT2I, "image_margin"), Rect2i())); r_options->push_back(ImportOption(PropertyInfo(Variant::RECT2I, "character_margin"), Rect2i())); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "ascent"), 0)); @@ -94,6 +94,8 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin Error err = ImageLoader::load_image(p_source_file, img); ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, vformat("Can't load font texture: \"%s\".", p_source_file)); + ERR_FAIL_COND_V_MSG(columns <= 0, ERR_FILE_CANT_READ, vformat("Columns (%d) must be positive.", columns)); + ERR_FAIL_COND_V_MSG(rows <= 0, ERR_FILE_CANT_READ, vformat("Rows (%d) must be positive.", rows)); int count = columns * rows; int chr_cell_width = (img->get_width() - img_margin.position.x - img_margin.size.x) / columns; int chr_cell_height = (img->get_height() - img_margin.position.y - img_margin.size.y) / rows; diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 8de00dfcd1..43d8bc332c 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -984,12 +984,12 @@ void AnimationPlayerEditor::_update_animation_list_icons() { Ref<Texture2D> icon; if (anim_name == player->get_autoplay()) { - if (anim_name == SceneStringNames::get_singleton()->RESET) { + if (anim_name == SceneStringName(RESET)) { icon = autoplay_reset_icon; } else { icon = autoplay_icon; } - } else if (anim_name == SceneStringNames::get_singleton()->RESET) { + } else if (anim_name == SceneStringName(RESET)) { icon = reset_icon; } @@ -1459,7 +1459,7 @@ void AnimationPlayerEditor::_onion_skinning_menu(int p_option) { onion.enabled = !onion.enabled; if (onion.enabled) { - if (get_player() && !get_player()->has_animation(SceneStringNames::get_singleton()->RESET)) { + if (get_player() && !get_player()->has_animation(SceneStringName(RESET))) { EditorNode::get_singleton()->show_warning(TTR("Onion skinning requires a RESET animation.")); } _start_onion_skinning(); // It will check for RESET animation anyway. @@ -1592,7 +1592,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_1() { return; } - if (!onion.enabled || !is_visible() || !get_player() || !get_player()->has_animation(SceneStringNames::get_singleton()->RESET)) { + if (!onion.enabled || !is_visible() || !get_player() || !get_player()->has_animation(SceneStringName(RESET))) { _stop_onion_skinning(); return; } @@ -1783,7 +1783,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2_epilog() { } void AnimationPlayerEditor::_start_onion_skinning() { - if (get_player() && !get_player()->has_animation(SceneStringNames::get_singleton()->RESET)) { + if (get_player() && !get_player()->has_animation(SceneStringName(RESET))) { onion.enabled = false; onion_toggle->set_pressed_no_signal(false); return; diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index f24747d903..1314b26b1a 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -119,7 +119,7 @@ String AnimationNodeStateMachineEditor::_get_root_playback_path(String &r_node_d if (node_directory_path.size()) { r_node_directory += "/"; } - base_path = !edited_path.size() ? String(SceneStringNames::get_singleton()->parameters_base_path) + "playback" : String(SceneStringNames::get_singleton()->parameters_base_path) + base_path + "/playback"; + base_path = !edited_path.size() ? String(SceneStringName(parameters_base_path)) + "playback" : String(SceneStringName(parameters_base_path)) + base_path + "/playback"; } else { // Hmmm, we have to return Grouped state machine playback... // It will give the user the error that Root/Nested state machine should be retrieved, that would be kind :-) diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index c7f132bec1..08e3cb34a4 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -221,7 +221,7 @@ void AnimationTreeEditor::remove_plugin(AnimationTreeNodeEditorPlugin *p_editor) } String AnimationTreeEditor::get_base_path() { - String path = SceneStringNames::get_singleton()->parameters_base_path; + String path = SceneStringName(parameters_base_path); for (int i = 0; i < edited_path.size(); i++) { path += edited_path[i] + "/"; } diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 258396ff31..b2ff03a6d3 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -387,7 +387,7 @@ void CollisionShape2DEditor::_shape_changed() { canvas_item_editor->update_viewport(); if (current_shape.is_valid()) { - current_shape->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); + current_shape->disconnect_changed(callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); current_shape = Ref<Shape2D>(); shape_type = -1; } @@ -399,7 +399,7 @@ void CollisionShape2DEditor::_shape_changed() { current_shape = node->get_shape(); if (current_shape.is_valid()) { - current_shape->connect(SceneStringNames::get_singleton()->changed, callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); + current_shape->connect_changed(callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); } else { return; } diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 92c9572a02..ce99b87a60 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -172,14 +172,14 @@ void MeshInstance3DEditor::_create_collision_shape() { ur->add_do_method(instance, "add_child", body, true); ur->add_do_method(body, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, body); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringName(_request_gizmo), body); for (Ref<Shape3D> shape : shapes) { CollisionShape3D *cshape = memnew(CollisionShape3D); cshape->set_shape(shape); body->add_child(cshape, true); ur->add_do_method(cshape, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, cshape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringName(_request_gizmo), cshape); } ur->add_do_reference(body); ur->add_undo_method(instance, "remove_child", body); @@ -191,7 +191,7 @@ void MeshInstance3DEditor::_create_collision_shape() { cshape->set_transform(node->get_transform()); ur->add_do_method(E, "add_sibling", cshape, true); ur->add_do_method(cshape, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, cshape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringName(_request_gizmo), cshape); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); } @@ -232,7 +232,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node, "add_child", nmi, true); ur->add_do_method(nmi, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, nmi); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringName(_request_gizmo), nmi); ur->add_do_reference(nmi); ur->add_undo_method(node, "remove_child", nmi); @@ -509,7 +509,7 @@ void MeshInstance3DEditor::_create_outline_mesh() { ur->add_do_method(node, "add_child", mi, true); ur->add_do_method(mi, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, mi); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringName(_request_gizmo), mi); ur->add_do_reference(mi); ur->add_undo_method(node, "remove_child", mi); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 723dbf5d6c..23937fa330 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -973,7 +973,7 @@ void ScriptEditor::_queue_close_tabs() { // Maybe there are unsaved changes. if (se->is_unsaved()) { _ask_close_current_unsaved_tab(se); - erase_tab_confirm->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &ScriptEditor::_queue_close_tabs), CONNECT_ONE_SHOT); + erase_tab_confirm->connect(SceneStringName(visibility_changed), callable_mp(this, &ScriptEditor::_queue_close_tabs), CONNECT_ONE_SHOT); break; } } @@ -4238,7 +4238,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { autosave_timer = memnew(Timer); autosave_timer->set_one_shot(false); - autosave_timer->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &ScriptEditor::_update_autosave_timer)); + autosave_timer->connect(SceneStringName(tree_entered), callable_mp(this, &ScriptEditor::_update_autosave_timer)); autosave_timer->connect("timeout", callable_mp(this, &ScriptEditor::_autosave_scripts)); add_child(autosave_timer); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 1bd6b4e5b1..c80dc1ea77 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -410,8 +410,8 @@ void Skeleton3DEditor::create_physical_skeleton() { ur->add_do_method(physical_bone, "set_joint_type", PhysicalBone3D::JOINT_TYPE_PIN); } - ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, physical_bone); - ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, collision_shape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringName(_request_gizmo), physical_bone); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringName(_request_gizmo), collision_shape); ur->add_do_reference(physical_bone); ur->add_undo_method(simulator, "remove_child", physical_bone); @@ -842,10 +842,10 @@ void Skeleton3DEditor::_notification(int p_what) { joint_tree->connect("item_selected", callable_mp(this, &Skeleton3DEditor::_joint_tree_selection_changed)); joint_tree->connect("item_mouse_selected", callable_mp(this, &Skeleton3DEditor::_joint_tree_rmb_select)); #ifdef TOOLS_ENABLED - skeleton->connect(SceneStringNames::get_singleton()->pose_updated, callable_mp(this, &Skeleton3DEditor::_draw_gizmo)); - skeleton->connect(SceneStringNames::get_singleton()->pose_updated, callable_mp(this, &Skeleton3DEditor::_update_properties)); - skeleton->connect(SceneStringNames::get_singleton()->bone_enabled_changed, callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed)); - skeleton->connect(SceneStringNames::get_singleton()->show_rest_only_changed, callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible)); + skeleton->connect(SceneStringName(pose_updated), callable_mp(this, &Skeleton3DEditor::_draw_gizmo)); + skeleton->connect(SceneStringName(pose_updated), callable_mp(this, &Skeleton3DEditor::_update_properties)); + skeleton->connect(SceneStringName(bone_enabled_changed), callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed)); + skeleton->connect(SceneStringName(show_rest_only_changed), callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible)); #endif get_tree()->connect("node_removed", callable_mp(this, &Skeleton3DEditor::_node_removed), Object::CONNECT_ONE_SHOT); @@ -870,10 +870,10 @@ void Skeleton3DEditor::_notification(int p_what) { if (skeleton) { select_bone(-1); // Requires that the joint_tree has not been deleted. #ifdef TOOLS_ENABLED - skeleton->disconnect(SceneStringNames::get_singleton()->show_rest_only_changed, callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible)); - skeleton->disconnect(SceneStringNames::get_singleton()->bone_enabled_changed, callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed)); - skeleton->disconnect(SceneStringNames::get_singleton()->pose_updated, callable_mp(this, &Skeleton3DEditor::_draw_gizmo)); - skeleton->disconnect(SceneStringNames::get_singleton()->pose_updated, callable_mp(this, &Skeleton3DEditor::_update_properties)); + skeleton->disconnect(SceneStringName(show_rest_only_changed), callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible)); + skeleton->disconnect(SceneStringName(bone_enabled_changed), callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed)); + skeleton->disconnect(SceneStringName(pose_updated), callable_mp(this, &Skeleton3DEditor::_draw_gizmo)); + skeleton->disconnect(SceneStringName(pose_updated), callable_mp(this, &Skeleton3DEditor::_update_properties)); skeleton->set_transform_gizmo_visible(true); #endif if (handles_mesh_instance->get_parent()) { diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp index 1d32965b4a..f52c89e736 100644 --- a/editor/plugins/text_shader_editor.cpp +++ b/editor/plugins/text_shader_editor.cpp @@ -49,6 +49,11 @@ Dictionary GDShaderSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l for (const Point2i ®ion : disabled_branch_regions) { if (p_line >= region.x && p_line <= region.y) { + // When "color_regions[0].p_start_key.length() > 2", + // disabled_branch_region causes color_region to break. + // This should be seen as a temporary solution. + CodeHighlighter::_get_line_syntax_highlighting_impl(p_line); + Dictionary highlighter_info; highlighter_info["color"] = disabled_branch_color; diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 1a1b14bb84..2878472c7b 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -135,7 +135,7 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::edit(Ref<TileSet> // Disconnect to changes. if (tile_set_atlas_source.is_valid()) { - tile_set_atlas_source->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + tile_set_atlas_source->disconnect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } tile_set = p_tile_set; @@ -144,8 +144,8 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::edit(Ref<TileSet> // Connect to changes. if (tile_set_atlas_source.is_valid()) { - if (!tile_set_atlas_source->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) { - tile_set_atlas_source->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + if (!tile_set_atlas_source->is_connected(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed))) { + tile_set_atlas_source->connect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } } @@ -522,8 +522,8 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::edit(Ref<TileSetAtlasSource if (tile_set_atlas_source.is_valid() && tile_set_atlas_source->has_tile(coords) && tile_set_atlas_source->has_alternative_tile(coords, alternative)) { TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); - if (tile_data->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) { - tile_data->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + if (tile_data->is_connected(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed))) { + tile_data->disconnect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } } } @@ -538,8 +538,8 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::edit(Ref<TileSetAtlasSource if (tile_set_atlas_source->has_tile(coords) && tile_set_atlas_source->has_alternative_tile(coords, alternative)) { TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); - if (!tile_data->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) { - tile_data->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + if (!tile_data->is_connected(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed))) { + tile_data->connect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } } } diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index e0151351b5..f42fac6d59 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -117,7 +117,7 @@ void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::ed // Disconnect to changes. if (tile_set_scenes_collection_source) { - tile_set_scenes_collection_source->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + tile_set_scenes_collection_source->disconnect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } tile_set = p_tile_set; @@ -126,8 +126,8 @@ void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::ed // Connect to changes. if (tile_set_scenes_collection_source) { - if (!tile_set_scenes_collection_source->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) { - tile_set_scenes_collection_source->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + if (!tile_set_scenes_collection_source->is_connected(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed))) { + tile_set_scenes_collection_source->connect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 35db52a42e..5cb5f5660e 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -45,6 +45,7 @@ #include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/shader_editor_plugin.h" #include "editor/themes/editor_scale.h" +#include "scene/animation/tween.h" #include "scene/gui/button.h" #include "scene/gui/check_box.h" #include "scene/gui/code_edit.h" @@ -104,6 +105,83 @@ void VisualShaderNodePlugin::_bind_methods() { /////////////////// +void VSGraphNode::_draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color, const Color &p_rim_color) { + Ref<Texture2D> port_icon = p_left ? get_slot_custom_icon_left(p_slot_index) : get_slot_custom_icon_right(p_slot_index); + + Point2 icon_offset; + if (!port_icon.is_valid()) { + port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); + } + + icon_offset = -port_icon->get_size() * 0.5; + + // Draw "shadow"/outline in the connection rim color. + draw_texture_rect(port_icon, Rect2(p_pos + icon_offset - Size2(2, 2), port_icon->get_size() + Size2(4, 4)), false, p_rim_color); + draw_texture(port_icon, p_pos + icon_offset, p_color); +} + +void VSGraphNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) { + Color rim_color = get_theme_color(SNAME("connection_rim_color"), SNAME("GraphEdit")); + _draw_port(p_slot_index, p_pos, p_left, p_color, rim_color); +} + +/////////////////// + +void VSRerouteNode::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + connect("mouse_entered", callable_mp(this, &VSRerouteNode::_on_mouse_entered)); + connect("mouse_exited", callable_mp(this, &VSRerouteNode::_on_mouse_exited)); + } break; + case NOTIFICATION_DRAW: { + Vector2 offset = Vector2(0, -16); + Color drag_bg_color = get_theme_color(SNAME("drag_background"), SNAME("VSRerouteNode")); + draw_circle(get_size() * 0.5 + offset, 16, Color(drag_bg_color, selected ? 1 : icon_opacity)); + + Ref<Texture2D> icon = get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")); + Point2 icon_offset = -icon->get_size() * 0.5 + get_size() * 0.5 + offset; + draw_texture(icon, icon_offset, Color(1, 1, 1, selected ? 1 : icon_opacity)); + } break; + } +} + +void VSRerouteNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) { + Color rim_color = selected ? get_theme_color("selected_rim_color", "VSRerouteNode") : get_theme_color("connection_rim_color", "GraphEdit"); + _draw_port(p_slot_index, p_pos, p_left, p_color, rim_color); +} + +VSRerouteNode::VSRerouteNode() { + Label *title_lbl = Object::cast_to<Label>(get_titlebar_hbox()->get_child(0)); + title_lbl->hide(); + + const Size2 size = Size2(32, 32) * EDSCALE; + + Control *slot_area = memnew(Control); + slot_area->set_custom_minimum_size(size); + slot_area->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); + add_child(slot_area); + + // Lay the input and output ports on top of each other to create the illusion of a single port. + add_theme_constant_override("port_h_offset", size.width / 2); +} + +void VSRerouteNode::set_icon_opacity(float p_opacity) { + icon_opacity = p_opacity; + queue_redraw(); +} + +void VSRerouteNode::_on_mouse_entered() { + Ref<Tween> tween = create_tween(); + tween->tween_method(callable_mp(this, &VSRerouteNode::set_icon_opacity), 0.0, 1.0, FADE_ANIMATION_LENGTH_SEC); +} + +void VSRerouteNode::_on_mouse_exited() { + Ref<Tween> tween = create_tween(); + tween->tween_method(callable_mp(this, &VSRerouteNode::set_icon_opacity), 1.0, 0.0, FADE_ANIMATION_LENGTH_SEC); +} + +/////////////////// + VisualShaderGraphPlugin::VisualShaderGraphPlugin() { vs_msdf_fonts_theme.instantiate(); } @@ -376,6 +454,15 @@ void VisualShaderGraphPlugin::set_frame_autoshrink_enabled(VisualShader::Type p_ frame->set_autoshrink_enabled(p_enable); } +void VisualShaderGraphPlugin::update_reroute_nodes() { + for (const KeyValue<int, Link> &E : links) { + Ref<VisualShaderNodeReroute> reroute_node = Object::cast_to<VisualShaderNodeReroute>(E.value.visual_node); + if (reroute_node.is_valid()) { + update_node(visual_shader->get_shader_type(), E.key); + } + } +} + Ref<Script> VisualShaderGraphPlugin::get_node_script(int p_node_id) const { if (!links.has(p_node_id)) { return Ref<Script>(); @@ -572,6 +659,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool bool is_expression = expression_node.is_valid(); String expression = ""; + Ref<VisualShaderNodeReroute> reroute_node = vsnode; + bool is_reroute = reroute_node.is_valid(); + Ref<VisualShaderNodeCustom> custom_node = vsnode; if (custom_node.is_valid()) { custom_node->_set_initialized(true); @@ -582,8 +672,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool GraphFrame *frame = memnew(GraphFrame); frame->set_title(vsnode->get_caption()); node = frame; + } else if (is_reroute) { + VSRerouteNode *reroute_gnode = memnew(VSRerouteNode); + reroute_gnode->set_ignore_invalid_connection_type(true); + node = reroute_gnode; } else { - GraphNode *gnode = memnew(GraphNode); + VSGraphNode *gnode = memnew(VSGraphNode); gnode->set_title(vsnode->get_caption()); node = gnode; } @@ -598,7 +692,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool node->set_theme(vs_msdf_fonts_theme); // Set the node's titlebar color based on its category. - if (vsnode->get_category() != VisualShaderNode::CATEGORY_NONE) { + if (vsnode->get_category() != VisualShaderNode::CATEGORY_NONE && !is_frame && !is_reroute) { Ref<StyleBoxFlat> sb_colored = editor->get_theme_stylebox("titlebar", "GraphNode")->duplicate(); sb_colored->set_bg_color(category_color[vsnode->get_category()]); node->add_theme_style_override("titlebar", sb_colored); @@ -685,9 +779,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool return; } - Control *content_offset = memnew(Control); - content_offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); - node->add_child(content_offset); + if (!is_reroute) { + Control *content_offset = memnew(Control); + content_offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); + node->add_child(content_offset); + } if (is_group) { port_offset += 1; @@ -696,7 +792,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool // Set the minimum width of a node based on the preview size to avoid a resize when toggling the preview. Ref<StyleBoxFlat> graph_node_stylebox = graph->get_theme_stylebox("panel", "GraphNode"); int port_preview_size = EDITOR_GET("editors/visual_editors/visual_shader/port_preview_size"); - node->set_custom_minimum_size(Size2((Math::ceil(graph_node_stylebox->get_minimum_size().width) + port_preview_size) * EDSCALE, 0)); + if (!is_frame && !is_reroute) { + node->set_custom_minimum_size(Size2((Math::ceil(graph_node_stylebox->get_minimum_size().width) + port_preview_size) * EDSCALE, 0)); + } Ref<VisualShaderNodeParticleEmit> emit = vsnode; if (emit.is_valid()) { @@ -1129,7 +1227,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool port_offset++; } - if (!is_first_hbox) { + if (!is_first_hbox && !is_reroute) { node->add_child(hb); if (curve_xyz.is_valid()) { node->move_child(hb, 1 + expanded_port_counter); @@ -1140,9 +1238,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool continue; } - int idx = 1; - if (!is_first_hbox) { - idx = i + port_offset; + int idx = is_first_hbox ? 1 : i + port_offset; + if (is_reroute) { + idx = 0; } if (!is_frame) { GraphNode *graph_node = Object::cast_to<GraphNode>(node); @@ -1243,7 +1341,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool if (vsnode->get_output_port_for_preview() >= 0) { has_relative_parameter_instances = is_node_has_parameter_instances_relatively(p_type, p_id); show_port_preview(p_type, p_id, vsnode->get_output_port_for_preview(), !has_relative_parameter_instances); - } else { + } else if (!is_reroute) { offset = memnew(Control); offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE)); node->add_child(offset); @@ -1342,6 +1440,13 @@ void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_fro } if (visual_shader.is_valid() && visual_shader->get_shader_type() == p_type) { + // Update reroute nodes since their port type might have changed. + Ref<VisualShaderNodeReroute> reroute_to = visual_shader->get_node(p_type, p_to_node); + Ref<VisualShaderNodeReroute> reroute_from = visual_shader->get_node(p_type, p_from_node); + if (reroute_to.is_valid() || reroute_from.is_valid()) { + update_reroute_nodes(); + } + graph->connect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port); connections.push_back({ p_from_node, p_from_port, p_to_node, p_to_port }); @@ -1954,6 +2059,7 @@ void VisualShaderEditor::_update_options_menu() { static Vector<String> type_filter_exceptions; if (type_filter_exceptions.is_empty()) { type_filter_exceptions.append("VisualShaderNodeExpression"); + type_filter_exceptions.append("VisualShaderNodeReroute"); } for (int i = 0; i < add_options.size(); i++) { @@ -3478,6 +3584,8 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, cons frame->set_size(Size2(320 * EDSCALE, 180 * EDSCALE)); } + Ref<VisualShaderNodeReroute> reroute = vsnode; + bool created_expression_port = false; // A node is inserted in an already present connection. @@ -3488,6 +3596,61 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, cons undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, to_node, to_slot); } + // Create a connection from the output port of an existing node to the new one. + if (from_node != -1 && from_slot != -1) { + VisualShaderNode::PortType output_port_type = visual_shader->get_node(type, from_node)->get_output_port_type(from_slot); + + if (expr && expr->is_editable()) { + expr->add_input_port(0, output_port_type, "input0"); + created_expression_port = true; + } + + if (vsnode->get_input_port_count() > 0 || created_expression_port) { + int _to_node = id_to_use; + + if (created_expression_port) { + int _to_slot = 0; + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); + } else { + int _to_slot = -1; + + // Attempting to connect to the default input port or to the first correct port (if it's not found). + for (int i = 0; i < vsnode->get_input_port_count(); i++) { + if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i)) || reroute.is_valid()) { + if (i == vsnode->get_default_input_port(output_port_type)) { + _to_slot = i; + break; + } else if (_to_slot == -1) { + _to_slot = i; + } + } + } + + if (_to_slot >= 0) { + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); + } + } + + if (output_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) { + if (is_texture2d) { + undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeTexture::SOURCE_PORT); + } + if (is_texture3d || is_texture2d_array) { + undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeSample3D::SOURCE_PORT); + } + if (is_cubemap) { + undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeCubemap::SOURCE_PORT); + } + } + } + } + // Create a connection from the new node to an input port of an existing one. if (to_node != -1 && to_slot != -1) { VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot); @@ -3548,7 +3711,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, cons // Attempting to connect to the first correct port. for (int i = 0; i < vsnode->get_output_port_count(); i++) { - if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(i), input_port_type)) { + if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(i), input_port_type) || reroute.is_valid()) { undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); @@ -3560,60 +3723,6 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, cons } } - // Create a connection from the output port of an existing node to the new one. - if (from_node != -1 && from_slot != -1) { - VisualShaderNode::PortType output_port_type = visual_shader->get_node(type, from_node)->get_output_port_type(from_slot); - - if (expr && expr->is_editable()) { - expr->add_input_port(0, output_port_type, "input0"); - created_expression_port = true; - } - - if (vsnode->get_input_port_count() > 0 || created_expression_port) { - int _to_node = id_to_use; - - if (created_expression_port) { - int _to_slot = 0; - undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); - undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); - undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); - } else { - int _to_slot = -1; - - // Attempting to connect to the default input port or to the first correct port (if it's not found). - for (int i = 0; i < vsnode->get_input_port_count(); i++) { - if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i))) { - if (i == vsnode->get_default_input_port(output_port_type)) { - _to_slot = i; - break; - } else if (_to_slot == -1) { - _to_slot = i; - } - } - } - - if (_to_slot >= 0) { - undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); - undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); - undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); - } - } - - if (output_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) { - if (is_texture2d) { - undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeTexture::SOURCE_PORT); - } - if (is_texture3d || is_texture2d_array) { - undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeSample3D::SOURCE_PORT); - } - if (is_cubemap) { - undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeCubemap::SOURCE_PORT); - } - } - } - } _member_cancel(); if (is_parameter) { @@ -3836,6 +3945,9 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index); undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index); + + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, from); + undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", (int)type, from); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, to); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", (int)type, to); undo_redo->commit_action(); @@ -3931,10 +4043,12 @@ bool VisualShaderEditor::_check_node_drop_on_connection(const Vector2 &p_positio VisualShaderNode::PortType original_port_type_from = visual_shader->get_node(shader_type, String(intersecting_connection->from_node).to_int())->get_output_port_type(intersecting_connection->from_port); VisualShaderNode::PortType original_port_type_to = visual_shader->get_node(shader_type, String(intersecting_connection->to_node).to_int())->get_input_port_type(intersecting_connection->to_port); + Ref<VisualShaderNodeReroute> reroute_node = selected_vsnode; + // Searching for the default port or the first compatible input port of the node to insert. int _to_port = -1; for (int i = 0; i < selected_vsnode->get_input_port_count(); i++) { - if (visual_shader->is_port_types_compatible(original_port_type_from, selected_vsnode->get_input_port_type(i))) { + if (visual_shader->is_port_types_compatible(original_port_type_from, selected_vsnode->get_input_port_type(i)) || reroute_node.is_valid()) { if (i == selected_vsnode->get_default_input_port(original_port_type_from)) { _to_port = i; break; @@ -3947,7 +4061,7 @@ bool VisualShaderEditor::_check_node_drop_on_connection(const Vector2 &p_positio // Searching for the first compatible output port of the node to insert. int _from_port = -1; for (int i = 0; i < selected_vsnode->get_output_port_count(); i++) { - if (visual_shader->is_port_types_compatible(selected_vsnode->get_output_port_type(i), original_port_type_to)) { + if (visual_shader->is_port_types_compatible(selected_vsnode->get_output_port_type(i), original_port_type_to) || reroute_node.is_valid()) { _from_port = i; break; } @@ -4529,6 +4643,8 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<GraphEdit::Connection> closest_connection = graph->get_closest_connection_at_point(menu_point); if (closest_connection.is_valid()) { clicked_connection = closest_connection; + saved_node_pos = graph->get_local_mouse_position(); + saved_node_pos_dirty = true; connection_popup_menu->set_position(gpos); connection_popup_menu->reset_size(); connection_popup_menu->popup(); @@ -5628,6 +5744,25 @@ void VisualShaderEditor::_connection_menu_id_pressed(int p_idx) { connection_node_insert_requested = true; _show_members_dialog(true, input_port_type, output_port_type); } break; + case ConnectionMenuOptions::INSERT_NEW_REROUTE: { + from_node = String(clicked_connection->from_node).to_int(); + from_slot = clicked_connection->from_port; + to_node = String(clicked_connection->to_node).to_int(); + to_slot = clicked_connection->to_port; + + // Manual offset to place the port exactly at the mouse position. + saved_node_pos -= Vector2(11 * EDSCALE * graph->get_zoom(), 50 * EDSCALE * graph->get_zoom()); + + // Find reroute addoptions. + int idx = -1; + for (int i = 0; i < add_options.size(); i++) { + if (add_options[i].name == "Reroute") { + idx = i; + break; + } + } + _add_node(idx, add_options[idx].ops); + } break; default: break; } @@ -6123,6 +6258,7 @@ VisualShaderEditor::VisualShaderEditor() { add_child(connection_popup_menu); connection_popup_menu->add_item(TTR("Disconnect"), ConnectionMenuOptions::DISCONNECT); connection_popup_menu->add_item(TTR("Insert New Node"), ConnectionMenuOptions::INSERT_NEW_NODE); + connection_popup_menu->add_item(TTR("Insert New Reroute"), ConnectionMenuOptions::INSERT_NEW_REROUTE); connection_popup_menu->connect("id_pressed", callable_mp(this, &VisualShaderEditor::_connection_menu_id_pressed)); /////////////////////////////////////// @@ -6962,6 +7098,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("VaryingSetter", "Special", "VisualShaderNodeVaryingSetter", TTR("Set varying parameter."), {}, -1, TYPE_FLAGS_VERTEX | TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("VaryingGetter", "Special", "VisualShaderNodeVaryingGetter", TTR("Get varying parameter."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("VaryingSetter", "Special", "VisualShaderNodeVaryingSetter", TTR("Set varying parameter."), {}, -1, TYPE_FLAGS_VERTEX | TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Reroute", "Special", "VisualShaderNodeReroute", TTR("Reroute connections freely, can be used to connect multiple input ports to single output port."))); custom_node_option_idx = add_options.size(); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 246e44a40d..ee2bf605d9 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -66,6 +66,34 @@ public: virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node); }; +class VSGraphNode : public GraphNode { + GDCLASS(VSGraphNode, GraphNode); + +protected: + void _draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color, const Color &p_rim_color); + virtual void draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) override; +}; + +class VSRerouteNode : public VSGraphNode { + GDCLASS(VSRerouteNode, GraphNode); + + const float FADE_ANIMATION_LENGTH_SEC = 0.3; + + float icon_opacity = 0.0; + +protected: + void _notification(int p_what); + + virtual void draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) override; + +public: + VSRerouteNode(); + void set_icon_opacity(float p_opacity); + + void _on_mouse_entered(); + void _on_mouse_exited(); +}; + class VisualShaderGraphPlugin : public RefCounted { GDCLASS(VisualShaderGraphPlugin, RefCounted); @@ -140,6 +168,7 @@ public: void set_frame_color_enabled(VisualShader::Type p_type, int p_node_id, bool p_enable); void set_frame_color(VisualShader::Type p_type, int p_node_id, const Color &p_color); void set_frame_autoshrink_enabled(VisualShader::Type p_type, int p_node_id, bool p_enable); + void update_reroute_nodes(); int get_constant_index(float p_constant) const; Ref<Script> get_node_script(int p_node_id) const; void update_theme(); @@ -297,6 +326,7 @@ class VisualShaderEditor : public VBoxContainer { enum ConnectionMenuOptions { INSERT_NEW_NODE, + INSERT_NEW_REROUTE, DISCONNECT, }; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 6f0a8bc909..cb379c198f 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -4357,7 +4357,6 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec scene_tree->set_v_size_flags(SIZE_EXPAND | SIZE_FILL); scene_tree->connect("rmb_pressed", callable_mp(this, &SceneTreeDock::_tree_rmb)); - scene_tree->connect("node_selected", callable_mp(this, &SceneTreeDock::_node_selected), CONNECT_DEFERRED); scene_tree->connect("node_renamed", callable_mp(this, &SceneTreeDock::_node_renamed), CONNECT_DEFERRED); scene_tree->connect("node_prerename", callable_mp(this, &SceneTreeDock::_node_prerenamed)); scene_tree->connect("open", callable_mp(this, &SceneTreeDock::_load_request)); diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index 2ef62c60a2..7417d14bf3 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -1650,7 +1650,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the p_theme->set_stylebox("titlebar_selected", "GraphFrame", make_empty_stylebox(4, 4, 4, 4)); p_theme->set_color("resizer_color", "GraphFrame", gn_decoration_color); - // GraphFrame's title Label + // GraphFrame's title Label. p_theme->set_type_variation("GraphFrameTitleLabel", "Label"); p_theme->set_stylebox("normal", "GraphFrameTitleLabel", memnew(StyleBoxEmpty)); p_theme->set_font_size("font_size", "GraphFrameTitleLabel", 22); @@ -1663,6 +1663,21 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the p_theme->set_constant("shadow_outline_size", "GraphFrameTitleLabel", 1 * EDSCALE); p_theme->set_constant("line_spacing", "GraphFrameTitleLabel", 3 * EDSCALE); } + + // VisualShader reroute node. + { + Ref<StyleBox> vs_reroute_panel_style = make_empty_stylebox(); + Ref<StyleBox> vs_reroute_titlebar_style = vs_reroute_panel_style->duplicate(); + vs_reroute_titlebar_style->set_content_margin_all(16); + p_theme->set_stylebox("panel", "VSRerouteNode", vs_reroute_panel_style); + p_theme->set_stylebox("panel_selected", "VSRerouteNode", vs_reroute_panel_style); + p_theme->set_stylebox("titlebar", "VSRerouteNode", vs_reroute_titlebar_style); + p_theme->set_stylebox("titlebar_selected", "VSRerouteNode", vs_reroute_titlebar_style); + p_theme->set_stylebox("slot", "VSRerouteNode", make_empty_stylebox()); + + p_theme->set_color("drag_background", "VSRerouteNode", p_config.dark_theme ? Color(0.19, 0.21, 0.24) : Color(0.8, 0.8, 0.8)); + p_theme->set_color("selected_rim_color", "VSRerouteNode", p_config.dark_theme ? Color(1, 1, 1) : Color(0, 0, 0)); + } } // ColorPicker and related nodes. diff --git a/main/SCsub b/main/SCsub index 3e7680bf89..27b746a937 100644 --- a/main/SCsub +++ b/main/SCsub @@ -20,7 +20,7 @@ env_main.CommandNoCache( env.Run(main_builders.make_splash), ) -if not env_main["no_editor_splash"]: +if env_main.editor_build and not env_main["no_editor_splash"]: env_main.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png") env_main.CommandNoCache( "#main/splash_editor.gen.h", diff --git a/main/main.cpp b/main/main.cpp index 1ba336221f..bcd7d8df22 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -104,7 +104,7 @@ #include "editor/project_manager.h" #include "editor/register_editor_types.h" -#ifndef NO_EDITOR_SPLASH +#if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) #include "main/splash_editor.gen.h" #endif diff --git a/misc/extension_api_validation/4.2-stable.expected b/misc/extension_api_validation/4.2-stable.expected index d7bb67cfbc..6761512c15 100644 --- a/misc/extension_api_validation/4.2-stable.expected +++ b/misc/extension_api_validation/4.2-stable.expected @@ -344,3 +344,16 @@ GH-91143 Validate extension JSON: Error: Field 'classes/Input/methods/vibrate_handheld/arguments': size changed value in new API, from 1 to 2. Added optional argument. Compatibility method registered. + + +GH-84523 +-------- +Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_dashed_line/arguments': size changed value in new API, from 6 to 7. +Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_multiline/arguments': size changed value in new API, from 3 to 4. +Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_multiline_colors/arguments': size changed value in new API, from 3 to 4. +Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_rect/arguments': size changed value in new API, from 4 to 5. +Validate extension JSON: Error: Field 'classes/RenderingServer/methods/canvas_item_add_circle/arguments': size changed value in new API, from 4 to 5. +Validate extension JSON: Error: Field 'classes/RenderingServer/methods/canvas_item_add_multiline/arguments': size changed value in new API, from 4 to 5. +Validate extension JSON: Error: Field 'classes/RenderingServer/methods/canvas_item_add_rect/arguments': size changed value in new API, from 3 to 4. + +Optional arguments added. Compatibility methods registered. diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 19b264d764..88383554b6 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2038,15 +2038,15 @@ void GDScriptInstance::notification(int p_notification, bool p_reversed) { } String GDScriptInstance::to_string(bool *r_valid) { - if (has_method(CoreStringNames::get_singleton()->_to_string)) { + if (has_method(CoreStringName(_to_string))) { Callable::CallError ce; - Variant ret = callp(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce); + Variant ret = callp(CoreStringName(_to_string), nullptr, 0, ce); if (ce.error == Callable::CallError::CALL_OK) { if (ret.get_type() != Variant::STRING) { if (r_valid) { *r_valid = false; } - ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String."); + ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringName(_to_string) + ", must be a String."); } if (r_valid) { *r_valid = true; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 4b6cc47218..ac5564cf12 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -231,7 +231,7 @@ bool GDScriptAnalyzer::has_member_name_conflict_in_native_type(const StringName if (ClassDB::has_integer_constant(p_native_type_string, p_member_name)) { return true; } - if (p_member_name == CoreStringNames::get_singleton()->_script) { + if (p_member_name == CoreStringName(script)) { return true; } @@ -2172,7 +2172,7 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) { List<GDScriptParser::DataType> par_types; int default_arg_count = 0; BitField<MethodFlags> method_flags; - if (get_function_signature(p_for->list, false, list_type, CoreStringNames::get_singleton()->_iter_get, return_type, par_types, default_arg_count, method_flags)) { + if (get_function_signature(p_for->list, false, list_type, CoreStringName(_iter_get), return_type, par_types, default_arg_count, method_flags)) { variable_type = return_type; variable_type.type_source = list_type.type_source; } else if (!list_type.is_hard_type()) { diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 01e5751dc8..4f8a554ce1 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -346,7 +346,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code scr = scr->_base; } - if (nc && (identifier == CoreStringNames::get_singleton()->_free || ClassDB::has_signal(nc->get_name(), identifier) || ClassDB::has_method(nc->get_name(), identifier))) { + if (nc && (identifier == CoreStringName(free_) || ClassDB::has_signal(nc->get_name(), identifier) || ClassDB::has_method(nc->get_name(), identifier))) { // Get like it was a property. GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here. GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF); diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 11bd1d224a..1efa9ece0d 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -1741,7 +1741,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (base_type == Variant::OBJECT) { if (base_obj) { MethodBind *method = ClassDB::get_method(base_class, *methodname); - if (*methodname == CoreStringNames::get_singleton()->_free || (method && !method->has_return())) { + if (*methodname == CoreStringName(free_) || (method && !method->has_return())) { err_text = R"(Trying to get a return value of a method that returns "void")"; OPCODE_BREAK; } @@ -3097,7 +3097,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const Variant *args[] = { &vref }; Callable::CallError ce; - Variant has_next = obj->callp(CoreStringNames::get_singleton()->_iter_init, args, 1, ce); + Variant has_next = obj->callp(CoreStringName(_iter_init), args, 1, ce); #ifdef DEBUG_ENABLED if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { @@ -3113,7 +3113,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *counter = ref[0]; GET_VARIANT_PTR(iterator, 2); - *iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)&counter, 1, ce); + *iterator = obj->callp(CoreStringName(_iter_get), (const Variant **)&counter, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container); @@ -3431,7 +3431,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const Variant *args[] = { &vref }; Callable::CallError ce; - Variant has_next = obj->callp(CoreStringNames::get_singleton()->_iter_next, args, 1, ce); + Variant has_next = obj->callp(CoreStringName(_iter_next), args, 1, ce); #ifdef DEBUG_ENABLED if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { @@ -3447,7 +3447,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *counter = ref[0]; GET_VARIANT_PTR(iterator, 2); - *iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)&counter, 1, ce); + *iterator = obj->callp(CoreStringName(_iter_get), (const Variant **)&counter, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container); diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 575702bc54..b92176a63a 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -105,10 +105,6 @@ static Ref<ImporterMesh> _mesh_to_importer_mesh(Ref<Mesh> p_mesh) { } Error GLTFDocument::_serialize(Ref<GLTFState> p_state) { - if (!p_state->buffers.size()) { - p_state->buffers.push_back(Vector<uint8_t>()); - } - for (Ref<GLTFDocumentExtension> ext : document_extensions) { ERR_CONTINUE(ext.is_null()); Error err = ext->export_preserialize(p_state); @@ -243,7 +239,6 @@ Error GLTFDocument::_serialize_gltf_extensions(Ref<GLTFState> p_state) const { } Error GLTFDocument::_serialize_scenes(Ref<GLTFState> p_state) { - ERR_FAIL_COND_V_MSG(p_state->root_nodes.is_empty(), ERR_INVALID_DATA, "GLTF export: The scene must have at least one root node."); // Godot only supports one scene per glTF file. Array scenes; Dictionary scene_dict; @@ -251,7 +246,9 @@ Error GLTFDocument::_serialize_scenes(Ref<GLTFState> p_state) { p_state->json["scenes"] = scenes; p_state->json["scene"] = 0; // Add nodes to the scene dict. - scene_dict["nodes"] = p_state->root_nodes; + if (!p_state->root_nodes.is_empty()) { + scene_dict["nodes"] = p_state->root_nodes; + } if (!p_state->scene_name.is_empty()) { scene_dict["name"] = p_state->scene_name; } @@ -458,9 +455,15 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) { ERR_CONTINUE(err != OK); } + if (extensions.is_empty()) { + node.erase("extensions"); + } + nodes.push_back(node); } - p_state->json["nodes"] = nodes; + if (!nodes.is_empty()) { + p_state->json["nodes"] = nodes; + } return OK; } @@ -691,11 +694,11 @@ static Vector<uint8_t> _parse_base64_uri(const String &p_uri) { Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_path) { print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size())); - if (!p_state->buffers.size()) { + if (p_state->buffers.is_empty()) { return OK; } Array buffers; - if (p_state->buffers.size()) { + if (!p_state->buffers.is_empty()) { Vector<uint8_t> buffer_data = p_state->buffers[0]; Dictionary gltf_buffer; @@ -730,7 +733,7 @@ Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_p Error GLTFDocument::_encode_buffer_bins(Ref<GLTFState> p_state, const String &p_path) { print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size())); - if (!p_state->buffers.size()) { + if (p_state->buffers.is_empty()) { return OK; } Array buffers; @@ -1543,6 +1546,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state, Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_SCALAR; int component_type; @@ -1654,6 +1660,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> p_state, Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_VEC2; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -1704,6 +1713,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> p_state Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -1768,6 +1780,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> p_sta Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -1816,6 +1831,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> p_stat Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; @@ -1866,6 +1884,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> p Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -1938,6 +1959,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_stat Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_SCALAR; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -1985,6 +2009,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> p_state, Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_VEC3; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -2058,6 +2085,9 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p Ref<GLTFAccessor> sparse_accessor; sparse_accessor.instantiate(); + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_VEC3; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -2160,6 +2190,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> p_state Ref<GLTFAccessor> accessor; accessor.instantiate(); GLTFBufferIndex buffer_view_i; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } int64_t size = p_state->buffers[0].size(); const GLTFType type = GLTFType::TYPE_MAT4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; @@ -6944,7 +6977,7 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path) const uint32_t text_chunk_type = 0x4E4F534A; //JSON uint32_t binary_data_length = 0; - if (p_state->buffers.size()) { + if (p_state->buffers.size() > 0) { binary_data_length = p_state->buffers[0].size(); } const uint32_t binary_chunk_length = ((binary_data_length + 3) & (~3)); @@ -6953,20 +6986,28 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path) file->create(FileAccess::ACCESS_RESOURCES); file->store_32(magic); file->store_32(p_state->major_version); // version - file->store_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_chunk_length); // length + uint32_t total_length = header_size + chunk_header_size + text_chunk_length; + if (binary_chunk_length) { + total_length += chunk_header_size + binary_chunk_length; + } + file->store_32(total_length); + + // Write the JSON text chunk. file->store_32(text_chunk_length); file->store_32(text_chunk_type); file->store_buffer((uint8_t *)&cs[0], cs.length()); for (uint32_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) { file->store_8(' '); } + + // Write a single binary chunk. if (binary_chunk_length) { file->store_32(binary_chunk_length); file->store_32(binary_chunk_type); file->store_buffer(p_state->buffers[0].ptr(), binary_data_length); - } - for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) { - file->store_8(0); + for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) { + file->store_8(0); + } } } else { err = _encode_buffer_bins(p_state, p_path); @@ -7073,7 +7114,7 @@ PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> p_state, Erro const uint32_t text_chunk_type = 0x4E4F534A; //JSON int32_t binary_data_length = 0; - if (p_state->buffers.size()) { + if (p_state->buffers.size() > 0) { binary_data_length = p_state->buffers[0].size(); } const int32_t binary_chunk_length = binary_data_length; diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index d53bf7f7ec..49c90cc775 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -949,7 +949,7 @@ void GridMapEditor::_update_mesh_library() { void GridMapEditor::edit(GridMap *p_gridmap) { if (node) { node->disconnect(SNAME("cell_size_changed"), callable_mp(this, &GridMapEditor::_draw_grids)); - node->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GridMapEditor::_update_mesh_library)); + node->disconnect(CoreStringName(changed), callable_mp(this, &GridMapEditor::_update_mesh_library)); if (mesh_library.is_valid()) { mesh_library->disconnect_changed(callable_mp(this, &GridMapEditor::update_palette)); mesh_library = Ref<MeshLibrary>(); @@ -987,7 +987,7 @@ void GridMapEditor::edit(GridMap *p_gridmap) { update_grid(); node->connect(SNAME("cell_size_changed"), callable_mp(this, &GridMapEditor::_draw_grids)); - node->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GridMapEditor::_update_mesh_library)); + node->connect(CoreStringName(changed), callable_mp(this, &GridMapEditor::_update_mesh_library)); _update_mesh_library(); } diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 25519c6e3c..abfbfebc02 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -266,7 +266,7 @@ void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) { } _recreate_octant_data(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } Ref<MeshLibrary> GridMap::get_mesh_library() const { @@ -1136,7 +1136,7 @@ void GridMap::_bind_methods() { BIND_CONSTANT(INVALID_CELL_ITEM); ADD_SIGNAL(MethodInfo("cell_size_changed", PropertyInfo(Variant::VECTOR3, "cell_size"))); - ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed)); + ADD_SIGNAL(MethodInfo(CoreStringName(changed))); } void GridMap::set_cell_scale(float p_scale) { diff --git a/modules/multiplayer/multiplayer_spawner.cpp b/modules/multiplayer/multiplayer_spawner.cpp index 6c0669b2f3..b871025491 100644 --- a/modules/multiplayer/multiplayer_spawner.cpp +++ b/modules/multiplayer/multiplayer_spawner.cpp @@ -216,7 +216,7 @@ void MultiplayerSpawner::_notification(int p_what) { for (const KeyValue<ObjectID, SpawnInfo> &E : tracked_nodes) { Node *node = Object::cast_to<Node>(ObjectDB::get_instance(E.key)); ERR_CONTINUE(!node); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &MultiplayerSpawner::_node_exit)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &MultiplayerSpawner::_node_exit)); get_multiplayer()->object_configuration_remove(node, this); } tracked_nodes.clear(); @@ -258,7 +258,7 @@ void MultiplayerSpawner::_track(Node *p_node, const Variant &p_argument, int p_s ObjectID oid = p_node->get_instance_id(); if (!tracked_nodes.has(oid)) { tracked_nodes[oid] = SpawnInfo(p_argument.duplicate(true), p_scene_id); - p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &MultiplayerSpawner::_node_exit).bind(p_node->get_instance_id()), CONNECT_ONE_SHOT); + p_node->connect(SceneStringName(tree_exiting), callable_mp(this, &MultiplayerSpawner::_node_exit).bind(p_node->get_instance_id()), CONNECT_ONE_SHOT); _spawn_notify(p_node->get_instance_id()); } } diff --git a/modules/multiplayer/scene_cache_interface.cpp b/modules/multiplayer/scene_cache_interface.cpp index c08ccbe4cc..39443029d3 100644 --- a/modules/multiplayer/scene_cache_interface.cpp +++ b/modules/multiplayer/scene_cache_interface.cpp @@ -42,7 +42,7 @@ SceneCacheInterface::NodeCache &SceneCacheInterface::_track(Node *p_node) { NodeCache *nc = nodes_cache.getptr(oid); if (!nc) { nodes_cache[oid] = NodeCache(); - p_node->connect(SceneStringNames::get_singleton()->tree_exited, callable_mp(this, &SceneCacheInterface::_remove_node_cache).bind(oid), Object::CONNECT_ONE_SHOT); + p_node->connect(SceneStringName(tree_exited), callable_mp(this, &SceneCacheInterface::_remove_node_cache).bind(oid), Object::CONNECT_ONE_SHOT); } return nodes_cache[oid]; } @@ -286,7 +286,7 @@ void SceneCacheInterface::clear() { for (KeyValue<ObjectID, NodeCache> &E : nodes_cache) { Object *obj = ObjectDB::get_instance(E.key); ERR_CONTINUE(!obj); - obj->disconnect(SceneStringNames::get_singleton()->tree_exited, callable_mp(this, &SceneCacheInterface::_remove_node_cache)); + obj->disconnect(SceneStringName(tree_exited), callable_mp(this, &SceneCacheInterface::_remove_node_cache)); } peers_info.clear(); nodes_cache.clear(); diff --git a/modules/multiplayer/scene_replication_interface.cpp b/modules/multiplayer/scene_replication_interface.cpp index 182e9b455c..f1a43a68b9 100644 --- a/modules/multiplayer/scene_replication_interface.cpp +++ b/modules/multiplayer/scene_replication_interface.cpp @@ -57,7 +57,7 @@ SceneReplicationInterface::TrackedNode &SceneReplicationInterface::_track(const if (!tracked_nodes.has(p_id)) { tracked_nodes[p_id] = TrackedNode(p_id); Node *node = get_id_as<Node>(p_id); - node->connect(SceneStringNames::get_singleton()->tree_exited, callable_mp(this, &SceneReplicationInterface::_untrack).bind(p_id), Node::CONNECT_ONE_SHOT); + node->connect(SceneStringName(tree_exited), callable_mp(this, &SceneReplicationInterface::_untrack).bind(p_id), Node::CONNECT_ONE_SHOT); } return tracked_nodes[p_id]; } @@ -135,8 +135,8 @@ void SceneReplicationInterface::on_network_process() { for (const ObjectID &oid : spawn_queue) { Node *node = get_id_as<Node>(oid); ERR_CONTINUE(!node); - if (node->is_connected(SceneStringNames::get_singleton()->ready, callable_mp(this, &SceneReplicationInterface::_node_ready))) { - node->disconnect(SceneStringNames::get_singleton()->ready, callable_mp(this, &SceneReplicationInterface::_node_ready)); + if (node->is_connected(SceneStringName(ready), callable_mp(this, &SceneReplicationInterface::_node_ready))) { + node->disconnect(SceneStringName(ready), callable_mp(this, &SceneReplicationInterface::_node_ready)); } } spawn_queue.clear(); @@ -168,7 +168,7 @@ Error SceneReplicationInterface::on_spawn(Object *p_obj, Variant p_config) { ERR_FAIL_COND_V(tobj.spawner != ObjectID(), ERR_ALREADY_IN_USE); tobj.spawner = spawner->get_instance_id(); spawn_queue.insert(oid); - node->connect(SceneStringNames::get_singleton()->ready, callable_mp(this, &SceneReplicationInterface::_node_ready).bind(oid), Node::CONNECT_ONE_SHOT); + node->connect(SceneStringName(ready), callable_mp(this, &SceneReplicationInterface::_node_ready).bind(oid), Node::CONNECT_ONE_SHOT); return OK; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt index fbdf07e6c2..290be727ab 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt @@ -38,7 +38,6 @@ import android.content.pm.PackageManager import android.content.res.Configuration import android.content.res.Resources import android.graphics.Color -import android.graphics.Rect import android.hardware.Sensor import android.hardware.SensorEvent import android.hardware.SensorEventListener @@ -46,10 +45,12 @@ import android.hardware.SensorManager import android.os.* import android.util.Log import android.view.* -import android.view.ViewTreeObserver.OnGlobalLayoutListener import android.widget.FrameLayout import androidx.annotation.Keep import androidx.annotation.StringRes +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsAnimationCompat +import androidx.core.view.WindowInsetsCompat import com.google.android.vending.expansion.downloader.* import org.godotengine.godot.input.GodotEditText import org.godotengine.godot.io.directory.DirectoryAccessHandler @@ -418,58 +419,42 @@ class Godot(private val context: Context) : SensorEventListener { io?.setEdit(editText) // Listeners for keyboard height. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - // Report the height of virtual keyboard as it changes during the animation. - val decorView = activity.window.decorView - decorView.setWindowInsetsAnimationCallback(object : WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) { - var startBottom = 0 - var endBottom = 0 - override fun onPrepare(animation: WindowInsetsAnimation) { - startBottom = decorView.rootWindowInsets.getInsets(WindowInsets.Type.ime()).bottom - } + val decorView = activity.window.decorView + // Report the height of virtual keyboard as it changes during the animation. + ViewCompat.setWindowInsetsAnimationCallback(decorView, object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) { + var startBottom = 0 + var endBottom = 0 + override fun onPrepare(animation: WindowInsetsAnimationCompat) { + startBottom = ViewCompat.getRootWindowInsets(decorView)?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0 + } - override fun onStart(animation: WindowInsetsAnimation, bounds: WindowInsetsAnimation.Bounds): WindowInsetsAnimation.Bounds { - endBottom = decorView.rootWindowInsets.getInsets(WindowInsets.Type.ime()).bottom - return bounds - } + override fun onStart(animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat): WindowInsetsAnimationCompat.BoundsCompat { + endBottom = ViewCompat.getRootWindowInsets(decorView)?.getInsets(WindowInsetsCompat.Type.ime())?.bottom ?: 0 + return bounds + } - override fun onProgress(windowInsets: WindowInsets, list: List<WindowInsetsAnimation>): WindowInsets { - // Find the IME animation. - var imeAnimation: WindowInsetsAnimation? = null - for (animation in list) { - if (animation.typeMask and WindowInsets.Type.ime() != 0) { - imeAnimation = animation - break - } - } - // Update keyboard height based on IME animation. - if (imeAnimation != null) { - val interpolatedFraction = imeAnimation.interpolatedFraction - // Linear interpolation between start and end values. - val keyboardHeight = startBottom * (1.0f - interpolatedFraction) + endBottom * interpolatedFraction - GodotLib.setVirtualKeyboardHeight(keyboardHeight.toInt()) + override fun onProgress(windowInsets: WindowInsetsCompat, animationsList: List<WindowInsetsAnimationCompat>): WindowInsetsCompat { + // Find the IME animation. + var imeAnimation: WindowInsetsAnimationCompat? = null + for (animation in animationsList) { + if (animation.typeMask and WindowInsetsCompat.Type.ime() != 0) { + imeAnimation = animation + break } - return windowInsets } - override fun onEnd(animation: WindowInsetsAnimation) {} - }) - } else { - // Infer the virtual keyboard height using visible area. - renderView?.view?.viewTreeObserver?.addOnGlobalLayoutListener(object : OnGlobalLayoutListener { - // Don't allocate a new Rect every time the callback is called. - val visibleSize = Rect() - override fun onGlobalLayout() { - renderView?.let { - val surfaceView = it.view - - surfaceView.getWindowVisibleDisplayFrame(visibleSize) - val keyboardHeight = surfaceView.height - visibleSize.bottom - GodotLib.setVirtualKeyboardHeight(keyboardHeight) - } + // Update keyboard height based on IME animation. + if (imeAnimation != null) { + val interpolatedFraction = imeAnimation.interpolatedFraction + // Linear interpolation between start and end values. + val keyboardHeight = startBottom * (1.0f - interpolatedFraction) + endBottom * interpolatedFraction + GodotLib.setVirtualKeyboardHeight(keyboardHeight.toInt()) } - }) - } + return windowInsets + } + + override fun onEnd(animation: WindowInsetsAnimationCompat) {} + }) if (host == primaryHost) { renderView?.queueOnRenderThread { diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index 37e9d1f8c1..f543412962 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -202,7 +202,7 @@ void AnimatedSprite2D::_notification(int p_what) { } else { frame = last_frame; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -211,7 +211,7 @@ void AnimatedSprite2D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 0.0; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN((1.0 - frame_progress) / abs_speed, remaining); frame_progress += to_process * abs_speed; @@ -226,7 +226,7 @@ void AnimatedSprite2D::_notification(int p_what) { } else { frame = 0; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -235,7 +235,7 @@ void AnimatedSprite2D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 1.0; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN(frame_progress / abs_speed, remaining); frame_progress -= to_process * abs_speed; @@ -291,12 +291,12 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { } if (frames.is_valid()) { - frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed)); + frames->disconnect(SceneStringName(changed), callable_mp(this, &AnimatedSprite2D::_res_changed)); } stop(); frames = p_frames; if (frames.is_valid()) { - frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed)); + frames->connect(SceneStringName(changed), callable_mp(this, &AnimatedSprite2D::_res_changed)); List<StringName> al; frames->get_animation_list(&al); @@ -363,7 +363,7 @@ void AnimatedSprite2D::set_frame_and_progress(int p_frame, real_t p_progress) { return; // No change, don't redraw. } queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } void AnimatedSprite2D::set_speed_scale(float p_speed_scale) { diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 4fc0fe0268..fb632e8f64 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -81,10 +81,10 @@ StringName AudioStreamPlayer2D::_get_actual_bus() { //check if any area is diverting sound into a bus Ref<World2D> world_2d = get_world_2d(); - ERR_FAIL_COND_V(world_2d.is_null(), SceneStringNames::get_singleton()->Master); + ERR_FAIL_COND_V(world_2d.is_null(), SceneStringName(Master)); PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space()); - ERR_FAIL_NULL_V(space_state, SceneStringNames::get_singleton()->Master); + ERR_FAIL_COND_V(space_state, SceneStringName(Master)); PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS]; PhysicsDirectSpaceState2D::PointParameters point_params; diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 2cd59776ec..3df635d75a 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -997,7 +997,7 @@ void CPUParticles2D::_particles_process(double p_delta) { } if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) { active = false; - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } } diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index bc39513c03..caac564500 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -731,7 +731,7 @@ void GPUParticles2D::_notification(int p_what) { } if (time > active_time) { if (active && !signal_canceled) { - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } active = false; if (!emitting) { diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 4fc375ff8d..28af4184ca 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -70,7 +70,7 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { } texture = p_texture; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> MeshInstance2D::get_texture() const { diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 9631b2cc4e..695e44664e 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -79,7 +79,7 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { } texture = p_texture; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> MultiMeshInstance2D::get_texture() const { diff --git a/scene/2d/physics/area_2d.cpp b/scene/2d/physics/area_2d.cpp index b1ff94dda4..3ed579b3b1 100644 --- a/scene/2d/physics/area_2d.cpp +++ b/scene/2d/physics/area_2d.cpp @@ -142,9 +142,9 @@ void Area2D::_body_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -156,9 +156,9 @@ void Area2D::_body_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -172,9 +172,9 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i lock_callback(); locked = true; if (body_in) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } else { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } locked = false; unlock_callback(); @@ -200,10 +200,10 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } } @@ -213,7 +213,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_area_shape); } } else { @@ -227,15 +227,15 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i if (E->value.rc == 0) { body_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + emit_signal(SceneStringName(body_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_area_shape); } } @@ -253,9 +253,9 @@ void Area2D::_area_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_entered), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -267,9 +267,9 @@ void Area2D::_area_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->area_exited, node); + emit_signal(SceneStringName(area_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -283,9 +283,9 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i lock_callback(); locked = true; if (area_in) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } else { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } locked = false; unlock_callback(); @@ -311,10 +311,10 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); } } } @@ -324,7 +324,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, node, p_area_shape, p_self_shape); } } else { @@ -338,15 +338,15 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i if (E->value.rc == 0) { area_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, obj, p_area_shape, p_self_shape); } } @@ -370,18 +370,18 @@ void Area2D::_clear_monitoring() { continue; } - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); } - emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + emit_signal(SceneStringName(body_exited), obj); } } @@ -398,18 +398,18 @@ void Area2D::_clear_monitoring() { continue; } - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); } - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } @@ -538,7 +538,7 @@ StringName Area2D::get_audio_bus_name() const { return audio_bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void Area2D::_validate_property(PropertyInfo &p_property) const { diff --git a/scene/2d/physics/collision_object_2d.cpp b/scene/2d/physics/collision_object_2d.cpp index 4e5852984b..35704ae382 100644 --- a/scene/2d/physics/collision_object_2d.cpp +++ b/scene/2d/physics/collision_object_2d.cpp @@ -519,27 +519,27 @@ bool CollisionObject2D::is_pickable() const { void CollisionObject2D::_input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) { GDVIRTUAL_CALL(_input_event, p_viewport, p_input_event, p_shape); - emit_signal(SceneStringNames::get_singleton()->input_event, p_viewport, p_input_event, p_shape); + emit_signal(SceneStringName(input_event), p_viewport, p_input_event, p_shape); } void CollisionObject2D::_mouse_enter() { GDVIRTUAL_CALL(_mouse_enter); - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } void CollisionObject2D::_mouse_exit() { GDVIRTUAL_CALL(_mouse_exit); - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } void CollisionObject2D::_mouse_shape_enter(int p_shape) { GDVIRTUAL_CALL(_mouse_shape_enter, p_shape); - emit_signal(SceneStringNames::get_singleton()->mouse_shape_entered, p_shape); + emit_signal(SceneStringName(mouse_shape_entered), p_shape); } void CollisionObject2D::_mouse_shape_exit(int p_shape) { GDVIRTUAL_CALL(_mouse_shape_exit, p_shape); - emit_signal(SceneStringNames::get_singleton()->mouse_shape_exited, p_shape); + emit_signal(SceneStringName(mouse_shape_exited), p_shape); } void CollisionObject2D::set_only_update_transform_changes(bool p_enable) { diff --git a/scene/2d/physics/joints/joint_2d.cpp b/scene/2d/physics/joints/joint_2d.cpp index 1afac7c150..5f61bebbb1 100644 --- a/scene/2d/physics/joints/joint_2d.cpp +++ b/scene/2d/physics/joints/joint_2d.cpp @@ -37,13 +37,13 @@ void Joint2D::_disconnect_signals() { Node *node_a = get_node_or_null(a); PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a); if (body_a) { - body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); + body_a->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); } Node *node_b = get_node_or_null(b); PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b); if (body_b) { - body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); + body_b->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); } } @@ -117,8 +117,8 @@ void Joint2D::_update_joint(bool p_only_free) { ba = body_a->get_rid(); bb = body_b->get_rid(); - body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); - body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); + body_a->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); + body_b->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision); } diff --git a/scene/2d/physics/rigid_body_2d.cpp b/scene/2d/physics/rigid_body_2d.cpp index 5e05c563a4..2495e7bc18 100644 --- a/scene/2d/physics/rigid_body_2d.cpp +++ b/scene/2d/physics/rigid_body_2d.cpp @@ -44,10 +44,10 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) { contact_monitor->locked = true; E->value.in_scene = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -65,10 +65,10 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) { contact_monitor->locked = true; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -93,10 +93,10 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan //E->value.rc=0; E->value.in_scene = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree).bind(objid)); if (E->value.in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } @@ -108,7 +108,7 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan } if (E->value.in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_local_shape); } } else { @@ -122,17 +122,17 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan if (E->value.shapes.is_empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree)); if (in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); } } contact_monitor->body_map.remove(E); } if (node && in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, node, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, node, p_body_shape, p_local_shape); } } } @@ -158,7 +158,7 @@ void RigidBody2D::_sync_body_state(PhysicsDirectBodyState2D *p_state) { if (sleeping != p_state->is_sleeping()) { sleeping = p_state->is_sleeping(); - emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + emit_signal(SceneStringName(sleeping_state_changed)); } } @@ -605,8 +605,8 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree)); } } diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index 5745a59297..af40de1dd1 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -146,7 +146,7 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) { } queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); item_rect_changed(); } @@ -260,7 +260,7 @@ void Sprite2D::set_frame(int p_frame) { frame = p_frame; item_rect_changed(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } int Sprite2D::get_frame() const { diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index fbe7563e6b..3ea69fe17e 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -54,7 +54,7 @@ void TileMap::_tile_set_changed() { } void TileMap::_emit_changed() { - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMap::_set_tile_map_data_using_compatibility_format(int p_layer, TileMapDataFormat p_format, const Vector<int> &p_data) { @@ -360,7 +360,7 @@ void TileMap::add_layer(int p_to_pos) { for (uint32_t i = 0; i < layers.size(); i++) { layers[i]->set_as_tile_map_internal_node(i); } - new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); + new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed)); notify_property_list_changed(); @@ -768,7 +768,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { new_layer->set_as_tile_map_internal_node(index); new_layer->set_name(vformat("Layer%d", index)); new_layer->set_tile_set(tile_set); - new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); + new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); } @@ -1051,7 +1051,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY_DEFAULT("format", TileMapDataFormat::TILE_MAP_DATA_FORMAT_1); - ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed)); + ADD_SIGNAL(MethodInfo(CoreStringName(changed))); BIND_ENUM_CONSTANT(VISIBILITY_MODE_DEFAULT); BIND_ENUM_CONSTANT(VISIBILITY_MODE_FORCE_HIDE); @@ -1064,7 +1064,7 @@ TileMap::TileMap() { new_layer->set_as_tile_map_internal_node(0); new_layer->set_name("Layer0"); new_layer->set_tile_set(tile_set); - new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); + new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); if (!base_property_helper.is_initialized()) { diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index fd1a638b58..e3abbea43a 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -1598,11 +1598,11 @@ RBSet<TerrainConstraint> TileMapLayer::_get_terrain_constraints_from_painted_cel void TileMapLayer::_tile_set_changed() { dirty.flags[DIRTY_FLAGS_TILE_SET] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::_renamed() { - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::_update_notify_local_transform() { @@ -1805,7 +1805,7 @@ void TileMapLayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "navigation_enabled"), "set_navigation_enabled", "is_navigation_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode"); - ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed)); + ADD_SIGNAL(MethodInfo(CoreStringName(changed))); ADD_PROPERTY_DEFAULT("tile_map_data_format", TileMapDataFormat::TILE_MAP_DATA_FORMAT_1); @@ -1819,7 +1819,7 @@ void TileMapLayer::_update_self_texture_filter(RS::CanvasItemTextureFilter p_tex CanvasItem::_update_self_texture_filter(p_texture_filter); dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_FILTER] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::_update_self_texture_repeat(RS::CanvasItemTextureRepeat p_texture_repeat) { @@ -1827,7 +1827,7 @@ void TileMapLayer::_update_self_texture_repeat(RS::CanvasItemTextureRepeat p_tex CanvasItem::_update_self_texture_repeat(p_texture_repeat); dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_REPEAT] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_as_tile_map_internal_node(int p_index) { @@ -2502,7 +2502,7 @@ void TileMapLayer::update_internals() { void TileMapLayer::notify_runtime_tile_data_update() { dirty.flags[TileMapLayer::DIRTY_FLAGS_LAYER_RUNTIME_UPDATE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } Vector2i TileMapLayer::map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern) { @@ -2537,7 +2537,7 @@ void TileMapLayer::set_enabled(bool p_enabled) { enabled = p_enabled; dirty.flags[DIRTY_FLAGS_LAYER_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_enabled() const { @@ -2563,7 +2563,7 @@ void TileMapLayer::set_tile_set(const Ref<TileSet> &p_tile_set) { tile_set->connect_changed(callable_mp(this, &TileMapLayer::_tile_set_changed)); } - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); // Trigger updates for TileSet's read-only status. notify_property_list_changed(); @@ -2675,7 +2675,7 @@ void TileMapLayer::set_self_modulate(const Color &p_self_modulate) { CanvasItem::set_self_modulate(p_self_modulate); dirty.flags[DIRTY_FLAGS_LAYER_SELF_MODULATE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) { @@ -2685,7 +2685,7 @@ void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) { CanvasItem::set_y_sort_enabled(p_y_sort_enabled); dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); _update_notify_local_transform(); } @@ -2697,7 +2697,7 @@ void TileMapLayer::set_y_sort_origin(int p_y_sort_origin) { y_sort_origin = p_y_sort_origin; dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } int TileMapLayer::get_y_sort_origin() const { @@ -2711,7 +2711,7 @@ void TileMapLayer::set_z_index(int p_z_index) { CanvasItem::set_z_index(p_z_index); dirty.flags[DIRTY_FLAGS_LAYER_Z_INDEX] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_light_mask(int p_light_mask) { @@ -2721,7 +2721,7 @@ void TileMapLayer::set_light_mask(int p_light_mask) { CanvasItem::set_light_mask(p_light_mask); dirty.flags[DIRTY_FLAGS_LAYER_LIGHT_MASK] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_rendering_quadrant_size(int p_size) { @@ -2733,7 +2733,7 @@ void TileMapLayer::set_rendering_quadrant_size(int p_size) { rendering_quadrant_size = p_size; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } int TileMapLayer::get_rendering_quadrant_size() const { @@ -2747,7 +2747,7 @@ void TileMapLayer::set_collision_enabled(bool p_enabled) { collision_enabled = p_enabled; dirty.flags[DIRTY_FLAGS_LAYER_COLLISION_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_collision_enabled() const { @@ -2758,7 +2758,7 @@ void TileMapLayer::set_use_kinematic_bodies(bool p_use_kinematic_bodies) { use_kinematic_bodies = p_use_kinematic_bodies; dirty.flags[DIRTY_FLAGS_LAYER_USE_KINEMATIC_BODIES] = p_use_kinematic_bodies; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_using_kinematic_bodies() const { @@ -2772,7 +2772,7 @@ void TileMapLayer::set_collision_visibility_mode(TileMapLayer::DebugVisibilityMo collision_visibility_mode = p_show_collision; dirty.flags[DIRTY_FLAGS_LAYER_COLLISION_VISIBILITY_MODE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } TileMapLayer::DebugVisibilityMode TileMapLayer::get_collision_visibility_mode() const { @@ -2786,7 +2786,7 @@ void TileMapLayer::set_navigation_enabled(bool p_enabled) { navigation_enabled = p_enabled; dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_navigation_enabled() const { @@ -2800,7 +2800,7 @@ void TileMapLayer::set_navigation_map(RID p_map) { navigation_map_override = p_map; dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_MAP] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } RID TileMapLayer::get_navigation_map() const { @@ -2819,7 +2819,7 @@ void TileMapLayer::set_navigation_visibility_mode(TileMapLayer::DebugVisibilityM navigation_visibility_mode = p_show_navigation; dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_VISIBILITY_MODE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } TileMapLayer::DebugVisibilityMode TileMapLayer::get_navigation_visibility_mode() const { diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 5ed7fadb2a..b7a47e8723 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -38,11 +38,11 @@ void TouchScreenButton::set_texture_normal(const Ref<Texture2D> &p_texture) { return; } if (texture_normal.is_valid()) { - texture_normal->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); + texture_normal->disconnect(SceneStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); } texture_normal = p_texture; if (texture_normal.is_valid()) { - texture_normal->connect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); + texture_normal->connect(SceneStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); } queue_redraw(); } @@ -56,11 +56,11 @@ void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pres return; } if (texture_pressed.is_valid()) { - texture_pressed->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); + texture_pressed->disconnect(SceneStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); } texture_pressed = p_texture_pressed; if (texture_pressed.is_valid()) { - texture_pressed->connect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); + texture_pressed->connect(SceneStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); } queue_redraw(); } diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp index 89b2c20b20..fd0f3a461e 100644 --- a/scene/2d/visible_on_screen_notifier_2d.cpp +++ b/scene/2d/visible_on_screen_notifier_2d.cpp @@ -48,7 +48,7 @@ void VisibleOnScreenNotifier2D::_visibility_enter() { } on_screen = true; - emit_signal(SceneStringNames::get_singleton()->screen_entered); + emit_signal(SceneStringName(screen_entered)); _screen_enter(); } void VisibleOnScreenNotifier2D::_visibility_exit() { @@ -57,7 +57,7 @@ void VisibleOnScreenNotifier2D::_visibility_exit() { } on_screen = false; - emit_signal(SceneStringNames::get_singleton()->screen_exited); + emit_signal(SceneStringName(screen_exited)); _screen_exit(); } diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 5aa50a4a21..71b96fc8ce 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -1156,7 +1156,7 @@ void CPUParticles3D::_particles_process(double p_delta) { } if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) { active = false; - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } } diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 16813b9017..865d91e4cc 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -478,7 +478,7 @@ void GPUParticles3D::_notification(int p_what) { } if (time > active_time) { if (active && !signal_canceled) { - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } active = false; if (!emitting) { diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 98a5134283..9bc5dc09df 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -193,12 +193,12 @@ void Node3D::_notification(int p_what) { ERR_FAIL_NULL(data.viewport); if (get_script_instance()) { - get_script_instance()->call(SceneStringNames::get_singleton()->_enter_world); + get_script_instance()->call(SceneStringName(_enter_world)); } #ifdef TOOLS_ENABLED if (is_part_of_edited_scene()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SNAME("_request_gizmo_for_id"), get_instance_id()); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_request_gizmo_for_id"), get_instance_id()); } #endif } break; @@ -211,7 +211,7 @@ void Node3D::_notification(int p_what) { #endif if (get_script_instance()) { - get_script_instance()->call(SceneStringNames::get_singleton()->_exit_world); + get_script_instance()->call(SceneStringName(_exit_world)); } data.viewport = nullptr; @@ -564,7 +564,7 @@ void Node3D::update_gizmos() { } if (data.gizmos.is_empty()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SNAME("_request_gizmo_for_id"), get_instance_id()); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_request_gizmo_for_id"), get_instance_id()); return; } if (data.gizmos_dirty) { @@ -583,7 +583,7 @@ void Node3D::set_subgizmo_selection(Ref<Node3DGizmo> p_gizmo, int p_id, Transfor } if (is_part_of_edited_scene()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_set_subgizmo_selection, this, p_gizmo, p_id, p_transform); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SceneStringName(_set_subgizmo_selection), this, p_gizmo, p_id, p_transform); } #endif } @@ -600,7 +600,7 @@ void Node3D::clear_subgizmo_selection() { } if (is_part_of_edited_scene()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_clear_subgizmo_selection, this); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SceneStringName(_clear_subgizmo_selection), this); } #endif } @@ -777,7 +777,7 @@ Ref<World3D> Node3D::get_world_3d() const { void Node3D::_propagate_visibility_changed() { notification(NOTIFICATION_VISIBILITY_CHANGED); - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); #ifdef TOOLS_ENABLED if (!data.gizmos.is_empty()) { diff --git a/scene/3d/physics/area_3d.cpp b/scene/3d/physics/area_3d.cpp index 014c33cad0..8cb316a2fe 100644 --- a/scene/3d/physics/area_3d.cpp +++ b/scene/3d/physics/area_3d.cpp @@ -199,9 +199,9 @@ void Area3D::_body_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -213,9 +213,9 @@ void Area3D::_body_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -229,9 +229,9 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i locked = true; // Emit the appropriate signals. if (body_in) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } else { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } locked = false; unlock_callback(); @@ -257,10 +257,10 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } } @@ -270,7 +270,7 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_area_shape); } } else { @@ -284,15 +284,15 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i if (E->value.rc == 0) { body_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + emit_signal(SceneStringName(body_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_area_shape); } } @@ -317,18 +317,18 @@ void Area3D::_clear_monitoring() { } //ERR_CONTINUE(!node); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); } - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); } } @@ -346,18 +346,18 @@ void Area3D::_clear_monitoring() { } //ERR_CONTINUE(!node); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); } - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } @@ -405,9 +405,9 @@ void Area3D::_area_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_entered), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -419,9 +419,9 @@ void Area3D::_area_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->area_exited, node); + emit_signal(SceneStringName(area_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -435,9 +435,9 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i locked = true; // Emit the appropriate signals. if (area_in) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } else { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } locked = false; unlock_callback(); @@ -463,10 +463,10 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); } } } @@ -476,7 +476,7 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, node, p_area_shape, p_self_shape); } } else { @@ -490,15 +490,15 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i if (E->value.rc == 0) { area_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, obj, p_area_shape, p_self_shape); } } @@ -605,7 +605,7 @@ StringName Area3D::get_audio_bus_name() const { return audio_bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void Area3D::set_use_reverb_bus(bool p_enable) { @@ -626,7 +626,7 @@ StringName Area3D::get_reverb_bus_name() const { return reverb_bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void Area3D::set_reverb_amount(float p_amount) { @@ -812,6 +812,8 @@ void Area3D::_bind_methods() { Area3D::Area3D() : CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) { + audio_bus = SceneStringName(Master); + reverb_bus = SceneStringName(Master); set_gravity(9.8); set_gravity_direction(Vector3(0, -1, 0)); set_monitoring(true); diff --git a/scene/3d/physics/area_3d.h b/scene/3d/physics/area_3d.h index 41382b6128..bb3694dff3 100644 --- a/scene/3d/physics/area_3d.h +++ b/scene/3d/physics/area_3d.h @@ -135,10 +135,10 @@ private: void _clear_monitoring(); bool audio_bus_override = false; - StringName audio_bus = SceneStringNames::get_singleton()->Master; + StringName audio_bus; bool use_reverb_bus = false; - StringName reverb_bus = SceneStringNames::get_singleton()->Master; + StringName reverb_bus; float reverb_amount = 0.0; float reverb_uniformity = 0.0; diff --git a/scene/3d/physics/collision_object_3d.cpp b/scene/3d/physics/collision_object_3d.cpp index 54752b1281..324620df4f 100644 --- a/scene/3d/physics/collision_object_3d.cpp +++ b/scene/3d/physics/collision_object_3d.cpp @@ -291,17 +291,17 @@ void CollisionObject3D::_apply_enabled() { void CollisionObject3D::_input_event_call(Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) { GDVIRTUAL_CALL(_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape); - emit_signal(SceneStringNames::get_singleton()->input_event, p_camera, p_input_event, p_pos, p_normal, p_shape); + emit_signal(SceneStringName(input_event), p_camera, p_input_event, p_pos, p_normal, p_shape); } void CollisionObject3D::_mouse_enter() { GDVIRTUAL_CALL(_mouse_enter); - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } void CollisionObject3D::_mouse_exit() { GDVIRTUAL_CALL(_mouse_exit); - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } void CollisionObject3D::set_body_mode(PhysicsServer3D::BodyMode p_mode) { diff --git a/scene/3d/physics/joints/joint_3d.cpp b/scene/3d/physics/joints/joint_3d.cpp index a9c2526bd0..dac52a4dd8 100644 --- a/scene/3d/physics/joints/joint_3d.cpp +++ b/scene/3d/physics/joints/joint_3d.cpp @@ -36,13 +36,13 @@ void Joint3D::_disconnect_signals() { Node *node_a = get_node_or_null(a); PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a); if (body_a) { - body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + body_a->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); } Node *node_b = get_node_or_null(b); PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b); if (body_b) { - body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + body_b->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); } } @@ -108,12 +108,12 @@ void Joint3D::_update_joint(bool p_only_free) { if (body_a) { ba = body_a->get_rid(); - body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + body_a->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); } if (body_b) { bb = body_b->get_rid(); - body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + body_b->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); } PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision); diff --git a/scene/3d/physics/rigid_body_3d.cpp b/scene/3d/physics/rigid_body_3d.cpp index 6cd621c1c7..a06680767c 100644 --- a/scene/3d/physics/rigid_body_3d.cpp +++ b/scene/3d/physics/rigid_body_3d.cpp @@ -45,10 +45,10 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) { contact_monitor->locked = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -66,10 +66,10 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) { contact_monitor->locked = true; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -94,10 +94,10 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan //E->value.rc=0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } } @@ -107,7 +107,7 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan } if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_local_shape); } } else { @@ -121,17 +121,17 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan if (E->value.shapes.is_empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); } } contact_monitor->body_map.remove(E); } if (node && in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_local_shape); } } } @@ -157,7 +157,7 @@ void RigidBody3D::_sync_body_state(PhysicsDirectBodyState3D *p_state) { if (sleeping != p_state->is_sleeping()) { sleeping = p_state->is_sleeping(); - emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + emit_signal(SceneStringName(sleeping_state_changed)); } } @@ -613,8 +613,8 @@ void RigidBody3D::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree)); } } diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 72b5b53b19..cd0aafbf29 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -314,7 +314,7 @@ void Skeleton3D::_notification(int p_what) { _process_modifiers(); } - emit_signal(SceneStringNames::get_singleton()->skeleton_updated); + emit_signal(SceneStringName(skeleton_updated)); // Update skins. RenderingServer *rs = RenderingServer::get_singleton(); @@ -605,7 +605,7 @@ void Skeleton3D::set_bone_enabled(int p_bone, bool p_enabled) { ERR_FAIL_INDEX(p_bone, bone_size); bones.write[p_bone].enabled = p_enabled; - emit_signal(SceneStringNames::get_singleton()->bone_enabled_changed, p_bone); + emit_signal(SceneStringName(bone_enabled_changed), p_bone); _make_dirty(); } @@ -617,7 +617,7 @@ bool Skeleton3D::is_bone_enabled(int p_bone) const { void Skeleton3D::set_show_rest_only(bool p_enabled) { show_rest_only = p_enabled; - emit_signal(SceneStringNames::get_singleton()->show_rest_only_changed); + emit_signal(SceneStringName(show_rest_only_changed)); _make_dirty(); } @@ -840,7 +840,7 @@ void Skeleton3D::force_update_all_bone_transforms() { if (updating) { return; } - emit_signal(SceneStringNames::get_singleton()->pose_updated); + emit_signal(SceneStringName(pose_updated)); } void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) { diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 7d2a821d16..6ccb0ee134 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -796,15 +796,15 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) { return; } if (texture.is_valid()) { - texture->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); + texture->disconnect(SceneStringName(changed), callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); } texture = p_texture; if (texture.is_valid()) { - texture->connect(SceneStringNames::get_singleton()->changed, callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); + texture->connect(SceneStringName(changed), callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); } _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> Sprite3D::get_texture() const { @@ -849,7 +849,7 @@ void Sprite3D::set_frame(int p_frame) { frame = p_frame; _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } int Sprite3D::get_frame() const { @@ -1122,7 +1122,7 @@ void AnimatedSprite3D::_notification(int p_what) { } else { frame = last_frame; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -1131,7 +1131,7 @@ void AnimatedSprite3D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 0.0; _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN((1.0 - frame_progress) / abs_speed, remaining); frame_progress += to_process * abs_speed; @@ -1146,7 +1146,7 @@ void AnimatedSprite3D::_notification(int p_what) { } else { frame = 0; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -1155,7 +1155,7 @@ void AnimatedSprite3D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 1.0; _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN(frame_progress / abs_speed, remaining); frame_progress -= to_process * abs_speed; @@ -1177,12 +1177,12 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { } if (frames.is_valid()) { - frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed)); + frames->disconnect(SceneStringName(changed), callable_mp(this, &AnimatedSprite3D::_res_changed)); } stop(); frames = p_frames; if (frames.is_valid()) { - frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed)); + frames->connect(SceneStringName(changed), callable_mp(this, &AnimatedSprite3D::_res_changed)); List<StringName> al; frames->get_animation_list(&al); @@ -1249,7 +1249,7 @@ void AnimatedSprite3D::set_frame_and_progress(int p_frame, real_t p_progress) { return; // No change, don't redraw. } _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } void AnimatedSprite3D::set_speed_scale(float p_speed_scale) { diff --git a/scene/3d/visible_on_screen_notifier_3d.cpp b/scene/3d/visible_on_screen_notifier_3d.cpp index 272852e8fa..36a1771b96 100644 --- a/scene/3d/visible_on_screen_notifier_3d.cpp +++ b/scene/3d/visible_on_screen_notifier_3d.cpp @@ -38,7 +38,7 @@ void VisibleOnScreenNotifier3D::_visibility_enter() { } on_screen = true; - emit_signal(SceneStringNames::get_singleton()->screen_entered); + emit_signal(SceneStringName(screen_entered)); _screen_enter(); } void VisibleOnScreenNotifier3D::_visibility_exit() { @@ -47,7 +47,7 @@ void VisibleOnScreenNotifier3D::_visibility_exit() { } on_screen = false; - emit_signal(SceneStringNames::get_singleton()->screen_exited); + emit_signal(SceneStringName(screen_exited)); _screen_exit(); } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index e0dc300a6b..84ae8f1f4f 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -169,11 +169,11 @@ VisualInstance3D::~VisualInstance3D() { void GeometryInstance3D::set_material_override(const Ref<Material> &p_material) { if (material_override.is_valid()) { - material_override->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + material_override->disconnect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } material_override = p_material; if (material_override.is_valid()) { - material_override->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + material_override->connect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } RS::get_singleton()->instance_geometry_set_material_override(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID()); } @@ -279,12 +279,12 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) return true; } #ifndef DISABLE_DEPRECATED - if (p_name == SceneStringNames::get_singleton()->use_in_baked_light && bool(p_value)) { + if (p_name == SceneStringName(use_in_baked_light) && bool(p_value)) { set_gi_mode(GI_MODE_STATIC); return true; } - if (p_name == SceneStringNames::get_singleton()->use_dynamic_gi && bool(p_value)) { + if (p_name == SceneStringName(use_dynamic_gi) && bool(p_value)) { set_gi_mode(GI_MODE_DYNAMIC); return true; } diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 1cf235a807..e0b84eb6c7 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -1421,7 +1421,7 @@ AnimationNodeOutput::AnimationNodeOutput() { void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) { ERR_FAIL_COND(nodes.has(p_name)); ERR_FAIL_COND(p_node.is_null()); - ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); + ERR_FAIL_COND(p_name == SceneStringName(output)); ERR_FAIL_COND(String(p_name).contains("/")); Node n; @@ -1491,7 +1491,7 @@ Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const Strin void AnimationNodeBlendTree::remove_node(const StringName &p_name) { ERR_FAIL_COND(!nodes.has(p_name)); - ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); //can't delete output + ERR_FAIL_COND(p_name == SceneStringName(output)); //can't delete output { Ref<AnimationNode> node = nodes[p_name].node; @@ -1520,8 +1520,8 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) { void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringName &p_new_name) { ERR_FAIL_COND(!nodes.has(p_name)); ERR_FAIL_COND(nodes.has(p_new_name)); - ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); - ERR_FAIL_COND(p_new_name == SceneStringNames::get_singleton()->output); + ERR_FAIL_COND(p_name == SceneStringName(output)); + ERR_FAIL_COND(p_new_name == SceneStringName(output)); nodes[p_name].node->disconnect_changed(callable_mp(this, &AnimationNodeBlendTree::_node_changed)); @@ -1546,7 +1546,7 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) { ERR_FAIL_COND(!nodes.has(p_output_node)); ERR_FAIL_COND(!nodes.has(p_input_node)); - ERR_FAIL_COND(p_output_node == SceneStringNames::get_singleton()->output); + ERR_FAIL_COND(p_output_node == SceneStringName(output)); ERR_FAIL_COND(p_input_node == p_output_node); Ref<AnimationNode> input = nodes[p_input_node].node; @@ -1574,7 +1574,7 @@ void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_inp } AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const { - if (!nodes.has(p_output_node) || p_output_node == SceneStringNames::get_singleton()->output) { + if (!nodes.has(p_output_node) || p_output_node == SceneStringName(output)) { return CONNECTION_ERROR_NO_OUTPUT; } @@ -1627,8 +1627,8 @@ String AnimationNodeBlendTree::get_caption() const { } AnimationNode::NodeTimeInfo AnimationNodeBlendTree::_process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { - Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node; - node_state.connections = nodes[SceneStringNames::get_singleton()->output].connections; + Ref<AnimationNodeOutput> output = nodes[SceneStringName(output)].node; + node_state.connections = nodes[SceneStringName(output)].connections; ERR_FAIL_COND_V(output.is_null(), NodeTimeInfo()); AnimationMixer::PlaybackInfo pi = p_playback_info; diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index d22b58346f..1671192fd9 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -628,9 +628,9 @@ bool AnimationMixer::_update_caches() { #endif Ref<Animation> reset_anim; - bool has_reset_anim = has_animation(SceneStringNames::get_singleton()->RESET); + bool has_reset_anim = has_animation(SceneStringName(RESET)); if (has_reset_anim) { - reset_anim = get_animation(SceneStringNames::get_singleton()->RESET); + reset_anim = get_animation(SceneStringName(RESET)); } for (const StringName &E : sname) { Ref<Animation> anim = get_animation(E); @@ -1926,7 +1926,7 @@ bool AnimationMixer::is_reset_on_save_enabled() const { } bool AnimationMixer::can_apply_reset() const { - return has_animation(SceneStringNames::get_singleton()->RESET); + return has_animation(SceneStringName(RESET)); } void AnimationMixer::_build_backup_track_cache() { @@ -2013,7 +2013,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() { Ref<AnimatedValuesBackup> backup; backup.instantiate(); - Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; + Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation; ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>()); _blend_init(); @@ -2022,7 +2022,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() { pi.delta = 0; pi.seeked = true; pi.weight = 1.0; - make_animation_instance(SceneStringNames::get_singleton()->RESET, pi); + make_animation_instance(SceneStringName(RESET), pi); _build_backup_track_cache(); backup->set_data(track_cache); @@ -2034,7 +2034,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() { void AnimationMixer::reset() { ERR_FAIL_COND(!can_apply_reset()); - Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; + Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation; ERR_FAIL_COND(reset_anim.is_null()); Node *root_node_object = get_node_or_null(root_node); @@ -2044,11 +2044,11 @@ void AnimationMixer::reset() { root_node_object->add_child(aux_player); Ref<AnimationLibrary> al; al.instantiate(); - al->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim); + al->add_animation(SceneStringName(RESET), reset_anim); aux_player->set_reset_on_save_enabled(false); aux_player->set_root_node(aux_player->get_path_to(root_node_object)); aux_player->add_animation_library("", al); - aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET); + aux_player->set_assigned_animation(SceneStringName(RESET)); aux_player->seek(0.0f, true); aux_player->queue_free(); } @@ -2068,7 +2068,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::apply_reset(bool p_user_initiated) { } ERR_FAIL_COND_V(!can_apply_reset(), Ref<AnimatedValuesBackup>()); - Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; + Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation; ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>()); Ref<AnimatedValuesBackup> backup_current = make_backup(); @@ -2286,7 +2286,7 @@ void AnimationMixer::_bind_methods() { } AnimationMixer::AnimationMixer() { - root_node = SceneStringNames::get_singleton()->path_pp; + root_node = SceneStringName(path_pp); } AnimationMixer::~AnimationMixer() { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 2213800476..2b6c9a335d 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -41,7 +41,7 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) { } else if (name.begins_with("next/")) { String which = name.get_slicec('/', 1); animation_set_next(which, p_value); - } else if (p_name == SceneStringNames::get_singleton()->blend_times) { + } else if (p_name == SceneStringName(blend_times)) { Array array = p_value; int len = array.size(); ERR_FAIL_COND_V(len % 3, false); @@ -326,14 +326,14 @@ void AnimationPlayer::_blend_post_process() { String new_name = playback.assigned; playback_queue.pop_front(); if (end_notify) { - emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); + emit_signal(SceneStringName(animation_changed), old, new_name); } } else { _clear_caches(); playing = false; _set_process(false); if (end_notify) { - emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); + emit_signal(SceneStringName(animation_finished), playback.assigned); if (movie_quit_on_finish && OS::get_singleton()->has_feature("movie")) { print_line(vformat("Movie Maker mode is enabled. Quitting on animation finish as requested by: %s", get_path())); get_tree()->quit(); @@ -463,7 +463,7 @@ void AnimationPlayer::_play(const StringName &p_name, double p_custom_blend, flo _set_process(true); // Always process when starting an animation. playing = true; - emit_signal(SceneStringNames::get_singleton()->animation_started, c.assigned); + emit_signal(SceneStringName(animation_started), c.assigned); if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { return; // No next in this case. diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 28a163768f..8fe05d9d1f 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -627,7 +627,7 @@ bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const for (int i = 0; i < p_track_count; i++) { src_blendsw[i] = 1.0; // By default all go to 1 for the root input. } - root_animation_node->node_state.base_path = SceneStringNames::get_singleton()->parameters_base_path; + root_animation_node->node_state.base_path = SceneStringName(parameters_base_path); root_animation_node->node_state.parent = nullptr; } @@ -788,7 +788,7 @@ void AnimationTree::_update_properties() { input_activity_map_get.clear(); if (root_animation_node.is_valid()) { - _update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root_animation_node); + _update_properties_for_node(SceneStringName(parameters_base_path), root_animation_node); } properties_dirty = false; @@ -810,7 +810,7 @@ void AnimationTree::_notification(int p_what) { void AnimationTree::set_animation_player(const NodePath &p_path) { animation_player = p_path; if (p_path.is_empty()) { - set_root_node(SceneStringNames::get_singleton()->path_pp); + set_root_node(SceneStringName(path_pp)); while (animation_libraries.size()) { remove_animation_library(animation_libraries[0].name); } diff --git a/scene/audio/audio_stream_player_internal.cpp b/scene/audio/audio_stream_player_internal.cpp index 19b3ec481b..ed3c43818e 100644 --- a/scene/audio/audio_stream_player_internal.cpp +++ b/scene/audio/audio_stream_player_internal.cpp @@ -307,14 +307,14 @@ StringName AudioStreamPlayerInternal::get_bus() const { return bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } AudioStreamPlayerInternal::AudioStreamPlayerInternal(Node *p_node, const Callable &p_play_callable, bool p_physical) { node = p_node; play_callable = p_play_callable; physical = p_physical; - bus = SceneStringNames::get_singleton()->Master; + bus = SceneStringName(Master); AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp((Object *)node, &Object::notify_property_list_changed)); AudioServer::get_singleton()->connect("bus_renamed", callable_mp((Object *)node, &Object::notify_property_list_changed).unbind(3)); diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 5db8d69eef..625964c5e3 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -86,10 +86,10 @@ void Container::_sort_children() { } notification(NOTIFICATION_PRE_SORT_CHILDREN); - emit_signal(SceneStringNames::get_singleton()->pre_sort_children); + emit_signal(SceneStringName(pre_sort_children)); notification(NOTIFICATION_SORT_CHILDREN); - emit_signal(SceneStringNames::get_singleton()->sort_children); + emit_signal(SceneStringName(sort_children)); pending_sort = false; } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 2dd12b92f3..9c27f46467 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1606,7 +1606,7 @@ void Control::_update_minimum_size() { if (minsize != data.last_minimum_size) { data.last_minimum_size = minsize; _size_changed(); - emit_signal(SceneStringNames::get_singleton()->minimum_size_changed); + emit_signal(SceneStringName(minimum_size_changed)); } } @@ -1770,7 +1770,7 @@ void Control::set_h_size_flags(BitField<SizeFlags> p_flags) { return; } data.h_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + emit_signal(SceneStringName(size_flags_changed)); } BitField<Control::SizeFlags> Control::get_h_size_flags() const { @@ -1784,7 +1784,7 @@ void Control::set_v_size_flags(BitField<SizeFlags> p_flags) { return; } data.v_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + emit_signal(SceneStringName(size_flags_changed)); } BitField<Control::SizeFlags> Control::get_v_size_flags() const { @@ -1799,7 +1799,7 @@ void Control::set_stretch_ratio(real_t p_ratio) { } data.expand = p_ratio; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + emit_signal(SceneStringName(size_flags_changed)); } real_t Control::get_stretch_ratio() const { @@ -1811,7 +1811,7 @@ real_t Control::get_stretch_ratio() const { void Control::_call_gui_input(const Ref<InputEvent> &p_event) { if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) { - emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); // Signal should be first, so it's possible to override an event (and then accept it). + emit_signal(SceneStringName(gui_input), p_event); // Signal should be first, so it's possible to override an event (and then accept it). } if (!is_inside_tree() || get_viewport()->is_input_handled()) { return; // Input was handled, abort. @@ -3299,7 +3299,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_RESIZED: { - emit_signal(SceneStringNames::get_singleton()->resized); + emit_signal(SceneStringName(resized)); } break; case NOTIFICATION_DRAW: { @@ -3309,25 +3309,25 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_MOUSE_ENTER: { - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } break; case NOTIFICATION_MOUSE_EXIT: { - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } break; case NOTIFICATION_FOCUS_ENTER: { - emit_signal(SceneStringNames::get_singleton()->focus_entered); + emit_signal(SceneStringName(focus_entered)); queue_redraw(); } break; case NOTIFICATION_FOCUS_EXIT: { - emit_signal(SceneStringNames::get_singleton()->focus_exited); + emit_signal(SceneStringName(focus_exited)); queue_redraw(); } break; case NOTIFICATION_THEME_CHANGED: { - emit_signal(SceneStringNames::get_singleton()->theme_changed); + emit_signal(SceneStringName(theme_changed)); _invalidate_theme_cache(); _update_theme_item_cache(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 646e45b27a..35d7146d20 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1059,7 +1059,7 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) { port_size.height = MAX(port_size.height, child ? child->get_size().y : 0); int type = graph_node->get_output_port_type(j); - if ((type == connecting_type || + if ((type == connecting_type || graph_node->is_ignoring_valid_connection_type() || valid_connection_types.has(ConnectionType(type, connecting_type))) && is_in_output_hotzone(graph_node, j, mpos, port_size)) { if (!is_node_hover_valid(graph_node->get_name(), j, connecting_from_node, connecting_from_port_index)) { @@ -1084,7 +1084,7 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) { port_size.height = MAX(port_size.height, child ? child->get_size().y : 0); int type = graph_node->get_input_port_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnectionType(connecting_type, type))) && + if ((type == connecting_type || graph_node->is_ignoring_valid_connection_type() || valid_connection_types.has(ConnectionType(connecting_type, type))) && is_in_input_hotzone(graph_node, j, mpos, port_size)) { if (!is_node_hover_valid(connecting_from_node, connecting_from_port_index, graph_node->get_name(), j)) { continue; @@ -1117,6 +1117,8 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) { emit_signal(SNAME("connection_from_empty"), connecting_from_node, connecting_from_port_index, mb->get_position()); } } + } else { + set_selected(get_node_or_null(NodePath(connecting_from_node))); } if (connecting) { @@ -1636,12 +1638,12 @@ void GraphEdit::_draw_grid() { void GraphEdit::set_selected(Node *p_child) { for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i)); - if (!graph_node) { + GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i)); + if (!graph_element) { continue; } - graph_node->set_selected(graph_node == p_child); + graph_element->set_selected(graph_element == p_child); } } diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 75ac5c5135..d804f83e1c 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -604,6 +604,14 @@ void GraphNode::set_slot_draw_stylebox(int p_slot_index, bool p_enable) { emit_signal(SNAME("slot_updated"), p_slot_index); } +void GraphNode::set_ignore_invalid_connection_type(bool p_ignore) { + ignore_invalid_connection_type = p_ignore; +} + +bool GraphNode::is_ignoring_valid_connection_type() const { + return ignore_invalid_connection_type; +} + Size2 GraphNode::get_minimum_size() const { Ref<StyleBox> sb_panel = theme_cache.panel; Ref<StyleBox> sb_titlebar = theme_cache.titlebar; @@ -859,6 +867,9 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("is_slot_draw_stylebox", "slot_index"), &GraphNode::is_slot_draw_stylebox); ClassDB::bind_method(D_METHOD("set_slot_draw_stylebox", "slot_index", "enable"), &GraphNode::set_slot_draw_stylebox); + ClassDB::bind_method(D_METHOD("set_ignore_invalid_connection_type", "ignore"), &GraphNode::set_ignore_invalid_connection_type); + ClassDB::bind_method(D_METHOD("is_ignoring_valid_connection_type"), &GraphNode::is_ignoring_valid_connection_type); + ClassDB::bind_method(D_METHOD("get_input_port_count"), &GraphNode::get_input_port_count); ClassDB::bind_method(D_METHOD("get_input_port_position", "port_idx"), &GraphNode::get_input_port_position); ClassDB::bind_method(D_METHOD("get_input_port_type", "port_idx"), &GraphNode::get_input_port_type); @@ -874,6 +885,8 @@ void GraphNode::_bind_methods() { GDVIRTUAL_BIND(_draw_port, "slot_index", "position", "left", "color") ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_invalid_connection_type"), "set_ignore_invalid_connection_type", "is_ignoring_valid_connection_type"); + ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "slot_index"))); BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, panel); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 71cc322baa..27af3192c8 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -95,6 +95,8 @@ class GraphNode : public GraphElement { bool port_pos_dirty = true; + bool ignore_invalid_connection_type = false; + void _port_pos_update(); protected: @@ -147,6 +149,9 @@ public: bool is_slot_draw_stylebox(int p_slot_index) const; void set_slot_draw_stylebox(int p_slot_index, bool p_enable); + void set_ignore_invalid_connection_type(bool p_ignore); + bool is_ignoring_valid_connection_type() const; + int get_input_port_count(); Vector2 get_input_port_position(int p_port_idx); int get_input_port_type(int p_port_idx); diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index e2ae824e60..7ebf8a63c2 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -111,7 +111,7 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) { queue_redraw(); update_minimum_size(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> NinePatchRect::get_texture() const { diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp index 687a9e46a0..e581d0b5db 100644 --- a/scene/gui/video_stream_player.cpp +++ b/scene/gui/video_stream_player.cpp @@ -163,7 +163,7 @@ void VideoStreamPlayer::_notification(int p_notification) { play(); return; } - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } } break; @@ -460,7 +460,7 @@ StringName VideoStreamPlayer::get_bus() const { return bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void VideoStreamPlayer::_validate_property(PropertyInfo &p_property) const { diff --git a/scene/main/canvas_item.compat.inc b/scene/main/canvas_item.compat.inc index 7136fded15..9bc3d01a69 100644 --- a/scene/main/canvas_item.compat.inc +++ b/scene/main/canvas_item.compat.inc @@ -30,12 +30,32 @@ #ifndef DISABLE_DEPRECATED -void CanvasItem::_draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) { +void CanvasItem::_draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) { draw_circle(p_pos, p_radius, p_color, true, -1.0, false); } +void CanvasItem::_draw_rect_bind_compat_84523(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width) { + draw_rect(p_rect, p_color, p_filled, p_width, false); +} + +void CanvasItem::_draw_dashed_line_bind_compat_84523(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) { + draw_dashed_line(p_from, p_to, p_color, p_width, p_dash, p_aligned, false); +} + +void CanvasItem::_draw_multiline_bind_compat_84523(const Vector<Point2> &p_points, const Color &p_color, real_t p_width) { + draw_multiline(p_points, p_color, p_width, false); +} + +void CanvasItem::_draw_multiline_colors_bind_compat_84523(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width) { + draw_multiline_colors(p_points, p_colors, p_width, false); +} + void CanvasItem::_bind_compatibility_methods() { - ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_compat_84472); + ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_bind_compat_84472); + ClassDB::bind_compatibility_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::_draw_rect_bind_compat_84523, DEFVAL(true), DEFVAL(-1.0)); + ClassDB::bind_compatibility_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned"), &CanvasItem::_draw_dashed_line_bind_compat_84523, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true)); + ClassDB::bind_compatibility_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::_draw_multiline_bind_compat_84523, DEFVAL(-1.0)); + ClassDB::bind_compatibility_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::_draw_multiline_colors_bind_compat_84523, DEFVAL(-1.0)); } #endif diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index cabba0f2ed..dca116086d 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -95,7 +95,7 @@ void CanvasItem::_handle_visibility_change(bool p_visible) { if (p_visible) { queue_redraw(); } else { - emit_signal(SceneStringNames::get_singleton()->hidden); + emit_signal(SceneStringName(hidden)); } _block(); @@ -141,7 +141,7 @@ void CanvasItem::_redraw_callback() { drawing = true; current_item_drawn = this; notification(NOTIFICATION_DRAW); - emit_signal(SceneStringNames::get_singleton()->draw); + emit_signal(SceneStringName(draw)); GDVIRTUAL_CALL(_draw); current_item_drawn = nullptr; drawing = false; @@ -309,7 +309,7 @@ void CanvasItem::_notification(int p_what) { window = Object::cast_to<Window>(viewport); if (window) { - window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window->connect(SceneStringName(visibility_changed), callable_mp(this, &CanvasItem::_window_visibility_changed)); parent_visible_in_tree = window->is_visible(); } else { parent_visible_in_tree = true; @@ -363,7 +363,7 @@ void CanvasItem::_notification(int p_what) { C = nullptr; } if (window) { - window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window->disconnect(SceneStringName(visibility_changed), callable_mp(this, &CanvasItem::_window_visibility_changed)); window = nullptr; } _set_global_invalid(true); @@ -383,7 +383,7 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { ERR_MAIN_THREAD_GUARD; - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); } break; case NOTIFICATION_WORLD_2D_CHANGED: { ERR_MAIN_THREAD_GUARD; @@ -555,7 +555,7 @@ void CanvasItem::item_rect_changed(bool p_size_changed) { if (p_size_changed) { queue_redraw(); } - emit_signal(SceneStringNames::get_singleton()->item_rect_changed); + emit_signal(SceneStringName(item_rect_changed)); } void CanvasItem::set_z_index(int p_z) { @@ -609,7 +609,7 @@ bool CanvasItem::is_y_sort_enabled() const { return y_sort_enabled; } -void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) { +void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; ERR_FAIL_COND(p_dash <= 0.0); @@ -618,7 +618,7 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons Vector2 step = p_dash * (p_to - p_from).normalized(); if (length < p_dash || step == Vector2()) { - RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width); + RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased); return; } @@ -642,7 +642,7 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons Vector<Color> colors = { p_color }; - RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width, p_antialiased); } void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, bool p_antialiased) { @@ -683,22 +683,22 @@ void CanvasItem::draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_sta draw_polyline(points, p_color, p_width, p_antialiased); } -void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width) { +void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; Vector<Color> colors = { p_color }; - RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased); } -void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width) { +void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; - RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased); } -void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width) { +void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; @@ -709,9 +709,9 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\"."); } - RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect, p_color); + RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect, p_color, p_antialiased); } else if (p_width >= rect.size.width || p_width >= rect.size.height) { - RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color); + RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color, p_antialiased); } else { Vector<Vector2> points; points.resize(5); @@ -723,7 +723,7 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil Vector<Color> colors = { p_color }; - RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width, p_antialiased); } } @@ -736,9 +736,9 @@ void CanvasItem::draw_circle(const Point2 &p_pos, real_t p_radius, const Color & WARN_PRINT("The draw_circle() \"width\" argument has no effect when \"filled\" is \"true\"."); } - RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color); + RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color, p_antialiased); } else if (p_width >= 2.0 * p_radius) { - RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius + 0.5 * p_width, p_color); + RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius + 0.5 * p_width, p_color, p_antialiased); } else { // Tessellation count is hardcoded. Keep in sync with the same variable in `RendererCanvasCull::canvas_item_add_circle()`. const int circle_segments = 64; @@ -1186,13 +1186,13 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("is_draw_behind_parent_enabled"), &CanvasItem::is_draw_behind_parent_enabled); ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(-1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned"), &CanvasItem::draw_dashed_line, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned", "antialiased"), &CanvasItem::draw_dashed_line, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(-1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::draw_multiline, DEFVAL(-1.0)); - ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::draw_multiline_colors, DEFVAL(-1.0)); - ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(-1.0)); + ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(-1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(-1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color", "filled", "width", "antialiased"), &CanvasItem::draw_circle, DEFVAL(true), DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false)); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index ae7b195ead..028c2cb2cf 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -168,7 +168,11 @@ protected: static void _bind_methods(); #ifndef DISABLE_DEPRECATED - void _draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color); + void _draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color); + void _draw_rect_bind_compat_84523(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width); + void _draw_dashed_line_bind_compat_84523(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned); + void _draw_multiline_bind_compat_84523(const Vector<Point2> &p_points, const Color &p_color, real_t p_width); + void _draw_multiline_colors_bind_compat_84523(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width); static void _bind_compatibility_methods(); #endif @@ -271,14 +275,14 @@ public: /* DRAWING API */ - void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, real_t p_dash = 2.0, bool p_aligned = true); + void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, real_t p_dash = 2.0, bool p_aligned = true, bool p_antialiased = false); void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0, bool p_antialiased = false); void draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_start_angle, real_t p_end_angle, int p_point_count, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); - void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0); - void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0); - void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = -1.0); + void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); + void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0, bool p_antialiased = false); + void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = -1.0, bool p_antialiased = false); void draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color, bool p_filled = true, real_t p_width = -1.0, bool p_antialiased = false); void draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1)); void draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e54209c1dd..15b4186aa1 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -266,7 +266,7 @@ void Node::_propagate_ready() { if (data.ready_first) { data.ready_first = false; notification(NOTIFICATION_READY); - emit_signal(SceneStringNames::get_singleton()->ready); + emit_signal(SceneStringName(ready)); } } @@ -295,7 +295,7 @@ void Node::_propagate_enter_tree() { GDVIRTUAL_CALL(_enter_tree); - emit_signal(SceneStringNames::get_singleton()->tree_entered); + emit_signal(SceneStringName(tree_entered)); data.tree->node_added(this); @@ -350,7 +350,7 @@ void Node::_propagate_after_exit_tree() { data.blocked--; - emit_signal(SceneStringNames::get_singleton()->tree_exited); + emit_signal(SceneStringName(tree_exited)); } void Node::_propagate_exit_tree() { @@ -372,7 +372,7 @@ void Node::_propagate_exit_tree() { GDVIRTUAL_CALL(_exit_tree); - emit_signal(SceneStringNames::get_singleton()->tree_exiting); + emit_signal(SceneStringName(tree_exiting)); notification(NOTIFICATION_EXIT_TREE, true); if (data.tree) { @@ -1738,11 +1738,11 @@ Node *Node::get_node_or_null(const NodePath &p_path) const { StringName name = p_path.get_name(i); Node *next = nullptr; - if (name == SceneStringNames::get_singleton()->dot) { // . + if (name == SceneStringName(dot)) { // . next = current; - } else if (name == SceneStringNames::get_singleton()->doubledot) { // .. + } else if (name == SceneStringName(doubledot)) { // .. if (current == nullptr || !current->data.parent) { return nullptr; @@ -2667,8 +2667,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c node->data.editable_instance = data.editable_instance; } - StringName script_property_name = CoreStringNames::get_singleton()->_script; - List<const Node *> hidden_roots; List<const Node *> node_tree; node_tree.push_front(this); @@ -2770,45 +2768,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c parent->move_child(dup, pos); } } - - for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { - Node *current_node = node->get_node(get_path_to(N->get())); - ERR_CONTINUE(!current_node); - - if (p_flags & DUPLICATE_SCRIPTS) { - bool is_valid = false; - Variant scr = N->get()->get(script_property_name, &is_valid); - if (is_valid) { - current_node->set(script_property_name, scr); - } - } - - List<PropertyInfo> plist; - N->get()->get_property_list(&plist); - - for (const PropertyInfo &E : plist) { - if (!(E.usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - String name = E.name; - if (name == script_property_name) { - continue; - } - - Variant value = N->get()->get(name).duplicate(true); - - if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) { - Resource *res = Object::cast_to<Resource>(value); - if (res) { // Duplicate only if it's a resource - current_node->set(name, res->duplicate()); - } - - } else { - current_node->set(name, value); - } - } - } - return node; } @@ -2820,7 +2779,7 @@ Node *Node::duplicate(int p_flags) const { _duplicate_signals(this, dupe); } - _duplicate_properties_node(this, this, dupe); + _duplicate_properties(this, this, dupe, p_flags); return dupe; } @@ -2831,7 +2790,8 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) con } Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const { - Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR, &r_duplimap); + int flags = DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR; + Node *dupe = _duplicate(flags, &r_duplimap); // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated. if (!p_resource_remap.is_empty()) { @@ -2843,7 +2803,7 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con // if the emitter node comes later in tree order than the receiver _duplicate_signals(this, dupe); - _duplicate_properties_node(this, this, dupe); + _duplicate_properties(this, this, dupe, flags); return dupe; } @@ -2897,34 +2857,58 @@ void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Re } #endif -// Duplicates properties that store a Node. -// This has to be called after nodes have been duplicated since -// only then do we get a full picture of how the duplicated node tree looks like. -void Node::_duplicate_properties_node(const Node *p_root, const Node *p_original, Node *p_copy) const { +// Duplicate node's properties. +// This has to be called after nodes have been duplicated since there might be properties +// of type Node that can be updated properly only if duplicated node tree is complete. +void Node::_duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const { List<PropertyInfo> props; - p_copy->get_property_list(&props); + p_original->get_property_list(&props); + const StringName &script_property_name = CoreStringName(script); + if (p_flags & DUPLICATE_SCRIPTS) { + bool is_valid = false; + Variant scr = p_original->get(script_property_name, &is_valid); + if (is_valid) { + p_copy->set(script_property_name, scr); + } + } for (const PropertyInfo &E : props) { if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - String name = E.name; + const StringName name = E.name; + + if (name == script_property_name) { + continue; + } + Variant value = p_original->get(name).duplicate(true); - if (value.get_type() == Variant::OBJECT) { - Node *property_node = Object::cast_to<Node>(value); - if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { - value = p_copy->get_node_or_null(p_original->get_path_to(property_node)); - p_copy->set(name, value); + + if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) { + Resource *res = Object::cast_to<Resource>(value); + if (res) { // Duplicate only if it's a resource + p_copy->set(name, res->duplicate()); } - } else if (value.get_type() == Variant::ARRAY) { - Array arr = value; - if (arr.get_typed_builtin() == Variant::OBJECT) { - for (int i = 0; i < arr.size(); i++) { - Node *property_node = Object::cast_to<Node>(arr[i]); - if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { - arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node)); + } else { + if (value.get_type() == Variant::OBJECT) { + Node *property_node = Object::cast_to<Node>(value); + Variant out_value = value; + if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { + out_value = p_copy->get_node_or_null(p_original->get_path_to(property_node)); + } + p_copy->set(name, out_value); + } else if (value.get_type() == Variant::ARRAY) { + Array arr = value; + if (arr.get_typed_builtin() == Variant::OBJECT) { + for (int i = 0; i < arr.size(); i++) { + Node *property_node = Object::cast_to<Node>(arr[i]); + if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { + arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node)); + } } + value = arr; + p_copy->set(name, value); } - value = arr; + } else { p_copy->set(name, value); } } @@ -2933,7 +2917,7 @@ void Node::_duplicate_properties_node(const Node *p_root, const Node *p_original for (int i = 0; i < p_original->get_child_count(); i++) { Node *copy_child = p_copy->get_child(i); ERR_FAIL_NULL_MSG(copy_child, "Child node disappeared while duplicating."); - _duplicate_properties_node(p_root, p_original->get_child(i), copy_child); + _duplicate_properties(p_root, p_original->get_child(i), copy_child, p_flags); } } @@ -3323,7 +3307,7 @@ void Node::update_configuration_warnings() { return; } if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_ancestor_of(this))) { - get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed, this); + get_tree()->emit_signal(SceneStringName(node_configuration_warning_changed), this); } #endif } diff --git a/scene/main/node.h b/scene/main/node.h index fe212ae0f7..65cbd2f2c0 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -266,7 +266,7 @@ private: void _propagate_groups_dirty(); Array _get_node_and_resource(const NodePath &p_path); - void _duplicate_properties_node(const Node *p_root, const Node *p_original, Node *p_copy) const; + void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const; void _duplicate_signals(const Node *p_original, Node *p_copy) const; Node *_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap = nullptr) const; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 091e6249bf..372d4c6640 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -223,11 +223,11 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const void ShaderGlobalsOverride::_activate() { ERR_FAIL_NULL(get_tree()); List<Node *> nodes; - get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes); + get_tree()->get_nodes_in_group(SceneStringName(shader_overrides_group_active), &nodes); if (nodes.size() == 0) { //good we are the only override, enable all active = true; - add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active); + add_to_group(SceneStringName(shader_overrides_group_active)); for (const KeyValue<StringName, Override> &E : overrides) { const Override *o = &E.value; @@ -248,7 +248,7 @@ void ShaderGlobalsOverride::_activate() { void ShaderGlobalsOverride::_notification(int p_what) { switch (p_what) { case Node::NOTIFICATION_ENTER_TREE: { - add_to_group(SceneStringNames::get_singleton()->shader_overrides_group); + add_to_group(SceneStringName(shader_overrides_group)); _activate(); } break; @@ -263,9 +263,9 @@ void ShaderGlobalsOverride::_notification(int p_what) { } } - remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active); - remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group); - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed + remove_from_group(SceneStringName(shader_overrides_group_active)); + remove_from_group(SceneStringName(shader_overrides_group)); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(shader_overrides_group), "_activate"); //another may want to activate when this is removed active = false; } break; } diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 929720fcf4..5ec300faee 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -846,7 +846,7 @@ void Window::set_visible(bool p_visible) { focused = false; } notification(NOTIFICATION_VISIBILITY_CHANGED); - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); RS::get_singleton()->viewport_set_active(get_viewport_rid(), visible); @@ -1321,7 +1321,7 @@ void Window::_notification(int p_what) { } if (visible) { notification(NOTIFICATION_VISIBILITY_CHANGED); - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); RS::get_singleton()->viewport_set_active(get_viewport_rid(), true); } @@ -1337,7 +1337,7 @@ void Window::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - emit_signal(SceneStringNames::get_singleton()->theme_changed); + emit_signal(SceneStringName(theme_changed)); _invalidate_theme_cache(); _update_theme_item_cache(); } break; @@ -1404,11 +1404,11 @@ void Window::_notification(int p_what) { } break; case NOTIFICATION_VP_MOUSE_ENTER: { - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } break; case NOTIFICATION_VP_MOUSE_EXIT: { - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } break; } } @@ -1622,7 +1622,7 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) { _input_from_window(p_ev); if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL && is_inside_tree()) { - emit_signal(SceneStringNames::get_singleton()->window_input, p_ev); + emit_signal(SceneStringName(window_input), p_ev); } if (is_inside_tree()) { diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index de94327d79..a5b0ac24b9 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -744,6 +744,7 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeVarying); GDREGISTER_CLASS(VisualShaderNodeVaryingSetter); GDREGISTER_CLASS(VisualShaderNodeVaryingGetter); + GDREGISTER_CLASS(VisualShaderNodeReroute); GDREGISTER_CLASS(VisualShaderNodeSDFToScreenUV); GDREGISTER_CLASS(VisualShaderNodeScreenUVToSDF); diff --git a/scene/resources/canvas_item_material.cpp b/scene/resources/canvas_item_material.cpp index 31c8e68ea5..76e99aca92 100644 --- a/scene/resources/canvas_item_material.cpp +++ b/scene/resources/canvas_item_material.cpp @@ -33,13 +33,11 @@ #include "core/version.h" Mutex CanvasItemMaterial::material_mutex; -SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = nullptr; +SelfList<CanvasItemMaterial>::List CanvasItemMaterial::dirty_materials; HashMap<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData, CanvasItemMaterial::MaterialKey> CanvasItemMaterial::shader_map; CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = nullptr; void CanvasItemMaterial::init_shaders() { - dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); - shader_names = memnew(ShaderNames); shader_names->particles_anim_h_frames = "particles_anim_h_frames"; @@ -48,14 +46,13 @@ void CanvasItemMaterial::init_shaders() { } void CanvasItemMaterial::finish_shaders() { - memdelete(dirty_materials); + dirty_materials.clear(); + memdelete(shader_names); - dirty_materials = nullptr; + shader_names = nullptr; } void CanvasItemMaterial::_update_shader() { - dirty_materials->remove(&element); - MaterialKey mk = _compute_key(); if (mk.key == current_key.key) { return; //no update required in the end @@ -153,8 +150,9 @@ void CanvasItemMaterial::_update_shader() { void CanvasItemMaterial::flush_changes() { MutexLock lock(material_mutex); - while (dirty_materials->first()) { - dirty_materials->first()->self()->_update_shader(); + while (dirty_materials.first()) { + dirty_materials.first()->self()->_update_shader(); + dirty_materials.first()->remove_from_list(); } } @@ -162,16 +160,10 @@ void CanvasItemMaterial::_queue_shader_change() { MutexLock lock(material_mutex); if (_is_initialized() && !element.in_list()) { - dirty_materials->add(&element); + dirty_materials.add(&element); } } -bool CanvasItemMaterial::_is_shader_dirty() const { - MutexLock lock(material_mutex); - - return element.in_list(); -} - void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) { blend_mode = p_blend_mode; _queue_shader_change(); @@ -288,7 +280,7 @@ CanvasItemMaterial::CanvasItemMaterial() : current_key.invalid_key = 1; - _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change)); + _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change), callable_mp(this, &CanvasItemMaterial::_update_shader)); } CanvasItemMaterial::~CanvasItemMaterial() { diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h index 7dddd74a31..ef498c2ff6 100644 --- a/scene/resources/canvas_item_material.h +++ b/scene/resources/canvas_item_material.h @@ -98,12 +98,11 @@ private: } static Mutex material_mutex; - static SelfList<CanvasItemMaterial>::List *dirty_materials; + static SelfList<CanvasItemMaterial>::List dirty_materials; SelfList<CanvasItemMaterial> element; void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; BlendMode blend_mode = BLEND_MODE_MIX; LightMode light_mode = LIGHT_MODE_NORMAL; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 15b40e776c..3784aa3da0 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -82,24 +82,25 @@ void Material::_validate_property(PropertyInfo &p_property) const { } } -void Material::_mark_initialized(const Callable &p_queue_shader_change_callable) { +void Material::_mark_ready() { + init_state = INIT_STATE_INITIALIZING; +} + +void Material::_mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader) { // If this is happening as part of resource loading, it is not safe to queue the update - // as an addition to the dirty list, unless the load is happening on the main thread. - if (ResourceLoader::is_within_load() && Thread::get_caller_id() != Thread::get_main_id()) { + // as an addition to the dirty list. It would be if the load is happening on the main thread, + // but even so we'd rather perform the update directly instead of using the dirty list. + if (ResourceLoader::is_within_load()) { DEV_ASSERT(init_state != INIT_STATE_READY); if (init_state == INIT_STATE_UNINITIALIZED) { // Prevent queueing twice. - // Let's mark this material as being initialized. init_state = INIT_STATE_INITIALIZING; - // Knowing that the ResourceLoader will eventually feed deferred calls into the main message queue, let's do these: - // 1. Queue setting the init state to INIT_STATE_READY finally. - callable_mp(this, &Material::_mark_initialized).bind(p_queue_shader_change_callable).call_deferred(); - // 2. Queue an individual update of this material. - p_queue_shader_change_callable.call_deferred(); + callable_mp(this, &Material::_mark_ready).call_deferred(); + p_update_shader.call_deferred(); } } else { // Straightforward conditions. init_state = INIT_STATE_READY; - p_queue_shader_change_callable.callv(Array()); + p_add_to_dirty_list.call(); } } @@ -603,8 +604,6 @@ void BaseMaterial3D::finish_shaders() { } void BaseMaterial3D::_update_shader() { - dirty_materials.remove(&element); - MaterialKey mk = _compute_key(); if (mk == current_key) { return; //no update required in the end @@ -1855,6 +1854,7 @@ void BaseMaterial3D::flush_changes() { while (dirty_materials.first()) { dirty_materials.first()->self()->_update_shader(); + dirty_materials.first()->remove_from_list(); } } @@ -1866,12 +1866,6 @@ void BaseMaterial3D::_queue_shader_change() { } } -bool BaseMaterial3D::_is_shader_dirty() const { - MutexLock lock(material_mutex); - - return element.in_list(); -} - void BaseMaterial3D::set_albedo(const Color &p_albedo) { albedo = p_albedo; @@ -2824,7 +2818,7 @@ BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const { RID BaseMaterial3D::get_shader_rid() const { MutexLock lock(material_mutex); - if (element.in_list()) { // _is_shader_dirty() would create anoder mutex lock + if (element.in_list()) { ((BaseMaterial3D *)this)->_update_shader(); } ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); @@ -3412,7 +3406,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : current_key.invalid_key = 1; - _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change)); + _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change), callable_mp(this, &BaseMaterial3D::_update_shader)); } BaseMaterial3D::~BaseMaterial3D() { diff --git a/scene/resources/material.h b/scene/resources/material.h index ecf79c581b..50a774e961 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -62,7 +62,8 @@ protected: void _validate_property(PropertyInfo &p_property) const; - void _mark_initialized(const Callable &p_queue_shader_change_callable); + void _mark_ready(); + void _mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader); bool _is_initialized() { return init_state == INIT_STATE_READY; } GDVIRTUAL0RC(RID, _get_shader_rid) @@ -466,7 +467,6 @@ private: void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; bool orm; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 407b12d72f..4158b178aa 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -328,7 +328,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr); - if (snames[nprops[j].name] == CoreStringNames::get_singleton()->_script) { + if (snames[nprops[j].name] == CoreStringName(script)) { //work around to avoid old script variables from disappearing, should be the proper fix to: //https://github.com/godotengine/godot/issues/2958 diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index 0b65b33240..81476eaa0f 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -33,14 +33,12 @@ #include "core/version.h" Mutex ParticleProcessMaterial::material_mutex; -SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr; +SelfList<ParticleProcessMaterial>::List ParticleProcessMaterial::dirty_materials; HashMap<ParticleProcessMaterial::MaterialKey, ParticleProcessMaterial::ShaderData, ParticleProcessMaterial::MaterialKey> ParticleProcessMaterial::shader_map; RBSet<String> ParticleProcessMaterial::min_max_properties; ParticleProcessMaterial::ShaderNames *ParticleProcessMaterial::shader_names = nullptr; void ParticleProcessMaterial::init_shaders() { - dirty_materials = memnew(SelfList<ParticleProcessMaterial>::List); - shader_names = memnew(ShaderNames); shader_names->direction = "direction"; @@ -140,15 +138,13 @@ void ParticleProcessMaterial::init_shaders() { } void ParticleProcessMaterial::finish_shaders() { - memdelete(dirty_materials); - dirty_materials = nullptr; + dirty_materials.clear(); memdelete(shader_names); + shader_names = nullptr; } void ParticleProcessMaterial::_update_shader() { - dirty_materials->remove(&element); - MaterialKey mk = _compute_key(); if (mk == current_key) { return; //no update required in the end @@ -1170,8 +1166,9 @@ void ParticleProcessMaterial::_update_shader() { void ParticleProcessMaterial::flush_changes() { MutexLock lock(material_mutex); - while (dirty_materials->first()) { - dirty_materials->first()->self()->_update_shader(); + while (dirty_materials.first()) { + dirty_materials.first()->self()->_update_shader(); + dirty_materials.first()->remove_from_list(); } } @@ -1179,16 +1176,10 @@ void ParticleProcessMaterial::_queue_shader_change() { MutexLock lock(material_mutex); if (_is_initialized() && !element.in_list()) { - dirty_materials->add(&element); + dirty_materials.add(&element); } } -bool ParticleProcessMaterial::_is_shader_dirty() const { - MutexLock lock(material_mutex); - - return element.in_list(); -} - bool ParticleProcessMaterial::has_min_max_property(const String &p_name) { return min_max_properties.has(p_name); } @@ -2330,7 +2321,7 @@ ParticleProcessMaterial::ParticleProcessMaterial() : current_key.invalid_key = 1; - _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change)); + _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change), callable_mp(this, &ParticleProcessMaterial::_update_shader)); } ParticleProcessMaterial::~ParticleProcessMaterial() { diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h index 94b2009654..25046b51cd 100644 --- a/scene/resources/particle_process_material.h +++ b/scene/resources/particle_process_material.h @@ -186,7 +186,7 @@ private: } static Mutex material_mutex; - static SelfList<ParticleProcessMaterial>::List *dirty_materials; + static SelfList<ParticleProcessMaterial>::List dirty_materials; struct ShaderNames { StringName direction; @@ -293,7 +293,6 @@ private: void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; Vector3 direction; float spread = 0.0f; diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index 42ffa2d25a..6e43ea9b17 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -277,5 +277,5 @@ void SpriteFrames::_bind_methods() { } SpriteFrames::SpriteFrames() { - add_animation(SceneStringNames::get_singleton()->_default); + add_animation(SceneStringName(default_)); } diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index a57af6886d..5a1b453a13 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1101,6 +1101,42 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod return result; } +bool VisualShader::_check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes) const { + const Graph *g = &graph[p_type]; + + // BFS to check whether connecting to the given subgraph (rooted at p_reroute_node) is valid. + List<int> queue; + queue.push_back(p_reroute_node); + if (r_visited_reroute_nodes != nullptr) { + r_visited_reroute_nodes->push_back(p_reroute_node); + } + while (!queue.is_empty()) { + int current_node_id = queue.front()->get(); + VisualShader::Node current_node = g->nodes[current_node_id]; + queue.pop_front(); + for (const int &next_node_id : current_node.next_connected_nodes) { + Ref<VisualShaderNodeReroute> next_vsnode = g->nodes[next_node_id].node; + if (next_vsnode.is_valid()) { + queue.push_back(next_node_id); + if (r_visited_reroute_nodes != nullptr) { + r_visited_reroute_nodes->push_back(next_node_id); + } + continue; + } + // Check whether all ports connected with the reroute node are compatible. + for (const Connection &c : g->connections) { + VisualShaderNode::PortType to_port_type = g->nodes[next_node_id].node->get_input_port_type(c.to_port); + if (c.from_node == current_node_id && + c.to_node == next_node_id && + !is_port_types_compatible(p_target_port_type, to_port_type)) { + return false; + } + } + } + } + return true; +} + bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false); const Graph *g = &graph[p_type]; @@ -1128,7 +1164,12 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port); VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port); - if (!is_port_types_compatible(from_port_type, to_port_type)) { + Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node; + if (to_node_reroute.is_valid()) { + if (!_check_reroute_subgraph(p_type, from_port_type, p_to_node)) { + return false; + } + } else if (!is_port_types_compatible(from_port_type, to_port_type)) { return false; } @@ -1141,7 +1182,6 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po if (is_nodes_connected_relatively(g, p_from_node, p_to_node)) { return false; } - return true; } @@ -1179,6 +1219,28 @@ void VisualShader::detach_node_from_frame(Type p_type, int p_node) { g->nodes[p_node].node->set_frame(-1); } +String VisualShader::get_reroute_parameter_name(Type p_type, int p_reroute_node) const { + ERR_FAIL_INDEX_V(p_type, TYPE_MAX, ""); + const Graph *g = &graph[p_type]; + + ERR_FAIL_COND_V(!g->nodes.has(p_reroute_node), ""); + + const VisualShader::Node *node = &g->nodes[p_reroute_node]; + while (node->prev_connected_nodes.size() > 0) { + int connected_node_id = node->prev_connected_nodes[0]; + node = &g->nodes[connected_node_id]; + Ref<VisualShaderNodeParameter> parameter_node = node->node; + if (parameter_node.is_valid() && parameter_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) { + return parameter_node->get_parameter_name(); + } + Ref<VisualShaderNodeInput> input_node = node->node; + if (input_node.is_valid() && input_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) { + return input_node->get_input_real_name(); + } + } + return ""; +} + void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { ERR_FAIL_INDEX(p_type, TYPE_MAX); Graph *g = &graph[p_type]; @@ -1217,10 +1279,30 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port, ERR_FAIL_COND_V(!g->nodes.has(p_to_node), ERR_INVALID_PARAMETER); ERR_FAIL_INDEX_V(p_to_port, g->nodes[p_to_node].node->get_input_port_count(), ERR_INVALID_PARAMETER); + Ref<VisualShaderNodeReroute> from_node_reroute = g->nodes[p_from_node].node; + Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node; + + // Allow connection with incompatible port types only if the reroute node isn't connected to anything. VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port); VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port); + bool port_types_are_compatible = is_port_types_compatible(from_port_type, to_port_type); + + if (to_node_reroute.is_valid()) { + List<int> visited_reroute_nodes; + port_types_are_compatible = _check_reroute_subgraph(p_type, from_port_type, p_to_node, &visited_reroute_nodes); + if (port_types_are_compatible) { + // Set the port type of all reroute nodes. + for (const int &E : visited_reroute_nodes) { + Ref<VisualShaderNodeReroute> reroute_node = g->nodes[E].node; + reroute_node->_set_port_type(from_port_type); + } + } + } else if (from_node_reroute.is_valid() && !from_node_reroute->is_input_port_connected(0)) { + from_node_reroute->_set_port_type(to_port_type); + port_types_are_compatible = true; + } - ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform."); + ERR_FAIL_COND_V_MSG(!port_types_are_compatible, ERR_INVALID_PARAMETER, "Incompatible port types."); for (const Connection &E : g->connections) { if (E.from_node == p_from_node && E.from_port == p_from_port && E.to_node == p_to_node && E.to_port == p_to_port) { @@ -1904,12 +1986,18 @@ Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringB if (in_type == VisualShaderNode::PORT_TYPE_SAMPLER && out_type == VisualShaderNode::PORT_TYPE_SAMPLER) { VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr()); + // FIXME: This needs to be refactored at some point. if (ptr->has_method("get_input_real_name")) { inputs[i] = ptr->call("get_input_real_name"); } else if (ptr->has_method("get_parameter_name")) { inputs[i] = ptr->call("get_parameter_name"); } else { - inputs[i] = ""; + Ref<VisualShaderNodeReroute> reroute = graph[type].nodes[from_node].node; + if (reroute.is_valid()) { + inputs[i] = get_reroute_parameter_name(type, from_node); + } else { + inputs[i] = ""; + } } } else if (in_type == out_type) { inputs[i] = src_var; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index d32e2465b9..18cdc8342b 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -163,6 +163,8 @@ private: void _input_type_changed(Type p_type, int p_id); bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const; + bool _check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes = nullptr) const; + protected: virtual void _update_shader() const override; static void _bind_methods(); @@ -229,6 +231,8 @@ public: // internal methods void attach_node_to_frame(Type p_type, int p_node, int p_frame); void detach_node_from_frame(Type p_type, int p_node); + String get_reroute_parameter_name(Type p_type, int p_reroute_node) const; + void rebuild(); void get_node_connections(Type p_type, List<Connection> *r_connections) const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index ccd730eef2..d5394c8af5 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -8150,3 +8150,82 @@ VisualShaderNodeRotationByAxis::VisualShaderNodeRotationByAxis() { simple_decl = false; } + +String VisualShaderNodeReroute::get_caption() const { + return "Reroute"; +} + +int VisualShaderNodeReroute::get_input_port_count() const { + return 1; +} + +VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_input_port_type(int p_port) const { + return input_port_type; +} + +String VisualShaderNodeReroute::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeReroute::get_output_port_count() const { + return 1; +} + +VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_output_port_type(int p_port) const { + return input_port_type; +} + +String VisualShaderNodeReroute::get_output_port_name(int p_port) const { + return String(); +} + +String VisualShaderNodeReroute::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + for (int i = 0; i < get_output_port_count(); i++) { + if (input_port_type == PORT_TYPE_SAMPLER) { + continue; + } + + String input = p_input_vars[0]; + if (input.is_empty()) { + code += vformat(" %s;\n", p_output_vars[i]); + continue; + } + code += vformat(" %s = %s;\n", p_output_vars[i], input); + } + return code; +} + +void VisualShaderNodeReroute::_set_port_type(PortType p_type) { + input_port_type = p_type; + switch (p_type) { + case PORT_TYPE_SCALAR: + set_input_port_default_value(0, 0.0); + break; + case PORT_TYPE_VECTOR_2D: + set_input_port_default_value(0, Vector2()); + break; + case PORT_TYPE_VECTOR_3D: + set_input_port_default_value(0, Vector3()); + break; + case PORT_TYPE_VECTOR_4D: + set_input_port_default_value(0, Vector4()); + break; + case PORT_TYPE_TRANSFORM: + set_input_port_default_value(0, Transform3D()); + break; + default: + break; + } +} + +void VisualShaderNodeReroute::_bind_methods() { + ClassDB::bind_method(D_METHOD("_set_port_type", "port_type"), &VisualShaderNodeReroute::_set_port_type); + ClassDB::bind_method(D_METHOD("get_port_type"), &VisualShaderNodeReroute::get_port_type); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "port_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_port_type", "get_port_type"); +} + +VisualShaderNodeReroute::VisualShaderNodeReroute() { + set_input_port_default_value(0, 0.0); +} diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 0bd0c631b8..a23ae72def 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -3092,4 +3092,35 @@ public: VisualShaderNodeRotationByAxis(); }; +class VisualShaderNodeReroute : public VisualShaderNode { + GDCLASS(VisualShaderNodeReroute, VisualShaderNode); + + PortType input_port_type = PORT_TYPE_SCALAR; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + virtual bool has_output_port_preview(int p_port) const override { return false; } + virtual bool is_output_port_expandable(int p_port) const override { return false; } + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + virtual Category get_category() const override { return CATEGORY_SPECIAL; } + + void _set_port_type(PortType p_type); + PortType get_port_type() const { return input_port_type; } + + VisualShaderNodeReroute(); +}; + #endif // VISUAL_SHADER_NODES_H diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 5610b2f642..d40cb9ab6c 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -196,7 +196,7 @@ SceneStringNames::SceneStringNames() { // Audio bus name. Master = StaticCString::create("Master"); - _default = StaticCString::create("default"); + default_ = StaticCString::create("default"); _window_group = StaticCString::create("_window_group"); _window_input = StaticCString::create("_window_input"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 60254e3006..0e3a2a403e 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -198,7 +198,7 @@ public: NodePath path_pp; - StringName _default; + StringName default_; // "default", conflict with C++ keyword. StringName node_configuration_warning_changed; @@ -224,4 +224,6 @@ public: #endif }; +#define SceneStringName(m_name) SceneStringNames::get_singleton()->m_name + #endif // SCENE_STRING_NAMES_H diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 820e0bbeb6..d37836ed96 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -762,7 +762,7 @@ void AudioServer::set_bus_count(int p_count) { buses[i]->bypass = false; buses[i]->volume_db = 0; if (i > 0) { - buses[i]->send = SceneStringNames::get_singleton()->Master; + buses[i]->send = SceneStringName(Master); } bus_map[attempt] = buses[i]; @@ -1600,7 +1600,7 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) { for (int i = 0; i < p_bus_layout->buses.size(); i++) { Bus *bus = memnew(Bus); if (i == 0) { - bus->name = SceneStringNames::get_singleton()->Master; + bus->name = SceneStringName(Master); } else { bus->name = p_bus_layout->buses[i].name; bus->send = p_bus_layout->buses[i].send; @@ -1923,5 +1923,5 @@ void AudioBusLayout::_get_property_list(List<PropertyInfo> *p_list) const { AudioBusLayout::AudioBusLayout() { buses.resize(1); - buses.write[0].name = SceneStringNames::get_singleton()->Master; + buses.write[0].name = SceneStringName(Master); } diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h index 7a44645b1e..38baa6a4fa 100644 --- a/servers/display_server_headless.h +++ b/servers/display_server_headless.h @@ -57,6 +57,9 @@ public: bool has_feature(Feature p_feature) const override { return false; } String get_name() const override { return "headless"; } + // Stub implementations to prevent warnings from being printed for methods + // that don't affect the project's behavior in headless mode. + int get_screen_count() const override { return 0; } int get_primary_screen() const override { return 0; }; Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Point2i(); } @@ -66,6 +69,8 @@ public: float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return 1; } float screen_get_max_scale() const override { return 1; } float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return SCREEN_REFRESH_RATE_FALLBACK; } + void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW) override {} + void screen_set_keep_on(bool p_enable) override {} Vector<DisplayServer::WindowID> get_window_list() const override { return Vector<DisplayServer::WindowID>(); } @@ -130,10 +135,47 @@ public: void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID) override {} void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID) override {} + int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override { return 0; } + void process_events() override {} + void set_native_icon(const String &p_filename) override {} void set_icon(const Ref<Image> &p_icon) override {} + void help_set_search_callbacks(const Callable &p_search_callback = Callable(), const Callable &p_action_callback = Callable()) override {} + + bool tts_is_speaking() const override { return false; } + bool tts_is_paused() const override { return false; } + TypedArray<Dictionary> tts_get_voices() const override { return TypedArray<Dictionary>(); } + void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.0f, float p_rate = 1.0f, int p_utterance_id = 0, bool p_interrupt = false) override {} + void tts_pause() override {} + void tts_resume() override {} + void tts_stop() override {} + + void mouse_set_mode(MouseMode p_mode) override {} + void clipboard_set(const String &p_text) override {} + void clipboard_set_primary(const String &p_text) override {} + + void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override {} + void virtual_keyboard_hide() override {} + + void cursor_set_shape(CursorShape p_shape) override {} + void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override {} + + Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) override { return ERR_UNAVAILABLE; } + Error dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) override { return ERR_UNAVAILABLE; } + Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) override { return ERR_UNAVAILABLE; } + Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) override { return ERR_UNAVAILABLE; } + + void release_rendering_thread() override {} + void swap_buffers() override {} + + IndicatorID create_status_indicator(const Ref<Texture2D> &p_icon, const String &p_tooltip, const Callable &p_callback) override { return INVALID_INDICATOR_ID; } + void status_indicator_set_icon(IndicatorID p_id, const Ref<Texture2D> &p_icon) override {} + void status_indicator_set_tooltip(IndicatorID p_id, const String &p_tooltip) override {} + void status_indicator_set_callback(IndicatorID p_id, const Callable &p_callback) override {} + void delete_status_indicator(IndicatorID p_id) override {} + DisplayServerHeadless() { native_menu = memnew(NativeMenu); } diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index e48c72cec7..42de831e7a 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -38,6 +38,12 @@ #include "rendering_server_globals.h" #include "servers/rendering/storage/texture_storage.h" +// Use the same antialiasing feather size as StyleBoxFlat's default +// (but doubled, as it's specified for both sides here). +// This value is empirically determined to provide good antialiasing quality +// while not making lines appear too soft. +const static float FEATHER_SIZE = 1.25f; + void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info) { RENDER_TIMESTAMP("Cull CanvasItem Tree"); @@ -638,11 +644,8 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, } if (p_antialiased) { - // Use the same antialiasing feather size as StyleBoxFlat's default - // (but doubled, as it's specified for both sides here). - // This value is empirically determined to provide good antialiasing quality - // while not making lines appear too soft. - float border_size = 1.25f; + float border_size = FEATHER_SIZE; + if (0.0f <= p_width && p_width < 1.0f) { border_size *= p_width; } @@ -651,7 +654,7 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, Vector2 border = dir * border_size; Vector2 border2 = dir2 * border_size; - Color transparent = Color(p_color.r, p_color.g, p_color.b, 0.0); + Color transparent = Color(p_color, 0.0); { Item::CommandPrimitive *left_border = canvas_item->alloc_command<Item::CommandPrimitive>(); @@ -903,11 +906,7 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point Color *colors_ptr = colors.ptrw(); if (p_antialiased) { - // Use the same antialiasing feather size as StyleBoxFlat's default - // (but doubled, as it's specified for both sides here). - // This value is empirically determined to provide good antialiasing quality - // while not making lines appear too soft. - float border_size = 1.25f; + float border_size = FEATHER_SIZE; if (p_width < 1.0f) { border_size *= p_width; } @@ -1094,12 +1093,15 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point pline->polygon.create(indices, points, colors); } -void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { +void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { ERR_FAIL_COND(p_points.is_empty() || p_points.size() % 2 != 0); ERR_FAIL_COND(p_colors.size() != 1 && p_colors.size() * 2 != p_points.size()); // TODO: `canvas_item_add_line`(`multiline`, `polyline`) share logic, should factor out. if (p_width < 0) { + if (p_antialiased) { + WARN_PRINT("Antialiasing is not supported for thin multilines drawn using line strips (`p_width < 0`)."); + } Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_NULL(canvas_item); @@ -1127,7 +1129,7 @@ void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Poin Vector2 from = p_points[i * 2 + 0]; Vector2 to = p_points[i * 2 + 1]; - canvas_item_add_line(p_item, from, to, color, p_width); + canvas_item_add_line(p_item, from, to, color, p_width, p_antialiased); } } else { //} else if (p_colors.size() << 1 == p_points.size()) { for (int i = 0; i < p_colors.size(); i++) { @@ -1135,13 +1137,13 @@ void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Poin Vector2 from = p_points[i * 2 + 0]; Vector2 to = p_points[i * 2 + 1]; - canvas_item_add_line(p_item, from, to, color, p_width); + canvas_item_add_line(p_item, from, to, color, p_width, p_antialiased); } } } } -void RendererCanvasCull::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) { +void RendererCanvasCull::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color, bool p_antialiased) { Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_NULL(canvas_item); @@ -1149,45 +1151,251 @@ void RendererCanvasCull::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, c ERR_FAIL_NULL(rect); rect->modulate = p_color; rect->rect = p_rect; + + // Add feathers. + if (p_antialiased) { + float border_size = FEATHER_SIZE; + + const real_t size = MIN(p_rect.size.width, p_rect.size.height); + if (0.0f <= size && size < 1.0f) { + border_size *= size; + } + + const Vector2 vec_down = Vector2(0.0f, p_rect.size.height); + const Vector2 vec_right = Vector2(p_rect.size.width, 0.0f); + + const Vector2 begin_left = p_rect.position; + const Vector2 begin_right = p_rect.position + vec_down; + const Vector2 end_left = p_rect.position + vec_right; + const Vector2 end_right = p_rect.position + p_rect.size; + + const Vector2 dir = Vector2(0.0f, -1.0f); + const Vector2 dir2 = Vector2(-1.0f, 0.0f); + const Vector2 border = dir * border_size; + const Vector2 border2 = dir2 * border_size; + + Color transparent = Color(p_color, 0.0); + + { + Item::CommandPrimitive *left_border = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(left_border); + + left_border->points[0] = begin_left; + left_border->points[1] = begin_left + border; + left_border->points[2] = end_left + border; + left_border->points[3] = end_left; + + left_border->colors[0] = p_color; + left_border->colors[1] = transparent; + left_border->colors[2] = transparent; + left_border->colors[3] = p_color; + + left_border->point_count = 4; + } + { + Item::CommandPrimitive *right_border = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(right_border); + + right_border->points[0] = begin_right; + right_border->points[1] = begin_right - border; + right_border->points[2] = end_right - border; + right_border->points[3] = end_right; + + right_border->colors[0] = p_color; + right_border->colors[1] = transparent; + right_border->colors[2] = transparent; + right_border->colors[3] = p_color; + + right_border->point_count = 4; + } + { + Item::CommandPrimitive *top_border = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(top_border); + + top_border->points[0] = begin_left; + top_border->points[1] = begin_left + border2; + top_border->points[2] = begin_right + border2; + top_border->points[3] = begin_right; + + top_border->colors[0] = p_color; + top_border->colors[1] = transparent; + top_border->colors[2] = transparent; + top_border->colors[3] = p_color; + + top_border->point_count = 4; + } + { + Item::CommandPrimitive *bottom_border = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(bottom_border); + + bottom_border->points[0] = end_left; + bottom_border->points[1] = end_left - border2; + bottom_border->points[2] = end_right - border2; + bottom_border->points[3] = end_right; + + bottom_border->colors[0] = p_color; + bottom_border->colors[1] = transparent; + bottom_border->colors[2] = transparent; + bottom_border->colors[3] = p_color; + + bottom_border->point_count = 4; + } + { + Item::CommandPrimitive *top_left_corner = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(top_left_corner); + + top_left_corner->points[0] = begin_left; + top_left_corner->points[1] = begin_left + border2; + top_left_corner->points[2] = begin_left + border + border2; + top_left_corner->points[3] = begin_left + border; + + top_left_corner->colors[0] = p_color; + top_left_corner->colors[1] = transparent; + top_left_corner->colors[2] = transparent; + top_left_corner->colors[3] = transparent; + + top_left_corner->point_count = 4; + } + { + Item::CommandPrimitive *top_right_corner = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(top_right_corner); + + top_right_corner->points[0] = begin_right; + top_right_corner->points[1] = begin_right + border2; + top_right_corner->points[2] = begin_right - border + border2; + top_right_corner->points[3] = begin_right - border; + + top_right_corner->colors[0] = p_color; + top_right_corner->colors[1] = transparent; + top_right_corner->colors[2] = transparent; + top_right_corner->colors[3] = transparent; + + top_right_corner->point_count = 4; + } + { + Item::CommandPrimitive *bottom_left_corner = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(bottom_left_corner); + + bottom_left_corner->points[0] = end_left; + bottom_left_corner->points[1] = end_left - border2; + bottom_left_corner->points[2] = end_left + border - border2; + bottom_left_corner->points[3] = end_left + border; + + bottom_left_corner->colors[0] = p_color; + bottom_left_corner->colors[1] = transparent; + bottom_left_corner->colors[2] = transparent; + bottom_left_corner->colors[3] = transparent; + + bottom_left_corner->point_count = 4; + } + { + Item::CommandPrimitive *bottom_right_corner = canvas_item->alloc_command<Item::CommandPrimitive>(); + ERR_FAIL_NULL(bottom_right_corner); + + bottom_right_corner->points[0] = end_right; + bottom_right_corner->points[1] = end_right - border2; + bottom_right_corner->points[2] = end_right - border - border2; + bottom_right_corner->points[3] = end_right - border; + + bottom_right_corner->colors[0] = p_color; + bottom_right_corner->colors[1] = transparent; + bottom_right_corner->colors[2] = transparent; + bottom_right_corner->colors[3] = transparent; + + bottom_right_corner->point_count = 4; + } + } } -void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) { +void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color, bool p_antialiased) { Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_NULL(canvas_item); - Item::CommandPolygon *circle = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_NULL(circle); + static const int circle_segments = 64; - circle->primitive = RS::PRIMITIVE_TRIANGLES; + { + Item::CommandPolygon *circle = canvas_item->alloc_command<Item::CommandPolygon>(); + ERR_FAIL_NULL(circle); - Vector<int> indices; - Vector<Vector2> points; + circle->primitive = RS::PRIMITIVE_TRIANGLES; - static const int circle_points = 64; + Vector<int> indices; + Vector<Vector2> points; - points.resize(circle_points); - Vector2 *points_ptr = points.ptrw(); - const real_t circle_point_step = Math_TAU / circle_points; + points.resize(circle_segments + 2); + Vector2 *points_ptr = points.ptrw(); - for (int i = 0; i < circle_points; i++) { - float angle = i * circle_point_step; - points_ptr[i].x = Math::cos(angle) * p_radius; - points_ptr[i].y = Math::sin(angle) * p_radius; - points_ptr[i] += p_pos; - } + // Store circle center in the last point. + points_ptr[circle_segments + 1] = p_pos; - indices.resize((circle_points - 2) * 3); - int *indices_ptr = indices.ptrw(); + const real_t circle_point_step = Math_TAU / circle_segments; + + for (int i = 0; i < circle_segments + 1; i++) { + float angle = i * circle_point_step; + points_ptr[i].x = Math::cos(angle) * p_radius; + points_ptr[i].y = Math::sin(angle) * p_radius; + points_ptr[i] += p_pos; + } - for (int i = 0; i < circle_points - 2; i++) { - indices_ptr[i * 3 + 0] = 0; - indices_ptr[i * 3 + 1] = i + 1; - indices_ptr[i * 3 + 2] = i + 2; + indices.resize(circle_segments * 3); + int *indices_ptr = indices.ptrw(); + + for (int i = 0; i < circle_segments; i++) { + indices_ptr[i * 3 + 0] = circle_segments + 1; + indices_ptr[i * 3 + 1] = i; + indices_ptr[i * 3 + 2] = i + 1; + } + + Vector<Color> color; + color.push_back(p_color); + circle->polygon.create(indices, points, color); } - Vector<Color> color; - color.push_back(p_color); - circle->polygon.create(indices, points, color); + if (p_antialiased) { + float border_size = FEATHER_SIZE; + + const float diameter = p_radius * 2.0f; + if (0.0f <= diameter && diameter < 1.0f) { + border_size *= p_radius; + } + + Item::CommandPolygon *feather = canvas_item->alloc_command<Item::CommandPolygon>(); + ERR_FAIL_NULL(feather); + feather->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; + + Color transparent = Color(p_color, 0.0); + + Vector<int> indices; + Vector<Color> colors; + Vector<Vector2> points; + + points.resize(2 * circle_segments + 2); + colors.resize(2 * circle_segments + 2); + + const real_t circle_point_step = Math_TAU / circle_segments; + + Vector2 *points_ptr = points.ptrw(); + Color *colors_ptr = colors.ptrw(); + + for (int i = 0; i < circle_segments + 1; i++) { + const float angle = i * circle_point_step; + const float c = Math::cos(angle); + const float s = Math::sin(angle); + + points_ptr[i * 2].x = c * p_radius; + points_ptr[i * 2].y = s * p_radius; + points_ptr[i * 2] += p_pos; + + points_ptr[i * 2 + 1].x = c * (p_radius + border_size); + points_ptr[i * 2 + 1].y = s * (p_radius + border_size); + points_ptr[i * 2 + 1] += p_pos; + + colors_ptr[i * 2] = p_color; + colors_ptr[i * 2 + 1] = transparent; + } + + feather->polygon.create(indices, points, colors); + } } void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) { diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 961506ca28..9f8cbea2e9 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -233,9 +233,9 @@ public: void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = -1.0, bool p_antialiased = false); void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0, bool p_antialiased = false); - void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0); - void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color); - void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color); + void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0, bool p_antialiased = false); + void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color, bool p_antialiased); + void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color, bool p_antialiased); void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false); void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false); void canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, float p_px_range = 1.0, float p_scale = 1.0); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 8175010caf..55c2908f59 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -3578,11 +3578,11 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RID RenderForwardClustered::_render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) { Ref<RenderBufferDataForwardClustered> rb_data = p_render_buffers->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED); - return p_render_buffers->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED ? rb_data->get_normal_roughness() : rb_data->get_normal_roughness_msaa(); + return rb_data->get_normal_roughness(); } RID RenderForwardClustered::_render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) { - return p_render_buffers->get_velocity_buffer(p_render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED); + return p_render_buffers->get_velocity_buffer(false); } void RenderForwardClustered::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) { diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index d0b6bc492d..164ec3cc09 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -885,9 +885,9 @@ public: FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool) FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) - FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float) - FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) - FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) + FUNC5(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) + FUNC4(canvas_item_add_rect, RID, const Rect2 &, const Color &, bool) + FUNC5(canvas_item_add_circle, RID, const Point2 &, float, const Color &, bool) FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool) FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool) FUNC8(canvas_item_add_msdf_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, int, float, float) diff --git a/servers/rendering_server.compat.inc b/servers/rendering_server.compat.inc index 0cef3c906c..99f2de9a9a 100644 --- a/servers/rendering_server.compat.inc +++ b/servers/rendering_server.compat.inc @@ -34,8 +34,23 @@ void RenderingServer::_environment_set_fog_bind_compat_84792(RID p_env, bool p_e environment_set_fog(p_env, p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_aerial_perspective, p_sky_affect, RS::EnvironmentFogMode::ENV_FOG_MODE_EXPONENTIAL); } +void RenderingServer::_canvas_item_add_multiline_bind_compat_84523(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { + canvas_item_add_multiline(p_item, p_points, p_colors, p_width, false); +} + +void RenderingServer::_canvas_item_add_rect_bind_compat_84523(RID p_item, const Rect2 &p_rect, const Color &p_color) { + canvas_item_add_rect(p_item, p_rect, p_color, false); +} + +void RenderingServer::_canvas_item_add_circle_bind_compat_84523(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) { + canvas_item_add_circle(p_item, p_pos, p_radius, p_color, false); +} + void RenderingServer::_bind_compatibility_methods() { ClassDB::bind_compatibility_method(D_METHOD("environment_set_fog", "env", "enable", "light_color", "light_energy", "sun_scatter", "density", "height", "height_density", "aerial_perspective", "sky_affect"), &RenderingServer::_environment_set_fog_bind_compat_84792); + ClassDB::bind_compatibility_method(D_METHOD("canvas_item_add_multiline", "item", "points", "colors", "width"), &RenderingServer::_canvas_item_add_multiline_bind_compat_84523, DEFVAL(-1.0)); + ClassDB::bind_compatibility_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &RenderingServer::_canvas_item_add_rect_bind_compat_84523); + ClassDB::bind_compatibility_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &RenderingServer::_canvas_item_add_circle_bind_compat_84523); } #endif diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index ab82e42f43..5cfd8d3cd2 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -3229,9 +3229,9 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width", "antialiased"), &RenderingServer::canvas_item_add_line, DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &RenderingServer::canvas_item_add_polyline, DEFVAL(-1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("canvas_item_add_multiline", "item", "points", "colors", "width"), &RenderingServer::canvas_item_add_multiline, DEFVAL(-1.0)); - ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &RenderingServer::canvas_item_add_rect); - ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &RenderingServer::canvas_item_add_circle); + ClassDB::bind_method(D_METHOD("canvas_item_add_multiline", "item", "points", "colors", "width", "antialiased"), &RenderingServer::canvas_item_add_multiline, DEFVAL(-1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color", "antialiased"), &RenderingServer::canvas_item_add_rect, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color", "antialiased"), &RenderingServer::canvas_item_add_circle, DEFVAL(false)); ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect", "item", "rect", "texture", "tile", "modulate", "transpose"), &RenderingServer::canvas_item_add_texture_rect, DEFVAL(false), DEFVAL(Color(1, 1, 1)), DEFVAL(false)); ClassDB::bind_method(D_METHOD("canvas_item_add_msdf_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "outline_size", "px_range", "scale"), &RenderingServer::canvas_item_add_msdf_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(1.0), DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("canvas_item_add_lcd_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate"), &RenderingServer::canvas_item_add_lcd_texture_rect_region); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 5bc028dfdd..e15dba4353 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -99,6 +99,10 @@ protected: #ifndef DISABLE_DEPRECATED void _environment_set_fog_bind_compat_84792(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect); + void _canvas_item_add_multiline_bind_compat_84523(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0); + void _canvas_item_add_rect_bind_compat_84523(RID p_item, const Rect2 &p_rect, const Color &p_color); + void _canvas_item_add_circle_bind_compat_84523(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color); + static void _bind_compatibility_methods(); #endif @@ -1465,9 +1469,9 @@ public: virtual void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = -1.0, bool p_antialiased = false) = 0; virtual void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0, bool p_antialiased = false) = 0; - virtual void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0) = 0; - virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0; - virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0; + virtual void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = -1.0, bool p_antialiased = false) = 0; + virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color, bool p_antialiased = false) = 0; + virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color, bool p_antialiased = false) = 0; virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) = 0; virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false) = 0; virtual void canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, float p_px_range = 1.0, float p_scale = 1.0) = 0; diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index d714d71416..2a629642d4 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -251,7 +251,7 @@ TEST_CASE("[Object] Script property setter") { Variant script; bool valid = false; - object.set(CoreStringNames::get_singleton()->_script, script, &valid); + object.set(CoreStringName(script), script, &valid); CHECK(valid); CHECK_MESSAGE( object.get_script() == script, @@ -264,7 +264,7 @@ TEST_CASE("[Object] Script property getter") { object.set_script(script); bool valid = false; - const Variant &actual_value = object.get(CoreStringNames::get_singleton()->_script, &valid); + const Variant &actual_value = object.get(CoreStringName(script), &valid); CHECK(valid); CHECK_MESSAGE( actual_value == script, |