diff options
441 files changed, 8333 insertions, 5820 deletions
diff --git a/.editorconfig b/.editorconfig index 7743622e78..92ee947a82 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,7 +13,7 @@ trim_trailing_whitespace = true indent_style = space indent_size = 4 -[{*.{py,cs},SConstruct,SCsub}] +[{*.py,SConstruct,SCsub}] indent_style = space indent_size = 4 @@ -21,7 +21,3 @@ indent_size = 4 [*.{yml,yaml}] indent_style = space indent_size = 2 - -[*.{csproj,props,targets,nuspec}] -indent_style = space -indent_size = 2 diff --git a/core/config/engine.cpp b/core/config/engine.cpp index ad31966a65..0b5b5627af 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -214,8 +214,8 @@ bool Engine::has_singleton(const String &p_name) const { } void Engine::get_singletons(List<Singleton> *p_singletons) { - for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) { - p_singletons->push_back(E->get()); + for (const Singleton &E : singletons) { + p_singletons->push_back(E); } } diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 84860b648d..c5e6c6d685 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -700,9 +700,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str int count = 0; for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { - for (List<String>::Element *F = E->get().front(); F; F = F->next()) { - count++; - } + count += E->get().size(); } if (p_custom_features != String()) { @@ -734,8 +732,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str } for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { - for (List<String>::Element *F = E->get().front(); F; F = F->next()) { - String key = F->get(); + for (String &key : E->get()) { if (E->key() != "") { key = E->key() + "/" + key; } @@ -803,8 +800,8 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin if (E->key() != "") { file->store_string("[" + E->key() + "]\n\n"); } - for (List<String>::Element *F = E->get().front(); F; F = F->next()) { - String key = F->get(); + for (const String &F : E->get()) { + String key = F; if (E->key() != "") { key = E->key() + "/" + key; } @@ -817,7 +814,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin String vstr; VariantWriter::write_to_string(value, vstr); - file->store_string(F->get().property_name_encode() + "=" + vstr + "\n"); + file->store_string(F.property_name_encode() + "=" + vstr + "\n"); } } @@ -931,11 +928,11 @@ Vector<String> ProjectSettings::get_optimizer_presets() const { ProjectSettings::get_singleton()->get_property_list(&pi); Vector<String> names; - for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { - if (!E->get().name.begins_with("optimizer_presets/")) { + for (const PropertyInfo &E : pi) { + if (!E.name.begins_with("optimizer_presets/")) { continue; } - names.push_back(E->get().name.get_slicec('/', 1)); + names.push_back(E.name.get_slicec('/', 1)); } names.sort(); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 9a58528bd7..12fca4215a 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -75,8 +75,8 @@ Vector<String> _ResourceLoader::get_recognized_extensions_for_type(const String List<String> exts; ResourceLoader::get_recognized_extensions_for_type(p_type, &exts); Vector<String> ret; - for (List<String>::Element *E = exts.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const String &E : exts) { + ret.push_back(E); } return ret; @@ -91,8 +91,8 @@ PackedStringArray _ResourceLoader::get_dependencies(const String &p_path) { ResourceLoader::get_dependencies(p_path, &deps); PackedStringArray ret; - for (List<String>::Element *E = deps.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const String &E : deps) { + ret.push_back(E); } return ret; @@ -141,8 +141,8 @@ Vector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource) List<String> exts; ResourceSaver::get_recognized_extensions(p_resource, &exts); Vector<String> ret; - for (List<String>::Element *E = exts.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const String &E : exts) { + ret.push_back(E); } return ret; } @@ -196,6 +196,10 @@ int _OS::get_low_processor_usage_mode_sleep_usec() const { return OS::get_singleton()->get_low_processor_usage_mode_sleep_usec(); } +void _OS::alert(const String &p_alert, const String &p_title) { + OS::get_singleton()->alert(p_alert, p_title); +} + String _OS::get_executable_path() const { return OS::get_singleton()->get_executable_path(); } @@ -264,8 +268,8 @@ String _OS::get_name() const { Vector<String> _OS::get_cmdline_args() { List<String> cmdline = OS::get_singleton()->get_cmdline_args(); Vector<String> cmdlinev; - for (List<String>::Element *E = cmdline.front(); E; E = E->next()) { - cmdlinev.push_back(E->get()); + for (const String &E : cmdline) { + cmdlinev.push_back(E); } return cmdlinev; @@ -351,20 +355,20 @@ void _OS::print_all_textures_by_size() { List<Ref<Resource>> rsrc; ResourceCache::get_cached_resources(&rsrc); - for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) { - if (!E->get()->is_class("ImageTexture")) { + for (Ref<Resource> E : rsrc) { + if (!E->is_class("ImageTexture")) { continue; } - Size2 size = E->get()->call("get_size"); - int fmt = E->get()->call("get_format"); + Size2 size = E->call("get_size"); + int fmt = E->call("get_format"); _OSCoreBindImg img; img.size = size; img.fmt = fmt; - img.path = E->get()->get_path(); + img.path = E->get_path(); img.vram = Image::get_image_data_size(img.size.width, img.size.height, Image::Format(img.fmt)); - img.id = E->get()->get_instance_id(); + img.id = E->get_instance_id(); total += img.vram; imgs.push_back(img); } @@ -372,8 +376,8 @@ void _OS::print_all_textures_by_size() { imgs.sort(); - for (List<_OSCoreBindImg>::Element *E = imgs.front(); E; E = E->next()) { - total -= E->get().vram; + for (_OSCoreBindImg &E : imgs) { + total -= E.vram; } } @@ -383,9 +387,7 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) { List<Ref<Resource>> resources; ResourceCache::get_cached_resources(&resources); - for (List<Ref<Resource>>::Element *E = resources.front(); E; E = E->next()) { - Ref<Resource> r = E->get(); - + for (Ref<Resource> r : resources) { bool found = false; for (int i = 0; i < p_types.size(); i++) { @@ -487,6 +489,8 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs); ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs); + ClassDB::bind_method(D_METHOD("alert", "text", "title"), &_OS::alert, DEFVAL("Alert!")); + ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &_OS::set_low_processor_usage_mode); ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &_OS::is_in_low_processor_usage_mode); @@ -1818,8 +1822,8 @@ PackedStringArray _ClassDB::get_class_list() const { PackedStringArray ret; ret.resize(classes.size()); int idx = 0; - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (const StringName &E : classes) { + ret.set(idx++, E); } return ret; @@ -1832,8 +1836,8 @@ PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) PackedStringArray ret; ret.resize(classes.size()); int idx = 0; - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (const StringName &E : classes) { + ret.set(idx++, E); } return ret; @@ -1887,8 +1891,8 @@ Array _ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const ClassDB::get_signal_list(p_class, &signals, p_no_inheritance); Array ret; - for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - ret.push_back(E->get().operator Dictionary()); + for (const MethodInfo &E : signals) { + ret.push_back(E.operator Dictionary()); } return ret; @@ -1898,8 +1902,8 @@ Array _ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) con List<PropertyInfo> plist; ClassDB::get_property_list(p_class, &plist, p_no_inheritance); Array ret; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - ret.push_back(E->get().operator Dictionary()); + for (const PropertyInfo &E : plist) { + ret.push_back(E.operator Dictionary()); } return ret; @@ -1931,12 +1935,12 @@ Array _ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const ClassDB::get_method_list(p_class, &methods, p_no_inheritance); Array ret; - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { + for (const MethodInfo &E : methods) { #ifdef DEBUG_METHODS_ENABLED - ret.push_back(E->get().operator Dictionary()); + ret.push_back(E.operator Dictionary()); #else Dictionary dict; - dict["name"] = E->get().name; + dict["name"] = E.name; ret.push_back(dict); #endif } @@ -1951,8 +1955,8 @@ PackedStringArray _ClassDB::get_integer_constant_list(const StringName &p_class, PackedStringArray ret; ret.resize(constants.size()); int idx = 0; - for (List<String>::Element *E = constants.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (const String &E : constants) { + ret.set(idx++, E); } return ret; diff --git a/core/core_bind.h b/core/core_bind.h index 673dbe32c4..1574c36d3c 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -58,9 +58,9 @@ public: }; enum CacheMode { - CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource. - CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available - CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk + CACHE_MODE_IGNORE, // Resource and subresources do not use path cache, no path is set into resource. + CACHE_MODE_REUSE, // Resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available. + CACHE_MODE_REPLACE, // Resource and subresource use path cache, but replace existing loaded resources when available with information from disk. }; static _ResourceLoader *get_singleton() { return singleton; } @@ -162,6 +162,8 @@ public: void set_low_processor_usage_mode_sleep_usec(int p_usec); int get_low_processor_usage_mode_sleep_usec() const; + void alert(const String &p_alert, const String &p_title = "ALERT!"); + String get_executable_path() const; int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false); int create_process(const String &p_path, const Vector<String> &p_arguments); diff --git a/core/debugger/debugger_marshalls.cpp b/core/debugger/debugger_marshalls.cpp index 26f82c2658..2353a6ebf8 100644 --- a/core/debugger/debugger_marshalls.cpp +++ b/core/debugger/debugger_marshalls.cpp @@ -40,11 +40,11 @@ Array DebuggerMarshalls::ResourceUsage::serialize() { Array arr; arr.push_back(infos.size() * 4); - for (List<ResourceInfo>::Element *E = infos.front(); E; E = E->next()) { - arr.push_back(E->get().path); - arr.push_back(E->get().format); - arr.push_back(E->get().type); - arr.push_back(E->get().vram); + for (const ResourceInfo &E : infos) { + arr.push_back(E.path); + arr.push_back(E.format); + arr.push_back(E.type); + arr.push_back(E.vram); } return arr; } diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index ab368471e4..24833711d5 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -320,13 +320,13 @@ void LocalDebugger::print_variables(const List<String> &names, const List<Varian String value; Vector<String> value_lines; const List<Variant>::Element *V = values.front(); - for (const List<String>::Element *E = names.front(); E; E = E->next()) { + for (const String &E : names) { value = String(V->get()); if (variable_prefix.is_empty()) { - print_line(E->get() + ": " + String(V->get())); + print_line(E + ": " + String(V->get())); } else { - print_line(E->get() + ":"); + print_line(E + ":"); value_lines = value.split("\n"); for (int i = 0; i < value_lines.size(); ++i) { print_line(variable_prefix + value_lines[i]); diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index bdbb7766fa..0add12ff3d 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -427,16 +427,16 @@ void RemoteDebugger::_send_resource_usage() { List<RS::TextureInfo> tinfo; RS::get_singleton()->texture_debug_usage(&tinfo); - for (List<RS::TextureInfo>::Element *E = tinfo.front(); E; E = E->next()) { + for (const RS::TextureInfo &E : tinfo) { DebuggerMarshalls::ResourceInfo info; - info.path = E->get().path; - info.vram = E->get().bytes; - info.id = E->get().texture; + info.path = E.path; + info.vram = E.bytes; + info.id = E.texture; info.type = "Texture"; - if (E->get().depth == 0) { - info.format = itos(E->get().width) + "x" + itos(E->get().height) + " " + Image::get_format_name(E->get().format); + if (E.depth == 0) { + info.format = itos(E.width) + "x" + itos(E.height) + " " + Image::get_format_name(E.format); } else { - info.format = itos(E->get().width) + "x" + itos(E->get().height) + "x" + itos(E->get().depth) + " " + Image::get_format_name(E->get().format); + info.format = itos(E.width) + "x" + itos(E.height) + "x" + itos(E.depth) + " " + Image::get_format_name(E.format); } usage.infos.push_back(info); } diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 3c132a619d..660e215478 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -94,8 +94,8 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::NODE_PATH, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, { Variant::RID, sizeof(uint64_t), sizeof(uint64_t), sizeof(uint64_t), sizeof(uint64_t) }, { Variant::OBJECT, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, - { Variant::CALLABLE, sizeof(Callable), sizeof(Callable), sizeof(Callable), sizeof(Callable) }, //harcoded align - { Variant::SIGNAL, sizeof(Signal), sizeof(Signal), sizeof(Signal), sizeof(Signal) }, //harcoded align + { Variant::CALLABLE, sizeof(Callable), sizeof(Callable), sizeof(Callable), sizeof(Callable) }, // Hardcoded align. + { Variant::SIGNAL, sizeof(Signal), sizeof(Signal), sizeof(Signal), sizeof(Signal) }, // Hardcoded align. { Variant::DICTIONARY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, { Variant::ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, { Variant::PACKED_BYTE_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, @@ -146,7 +146,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { } { - //member offsets sizes + // Member offsets sizes. struct { Variant::Type type; const char *member; @@ -180,7 +180,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::QUATERNION, "w", 3 * sizeof(float), 3 * sizeof(float), 3 * sizeof(double), 3 * sizeof(double) }, { Variant::AABB, "position", 0, 0, 0, 0 }, { Variant::AABB, "size", vec3_elems * sizeof(float), vec3_elems * sizeof(float), vec3_elems * sizeof(double), vec3_elems * sizeof(double) }, - //rememer that basis vectors are flipped! + // Remember that basis vectors are flipped! { Variant::BASIS, "x", 0, 0, 0, 0 }, { Variant::BASIS, "y", vec3_elems * sizeof(float), vec3_elems * sizeof(float), vec3_elems * sizeof(double), vec3_elems * sizeof(double) }, { Variant::BASIS, "z", vec3_elems * 2 * sizeof(float), vec3_elems * 2 * sizeof(float), vec3_elems * 2 * sizeof(double), vec3_elems * 2 * sizeof(double) }, @@ -251,7 +251,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { } { - // global enums and constants + // Global enums and constants. Array constants; Map<String, List<Pair<String, int>>> enum_list; @@ -276,10 +276,10 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Dictionary d1; d1["name"] = E->key(); Array values; - for (List<Pair<String, int>>::Element *F = E->get().front(); F; F = F->next()) { + for (const Pair<String, int> &F : E->get()) { Dictionary d2; - d2["name"] = F->get().first; - d2["value"] = F->get().second; + d2["name"] = F.first; + d2["value"] = F.second; values.push_back(d2); } d1["values"] = values; @@ -294,8 +294,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> utility_func_names; Variant::get_utility_function_list(&utility_func_names); - for (List<StringName>::Element *E = utility_func_names.front(); E; E = E->next()) { - StringName name = E->get(); + for (const StringName &name : utility_func_names) { Dictionary func; func["name"] = String(name); if (Variant::has_utility_function_return_value(name)) { @@ -363,8 +362,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> member_names; Variant::get_member_list(type, &member_names); - for (List<StringName>::Element *E = member_names.front(); E; E = E->next()) { - StringName member_name = E->get(); + for (const StringName &member_name : member_names) { Dictionary d2; d2["name"] = String(member_name); d2["type"] = Variant::get_type_name(Variant::get_member_type(type, member_name)); @@ -380,8 +378,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> constant_names; Variant::get_constants_for_type(type, &constant_names); - for (List<StringName>::Element *E = constant_names.front(); E; E = E->next()) { - StringName constant_name = E->get(); + for (const StringName &constant_name : constant_names) { Dictionary d2; d2["name"] = String(constant_name); Variant constant = Variant::get_constant_value(type, constant_name); @@ -420,8 +417,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> method_names; Variant::get_builtin_method_list(type, &method_names); - for (List<StringName>::Element *E = method_names.front(); E; E = E->next()) { - StringName method_name = E->get(); + for (const StringName &method_name : method_names) { Dictionary d2; d2["name"] = String(method_name); if (Variant::has_builtin_method_return_value(type, method_name)) { @@ -503,9 +499,8 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { class_list.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = class_list.front(); E; E = E->next()) { + for (const StringName &class_name : class_list) { Dictionary d; - StringName class_name = E->get(); d["name"] = String(class_name); d["is_refcounted"] = ClassDB::is_parent_class(class_name, "RefCounted"); d["is_instantiable"] = ClassDB::can_instantiate(class_name); @@ -525,15 +520,15 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array constants; List<String> constant_list; ClassDB::get_integer_constant_list(class_name, &constant_list, true); - for (List<String>::Element *F = constant_list.front(); F; F = F->next()) { - StringName enum_name = ClassDB::get_integer_constant_enum(class_name, F->get()); + for (const String &F : constant_list) { + StringName enum_name = ClassDB::get_integer_constant_enum(class_name, F); if (enum_name != StringName()) { continue; //enums will be handled on their own } Dictionary d2; - d2["name"] = String(F->get()); - d2["value"] = ClassDB::get_integer_constant(class_name, F->get()); + d2["name"] = String(F); + d2["value"] = ClassDB::get_integer_constant(class_name, F); constants.push_back(d2); } @@ -547,13 +542,13 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array enums; List<StringName> enum_list; ClassDB::get_enum_list(class_name, &enum_list, true); - for (List<StringName>::Element *F = enum_list.front(); F; F = F->next()) { + for (const StringName &F : enum_list) { Dictionary d2; - d2["name"] = String(F->get()); + d2["name"] = String(F); Array values; List<StringName> enum_constant_list; - ClassDB::get_enum_constants(class_name, F->get(), &enum_constant_list, true); + ClassDB::get_enum_constants(class_name, F, &enum_constant_list, true); for (List<StringName>::Element *G = enum_constant_list.front(); G; G = G->next()) { Dictionary d3; d3["name"] = String(G->get()); @@ -575,14 +570,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array methods; List<MethodInfo> method_list; ClassDB::get_method_list(class_name, &method_list, true); - for (List<MethodInfo>::Element *F = method_list.front(); F; F = F->next()) { - StringName method_name = F->get().name; - if (F->get().flags & METHOD_FLAG_VIRTUAL) { + for (const MethodInfo &F : method_list) { + StringName method_name = F.name; + if (F.flags & METHOD_FLAG_VIRTUAL) { //virtual method - const MethodInfo &mi = F->get(); + const MethodInfo &mi = F; Dictionary d2; d2["name"] = String(method_name); - d2["is_const"] = (F->get().flags & METHOD_FLAG_CONST) ? true : false; + d2["is_const"] = (F.flags & METHOD_FLAG_CONST) ? true : false; d2["is_vararg"] = false; d2["is_virtual"] = true; // virtual functions have no hash since no MethodBind is involved @@ -619,7 +614,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { methods.push_back(d2); - } else if (F->get().name.begins_with("_")) { + } else if (F.name.begins_with("_")) { //hidden method, ignore } else { @@ -692,19 +687,19 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array signals; List<MethodInfo> signal_list; ClassDB::get_signal_list(class_name, &signal_list, true); - for (List<MethodInfo>::Element *F = signal_list.front(); F; F = F->next()) { - StringName signal_name = F->get().name; + for (const MethodInfo &F : signal_list) { + StringName signal_name = F.name; Dictionary d2; d2["name"] = String(signal_name); Array arguments; - for (int i = 0; i < F->get().arguments.size(); i++) { + for (int i = 0; i < F.arguments.size(); i++) { Dictionary d3; - d3["name"] = F->get().arguments[i].name; - Variant::Type type = F->get().arguments[i].type; - if (F->get().arguments[i].class_name != StringName()) { - d3["type"] = String(F->get().arguments[i].class_name); + d3["name"] = F.arguments[i].name; + Variant::Type type = F.arguments[i].type; + if (F.arguments[i].class_name != StringName()) { + d3["type"] = String(F.arguments[i].class_name); } else if (type == Variant::NIL) { d3["type"] = "Variant"; } else { @@ -728,28 +723,28 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array properties; List<PropertyInfo> property_list; ClassDB::get_property_list(class_name, &property_list, true); - for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) { - if (F->get().usage & PROPERTY_USAGE_CATEGORY || F->get().usage & PROPERTY_USAGE_GROUP || F->get().usage & PROPERTY_USAGE_SUBGROUP) { + for (const PropertyInfo &F : property_list) { + if (F.usage & PROPERTY_USAGE_CATEGORY || F.usage & PROPERTY_USAGE_GROUP || F.usage & PROPERTY_USAGE_SUBGROUP) { continue; //not real properties } - if (F->get().name.begins_with("_")) { + if (F.name.begins_with("_")) { continue; //hidden property } - StringName property_name = F->get().name; + StringName property_name = F.name; Dictionary d2; d2["name"] = String(property_name); - if (F->get().class_name != StringName()) { - d2["type"] = String(F->get().class_name); - } else if (F->get().type == Variant::NIL && F->get().usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + if (F.class_name != StringName()) { + d2["type"] = String(F.class_name); + } else if (F.type == Variant::NIL && F.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { d2["type"] = "Variant"; } else { - d2["type"] = Variant::get_type_name(F->get().type); + d2["type"] = Variant::get_type_name(F.type); } - d2["setter"] = ClassDB::get_property_setter(class_name, F->get().name); - d2["getter"] = ClassDB::get_property_getter(class_name, F->get().name); - d2["index"] = ClassDB::get_property_index(class_name, F->get().name); + d2["setter"] = ClassDB::get_property_setter(class_name, F.name); + d2["getter"] = ClassDB::get_property_getter(class_name, F.name); + d2["index"] = ClassDB::get_property_index(class_name, F.name); properties.push_back(d2); } @@ -771,8 +766,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<Engine::Singleton> singleton_list; Engine::get_singleton()->get_singletons(&singleton_list); - for (List<Engine::Singleton>::Element *E = singleton_list.front(); E; E = E->next()) { - const Engine::Singleton &s = E->get(); + for (const Engine::Singleton &s : singleton_list) { Dictionary d; d["name"] = s.name; if (s.class_name != StringName()) { diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index 8f68b8d848..88fff342ee 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -281,8 +281,9 @@ static GDNativeBool gdnative_variant_has_key(const GDNativeVariantPtr p_self, co const Variant *self = (const Variant *)p_self; const Variant *key = (const Variant *)p_key; bool valid; - return self->has_key(*key, valid); + bool ret = self->has_key(*key, valid); *r_valid = valid; + return ret; } static void gdnative_variant_get_type_name(GDNativeVariantType p_type, GDNativeStringPtr r_ret) { diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp index 65718a7507..16bc28e0a2 100644 --- a/core/extension/native_extension.cpp +++ b/core/extension/native_extension.cpp @@ -351,8 +351,8 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or String library_path; - for (List<String>::Element *E = libraries.front(); E; E = E->next()) { - Vector<String> tags = E->get().split("."); + for (const String &E : libraries) { + Vector<String> tags = E.split("."); bool all_tags_met = true; for (int i = 0; i < tags.size(); i++) { String tag = tags[i].strip_edges(); @@ -363,7 +363,7 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or } if (all_tags_met) { - library_path = config->get_value("libraries", E->get()); + library_path = config->get_value("libraries", E); break; } } diff --git a/core/input/input.cpp b/core/input/input.cpp index f57985831a..c205726b0a 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -101,7 +101,7 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action", "exact_match"), &Input::is_action_just_pressed, DEFVAL(false)); ClassDB::bind_method(D_METHOD("is_action_just_released", "action", "exact_match"), &Input::is_action_just_released, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_raw_strength, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_axis", "negative_action", "positive_action"), &Input::get_axis); ClassDB::bind_method(D_METHOD("get_vector", "negative_x", "positive_x", "negative_y", "positive_y", "deadzone"), &Input::get_vector, DEFVAL(-1.0f)); ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false)); @@ -169,13 +169,12 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S String pf = p_function; if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released" || - pf == "get_action_strength" || pf == "get_axis" || pf == "get_vector")) { + pf == "get_action_strength" || pf == "get_action_raw_strength" || + pf == "get_axis" || pf == "get_vector")) { List<PropertyInfo> pinfo; ProjectSettings::get_singleton()->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (const PropertyInfo &pi : pinfo) { if (!pi.name.begins_with("input/")) { continue; } diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index b5f067d499..6714705bb5 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -65,11 +65,11 @@ String InputMap::_suggest_actions(const StringName &p_action) const { float closest_similarity = 0.0; // Find the most action with the most similar name. - for (List<StringName>::Element *E = actions.front(); E; E = E->next()) { - const float similarity = String(E->get()).similarity(p_action); + for (const StringName &action : actions) { + const float similarity = String(action).similarity(p_action); if (similarity > closest_similarity) { - closest_action = E->get(); + closest_action = action; closest_similarity = similarity; } } @@ -105,8 +105,8 @@ Array InputMap::_get_actions() { return ret; } - for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const StringName &E : actions) { + ret.push_back(E); } return ret; @@ -129,13 +129,11 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re ERR_FAIL_COND_V(!p_event.is_valid(), nullptr); for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { - const Ref<InputEvent> e = E->get(); - - int device = e->get_device(); + int device = E->get()->get_device(); if (device == ALL_DEVICES || device == p_event->get_device()) { - if (p_exact_match && e->is_match(p_event, true)) { + if (p_exact_match && E->get()->is_match(p_event, true)) { return E; - } else if (!p_exact_match && e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { + } else if (!p_exact_match && E->get()->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { return E; } } @@ -198,7 +196,7 @@ Array InputMap::_action_get_events(const StringName &p_action) { const List<Ref<InputEvent>> *al = action_get_events(p_action); if (al) { for (const List<Ref<InputEvent>>::Element *E = al->front(); E; E = E->next()) { - ret.push_back(E->get()); + ret.push_back(E); } } @@ -263,9 +261,7 @@ void InputMap::load_from_project_settings() { List<PropertyInfo> pinfo; ProjectSettings::get_singleton()->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (const PropertyInfo &pi : pinfo) { if (!pi.name.begins_with("input/")) { continue; } diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 10f68f3cef..aeaf25f321 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -40,8 +40,8 @@ PackedStringArray ConfigFile::_get_sections() const { PackedStringArray arr; arr.resize(s.size()); int idx = 0; - for (const List<String>::Element *E = s.front(); E; E = E->next()) { - arr.set(idx++, E->get()); + for (const String &E : s) { + arr.set(idx++, E); } return arr; @@ -53,8 +53,8 @@ PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const { PackedStringArray arr; arr.resize(s.size()); int idx = 0; - for (const List<String>::Element *E = s.front(); E; E = E->next()) { - arr.set(idx++, E->get()); + for (const String &E : s) { + arr.set(idx++, E); } return arr; diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index dfba00067f..8234adea06 100644 --- a/core/io/dir_access.cpp +++ b/core/io/dir_access.cpp @@ -93,8 +93,8 @@ static Error _erase_recursive(DirAccess *da) { da->list_dir_end(); - for (List<String>::Element *E = dirs.front(); E; E = E->next()) { - Error err = da->change_dir(E->get()); + for (const String &E : dirs) { + Error err = da->change_dir(E); if (err == OK) { err = _erase_recursive(da); if (err) { @@ -105,7 +105,7 @@ static Error _erase_recursive(DirAccess *da) { if (err) { return err; } - err = da->remove(da->get_current_dir().plus_file(E->get())); + err = da->remove(da->get_current_dir().plus_file(E)); if (err) { return err; } @@ -114,8 +114,8 @@ static Error _erase_recursive(DirAccess *da) { } } - for (List<String>::Element *E = files.front(); E; E = E->next()) { - Error err = da->remove(da->get_current_dir().plus_file(E->get())); + for (const String &E : files) { + Error err = da->remove(da->get_current_dir().plus_file(E)); if (err) { return err; } @@ -362,16 +362,15 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag list_dir_end(); - for (List<String>::Element *E = dirs.front(); E; E = E->next()) { - String rel_path = E->get(); + for (const String &rel_path : dirs) { String target_dir = p_to + rel_path; if (!p_target_da->dir_exists(target_dir)) { Error err = p_target_da->make_dir(target_dir); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot create directory '" + target_dir + "'."); } - Error err = change_dir(E->get()); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot change current directory to '" + E->get() + "'."); + Error err = change_dir(rel_path); + ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot change current directory to '" + rel_path + "'."); err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags, p_copy_links); if (err) { diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 8000dd4290..5c1352c1b6 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -93,8 +93,7 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() { List<String> rh; get_response_headers(&rh); Dictionary ret; - for (const List<String>::Element *E = rh.front(); E; E = E->next()) { - const String &s = E->get(); + for (const String &s : rh) { int sp = s.find(":"); if (sp == -1) { continue; @@ -113,8 +112,8 @@ PackedStringArray HTTPClient::_get_response_headers() { PackedStringArray ret; ret.resize(rh.size()); int idx = 0; - for (const List<String>::Element *E = rh.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (const String &E : rh) { + ret.set(idx++, E); } return ret; diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index b45e9d26b1..b9fc416f65 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -35,8 +35,8 @@ bool ImageFormatLoader::recognize(const String &p_extension) const { List<String> extensions; get_recognized_extensions(&extensions); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(p_extension) == 0) { + for (const String &E : extensions) { + if (E.nocasecmp_to(p_extension) == 0) { return true; } } diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 001b1c4757..cd1b6d1994 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -252,8 +252,8 @@ Array IP::_get_local_addresses() const { Array addresses; List<IPAddress> ip_addresses; get_local_addresses(&ip_addresses); - for (List<IPAddress>::Element *E = ip_addresses.front(); E; E = E->next()) { - addresses.push_back(E->get()); + for (const IPAddress &E : ip_addresses) { + addresses.push_back(E); } return addresses; @@ -271,8 +271,8 @@ Array IP::_get_local_interfaces() const { rc["index"] = c.index; Array ips; - for (const List<IPAddress>::Element *F = c.ip_addresses.front(); F; F = F->next()) { - ips.push_front(F->get()); + for (const IPAddress &F : c.ip_addresses) { + ips.push_front(F); } rc["addresses"] = ips; @@ -286,8 +286,8 @@ void IP::get_local_addresses(List<IPAddress> *r_addresses) const { Map<String, Interface_Info> interfaces; get_local_interfaces(&interfaces); for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) { - for (const List<IPAddress>::Element *F = E->get().ip_addresses.front(); F; F = F->next()) { - r_addresses->push_front(F->get()); + for (const IPAddress &F : E->get().ip_addresses) { + r_addresses->push_front(F); } } } diff --git a/core/io/json.cpp b/core/io/json.cpp index b3a2498212..5823afbdcd 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -121,14 +121,17 @@ String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_ keys.sort(); } - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - if (E != keys.front()) { + bool first_key = true; + for (const Variant &E : keys) { + if (first_key) { + first_key = false; + } else { s += ","; s += end_statement; } - s += _make_indent(p_indent, p_cur_indent + 1) + _stringify(String(E->get()), p_indent, p_cur_indent + 1, p_sort_keys, p_markers); + s += _make_indent(p_indent, p_cur_indent + 1) + _stringify(String(E), p_indent, p_cur_indent + 1, p_sort_keys, p_markers); s += colon; - s += _stringify(d[E->get()], p_indent, p_cur_indent + 1, p_sort_keys, p_markers); + s += _stringify(d[E], p_indent, p_cur_indent + 1, p_sort_keys, p_markers); } s += end_statement + _make_indent(p_indent, p_cur_indent) + "}"; diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index f342db2dad..4a1d3e5212 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -1358,8 +1358,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo obj->get_property_list(&props); int pc = 0; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } pc++; @@ -1372,15 +1372,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - _encode_string(E->get().name, buf, r_len); + _encode_string(E.name, buf, r_len); int len; - Error err = encode_variant(obj->get(E->get().name), buf, len, p_full_objects); + Error err = encode_variant(obj->get(E.name), buf, len, p_full_objects); if (err) { return err; } @@ -1418,7 +1418,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (const Variant &E : keys) { /* CharString utf8 = E->->utf8(); @@ -1433,13 +1433,13 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len++; //pad */ int len; - encode_variant(E->get(), buf, len, p_full_objects); + encode_variant(E, buf, len, p_full_objects); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { buf += len; } - Variant *v = d.getptr(E->get()); + Variant *v = d.getptr(E); ERR_FAIL_COND_V(!v, ERR_BUG); encode_variant(*v, buf, len, p_full_objects); ERR_FAIL_COND_V(len % 4, ERR_BUG); diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index e99c60613a..80610e12cb 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -555,12 +555,12 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC ofs += encode_cstring(path.get_data(), &packet.write[ofs]); - for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) { - network_peer->set_target_peer(E->get()); // To all of you. + for (int &E : peers_to_add) { + network_peer->set_target_peer(E); // To all of you. network_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); network_peer->put_packet(packet.ptr(), packet.size()); - psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed. + psc->confirmed_peers.insert(E, false); // Insert into confirmed, but as false since it was not confirmed. } } @@ -917,8 +917,8 @@ void MultiplayerAPI::_del_peer(int p_id) { // Some refactoring is needed to make this faster and do paths GC. List<NodePath> keys; path_send_cache.get_key_list(&keys); - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - PathSentCache *psc = path_send_cache.getptr(E->get()); + for (const NodePath &E : keys) { + PathSentCache *psc = path_send_cache.getptr(E); psc->confirmed_peers.erase(p_id); } emit_signal(SNAME("network_peer_disconnected"), p_id); diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp index cf6a0b6027..4a76f0191d 100644 --- a/core/io/packed_data_container.cpp +++ b/core/io/packed_data_container.cpp @@ -268,21 +268,21 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd d.get_key_list(&keys); List<DictKey> sortk; - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (const Variant &key : keys) { DictKey dk; - dk.hash = E->get().hash(); - dk.key = E->get(); + dk.hash = key.hash(); + dk.key = key; sortk.push_back(dk); } sortk.sort(); int idx = 0; - for (List<DictKey>::Element *E = sortk.front(); E; E = E->next()) { - encode_uint32(E->get().hash, &tmpdata.write[pos + 8 + idx * 12 + 0]); - uint32_t ofs = _pack(E->get().key, tmpdata, string_cache); + for (const DictKey &E : sortk) { + encode_uint32(E.hash, &tmpdata.write[pos + 8 + idx * 12 + 0]); + uint32_t ofs = _pack(E.key, tmpdata, string_cache); encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 4]); - ofs = _pack(d[E->get().key], tmpdata, string_cache); + ofs = _pack(d[E.key], tmpdata, string_cache); encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 8]); idx++; } diff --git a/core/io/resource.cpp b/core/io/resource.cpp index efa622d976..727611a573 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -33,6 +33,7 @@ #include "core/core_string_names.h" #include "core/io/file_access.h" #include "core/io/resource_loader.h" +#include "core/math/math_funcs.h" #include "core/object/script_language.h" #include "core/os/os.h" #include "scene/main/node.h" //only so casting works @@ -94,12 +95,43 @@ String Resource::get_path() const { return path_cache; } -void Resource::set_subindex(int p_sub_index) { - subindex = p_sub_index; +String Resource::generate_scene_unique_id() { + // Generate a unique enough hash, but still user-readable. + // If it's not unique it does not matter because the saver will try again. + OS::Date date = OS::get_singleton()->get_date(); + OS::Time time = OS::get_singleton()->get_time(); + uint32_t hash = hash_djb2_one_32(OS::get_singleton()->get_ticks_usec()); + hash = hash_djb2_one_32(date.year, hash); + hash = hash_djb2_one_32(date.month, hash); + hash = hash_djb2_one_32(date.day, hash); + hash = hash_djb2_one_32(time.hour, hash); + hash = hash_djb2_one_32(time.minute, hash); + hash = hash_djb2_one_32(time.second, hash); + hash = hash_djb2_one_32(Math::rand(), hash); + + static constexpr uint32_t characters = 5; + static constexpr uint32_t char_count = ('z' - 'a'); + static constexpr uint32_t base = char_count + ('9' - '0'); + String id; + for (uint32_t i = 0; i < characters; i++) { + uint32_t c = hash % base; + if (c < char_count) { + id += String::chr('a' + c); + } else { + id += String::chr('0' + (c - char_count)); + } + hash /= base; + } + + return id; +} + +void Resource::set_scene_unique_id(const String &p_id) { + scene_unique_id = p_id; } -int Resource::get_subindex() const { - return subindex; +String Resource::get_scene_unique_id() const { + return scene_unique_id; } void Resource::set_name(const String &p_name) { @@ -133,15 +165,15 @@ Error Resource::copy_from(const Ref<Resource> &p_resource) { List<PropertyInfo> pi; p_resource->get_property_list(&pi); - for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : pi) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - if (E->get().name == "resource_path") { + if (E.name == "resource_path") { continue; //do not change path } - set(E->get().name, p_resource->get(E->get().name)); + set(E.name, p_resource->get(E.name)); } return OK; } @@ -169,11 +201,11 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res r->local_scene = p_for_scene; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant p = get(E->get().name); + Variant p = get(E.name); if (p.get_type() == Variant::OBJECT) { RES sr = p; if (sr.is_valid()) { @@ -189,7 +221,7 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res } } - r->set(E->get().name, p); + r->set(E.name, p); } return r; @@ -201,11 +233,11 @@ void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, R local_scene = p_for_scene; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant p = get(E->get().name); + Variant p = get(E.name); if (p.get_type() == Variant::OBJECT) { RES sr = p; if (sr.is_valid()) { @@ -227,21 +259,21 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const { Ref<Resource> r = (Resource *)ClassDB::instantiate(get_class()); ERR_FAIL_COND_V(r.is_null(), Ref<Resource>()); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant p = get(E->get().name); + Variant p = get(E.name); if ((p.get_type() == Variant::DICTIONARY || p.get_type() == Variant::ARRAY)) { - r->set(E->get().name, p.duplicate(p_subresources)); - } else if (p.get_type() == Variant::OBJECT && (p_subresources || (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) { + r->set(E.name, p.duplicate(p_subresources)); + } else if (p.get_type() == Variant::OBJECT && (p_subresources || (E.usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) { RES sr = p; if (sr.is_valid()) { - r->set(E->get().name, sr->duplicate(p_subresources)); + r->set(E.name, sr->duplicate(p_subresources)); } } else { - r->set(E->get().name, p); + r->set(E.name, p); } } @@ -285,9 +317,9 @@ uint32_t Resource::hash_edited_version() const { List<PropertyInfo> plist; get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE && E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { - RES res = get(E->get().name); + for (const PropertyInfo &E : plist) { + if (E.usage & PROPERTY_USAGE_STORAGE && E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_RESOURCE_TYPE) { + RES res = get(E.name); if (res.is_valid()) { hash = hash_djb2_one_32(res->hash_edited_version(), hash); } @@ -350,8 +382,8 @@ bool Resource::is_translation_remapped() const { #ifdef TOOLS_ENABLED //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored -void Resource::set_id_for_path(const String &p_path, int p_id) { - if (p_id == -1) { +void Resource::set_id_for_path(const String &p_path, const String &p_id) { + if (p_id == "") { ResourceCache::path_cache_lock.write_lock(); ResourceCache::resource_path_cache[p_path].erase(get_path()); ResourceCache::path_cache_lock.write_unlock(); @@ -362,15 +394,15 @@ void Resource::set_id_for_path(const String &p_path, int p_id) { } } -int Resource::get_id_for_path(const String &p_path) const { +String Resource::get_id_for_path(const String &p_path) const { ResourceCache::path_cache_lock.read_lock(); if (ResourceCache::resource_path_cache[p_path].has(get_path())) { - int result = ResourceCache::resource_path_cache[p_path][get_path()]; + String result = ResourceCache::resource_path_cache[p_path][get_path()]; ResourceCache::path_cache_lock.read_unlock(); return result; } else { ResourceCache::path_cache_lock.read_unlock(); - return -1; + return ""; } } #endif @@ -414,7 +446,7 @@ Resource::~Resource() { HashMap<String, Resource *> ResourceCache::resources; #ifdef TOOLS_ENABLED -HashMap<String, HashMap<String, int>> ResourceCache::resource_path_cache; +HashMap<String, HashMap<String, String>> ResourceCache::resource_path_cache; #endif RWLock ResourceCache::lock; diff --git a/core/io/resource.h b/core/io/resource.h index 028fed1c6e..e864b371ad 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -31,6 +31,7 @@ #ifndef RESOURCE_H #define RESOURCE_H +#include "core/io/resource_uid.h" #include "core/object/class_db.h" #include "core/object/ref_counted.h" #include "core/templates/safe_refcount.h" @@ -59,7 +60,7 @@ private: String name; String path_cache; - int subindex = 0; + String scene_unique_id; virtual bool _use_builtin_script() const { return true; } @@ -105,8 +106,9 @@ public: virtual void set_path(const String &p_path, bool p_take_over = false); String get_path() const; - void set_subindex(int p_sub_index); - int get_subindex() const; + static String generate_scene_unique_id(); + void set_scene_unique_id(const String &p_id); + String get_scene_unique_id() const; virtual Ref<Resource> duplicate(bool p_subresources = false) const; Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache); @@ -140,8 +142,8 @@ public: #ifdef TOOLS_ENABLED //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored - void set_id_for_path(const String &p_path, int p_id); - int get_id_for_path(const String &p_path) const; + void set_id_for_path(const String &p_path, const String &p_id); + String get_id_for_path(const String &p_path) const; #endif Resource(); @@ -156,7 +158,7 @@ class ResourceCache { static RWLock lock; static HashMap<String, Resource *> resources; #ifdef TOOLS_ENABLED - static HashMap<String, HashMap<String, int>> resource_path_cache; // each tscn has a set of resource paths and IDs + static HashMap<String, HashMap<String, String>> resource_path_cache; // Each tscn has a set of resource paths and IDs. static RWLock path_cache_lock; #endif // TOOLS_ENABLED friend void unregister_core_types(); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 0e9815245f..a3ebc32cc5 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -84,9 +84,10 @@ enum { OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, OBJECT_EXTERNAL_RESOURCE_INDEX = 3, - //version 2: added 64 bits support for float and int - //version 3: changed nodepath encoding - FORMAT_VERSION = 3, + // Version 2: added 64 bits support for float and int. + // Version 3: changed nodepath encoding. + // Version 4: new string ID for ext/subresources, breaks forward compat. + FORMAT_VERSION = 4, FORMAT_VERSION_CAN_RENAME_DEPS = 1, FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3, }; @@ -311,7 +312,14 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index = f->get_32(); - String path = res_path + "::" + itos(index); + String path; + + if (using_named_scene_ids) { // New format. + ERR_FAIL_INDEX_V((int)index, internal_resources.size(), ERR_PARSE_ERROR); + path = internal_resources[index].path; + } else { + path += res_path + "::" + itos(index); + } //always use internal cache for loading internal resources if (!internal_index_cache.has(path)) { @@ -320,7 +328,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } else { r_v = internal_index_cache[path]; } - } break; case OBJECT_EXTERNAL_RESOURCE: { //old file format, still around for compatibility @@ -378,7 +385,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { ERR_FAIL_V(ERR_FILE_CORRUPT); } break; } - } break; case VARIANT_CALLABLE: { r_v = Callable(); @@ -659,15 +665,17 @@ Error ResourceLoaderBinary::load() { //maybe it is loaded already String path; - int subindex = 0; + String id; if (!main) { path = internal_resources[i].path; if (path.begins_with("local://")) { path = path.replace_first("local://", ""); - subindex = path.to_int(); + id = path; path = res_path + "::" + path; + + internal_resources.write[i].path = path; // Update path. } if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE) { @@ -722,7 +730,7 @@ Error ResourceLoaderBinary::load() { if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it } - r->set_subindex(subindex); + r->set_scene_unique_id(id); } if (!main) { @@ -808,13 +816,18 @@ String ResourceLoaderBinary::get_unicode_string() { } void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) { - open(p_f); + open(p_f, false, true); if (error) { return; } for (int i = 0; i < external_resources.size(); i++) { - String dep = external_resources[i].path; + String dep; + if (external_resources[i].uid != ResourceUID::INVALID_ID) { + dep = ResourceUID::get_singleton()->id_to_text(external_resources[i].uid); + } else { + dep = external_resources[i].path; + } if (p_add_types && external_resources[i].type != String()) { dep += "::" + external_resources[i].type; @@ -824,7 +837,7 @@ void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dep } } -void ResourceLoaderBinary::open(FileAccess *p_f) { +void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_keep_uuid_paths) { error = OK; f = p_f; @@ -879,10 +892,28 @@ void ResourceLoaderBinary::open(FileAccess *p_f) { print_bl("type: " + type); importmd_ofs = f->get_64(); - for (int i = 0; i < 14; i++) { + uint32_t flags = f->get_32(); + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_NAMED_SCENE_IDS) { + using_named_scene_ids = true; + } + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS) { + using_uids = true; + } + + if (using_uids) { + uid = f->get_64(); + } else { + uid = ResourceUID::INVALID_ID; + } + + for (int i = 0; i < 5; i++) { f->get_32(); //skip a few reserved fields } + if (p_no_resources) { + return; + } + uint32_t string_table_size = f->get_32(); string_map.resize(string_table_size); for (uint32_t i = 0; i < string_table_size; i++) { @@ -896,8 +927,18 @@ void ResourceLoaderBinary::open(FileAccess *p_f) { for (uint32_t i = 0; i < ext_resources_size; i++) { ExtResource er; er.type = get_unicode_string(); - er.path = get_unicode_string(); + if (using_uids) { + er.uid = f->get_64(); + if (!p_keep_uuid_paths && er.uid != ResourceUID::INVALID_ID) { + if (ResourceUID::get_singleton()->has_id(er.uid)) { + // If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path. + er.path = ResourceUID::get_singleton()->get_id_path(er.uid); + } else { + WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UUID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data()); + } + } + } external_resources.push_back(er); } @@ -1013,8 +1054,8 @@ void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String extensions.sort(); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - String ext = E->get().to_lower(); + for (const String &E : extensions) { + String ext = E.to_lower(); p_extensions->push_back(ext); } } @@ -1024,8 +1065,8 @@ void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_exten ClassDB::get_resource_base_extensions(&extensions); extensions.sort(); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - String ext = E->get().to_lower(); + for (const String &E : extensions) { + String ext = E.to_lower(); p_extensions->push_back(ext); } } @@ -1161,8 +1202,15 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons uint64_t importmd_ofs = f->get_64(); fw->store_64(0); //metadata offset - for (int i = 0; i < 14; i++) { - fw->store_32(0); + uint32_t flags = f->get_32(); + bool using_uids = (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS); + uint64_t uid_data = f->get_64(); + + fw->store_32(flags); + fw->store_64(uid_data); + + for (int i = 0; i < 5; i++) { + f->store_32(0); // reserved f->get_32(); } @@ -1183,6 +1231,16 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons String type = get_ustring(f); String path = get_ustring(f); + if (using_uids) { + ResourceUID::ID uid = f->get_64(); + if (uid != ResourceUID::INVALID_ID) { + if (ResourceUID::get_singleton()->has_id(uid)) { + // If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path. + path = ResourceUID::get_singleton()->get_id_path(uid); + } + } + } + bool relative = false; if (!path.begins_with("res://")) { path = local_path.plus_file(path).simplify_path(); @@ -1194,6 +1252,8 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons path = np; } + String full_path = path; + if (relative) { //restore relative path = local_path.path_to_file(path); @@ -1201,6 +1261,11 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons save_ustring(fw, type); save_ustring(fw, path); + + if (using_uids) { + ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(full_path); + f->store_64(uid); + } } int64_t size_diff = (int64_t)fw->get_position() - (int64_t)f->get_position(); @@ -1256,6 +1321,28 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const return ClassDB::get_compatibility_remapped_class(r); } +ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_path) const { + String ext = p_path.get_extension().to_lower(); + if (!ClassDB::is_resource_extension(ext)) { + return ResourceUID::INVALID_ID; + } + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ); + if (!f) { + return ResourceUID::INVALID_ID; //could not read + } + + ResourceLoaderBinary loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + //loader.set_local_path( Globals::get_singleton()->localize_path(p_path) ); + loader.open(f, true); + if (loader.error != OK) { + return ResourceUID::INVALID_ID; //could not read + } + return loader.uid; +} + /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// @@ -1269,11 +1356,7 @@ void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes) } } -void ResourceFormatSaverBinaryInstance::_write_variant(const Variant &p_property, const PropertyInfo &p_hint) { - write_variant(f, p_property, resource_set, external_resources, string_map, p_hint); -} - -void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Variant &p_property, Set<RES> &resource_set, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) { +void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) { switch (p_property.get_type()) { case Variant::NIL: { f->store_32(VARIANT_NIL); @@ -1492,13 +1575,13 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX); f->store_32(external_resources[res]); } else { - if (!resource_set.has(res)) { + if (!resource_map.has(res)) { f->store_32(OBJECT_EMPTY); ERR_FAIL_MSG("Resource was not pre cached for the resource section, most likely due to circular reference."); } f->store_32(OBJECT_INTERNAL_RESOURCE); - f->store_32(res->get_subindex()); + f->store_32(resource_map[res]); //internal resource } @@ -1520,14 +1603,14 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (const Variant &E : keys) { /* - if (!_check_type(dict[E->get()])) + if (!_check_type(dict[E])) continue; */ - write_variant(f, E->get(), resource_set, external_resources, string_map); - write_variant(f, d[E->get()], resource_set, external_resources, string_map); + write_variant(f, E, resource_map, external_resources, string_map); + write_variant(f, d[E], resource_map, external_resources, string_map); } } break; @@ -1536,7 +1619,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia Array a = p_property; f->store_32(uint32_t(a.size())); for (int i = 0; i < a.size(); i++) { - write_variant(f, a[i], resource_set, external_resources, string_map); + write_variant(f, a[i], resource_map, external_resources, string_map); } } break; @@ -1677,15 +1760,15 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant res->get_property_list(&property_list); - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE) { - Variant value = res->get(E->get().name); - if (E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + for (const PropertyInfo &E : property_list) { + if (E.usage & PROPERTY_USAGE_STORAGE) { + Variant value = res->get(E.name); + if (E.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { RES sres = value; if (sres.is_valid()) { NonPersistentKey npk; npk.base = res; - npk.property = E->get().name; + npk.property = E.name; non_persistent_map[npk] = sres; resource_set.insert(sres); saved_resources.push_back(sres); @@ -1715,9 +1798,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant Dictionary d = p_variant; List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - _find_resources(E->get()); - Variant v = d[E->get()]; + for (const Variant &E : keys) { + _find_resources(E); + Variant v = d[E]; _find_resources(v); } } break; @@ -1816,46 +1899,49 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p save_unicode_string(f, p_resource->get_class()); f->store_64(0); //offset to import metadata - for (int i = 0; i < 14; i++) { + f->store_32(FORMAT_FLAG_NAMED_SCENE_IDS | FORMAT_FLAG_UIDS); + ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(p_path, true); + f->store_64(uid); + for (int i = 0; i < 5; i++) { f->store_32(0); // reserved } List<ResourceData> resources; { - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { + for (const RES &E : saved_resources) { ResourceData &rd = resources.push_back(ResourceData())->get(); - rd.type = E->get()->get_class(); + rd.type = E->get_class(); List<PropertyInfo> property_list; - E->get()->get_property_list(&property_list); + E->get_property_list(&property_list); - for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) { - if (skip_editor && F->get().name.begins_with("__editor")) { + for (const PropertyInfo &F : property_list) { + if (skip_editor && F.name.begins_with("__editor")) { continue; } - if ((F->get().usage & PROPERTY_USAGE_STORAGE)) { + if ((F.usage & PROPERTY_USAGE_STORAGE)) { Property p; - p.name_idx = get_string_index(F->get().name); + p.name_idx = get_string_index(F.name); - if (F->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + if (F.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { NonPersistentKey npk; - npk.base = E->get(); - npk.property = F->get().name; + npk.base = E; + npk.property = F.name; if (non_persistent_map.has(npk)) { p.value = non_persistent_map[npk]; } } else { - p.value = E->get()->get(F->get().name); + p.value = E->get(F.name); } - Variant default_value = ClassDB::class_get_default_property_value(E->get()->get_class(), F->get().name); + Variant default_value = ClassDB::class_get_default_property_value(E->get_class(), F.name); if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, p.value, default_value))) { continue; } - p.pi = F->get(); + p.pi = F; rd.properties.push_back(p); } @@ -1882,41 +1968,47 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p String path = save_order[i]->get_path(); path = relative_paths ? local_path.path_to_file(path) : path; save_unicode_string(f, path); + ResourceUID::ID ruid = ResourceSaver::get_resource_id_for_path(save_order[i]->get_path(), false); + f->store_64(ruid); } // save internal resource table f->store_32(saved_resources.size()); //amount of internal resources Vector<uint64_t> ofs_pos; - Set<int> used_indices; + Set<String> used_unique_ids; - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { - RES r = E->get(); + for (RES &r : saved_resources) { if (r->get_path() == "" || r->get_path().find("::") != -1) { - if (r->get_subindex() != 0) { - if (used_indices.has(r->get_subindex())) { - r->set_subindex(0); //repeated + if (r->get_scene_unique_id() != "") { + if (used_unique_ids.has(r->get_scene_unique_id())) { + r->set_scene_unique_id(""); } else { - used_indices.insert(r->get_subindex()); + used_unique_ids.insert(r->get_scene_unique_id()); } } } } - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { - RES r = E->get(); + Map<RES, int> resource_map; + int res_index = 0; + for (RES &r : saved_resources) { if (r->get_path() == "" || r->get_path().find("::") != -1) { - if (r->get_subindex() == 0) { - int new_subindex = 1; - if (used_indices.size()) { - new_subindex = used_indices.back()->get() + 1; + if (r->get_scene_unique_id() == "") { + String new_id; + + while (true) { + new_id = r->get_class() + "_" + Resource::generate_scene_unique_id(); + if (!used_unique_ids.has(new_id)) { + break; + } } - r->set_subindex(new_subindex); - used_indices.insert(new_subindex); + r->set_scene_unique_id(new_id); + used_unique_ids.insert(new_id); } - save_unicode_string(f, "local://" + itos(r->get_subindex())); + save_unicode_string(f, "local://" + r->get_scene_unique_id()); if (takeover_paths) { - r->set_path(p_path + "::" + itos(r->get_subindex()), true); + r->set_path(p_path + "::" + r->get_scene_unique_id(), true); } #ifdef TOOLS_ENABLED r->set_edited(false); @@ -1926,22 +2018,20 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p } ofs_pos.push_back(f->get_position()); f->store_64(0); //offset in 64 bits + resource_map[r] = res_index++; } Vector<uint64_t> ofs_table; //now actually save the resources - for (List<ResourceData>::Element *E = resources.front(); E; E = E->next()) { - ResourceData &rd = E->get(); - + for (const ResourceData &rd : resources) { ofs_table.push_back(f->get_position()); save_unicode_string(f, rd.type); f->store_32(rd.properties.size()); - for (List<Property>::Element *F = rd.properties.front(); F; F = F->next()) { - Property &p = F->get(); + for (const Property &p : rd.properties) { f->store_32(p.name_idx); - _write_variant(p.value, F->get().pi); + write_variant(f, p.value, resource_map, external_resources, string_map, p.pi); } } diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index abc7403935..ac964d2053 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -47,6 +47,8 @@ class ResourceLoaderBinary { uint64_t importmd_ofs = 0; + ResourceUID::ID uid = ResourceUID::INVALID_ID; + Vector<char> str_buf; List<RES> resource_cache; @@ -57,9 +59,12 @@ class ResourceLoaderBinary { struct ExtResource { String path; String type; + ResourceUID::ID uid = ResourceUID::INVALID_ID; RES cache; }; + bool using_named_scene_ids = false; + bool using_uids = false; bool use_sub_threads = false; float *progress = nullptr; Vector<ExtResource> external_resources; @@ -93,7 +98,7 @@ public: void set_translation_remapped(bool p_remapped); void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; } - void open(FileAccess *p_f); + void open(FileAccess *p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false); String recognize(FileAccess *p_f); void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); @@ -108,6 +113,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); }; @@ -150,14 +156,17 @@ class ResourceFormatSaverBinaryInstance { }; static void _pad_buffer(FileAccess *f, int p_bytes); - void _write_variant(const Variant &p_property, const PropertyInfo &p_hint = PropertyInfo()); void _find_resources(const Variant &p_variant, bool p_main = false); static void save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false); int get_string_index(const String &p_string); public: + enum { + FORMAT_FLAG_NAMED_SCENE_IDS = 1, + FORMAT_FLAG_UIDS = 2, + }; Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - static void write_variant(FileAccess *f, const Variant &p_property, Set<RES> &resource_set, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo()); + static void write_variant(FileAccess *f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo()); }; class ResourceFormatSaverBinary : public ResourceFormatSaver { diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index b503655edd..1e166015b0 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -93,6 +93,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value); } else if (assign == "importer") { r_path_and_type.importer = value; + } else if (assign == "uid") { + r_path_and_type.uid = ResourceUID::get_singleton()->text_to_id(value); } else if (assign == "group_file") { r_path_and_type.group_file = value; } else if (assign == "metadata") { @@ -146,10 +148,10 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension for (int i = 0; i < importers.size(); i++) { List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (!found.has(F->get())) { - p_extensions->push_back(F->get()); - found.insert(F->get()); + for (const String &F : local_exts) { + if (!found.has(F)) { + p_extensions->push_back(F); + found.insert(F); } } } @@ -175,10 +177,10 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_ List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (!found.has(F->get())) { - p_extensions->push_back(F->get()); - found.insert(F->get()); + for (const String &F : local_exts) { + if (!found.has(F)) { + p_extensions->push_back(F); + found.insert(F); } } } @@ -336,6 +338,17 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const { return pat.type; } +ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) const { + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + return ResourceUID::INVALID_ID; + } + + return pat.uid; +} + Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const { PathAndType pat; Error err = _get_path_and_type(p_path, pat); @@ -372,8 +385,8 @@ void ResourceFormatImporter::get_importers_for_extension(const String &p_extensi for (int i = 0; i < importers.size(); i++) { List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (p_extension.to_lower() == F->get()) { + for (const String &F : local_exts) { + if (p_extension.to_lower() == F) { r_importers->push_back(importers[i]); } } @@ -393,8 +406,8 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const St for (int i = 0; i < importers.size(); i++) { List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (p_extension.to_lower() == F->get() && importers[i]->get_priority() > priority) { + for (const String &F : local_exts) { + if (p_extension.to_lower() == F && importers[i]->get_priority() > priority) { importer = importers[i]; priority = importers[i]->get_priority(); } @@ -445,3 +458,8 @@ ResourceFormatImporter *ResourceFormatImporter::singleton = nullptr; ResourceFormatImporter::ResourceFormatImporter() { singleton = this; } + +void ResourceImporter::_bind_methods() { + BIND_ENUM_CONSTANT(IMPORT_ORDER_DEFAULT); + BIND_ENUM_CONSTANT(IMPORT_ORDER_SCENE); +} diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 2ceeb176e5..a1cacbd306 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -42,6 +42,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { String importer; String group_file; Variant metadata; + uint64_t uid = ResourceUID::INVALID_ID; }; Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = nullptr) const; @@ -63,6 +64,8 @@ public: virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const; + virtual Variant get_resource_metadata(const String &p_path) const; virtual bool is_import_valid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -96,6 +99,9 @@ public: class ResourceImporter : public RefCounted { GDCLASS(ResourceImporter, RefCounted); +protected: + static void _bind_methods(); + public: virtual String get_importer_name() const = 0; virtual String get_visible_name() const = 0; @@ -103,7 +109,7 @@ public: virtual String get_save_extension() const = 0; virtual String get_resource_type() const = 0; virtual float get_priority() const { return 1.0; } - virtual int get_import_order() const { return 0; } + virtual int get_import_order() const { return IMPORT_ORDER_DEFAULT; } virtual int get_format_version() const { return 0; } struct ImportOption { @@ -117,6 +123,11 @@ public: ImportOption() {} }; + enum ImportOrder { + IMPORT_ORDER_DEFAULT = 0, + IMPORT_ORDER_SCENE = 100, + }; + virtual bool has_advanced_options() const { return false; } virtual void show_advanced_options(const String &p_path) {} @@ -137,4 +148,6 @@ public: virtual String get_import_settings_string() const { return String(); } }; +VARIANT_ENUM_CAST(ResourceImporter::ImportOrder); + #endif // RESOURCE_IMPORTER_H diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index c5dfe1f2b0..d02d827443 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -58,8 +58,8 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_ get_recognized_extensions_for_type(p_for_type, &extensions); } - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(extension) == 0) { + for (const String &E : extensions) { + if (E.nocasecmp_to(extension) == 0) { return true; } } @@ -84,6 +84,14 @@ String ResourceFormatLoader::get_resource_type(const String &p_path) const { return ""; } +ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const { + if (get_script_instance() && get_script_instance()->has_method("_get_resource_uid")) { + return get_script_instance()->call("_get_resource_uid", p_path); + } + + return ResourceUID::INVALID_ID; +} + void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { if (p_type == "" || handles_type(p_type)) { get_recognized_extensions(p_extensions); @@ -270,13 +278,18 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { thread_load_mutex->unlock(); } -Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, ResourceFormatLoader::CacheMode p_cache_mode, const String &p_source_resource) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; +static String _validate_local_path(const String &p_path) { + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(p_path); + if (uid != ResourceUID::INVALID_ID) { + return ResourceUID::get_singleton()->get_id_path(uid); + } else if (p_path.is_rel_path()) { + return "res://" + p_path; } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); + return ProjectSettings::get_singleton()->localize_path(p_path); } +} +Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, ResourceFormatLoader::CacheMode p_cache_mode, const String &p_source_resource) { + String local_path = _validate_local_path(p_path); thread_load_mutex->lock(); @@ -399,12 +412,7 @@ float ResourceLoader::_dependency_get_progress(const String &p_path) { } ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, float *r_progress) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); thread_load_mutex->lock(); if (!thread_load_tasks.has(local_path)) { @@ -424,12 +432,7 @@ ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const } RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); thread_load_mutex->lock(); if (!thread_load_tasks.has(local_path)) { @@ -510,12 +513,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour *r_error = ERR_CANT_OPEN; } - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); if (p_cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { thread_load_mutex->lock(); @@ -612,12 +610,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour } bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); if (ResourceCache::has(local_path)) { return true; // If cached, it probably exists @@ -677,14 +670,7 @@ void ResourceLoader::remove_resource_format_loader(Ref<ResourceFormatLoader> p_f } int ResourceLoader::get_import_order(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -702,14 +688,7 @@ int ResourceLoader::get_import_order(const String &p_path) { } String ResourceLoader::get_import_group_file(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -727,14 +706,7 @@ String ResourceLoader::get_import_group_file(const String &p_path) { } bool ResourceLoader::is_import_valid(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -752,14 +724,7 @@ bool ResourceLoader::is_import_valid(const String &p_path) { } bool ResourceLoader::is_imported(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -777,14 +742,7 @@ bool ResourceLoader::is_imported(const String &p_path) { } void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -800,14 +758,7 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe } Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -825,12 +776,7 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String } String ResourceLoader::get_resource_type(const String &p_path) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); for (int i = 0; i < loader_count; i++) { String result = loader[i]->get_resource_type(local_path); @@ -842,6 +788,19 @@ String ResourceLoader::get_resource_type(const String &p_path) { return ""; } +ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { + String local_path = _validate_local_path(p_path); + + for (int i = 0; i < loader_count; i++) { + ResourceUID::ID id = loader[i]->get_resource_uid(local_path); + if (id != ResourceUID::INVALID_ID) { + return id; + } + } + + return ResourceUID::INVALID_ID; +} + String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { String new_path = p_path; @@ -978,15 +937,15 @@ void ResourceLoader::load_translation_remaps() { Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); List<Variant> keys; remaps.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - Array langs = remaps[E->get()]; + for (const Variant &E : keys) { + Array langs = remaps[E]; Vector<String> lang_remaps; lang_remaps.resize(langs.size()); for (int i = 0; i < langs.size(); i++) { lang_remaps.write[i] = langs[i]; } - translation_remaps[String(E->get())] = lang_remaps; + translation_remaps[String(E)] = lang_remaps; } } @@ -1071,8 +1030,7 @@ void ResourceLoader::add_custom_loaders() { List<StringName> global_classes; ScriptServer::get_global_class_list(&global_classes); - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - StringName class_name = E->get(); + for (const StringName &class_name : global_classes) { StringName base_class = ScriptServer::get_global_class_native_base(class_name); if (base_class == custom_loader_base_class) { diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index c656b9a69c..e525e80a9d 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -40,9 +40,9 @@ class ResourceFormatLoader : public RefCounted { public: enum CacheMode { - CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource. - CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available - CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk + CACHE_MODE_IGNORE, // Resource and subresources do not use path cache, no path is set into resource. + CACHE_MODE_REUSE, // Resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available. + CACHE_MODE_REPLACE, // Resource and subresource use path cache, but replace existing loaded resources when available with information from disk. }; protected: @@ -56,6 +56,7 @@ public: virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); virtual bool is_import_valid(const String &p_path) const { return true; } @@ -107,7 +108,7 @@ private: friend class ResourceFormatImporter; friend class ResourceInteractiveLoader; - //internal load function + // Internal load function. static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress); static ResourceLoadedCallback _loaded_callback; @@ -157,6 +158,7 @@ public: static void add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front = false); static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader); static String get_resource_type(const String &p_path); + static ResourceUID::ID get_resource_uid(const String &p_path); static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); static bool is_import_valid(const String &p_path); diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 80cb85fba3..564de5ee69 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -39,6 +39,7 @@ Ref<ResourceFormatSaver> ResourceSaver::saver[MAX_SAVERS]; int ResourceSaver::saver_count = 0; bool ResourceSaver::timestamp_on_save = false; ResourceSavedCallback ResourceSaver::save_callback = nullptr; +ResourceSaverGetResourceIDForPath ResourceSaver::save_get_id_for_path = nullptr; Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { if (get_script_instance() && get_script_instance()->has_method("_save")) { @@ -94,8 +95,8 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t bool recognized = false; saver[i]->get_recognized_extensions(p_resource, &extensions); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(extension) == 0) { + for (const String &E : extensions) { + if (E.nocasecmp_to(extension) == 0) { recognized = true; } } @@ -236,8 +237,7 @@ void ResourceSaver::add_custom_savers() { List<StringName> global_classes; ScriptServer::get_global_class_list(&global_classes); - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - StringName class_name = E->get(); + for (const StringName &class_name : global_classes) { StringName base_class = ScriptServer::get_global_class_native_base(class_name); if (base_class == custom_saver_base_class) { @@ -259,3 +259,14 @@ void ResourceSaver::remove_custom_savers() { remove_resource_format_saver(custom_savers[i]); } } + +ResourceUID::ID ResourceSaver::get_resource_id_for_path(const String &p_path, bool p_generate) { + if (save_get_id_for_path) { + return save_get_id_for_path(p_path, p_generate); + } + return ResourceUID::INVALID_ID; +} + +void ResourceSaver::set_get_resource_id_for_path(ResourceSaverGetResourceIDForPath p_callback) { + save_get_id_for_path = p_callback; +} diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 07154aac4d..2fc8d32126 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -48,6 +48,7 @@ public: }; typedef void (*ResourceSavedCallback)(Ref<Resource> p_resource, const String &p_path); +typedef ResourceUID::ID (*ResourceSaverGetResourceIDForPath)(const String &p_path, bool p_generate); class ResourceSaver { enum { @@ -58,6 +59,7 @@ class ResourceSaver { static int saver_count; static bool timestamp_on_save; static ResourceSavedCallback save_callback; + static ResourceSaverGetResourceIDForPath save_get_id_for_path; static Ref<ResourceFormatSaver> _find_custom_resource_format_saver(String path); @@ -80,7 +82,10 @@ public: static void set_timestamp_on_save(bool p_timestamp) { timestamp_on_save = p_timestamp; } static bool get_timestamp_on_save() { return timestamp_on_save; } + static ResourceUID::ID get_resource_id_for_path(const String &p_path, bool p_generate = false); + static void set_save_callback(ResourceSavedCallback p_callback); + static void set_get_resource_id_for_path(ResourceSaverGetResourceIDForPath p_callback); static bool add_custom_resource_format_saver(String script_path); static void remove_custom_resource_format_saver(String script_path); diff --git a/core/io/resource_uid.cpp b/core/io/resource_uid.cpp new file mode 100644 index 0000000000..97d683f415 --- /dev/null +++ b/core/io/resource_uid.cpp @@ -0,0 +1,262 @@ +/*************************************************************************/ +/* resource_uid.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "resource_uid.h" +#include "core/crypto/crypto.h" +#include "core/io/dir_access.h" +#include "core/io/file_access.h" + +static constexpr uint32_t char_count = ('z' - 'a'); +static constexpr uint32_t base = char_count + ('9' - '0'); + +const char *ResourceUID::CACHE_FILE = "res://.godot/uid_cache.bin"; + +String ResourceUID::id_to_text(ID p_id) const { + if (p_id < 0) { + return "uid://<invalid>"; + } + String txt; + + while (p_id) { + uint32_t c = p_id % base; + if (c < char_count) { + txt = String::chr('a' + c) + txt; + } else { + txt = String::chr('0' + (c - char_count)) + txt; + } + p_id /= base; + } + + return "uid://" + txt; +} + +ResourceUID::ID ResourceUID::text_to_id(const String &p_text) const { + if (!p_text.begins_with("uid://") || p_text == "uid://<invalid>") { + return INVALID_ID; + } + + uint32_t l = p_text.length(); + uint64_t uid = 0; + for (uint32_t i = 6; i < l; i++) { + uid *= base; + uint32_t c = p_text[i]; + if (c >= 'a' && c <= 'z') { + uid += c - 'a'; + } else if (c >= '0' && c <= '9') { + uid += c - '0' + char_count; + } else { + return INVALID_ID; + } + } + return ID(uid & 0x7FFFFFFFFFFFFFFF); +} + +ResourceUID::ID ResourceUID::create_id() const { + mutex.lock(); + if (crypto.is_null()) { + crypto = Ref<Crypto>(Crypto::create()); + } + mutex.unlock(); + while (true) { + PackedByteArray bytes = crypto->generate_random_bytes(8); + ERR_FAIL_COND_V(bytes.size() != 8, INVALID_ID); + const uint64_t *ptr64 = (const uint64_t *)bytes.ptr(); + ID id = int64_t((*ptr64) & 0x7FFFFFFFFFFFFFFF); + mutex.lock(); + bool exists = unique_ids.has(id); + mutex.unlock(); + if (!exists) { + return id; + } + } +} + +bool ResourceUID::has_id(ID p_id) const { + MutexLock l(mutex); + return unique_ids.has(p_id); +} +void ResourceUID::add_id(ID p_id, const String &p_path) { + MutexLock l(mutex); + ERR_FAIL_COND(unique_ids.has(p_id)); + Cache c; + c.cs = p_path.utf8(); + unique_ids[p_id] = c; + changed = true; +} + +void ResourceUID::set_id(ID p_id, const String &p_path) { + MutexLock l(mutex); + ERR_FAIL_COND(!unique_ids.has(p_id)); + CharString cs = p_path.utf8(); + if (strcmp(cs.ptr(), unique_ids[p_id].cs.ptr()) != 0) { + unique_ids[p_id].cs = cs; + unique_ids[p_id].saved_to_cache = false; //changed + changed = true; + } +} + +String ResourceUID::get_id_path(ID p_id) const { + MutexLock l(mutex); + ERR_FAIL_COND_V(!unique_ids.has(p_id), String()); + const CharString &cs = unique_ids[p_id].cs; + String s(cs.ptr()); + return s; +} +void ResourceUID::remove_id(ID p_id) { + MutexLock l(mutex); + ERR_FAIL_COND(!unique_ids.has(p_id)); + unique_ids.erase(p_id); +} + +Error ResourceUID::save_to_cache() { + if (!FileAccess::exists(CACHE_FILE)) { + DirAccessRef d = DirAccess::create(DirAccess::ACCESS_RESOURCES); + d->make_dir_recursive(String(CACHE_FILE).get_base_dir()); //ensure base dir exists + } + + FileAccessRef f = FileAccess::open(CACHE_FILE, FileAccess::WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + MutexLock l(mutex); + f->store_32(unique_ids.size()); + + cache_entries = 0; + + for (OrderedHashMap<ID, Cache>::Element E = unique_ids.front(); E; E = E.next()) { + f->store_64(E.key()); + uint32_t s = E.get().cs.length(); + f->store_32(s); + f->store_buffer((const uint8_t *)E.get().cs.ptr(), s); + E.get().saved_to_cache = true; + cache_entries++; + } + + changed = false; + return OK; +} + +Error ResourceUID::load_from_cache() { + FileAccessRef f = FileAccess::open(CACHE_FILE, FileAccess::READ); + if (!f) { + return ERR_CANT_OPEN; + } + + MutexLock l(mutex); + unique_ids.clear(); + + uint32_t entry_count = f->get_32(); + for (uint32_t i = 0; i < entry_count; i++) { + int64_t id = f->get_64(); + int32_t len = f->get_32(); + Cache c; + c.cs.resize(len + 1); + ERR_FAIL_COND_V(c.cs.size() != len + 1, ERR_FILE_CORRUPT); // out of memory + c.cs[len] = 0; + int32_t rl = f->get_buffer((uint8_t *)c.cs.ptrw(), len); + ERR_FAIL_COND_V(rl != len, ERR_FILE_CORRUPT); + + c.saved_to_cache = true; + unique_ids[id] = c; + } + + cache_entries = entry_count; + changed = false; + return OK; +} + +Error ResourceUID::update_cache() { + if (!changed) { + return OK; + } + + if (cache_entries == 0) { + return save_to_cache(); + } + MutexLock l(mutex); + + FileAccess *f = nullptr; + for (OrderedHashMap<ID, Cache>::Element E = unique_ids.front(); E; E = E.next()) { + if (!E.get().saved_to_cache) { + if (f == nullptr) { + f = FileAccess::open(CACHE_FILE, FileAccess::READ_WRITE); //append + if (!f) { + return ERR_CANT_OPEN; + } + f->seek_end(); + } + f->store_64(E.key()); + uint32_t s = E.get().cs.length(); + f->store_32(s); + f->store_buffer((const uint8_t *)E.get().cs.ptr(), s); + E.get().saved_to_cache = true; + cache_entries++; + } + } + + if (f != nullptr) { + f->seek(0); + f->store_32(cache_entries); //update amount of entries + f->close(); + memdelete(f); + } + + changed = false; + + return OK; +} + +void ResourceUID::clear() { + cache_entries = 0; + unique_ids.clear(); + changed = false; +} +void ResourceUID::_bind_methods() { + ClassDB::bind_method(D_METHOD("id_to_text", "id"), &ResourceUID::id_to_text); + ClassDB::bind_method(D_METHOD("text_to_id", "text_id"), &ResourceUID::text_to_id); + + ClassDB::bind_method(D_METHOD("create_id"), &ResourceUID::create_id); + + ClassDB::bind_method(D_METHOD("has_id", "id"), &ResourceUID::has_id); + ClassDB::bind_method(D_METHOD("add_id", "id", "path"), &ResourceUID::add_id); + ClassDB::bind_method(D_METHOD("set_id", "id", "path"), &ResourceUID::set_id); + ClassDB::bind_method(D_METHOD("get_id_path", "id"), &ResourceUID::get_id_path); + ClassDB::bind_method(D_METHOD("remove_id", "id"), &ResourceUID::remove_id); + + BIND_CONSTANT(INVALID_ID) +} +ResourceUID *ResourceUID::singleton = nullptr; +ResourceUID::ResourceUID() { + ERR_FAIL_COND(singleton != nullptr); + singleton = this; +} +ResourceUID::~ResourceUID() { +} diff --git a/core/io/resource_uid.h b/core/io/resource_uid.h new file mode 100644 index 0000000000..b12138425a --- /dev/null +++ b/core/io/resource_uid.h @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* resource_uid.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RESOURCE_UUID_H +#define RESOURCE_UUID_H + +#include "core/object/ref_counted.h" +#include "core/string/string_name.h" +#include "core/templates/ordered_hash_map.h" + +class Crypto; +class ResourceUID : public Object { + GDCLASS(ResourceUID, Object) +public: + typedef int64_t ID; + enum { + INVALID_ID = -1 + }; + + static const char *CACHE_FILE; + +private: + mutable Ref<Crypto> crypto; + Mutex mutex; + struct Cache { + CharString cs; + bool saved_to_cache = false; + }; + + OrderedHashMap<ID, Cache> unique_ids; //unique IDs and utf8 paths (less memory used) + static ResourceUID *singleton; + + uint32_t cache_entries = 0; + bool changed = false; + +protected: + static void _bind_methods(); + +public: + String id_to_text(ID p_id) const; + ID text_to_id(const String &p_text) const; + + ID create_id() const; + bool has_id(ID p_id) const; + void add_id(ID p_id, const String &p_path); + void set_id(ID p_id, const String &p_path); + String get_id_path(ID p_id) const; + void remove_id(ID p_id); + + Error load_from_cache(); + Error save_to_cache(); + Error update_cache(); + + void clear(); + + static ResourceUID *get_singleton() { return singleton; } + + ResourceUID(); + ~ResourceUID(); +}; + +#endif // RESOURCEUUID_H diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 6f7209556e..81adf4d19a 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -375,8 +375,7 @@ public: OutputSimplex *ret_simplicesw = ret_simplices.ptrw(); uint32_t simplices_written = 0; - for (List<Simplex *>::Element *E = simplex_list.front(); E; E = E->next()) { - Simplex *simplex = E->get(); + for (Simplex *simplex : simplex_list) { bool invalid = false; for (int j = 0; j < 4; j++) { if (simplex->points[j] >= point_count) { diff --git a/core/math/face3.h b/core/math/face3.h index 5091b338ef..9e9026e54e 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -50,8 +50,8 @@ public: /** * * @param p_plane plane used to split the face - * @param p_res array of at least 3 faces, amount used in functio return - * @param p_is_point_over array of at least 3 booleans, determining which face is over the plane, amount used in functio return + * @param p_res array of at least 3 faces, amount used in function return + * @param p_is_point_over array of at least 3 booleans, determining which face is over the plane, amount used in function return * @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen) * @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3 */ diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 4ef9b4dbe6..766689e222 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -40,7 +40,7 @@ class Geometry3D { public: static void get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2, Vector3 &c1, Vector3 &c2) { -// Do the function 'd' as defined by pb. I think is is dot product of some sort. +// Do the function 'd' as defined by pb. I think it's a dot product of some sort. #define d_of(m, n, o, p) ((m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z)) // Calculate the parametric position on the 2 curves, mua and mub. diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 0d77bfe933..0960fe19a6 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -192,9 +192,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ continue; } - for (List<Face>::Element *E = faces.front(); E; E = E->next()) { - if (E->get().plane.distance_to(p_points[i]) > over_tolerance) { - E->get().points_over.push_back(i); + for (Face &E : faces) { + if (E.plane.distance_to(p_points[i]) > over_tolerance) { + E.points_over.push_back(i); break; } } @@ -292,8 +292,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ //distribute points into new faces - for (List<List<Face>::Element *>::Element *F = lit_faces.front(); F; F = F->next()) { - Face &lf = F->get()->get(); + for (List<Face>::Element *&F : lit_faces) { + Face &lf = F->get(); for (int i = 0; i < lf.points_over.size(); i++) { if (lf.points_over[i] == f.points_over[next]) { //do not add current one @@ -301,8 +301,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ } Vector3 p = p_points[lf.points_over[i]]; - for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) { - Face &f2 = E->get()->get(); + for (List<Face>::Element *&E : new_faces) { + Face &f2 = E->get(); if (f2.plane.distance_to(p) > over_tolerance) { f2.points_over.push_back(lf.points_over[i]); break; @@ -320,10 +320,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ //put faces that contain no points on the front - for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) { - Face &f2 = E->get()->get(); + for (List<Face>::Element *&E : new_faces) { + Face &f2 = E->get(); if (f2.points_over.size() == 0) { - faces.move_to_front(E->get()); + faces.move_to_front(E); } } @@ -336,19 +336,19 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ Map<Edge, RetFaceConnect> ret_edges; List<Geometry3D::MeshData::Face> ret_faces; - for (List<Face>::Element *E = faces.front(); E; E = E->next()) { + for (const Face &E : faces) { Geometry3D::MeshData::Face f; - f.plane = E->get().plane; + f.plane = E.plane; for (int i = 0; i < 3; i++) { - f.indices.push_back(E->get().vertices[i]); + f.indices.push_back(E.vertices[i]); } List<Geometry3D::MeshData::Face>::Element *F = ret_faces.push_back(f); for (int i = 0; i < 3; i++) { - uint32_t a = E->get().vertices[i]; - uint32_t b = E->get().vertices[(i + 1) % 3]; + uint32_t a = E.vertices[i]; + uint32_t b = E.vertices[(i + 1) % 3]; Edge e(a, b); Map<Edge, RetFaceConnect>::Element *G = ret_edges.find(e); @@ -439,8 +439,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ r_mesh.faces.resize(ret_faces.size()); int idx = 0; - for (List<Geometry3D::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) { - r_mesh.faces.write[idx++] = E->get(); + for (const Geometry3D::MeshData::Face &E : ret_faces) { + r_mesh.faces.write[idx++] = E; } r_mesh.edges.resize(ret_edges.size()); idx = 0; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 903d5951a8..bf06c848c5 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -32,9 +32,9 @@ #include "core/templates/sort_array.h" -int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) { - if (p_depth > max_depth) { - max_depth = p_depth; +int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc) { + if (p_depth > r_max_depth) { + r_max_depth = p_depth; } if (p_size == 1) { @@ -70,10 +70,10 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in } break; } - int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, max_depth, max_alloc); - int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, max_depth, max_alloc); + int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, r_max_depth, r_max_alloc); + int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, r_max_depth, r_max_alloc); - int index = max_alloc++; + int index = r_max_alloc++; BVH *_new = &p_bvh[index]; _new->aabb = aabb; _new->center = aabb.position + aabb.size * 0.5; diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index e2db5918e3..c6ba39be94 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -359,9 +359,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { //must be alphabetically sorted for hash to compute names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - ClassInfo *t = classes.getptr(E->get()); - ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E->get()) + "'."); + for (const StringName &E : names) { + ClassInfo *t = classes.getptr(E); + ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E) + "'."); if (t->api != p_api || !t->exposed) { continue; } @@ -388,8 +388,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - MethodBind *mb = t->method_map[F->get()]; + for (const StringName &F : snames) { + MethodBind *mb = t->method_map[F]; hash = hash_djb2_one_64(mb->get_name().hash(), hash); hash = hash_djb2_one_64(mb->get_argument_count(), hash); hash = hash_djb2_one_64(mb->get_argument_type(-1), hash); //return @@ -426,9 +426,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - hash = hash_djb2_one_64(F->get().hash(), hash); - hash = hash_djb2_one_64(t->constant_map[F->get()], hash); + for (const StringName &F : snames) { + hash = hash_djb2_one_64(F.hash(), hash); + hash = hash_djb2_one_64(t->constant_map[F], hash); } } @@ -444,9 +444,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - MethodInfo &mi = t->signal_map[F->get()]; - hash = hash_djb2_one_64(F->get().hash(), hash); + for (const StringName &F : snames) { + MethodInfo &mi = t->signal_map[F]; + hash = hash_djb2_one_64(F.hash(), hash); for (int i = 0; i < mi.arguments.size(); i++) { hash = hash_djb2_one_64(mi.arguments[i].type, hash); } @@ -465,23 +465,23 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - PropertySetGet *psg = t->property_setget.getptr(F->get()); + for (const StringName &F : snames) { + PropertySetGet *psg = t->property_setget.getptr(F); ERR_FAIL_COND_V(!psg, 0); - hash = hash_djb2_one_64(F->get().hash(), hash); + hash = hash_djb2_one_64(F.hash(), hash); hash = hash_djb2_one_64(psg->setter.hash(), hash); hash = hash_djb2_one_64(psg->getter.hash(), hash); } } //property list - for (List<PropertyInfo>::Element *F = t->property_list.front(); F; F = F->next()) { - hash = hash_djb2_one_64(F->get().name.hash(), hash); - hash = hash_djb2_one_64(F->get().type, hash); - hash = hash_djb2_one_64(F->get().hint, hash); - hash = hash_djb2_one_64(F->get().hint_string.hash(), hash); - hash = hash_djb2_one_64(F->get().usage, hash); + for (const PropertyInfo &F : t->property_list) { + hash = hash_djb2_one_64(F.name.hash(), hash); + hash = hash_djb2_one_64(F.type, hash); + hash = hash_djb2_one_64(F.hint, hash); + hash = hash_djb2_one_64(F.hint_string.hash(), hash); + hash = hash_djb2_one_64(F.usage, hash); } } @@ -619,16 +619,16 @@ void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_met #ifdef DEBUG_METHODS_ENABLED - for (List<MethodInfo>::Element *E = type->virtual_methods.front(); E; E = E->next()) { - p_methods->push_back(E->get()); + for (const MethodInfo &E : type->virtual_methods) { + p_methods->push_back(E); } - for (List<StringName>::Element *E = type->method_order.front(); E; E = E->next()) { - if (p_exclude_from_properties && type->methods_in_properties.has(E->get())) { + for (const StringName &E : type->method_order) { + if (p_exclude_from_properties && type->methods_in_properties.has(E)) { continue; } - MethodBind *method = type->method_map.get(E->get()); + MethodBind *method = type->method_map.get(E); MethodInfo minfo = info_from_bind(method); p_methods->push_back(minfo); @@ -763,8 +763,8 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List<String> while (type) { #ifdef DEBUG_METHODS_ENABLED - for (List<StringName>::Element *E = type->constant_order.front(); E; E = E->next()) { - p_constants->push_back(E->get()); + for (const StringName &E : type->constant_order) { + p_constants->push_back(E); } #else const StringName *K = nullptr; @@ -1073,13 +1073,14 @@ void ClassDB::get_property_list(const StringName &p_class, List<PropertyInfo> *p ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { - for (List<PropertyInfo>::Element *E = check->property_list.front(); E; E = E->next()) { + for (const PropertyInfo &pi : check->property_list) { if (p_validator) { - PropertyInfo pi = E->get(); - p_validator->_validate_property(pi); - p_list->push_back(pi); + // Making a copy as we may modify it. + PropertyInfo pi_mut = pi; + p_validator->_validate_property(pi_mut); + p_list->push_back(pi_mut); } else { - p_list->push_back(E->get()); + p_list->push_back(pi); } } @@ -1429,8 +1430,8 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { - for (List<MethodInfo>::Element *E = check->virtual_methods.front(); E; E = E->next()) { - p_methods->push_back(E->get()); + for (const MethodInfo &E : check->virtual_methods) { + p_methods->push_back(E); } if (p_no_inheritance) { @@ -1496,6 +1497,10 @@ void ClassDB::get_resource_base_extensions(List<String> *p_extensions) { } } +bool ClassDB::is_resource_extension(const StringName &p_extension) { + return resource_base_extensions.has(p_extension); +} + void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p_extensions) { const StringName *K = nullptr; @@ -1530,11 +1535,11 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con if (c) { List<PropertyInfo> plist; c->get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) { - if (!default_values[p_class].has(E->get().name)) { - Variant v = c->get(E->get().name); - default_values[p_class][E->get().name] = v; + for (const PropertyInfo &E : plist) { + if (E.usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) { + if (!default_values[p_class].has(E.name)) { + Variant v = c->get(E.name); + default_values[p_class][E.name] = v; } } } diff --git a/core/object/class_db.h b/core/object/class_db.h index fd574fd2d8..3a84e9ab38 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -396,6 +396,7 @@ public: static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class); static void get_resource_base_extensions(List<String> *p_extensions); static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions); + static bool is_resource_extension(const StringName &p_extension); static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback); diff --git a/core/object/object.cpp b/core/object/object.cpp index 0644012318..d552d5e5e0 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -922,11 +922,11 @@ Variant Object::get_script() const { return script; } -bool Object::has_meta(const String &p_name) const { +bool Object::has_meta(const StringName &p_name) const { return metadata.has(p_name); } -void Object::set_meta(const String &p_name, const Variant &p_value) { +void Object::set_meta(const StringName &p_name, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { metadata.erase(p_name); return; @@ -935,12 +935,12 @@ void Object::set_meta(const String &p_name, const Variant &p_value) { metadata[p_name] = p_value; } -Variant Object::get_meta(const String &p_name) const { +Variant Object::get_meta(const StringName &p_name) const { ERR_FAIL_COND_V_MSG(!metadata.has(p_name), Variant(), "The object does not have any 'meta' values with the key '" + p_name + "'."); return metadata[p_name]; } -void Object::remove_meta(const String &p_name) { +void Object::remove_meta(const StringName &p_name) { metadata.erase(p_name); } @@ -964,23 +964,23 @@ Array Object::_get_method_list_bind() const { return ret; } -Vector<String> Object::_get_meta_list_bind() const { - Vector<String> _metaret; +Vector<StringName> Object::_get_meta_list_bind() const { + Vector<StringName> _metaret; List<Variant> keys; metadata.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - _metaret.push_back(E->get()); + for (const Variant &E : keys) { + _metaret.push_back(E); } return _metaret; } -void Object::get_meta_list(List<String> *p_list) const { +void Object::get_meta_list(List<StringName> *p_list) const { List<Variant> keys; metadata.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (const Variant &E : keys) { + p_list->push_back(E); } } @@ -1184,8 +1184,8 @@ Array Object::_get_signal_list() const { get_signal_list(&signal_list); Array ret; - for (List<MethodInfo>::Element *E = signal_list.front(); E; E = E->next()) { - ret.push_back(Dictionary(E->get())); + for (const MethodInfo &E : signal_list) { + ret.push_back(Dictionary(E)); } return ret; @@ -1197,8 +1197,7 @@ Array Object::_get_signal_connection_list(const String &p_signal) const { Array ret; - for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { - Connection &c = E->get(); + for (const Connection &c : conns) { if (c.signal.get_name() == p_signal) { ret.push_back(c); } @@ -1297,8 +1296,8 @@ int Object::get_persistent_signal_connection_count() const { } void Object::get_signals_connected_to_this(List<Connection> *p_connections) const { - for (const List<Connection>::Element *E = connections.front(); E; E = E->next()) { - p_connections->push_back(E->get()); + for (const Connection &E : connections) { + p_connections->push_back(E); } } @@ -1500,9 +1499,9 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - _clear_internal_resource_paths(E->get()); - _clear_internal_resource_paths(d[E->get()]); + for (const Variant &E : keys) { + _clear_internal_resource_paths(E); + _clear_internal_resource_paths(d[E]); } } break; default: { @@ -1531,8 +1530,8 @@ void Object::clear_internal_resource_paths() { get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - _clear_internal_resource_paths(get(E->get().name)); + for (const PropertyInfo &E : pinfo) { + _clear_internal_resource_paths(get(E.name)); } } @@ -1666,12 +1665,12 @@ void Object::get_translatable_strings(List<String> *p_strings) const { List<PropertyInfo> plist; get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_INTERNATIONALIZED)) { + for (const PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_INTERNATIONALIZED)) { continue; } - String text = get(E->get().name); + String text = get(E.name); if (text == "") { continue; diff --git a/core/object/object.h b/core/object/object.h index 296e07983d..b7d0916a54 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -615,7 +615,7 @@ protected: return &_class_name; } - Vector<String> _get_meta_list_bind() const; + Vector<StringName> _get_meta_list_bind() const; Array _get_property_list_bind() const; Array _get_method_list_bind() const; @@ -743,11 +743,11 @@ public: /* SCRIPT */ - bool has_meta(const String &p_name) const; - void set_meta(const String &p_name, const Variant &p_value); - void remove_meta(const String &p_name); - Variant get_meta(const String &p_name) const; - void get_meta_list(List<String> *p_list) const; + bool has_meta(const StringName &p_name) const; + void set_meta(const StringName &p_name, const Variant &p_value); + void remove_meta(const StringName &p_name); + Variant get_meta(const StringName &p_name) const; + void get_meta_list(List<StringName> *p_list) const; #ifdef TOOLS_ENABLED void set_edited(bool p_edited); diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 626a7413e7..0fb8c7350c 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -63,8 +63,8 @@ Array Script::_get_script_property_list() { Array ret; List<PropertyInfo> list; get_script_property_list(&list); - for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) { - ret.append(E->get().operator Dictionary()); + for (const PropertyInfo &E : list) { + ret.append(E.operator Dictionary()); } return ret; } @@ -73,8 +73,8 @@ Array Script::_get_script_method_list() { Array ret; List<MethodInfo> list; get_script_method_list(&list); - for (List<MethodInfo>::Element *E = list.front(); E; E = E->next()) { - ret.append(E->get().operator Dictionary()); + for (const MethodInfo &E : list) { + ret.append(E.operator Dictionary()); } return ret; } @@ -83,8 +83,8 @@ Array Script::_get_script_signal_list() { Array ret; List<MethodInfo> list; get_script_signal_list(&list); - for (List<MethodInfo>::Element *E = list.front(); E; E = E->next()) { - ret.append(E->get().operator Dictionary()); + for (const MethodInfo &E : list) { + ret.append(E.operator Dictionary()); } return ret; } @@ -257,8 +257,8 @@ void ScriptServer::get_global_class_list(List<StringName> *r_global_classes) { classes.push_back(*K); } classes.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - r_global_classes->push_back(E->get()); + for (const StringName &E : classes) { + r_global_classes->push_back(E); } } @@ -266,12 +266,12 @@ void ScriptServer::save_global_classes() { List<StringName> gc; get_global_class_list(&gc); Array gcarr; - for (List<StringName>::Element *E = gc.front(); E; E = E->next()) { + for (const StringName &E : gc) { Dictionary d; - d["class"] = E->get(); - d["language"] = global_classes[E->get()].language; - d["path"] = global_classes[E->get()].path; - d["base"] = global_classes[E->get()].base; + d["class"] = E; + d["language"] = global_classes[E].language; + d["path"] = global_classes[E].path; + d["base"] = global_classes[E].base; gcarr.push_back(d); } @@ -297,10 +297,10 @@ void ScriptServer::save_global_classes() { void ScriptInstance::get_property_state(List<Pair<StringName, Variant>> &state) { List<PropertyInfo> pinfo; get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE) { + for (const PropertyInfo &E : pinfo) { + if (E.usage & PROPERTY_USAGE_STORAGE) { Pair<StringName, Variant> p; - p.first = E->get().name; + p.first = E.name; if (get(p.first, p.second)) { state.push_back(p); } @@ -430,16 +430,16 @@ bool PlaceHolderScriptInstance::get(const StringName &p_name, Variant &r_ret) co void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { if (script->is_placeholder_fallback_enabled()) { - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - p_properties->push_back(E->get()); + for (const PropertyInfo &E : properties) { + p_properties->push_back(E); } } else { - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - PropertyInfo pinfo = E->get(); + for (const PropertyInfo &E : properties) { + PropertyInfo pinfo = E; if (!values.has(pinfo.name)) { pinfo.usage |= PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE; } - p_properties->push_back(E->get()); + p_properties->push_back(E); } } } @@ -489,11 +489,11 @@ bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const { void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, const Map<StringName, Variant> &p_values) { Set<StringName> new_values; - for (const List<PropertyInfo>::Element *E = p_properties.front(); E; E = E->next()) { - StringName n = E->get().name; + for (const PropertyInfo &E : p_properties) { + StringName n = E.name; new_values.insert(n); - if (!values.has(n) || values[n].get_type() != E->get().type) { + if (!values.has(n) || values[n].get_type() != E.type) { if (p_values.has(n)) { values[n] = p_values[n]; } @@ -511,7 +511,7 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c Variant defval; if (script->get_property_default_value(E->key(), defval)) { //remove because it's the same as the default value - if (defval == E->get()) { + if (defval == E) { to_remove.push_back(E->key()); } } @@ -542,8 +542,8 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name, } bool found = false; - for (const List<PropertyInfo>::Element *F = properties.front(); F; F = F->next()) { - if (F->get().name == p_name) { + for (const PropertyInfo &F : properties) { + if (F.name == p_name) { found = true; break; } diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index 0532b2ae40..adf068eb2f 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -39,11 +39,15 @@ void UndoRedo::_discard_redo() { } for (int i = current_action + 1; i < actions.size(); i++) { - for (List<Operation>::Element *E = actions.write[i].do_ops.front(); E; E = E->next()) { - if (E->get().type == Operation::TYPE_REFERENCE) { - Object *obj = ObjectDB::get_instance(E->get().object); - if (obj) { - memdelete(obj); + for (Operation &E : actions.write[i].do_ops) { + if (E.type == Operation::TYPE_REFERENCE) { + if (E.ref.is_valid()) { + E.ref.unref(); + } else { + Object *obj = ObjectDB::get_instance(E.object); + if (obj) { + memdelete(obj); + } } } } @@ -240,11 +244,15 @@ void UndoRedo::_pop_history_tail() { return; } - for (List<Operation>::Element *E = actions.write[0].undo_ops.front(); E; E = E->next()) { - if (E->get().type == Operation::TYPE_REFERENCE) { - Object *obj = ObjectDB::get_instance(E->get().object); - if (obj) { - memdelete(obj); + for (Operation &E : actions.write[0].undo_ops) { + if (E.type == Operation::TYPE_REFERENCE) { + if (E.ref.is_valid()) { + E.ref.unref(); + } else { + Object *obj = ObjectDB::get_instance(E.object); + if (obj) { + memdelete(obj); + } } } } diff --git a/core/os/os.cpp b/core/os/os.cpp index 535eee4797..f7af74da3e 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -110,6 +110,10 @@ void OS::printerr(const char *p_format, ...) { va_end(argp); } +void OS::alert(const String &p_alert, const String &p_title) { + fprintf(stderr, "%s: %s\n", p_title.utf8().get_data(), p_alert.utf8().get_data()); +} + void OS::set_low_processor_usage_mode(bool p_enabled) { low_processor_usage_mode = p_enabled; } diff --git a/core/os/os.h b/core/os/os.h index 301718a8b3..fcb195afe1 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -120,6 +120,8 @@ public: virtual void open_midi_inputs(); virtual void close_midi_inputs(); + virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; } virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; } virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; } diff --git a/core/os/pool_allocator.h b/core/os/pool_allocator.h index 15e50dac90..49f433ba97 100644 --- a/core/os/pool_allocator.h +++ b/core/os/pool_allocator.h @@ -37,7 +37,7 @@ @author Juan Linietsky <reduzio@gmail.com> * Generic Pool Allocator. * This is a generic memory pool allocator, with locking, compacting and alignment. (@TODO alignment) - * It used as a standard way to manage alloction in a specific region of memory, such as texture memory, + * It used as a standard way to manage allocation in a specific region of memory, such as texture memory, * audio sample memory, or just any kind of memory overall. * (@TODO) abstraction should be greater, because in many platforms, you need to manage a nonreachable memory. */ diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index eb37267546..3d1cb4a8e1 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -56,6 +56,7 @@ #include "core/io/pck_packer.h" #include "core/io/resource_format_binary.h" #include "core/io/resource_importer.h" +#include "core/io/resource_uid.h" #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/translation_loader_po.h" @@ -102,6 +103,8 @@ static NativeExtensionManager *native_extension_manager = nullptr; extern void register_global_constants(); extern void unregister_global_constants(); +static ResourceUID *resource_uid = nullptr; + void register_core_types() { //consistency check static_assert(sizeof(Callable) <= 16); @@ -225,6 +228,10 @@ void register_core_types() { GDREGISTER_VIRTUAL_CLASS(NativeExtensionManager); + GDREGISTER_VIRTUAL_CLASS(ResourceUID); + + resource_uid = memnew(ResourceUID); + native_extension_manager = memnew(NativeExtensionManager); ip = IP::create(); @@ -286,10 +293,11 @@ void register_core_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("EngineDebugger", _EngineDebugger::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("NativeExtensionManager", NativeExtensionManager::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceUID", ResourceUID::get_singleton())); } void register_core_extensions() { - //harcoded for now + // Hardcoded for now. if (ProjectSettings::get_singleton()->has_setting("native_extensions/paths")) { Vector<String> paths = ProjectSettings::get_singleton()->get("native_extensions/paths"); for (int i = 0; i < paths.size(); i++) { @@ -304,6 +312,8 @@ void unregister_core_types() { native_extension_manager->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_CORE); memdelete(native_extension_manager); + + memdelete(resource_uid); memdelete(_resource_loader); memdelete(_resource_saver); memdelete(_os); diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index d3afa7b4dd..5fae13779e 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -240,19 +240,26 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const { common_parent--; Vector<StringName> relpath; + relpath.resize(src_dirs.size() + dst_dirs.size() + 1); - for (int i = src_dirs.size() - 1; i > common_parent; i--) { - relpath.push_back(".."); + StringName *relpath_ptr = relpath.ptrw(); + + int path_size = 0; + StringName back_str(".."); + for (int i = common_parent + 1; i < src_dirs.size(); i++) { + relpath_ptr[path_size++] = back_str; } for (int i = common_parent + 1; i < dst_dirs.size(); i++) { - relpath.push_back(dst_dirs[i]); + relpath_ptr[path_size++] = dst_dirs[i]; } - if (relpath.size() == 0) { - relpath.push_back("."); + if (path_size == 0) { + relpath_ptr[path_size++] = "."; } + relpath.resize(path_size); + return NodePath(relpath, p_np.get_subnames(), false); } diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp index 268562d971..5863bd1c46 100644 --- a/core/string/optimized_translation.cpp +++ b/core/string/optimized_translation.cpp @@ -66,9 +66,9 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { int total_compression_size = 0; int total_string_size = 0; - for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { + for (const StringName &E : keys) { //hash string - CharString cs = E->get().operator String().utf8(); + CharString cs = E.operator String().utf8(); uint32_t h = hash(0, cs.get_data()); Pair<int, CharString> p; p.first = idx; @@ -76,7 +76,7 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { buckets.write[h % size].push_back(p); //compress string - CharString src_s = p_from->get_message(E->get()).operator String().utf8(); + CharString src_s = p_from->get_message(E).operator String().utf8(); CompressedString ps; ps.orig_len = src_s.size(); ps.offset = total_compression_size; diff --git a/core/string/translation.cpp b/core/string/translation.cpp index 678f8fb207..19d23fd375 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -841,8 +841,8 @@ Vector<String> Translation::_get_message_list() const { void Translation::_set_messages(const Dictionary &p_messages) { List<Variant> keys; p_messages.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - translation_map[E->get()] = p_messages[E->get()]; + for (const Variant &E : keys) { + translation_map[E] = p_messages[E]; } } diff --git a/core/string/translation_po.cpp b/core/string/translation_po.cpp index f9b4e661e4..1da00aa54b 100644 --- a/core/string/translation_po.cpp +++ b/core/string/translation_po.cpp @@ -47,8 +47,7 @@ void TranslationPO::print_translation_map() { List<StringName> context_l; translation_map.get_key_list(&context_l); - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - StringName ctx = E->get(); + for (const StringName &ctx : context_l) { file->store_line(" ===== Context: " + String::utf8(String(ctx).utf8()) + " ===== "); const HashMap<StringName, Vector<StringName>> &inner_map = translation_map[ctx]; @@ -74,8 +73,7 @@ Dictionary TranslationPO::_get_messages() const { List<StringName> context_l; translation_map.get_key_list(&context_l); - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - StringName ctx = E->get(); + for (const StringName &ctx : context_l) { const HashMap<StringName, Vector<StringName>> &id_str_map = translation_map[ctx]; Dictionary d2; @@ -98,8 +96,7 @@ void TranslationPO::_set_messages(const Dictionary &p_messages) { List<Variant> context_l; p_messages.get_key_list(&context_l); - for (List<Variant>::Element *E = context_l.front(); E; E = E->next()) { - StringName ctx = E->get(); + for (const Variant &ctx : context_l) { const Dictionary &id_str_map = p_messages[ctx]; HashMap<StringName, Vector<StringName>> temp_map; @@ -121,8 +118,8 @@ Vector<String> TranslationPO::_get_message_list() const { get_message_list(&msgs); Vector<String> v; - for (List<StringName>::Element *E = msgs.front(); E; E = E->next()) { - v.push_back(E->get()); + for (const StringName &E : msgs) { + v.push_back(E); } return v; @@ -281,13 +278,13 @@ void TranslationPO::get_message_list(List<StringName> *r_messages) const { List<StringName> context_l; translation_map.get_key_list(&context_l); - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - if (String(E->get()) != "") { + for (const StringName &E : context_l) { + if (String(E) != "") { continue; } List<StringName> msgid_l; - translation_map[E->get()].get_key_list(&msgid_l); + translation_map[E].get_key_list(&msgid_l); for (List<StringName>::Element *E2 = msgid_l.front(); E2; E2 = E2->next()) { r_messages->push_back(E2->get()); @@ -300,8 +297,8 @@ int TranslationPO::get_message_count() const { translation_map.get_key_list(&context_l); int count = 0; - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - count += translation_map[E->get()].size(); + for (const StringName &E : context_l) { + count += translation_map[E].size(); } return count; } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 4cd2915ffa..7beecdb6b5 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3421,11 +3421,8 @@ String String::format(const Variant &values, String placeholder) const { List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - String key = E->get(); - String val = d[E->get()]; - - new_string = new_string.replace(placeholder.replace("_", key), val); + for (const Variant &key : keys) { + new_string = new_string.replace(placeholder.replace("_", key), d[key]); } } else { ERR_PRINT(String("Invalid type: use Array or Dictionary.").ascii().get_data()); diff --git a/core/templates/command_queue_mt.h b/core/templates/command_queue_mt.h index acc46da0d5..519a896ffc 100644 --- a/core/templates/command_queue_mt.h +++ b/core/templates/command_queue_mt.h @@ -321,7 +321,7 @@ class CommandQueueMT { DECL_CMD(0) SPACE_SEP_LIST(DECL_CMD, 15) - /* comands that return */ + // Commands that return. DECL_CMD_RET(0) SPACE_SEP_LIST(DECL_CMD_RET, 15) diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index 4f5c74ca46..8d139551ef 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -101,7 +101,7 @@ class RID_Alloc : public RID_AllocBase { //initialize for (uint32_t i = 0; i < elements_in_chunk; i++) { - //dont initialize chunk + // Don't initialize chunk. validator_chunks[chunk_count][i] = 0xFFFFFFFF; free_list_chunks[chunk_count][i] = alloc_count + i; } diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index ca6f3d615e..f487e718f4 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -407,8 +407,8 @@ Array Signal::get_connections() const { object->get_signal_connection_list(name, &connections); Array arr; - for (List<Object::Connection>::Element *E = connections.front(); E; E = E->next()) { - arr.push_back(E->get()); + for (const Object::Connection &E : connections) { + arr.push_back(E); } return arr; } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index badb5ba103..97a1b4c02a 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1681,10 +1681,10 @@ String Variant::stringify(List<const void *> &stack) const { Vector<_VariantStrPair> pairs; - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (const Variant &E : keys) { _VariantStrPair sp; - sp.key = E->get().stringify(stack); - sp.value = d[E->get()].stringify(stack); + sp.key = E.stringify(stack); + sp.value = d[E].stringify(stack); pairs.push_back(sp); } diff --git a/core/variant/variant.h b/core/variant/variant.h index 6d1b4da9e8..4dc706e853 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -253,7 +253,7 @@ private: true, //PACKED_COLOR_ARRAY, }; - if (unlikely(needs_deinit[type])) { //make it fast for types that dont need deinit + if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit. _clear_internal(); } type = NIL; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 65ad27d0b4..f8538f71d3 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -750,6 +750,42 @@ struct _VariantCall { return 0; } + static PackedInt32Array func_PackedByteArray_decode_s32_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedInt32Array dest; + dest.resize(size / sizeof(int32_t)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedInt64Array func_PackedByteArray_decode_s64_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedInt64Array dest; + dest.resize(size / sizeof(int64_t)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedFloat32Array func_PackedByteArray_decode_float_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedFloat32Array dest; + dest.resize(size / sizeof(float)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedFloat64Array func_PackedByteArray_decode_double_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedFloat64Array dest; + dest.resize(size / sizeof(double)); + memcpy(dest.ptrw(), r, size); + return dest; + } + static void func_PackedByteArray_encode_u8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { uint64_t size = p_instance->size(); ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1); @@ -1088,8 +1124,8 @@ bool Variant::has_builtin_method_return_value(Variant::Type p_type, const String void Variant::get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list) { ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); - for (List<StringName>::Element *E = builtin_method_names[p_type].front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (const StringName &E : builtin_method_names[p_type]) { + p_list->push_back(E); } } @@ -1152,12 +1188,12 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { obj->get_method_list(p_list); } } else { - for (List<StringName>::Element *E = builtin_method_names[type].front(); E; E = E->next()) { - const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E->get()); + for (const StringName &E : builtin_method_names[type]) { + const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E); ERR_CONTINUE(!method); MethodInfo mi; - mi.name = E->get(); + mi.name = E; //return type if (method->has_return_type) { @@ -1824,6 +1860,11 @@ static void _register_variant_builtin_methods() { bind_function(PackedByteArray, decode_var, _VariantCall::func_PackedByteArray_decode_var, sarray("byte_offset", "allow_objects"), varray(false)); bind_function(PackedByteArray, decode_var_size, _VariantCall::func_PackedByteArray_decode_var_size, sarray("byte_offset", "allow_objects"), varray(false)); + bind_function(PackedByteArray, to_int32_array, _VariantCall::func_PackedByteArray_decode_s32_array, sarray(), varray()); + bind_function(PackedByteArray, to_int64_array, _VariantCall::func_PackedByteArray_decode_s64_array, sarray(), varray()); + bind_function(PackedByteArray, to_float32_array, _VariantCall::func_PackedByteArray_decode_float_array, sarray(), varray()); + bind_function(PackedByteArray, to_float64_array, _VariantCall::func_PackedByteArray_decode_double_array, sarray(), varray()); + bind_functionnc(PackedByteArray, encode_u8, _VariantCall::func_PackedByteArray_encode_u8, sarray("byte_offset", "value"), varray()); bind_functionnc(PackedByteArray, encode_s8, _VariantCall::func_PackedByteArray_encode_s8, sarray("byte_offset", "value"), varray()); bind_functionnc(PackedByteArray, encode_u16, _VariantCall::func_PackedByteArray_encode_u16, sarray("byte_offset", "value"), varray()); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index f9c604fe3e..50c48fd386 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1586,8 +1586,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str List<PropertyInfo> props; obj->get_property_list(&props); bool first = true; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) { + for (const PropertyInfo &E : props) { + if (E.usage & PROPERTY_USAGE_STORAGE || E.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) { //must be serialized if (first) { @@ -1596,8 +1596,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, ","); } - p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":"); - write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); + p_store_string_func(p_store_string_ud, "\"" + E.name + "\":"); + write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); } } @@ -1615,7 +1615,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "{\n"); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { /* - if (!_check_type(dict[E->get()])) + if (!_check_type(dict[E])) continue; */ write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index de1deace63..ae3c7685fd 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -1093,9 +1093,9 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); List<Variant> keys; dic->get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - if (E->get().get_type() == Variant::STRING) { - p_list->push_back(PropertyInfo(Variant::STRING, E->get())); + for (const Variant &E : keys) { + if (E.get_type() == Variant::STRING) { + p_list->push_back(PropertyInfo(Variant::STRING, E)); } } } else if (type == OBJECT) { @@ -1106,10 +1106,10 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { } else { List<StringName> members; get_member_list(type, &members); - for (List<StringName>::Element *E = members.front(); E; E = E->next()) { + for (const StringName &E : members) { PropertyInfo pi; - pi.name = E->get(); - pi.type = get_member_type(type, E->get()); + pi.name = E; + pi.type = get_member_type(type, E); p_list->push_back(pi); } } diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 1f69e81d99..64f07e075e 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -1397,8 +1397,8 @@ uint32_t Variant::get_utility_function_hash(const StringName &p_name) { } void Variant::get_utility_function_list(List<StringName> *r_functions) { - for (List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) { - r_functions->push_back(E->get()); + for (const StringName &E : utility_function_name_table) { + r_functions->push_back(E); } } diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index d0bd517050..c0e8b76969 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1259,6 +1259,8 @@ <member name="ResourceSaver" type="ResourceSaver" setter="" getter=""> The [ResourceSaver] singleton. </member> + <member name="ResourceUID" type="ResourceUID" setter="" getter=""> + </member> <member name="TextServerManager" type="TextServerManager" setter="" getter=""> The [TextServerManager] singleton. </member> diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml index cc7f7072b9..327785a3b6 100644 --- a/doc/classes/AStar.xml +++ b/doc/classes/AStar.xml @@ -33,7 +33,7 @@ [/csharp] [/codeblocks] [method _estimate_cost] should return a lower bound of the distance, i.e. [code]_estimate_cost(u, v) <= _compute_cost(u, v)[/code]. This serves as a hint to the algorithm because the custom [code]_compute_cost[/code] might be computation-heavy. If this is not the case, make [method _estimate_cost] return the same value as [method _compute_cost] to provide the algorithm with the most accurate information. - If the default [method _estimate_cost] and [method _compute_cost] methods are used, or if the supplied [method _estimate_cost] method returns a lower bound of the cost, then the paths returned by A* will be the lowest cost paths. Here, the cost of a path equals to the sum of the [method _compute_cost] results of all segments in the path multiplied by the [code]weight_scale[/code]s of the end points of the respective segments. If the default methods are used and the [code]weight_scale[/code]s of all points are set to [code]1.0[/code], then this equals to the sum of Euclidean distances of all segments in the path. + If the default [method _estimate_cost] and [method _compute_cost] methods are used, or if the supplied [method _estimate_cost] method returns a lower bound of the cost, then the paths returned by A* will be the lowest-cost paths. Here, the cost of a path equals the sum of the [method _compute_cost] results of all segments in the path multiplied by the [code]weight_scale[/code]s of the endpoints of the respective segments. If the default methods are used and the [code]weight_scale[/code]s of all points are set to [code]1.0[/code], then this equals the sum of Euclidean distances of all segments in the path. </description> <tutorials> </tutorials> diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index 894e784397..4d192f8e97 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -616,7 +616,7 @@ <argument index="1" name="path" type="NodePath"> </argument> <description> - Sets the path of a track. Paths must be valid scene-tree paths to a node, and must be specified starting from the parent node of the node that will reproduce the animation. Tracks that control properties or bones must append their name after the path, separated by [code]":"[/code]. + Sets the path of a track. Paths must be valid scene-tree paths to a node and must be specified starting from the parent node of the node that will reproduce the animation. Tracks that control properties or bones must append their name after the path, separated by [code]":"[/code]. For example, [code]"character/skeleton:ankle"[/code] or [code]"character/mesh:transform/local"[/code]. </description> </method> diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index af7d8d73e8..63460b70c5 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -7,7 +7,7 @@ Note: When linked with an [AnimationPlayer], several properties and methods of the corresponding [AnimationPlayer] will not function as expected. Playback and transitions should be handled using only the [AnimationTree] and its constituent [AnimationNode](s). The [AnimationPlayer] node should be used solely for adding, deleting, and editing animations. </description> <tutorials> - <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> + <link title="Using AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link> <link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link> </tutorials> <methods> @@ -24,7 +24,7 @@ <return type="Transform3D"> </return> <description> - Retrieve the motion of the [member root_motion_track] as a [Transform3D] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_TRANSFORM3D], returns an identity transformation. + Retrieve the motion of the [member root_motion_track] as a [Transform3D] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_TRANSFORM3D], returns an identity transformation. See also [member root_motion_track] and [RootMotionView]. </description> </method> <method name="rename_parameter"> @@ -50,7 +50,7 @@ </member> <member name="root_motion_track" type="NodePath" setter="set_root_motion_track" getter="get_root_motion_track" default="NodePath("")"> The path to the Animation track used for root motion. Paths must be valid scene-tree paths to a node, and must be specified starting from the parent node of the node that will reproduce the animation. To specify a track that controls properties or bones, append its name after the path, separated by [code]":"[/code]. For example, [code]"character/skeleton:ankle"[/code] or [code]"character/mesh:transform/local"[/code]. - If the track has type [constant Animation.TYPE_TRANSFORM3D], the transformation will be cancelled visually, and the animation will appear to stay in place. + If the track has type [constant Animation.TYPE_TRANSFORM3D], the transformation will be cancelled visually, and the animation will appear to stay in place. See also [method get_root_motion_transform] and [RootMotionView]. </member> <member name="tree_root" type="AnimationNode" setter="set_tree_root" getter="get_tree_root"> The root animation node of this [AnimationTree]. See [AnimationNode]. diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index f52c810ad2..cf2e7044af 100644 --- a/doc/classes/Area2D.xml +++ b/doc/classes/Area2D.xml @@ -34,7 +34,7 @@ </argument> <description> If [code]true[/code], the given area overlaps the Area2D. - [b]Note:[/b] The result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead. + [b]Note:[/b] The result of this test is not immediate after moving objects. For performance, the list of overlaps is updated once per frame and before the physics step. Consider using signals instead. </description> </method> <method name="overlaps_body" qualifiers="const"> @@ -45,7 +45,7 @@ <description> If [code]true[/code], the given physics body overlaps the Area2D. [b]Note:[/b] The result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead. - The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics bodies themselves, they register their tiles with collision shapes as a virtual physics body). </description> </method> </methods> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 543ec096c7..1ed7250adc 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Array" version="4.0"> <brief_description> - Generic array datatype. + A generic array datatype. </brief_description> <description> - Generic array which can contain several elements of any type, accessible by a numerical index starting at 0. Negative indices can be used to count from the back, like in Python (-1 is the last element, -2 the second to last, etc.). + A generic array that can contain several elements of any type, accessible by a numerical index starting at 0. Negative indices can be used to count from the back, like in Python (-1 is the last element, -2 is the second to last, etc.). [b]Example:[/b] [codeblocks] [gdscript] @@ -39,7 +39,7 @@ [/csharp] [/codeblocks] [b]Note:[/b] Concatenating with the [code]+=[/code] operator will create a new array, which has a cost. If you want to append another array to an existing array, [method append_array] is more efficient. - [b]Note:[/b] Arrays are always passed by reference. To get a copy of an array which can be modified independently of the original array, use [method duplicate]. + [b]Note:[/b] Arrays are always passed by reference. To get a copy of an array that can be modified independently of the original array, use [method duplicate]. [b]Note:[/b] When declaring an array with [code]const[/code], the array itself can still be mutated by defining the values at individual indices or pushing/removing elements. Using [code]const[/code] will only prevent assigning the constant with another value after it was initialized. </description> <tutorials> diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 7fbf53c7d1..e3d2eb74ff 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -75,7 +75,7 @@ </argument> <description> Creates a new surface. - Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface. + Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines, or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface. The [code]arrays[/code] argument is an array of arrays. See [enum Mesh.ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant Mesh.ARRAY_INDEX] if it is used. </description> </method> diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index e8f4cb49b6..ac90b6950b 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -5,7 +5,7 @@ </brief_description> <description> Camera node for 2D scenes. It forces the screen (current layer) to scroll following this node. This makes it easier (and faster) to program scrollable scenes than manually changing the position of [CanvasItem]-based nodes. - This node is intended to be a simple helper to get things going quickly and it may happen that more functionality is desired to change how the camera works. To make your own custom camera node, inherit from [Node2D] and change the transform of the canvas by setting [member Viewport.canvas_transform] in [Viewport] (you can obtain the current [Viewport] by using [method Node.get_viewport]). + This node is intended to be a simple helper to get things going quickly, but more functionality may be desired to change how the camera works. To make your own custom camera node, inherit it from [Node2D] and change the transform of the canvas by setting [member Viewport.canvas_transform] in [Viewport] (you can obtain the current [Viewport] by using [method Node.get_viewport]). Note that the [Camera2D] node's [code]position[/code] doesn't represent the actual position of the screen, which may differ due to applied smoothing or limits. You can use [method get_camera_screen_center] to get the real position. </description> <tutorials> diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml index 0f0bfdc654..f74baa00a0 100644 --- a/doc/classes/Camera3D.xml +++ b/doc/classes/Camera3D.xml @@ -46,7 +46,7 @@ <return type="Array"> </return> <description> - Returns the camera's frustum planes in world-space units as an array of [Plane]s in the following order: near, far, left, top, right, bottom. Not to be confused with [member frustum_offset]. + Returns the camera's frustum planes in world space units as an array of [Plane]s in the following order: near, far, left, top, right, bottom. Not to be confused with [member frustum_offset]. </description> </method> <method name="is_position_behind" qualifiers="const"> @@ -92,7 +92,7 @@ <argument index="1" name="z_depth" type="float"> </argument> <description> - Returns the 3D point in worldspace that maps to the given 2D coordinate in the [Viewport] rectangle on a plane that is the given [code]z_depth[/code] distance into the scene away from the camera. + Returns the 3D point in world space that maps to the given 2D coordinate in the [Viewport] rectangle on a plane that is the given [code]z_depth[/code] distance into the scene away from the camera. </description> </method> <method name="project_ray_normal" qualifiers="const"> @@ -101,7 +101,7 @@ <argument index="0" name="screen_point" type="Vector2"> </argument> <description> - Returns a normal vector in worldspace, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. + Returns a normal vector in world space, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. </description> </method> <method name="project_ray_origin" qualifiers="const"> @@ -110,7 +110,7 @@ <argument index="0" name="screen_point" type="Vector2"> </argument> <description> - Returns a 3D position in worldspace, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. + Returns a 3D position in world space, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. </description> </method> <method name="set_cull_mask_bit"> @@ -136,7 +136,7 @@ <argument index="3" name="z_far" type="float"> </argument> <description> - Sets the camera projection to frustum mode (see [constant PROJECTION_FRUSTUM]), by specifying a [code]size[/code], an [code]offset[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world-space units. + Sets the camera projection to frustum mode (see [constant PROJECTION_FRUSTUM]), by specifying a [code]size[/code], an [code]offset[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units. </description> </method> <method name="set_orthogonal"> @@ -149,7 +149,7 @@ <argument index="2" name="z_far" type="float"> </argument> <description> - Sets the camera projection to orthogonal mode (see [constant PROJECTION_ORTHOGONAL]), by specifying a [code]size[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world-space units. (As a hint, 2D games often use this projection, with values specified in pixels.) + Sets the camera projection to orthogonal mode (see [constant PROJECTION_ORTHOGONAL]), by specifying a [code]size[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units. (As a hint, 2D games often use this projection, with values specified in pixels.) </description> </method> <method name="set_perspective"> @@ -162,7 +162,7 @@ <argument index="2" name="z_far" type="float"> </argument> <description> - Sets the camera projection to perspective mode (see [constant PROJECTION_PERSPECTIVE]), by specifying a [code]fov[/code] (field of view) angle in degrees, and the [code]z_near[/code] and [code]z_far[/code] clip planes in world-space units. + Sets the camera projection to perspective mode (see [constant PROJECTION_PERSPECTIVE]), by specifying a [code]fov[/code] (field of view) angle in degrees, and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units. </description> </method> <method name="unproject_position" qualifiers="const"> @@ -171,7 +171,7 @@ <argument index="0" name="world_point" type="Vector3"> </argument> <description> - Returns the 2D coordinate in the [Viewport] rectangle that maps to the given 3D point in worldspace. + Returns the 2D coordinate in the [Viewport] rectangle that maps to the given 3D point in world space. [b]Note:[/b] When using this to position GUI elements over a 3D viewport, use [method is_position_behind] to prevent them from appearing if the 3D point is behind the camera: [codeblock] # This code block is part of a script that inherits from Node3D. diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml index b0afbb201c..097bbc2de8 100644 --- a/doc/classes/CollisionObject2D.xml +++ b/doc/classes/CollisionObject2D.xml @@ -107,8 +107,8 @@ <argument index="1" name="value" type="bool"> </argument> <description> - If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer]. - If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer]. + If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer]. + If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer]. </description> </method> <method name="set_collision_mask_bit"> @@ -119,8 +119,8 @@ <argument index="1" name="value" type="bool"> </argument> <description> - If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask]. - If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask]. + If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask]. + If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask]. </description> </method> <method name="shape_find_owner" qualifiers="const"> diff --git a/doc/classes/CollisionObject3D.xml b/doc/classes/CollisionObject3D.xml index dfd1e85e56..ac6a84dda6 100644 --- a/doc/classes/CollisionObject3D.xml +++ b/doc/classes/CollisionObject3D.xml @@ -93,8 +93,8 @@ <argument index="1" name="value" type="bool"> </argument> <description> - If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer]. - If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer]. + If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer]. + If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer]. </description> </method> <method name="set_collision_mask_bit"> @@ -105,8 +105,8 @@ <argument index="1" name="value" type="bool"> </argument> <description> - If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask]. - If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask]. + If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask]. + If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask]. </description> </method> <method name="shape_find_owner" qualifiers="const"> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 23cbdd8cab..5c0856cb6a 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -9,7 +9,7 @@ [b]User Interface nodes and input[/b] Godot sends input events to the scene's root node first, by calling [method Node._input]. [method Node._input] forwards the event down the node tree to the nodes under the mouse cursor, or on keyboard focus. To do so, it calls [code]MainLoop._input_event[/code]. [b]FIXME:[/b] No longer valid after DisplayServer split and Input refactoring. - Call [method accept_event] so no other node receives the event. Once you accepted an input, it becomes handled so [method Node._unhandled_input] will not process it. + Call [method accept_event] so no other node receives the event. Once you accept an input, it becomes handled so [method Node._unhandled_input] will not process it. Only one [Control] node can be in keyboard focus. Only the node in focus will receive keyboard events. To get the focus, call [method grab_focus]. [Control] nodes lose focus when another node grabs it, or if you hide the node in focus. Sets [member mouse_filter] to [constant MOUSE_FILTER_IGNORE] to tell a [Control] node to ignore mouse or touch events. You'll need it if you place an icon on top of a button. [Theme] resources change the Control's appearance. If you change the [Theme] on a [Control] node, it affects all of its children. To override some of the theme's parameters, call one of the [code]add_theme_*_override[/code] methods, like [method add_theme_font_override]. You can override the theme with the inspector. @@ -147,7 +147,7 @@ * control has [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE]; * control is obstructed by another [Control] on top of it, which doesn't have [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE]; * control's parent has [member mouse_filter] set to [constant MOUSE_FILTER_STOP] or has accepted the event; - * it happens outside parent's rectangle and the parent has either [member rect_clip_content] enabled. + * it happens outside the parent's rectangle and the parent has either [member rect_clip_content] enabled. </description> </method> <method name="_has_point" qualifiers="virtual const"> @@ -168,10 +168,10 @@ </argument> <description> Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. The [code]for_text[/code] includes the contents of the [member hint_tooltip] property. - The returned node must be of type [Control] or Control-derived. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance (if you want to use a pre-existing node from your scene tree, you can duplicate it and pass the duplicated instance).When [code]null[/code] or a non-Control node is returned, the default tooltip will be used instead. + The returned node must be of type [Control] or Control-derived. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance (if you want to use a pre-existing node from your scene tree, you can duplicate it and pass the duplicated instance). When [code]null[/code] or a non-Control node is returned, the default tooltip will be used instead. The returned node will be added as child to a [PopupPanel], so you should only provide the contents of that panel. That [PopupPanel] can be themed using [method Theme.set_stylebox] for the type [code]"TooltipPanel"[/code] (see [member hint_tooltip] for an example). [b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member rect_min_size] to some non-zero value. - [b]Note:[/b] The node (and any relevant children) should be [member CanvasItem.visible] when returned, otherwise the viewport that instantiates it will not be able to calculate its minimum size reliably. + [b]Note:[/b] The node (and any relevant children) should be [member CanvasItem.visible] when returned, otherwise, the viewport that instantiates it will not be able to calculate its minimum size reliably. Example of usage with a custom-constructed node: [codeblocks] [gdscript] @@ -860,7 +860,7 @@ <argument index="1" name="keep_offsets" type="bool" default="false"> </argument> <description> - Sets the anchors to a [code]preset[/code] from [enum Control.LayoutPreset] enum. This is code equivalent of using the Layout menu in 2D editor. + Sets the anchors to a [code]preset[/code] from [enum Control.LayoutPreset] enum. This is the code equivalent to using the Layout menu in the 2D editor. If [code]keep_offsets[/code] is [code]true[/code], control's position will also be updated. </description> </method> @@ -1029,7 +1029,7 @@ <argument index="2" name="margin" type="int" default="0"> </argument> <description> - Sets the offsets to a [code]preset[/code] from [enum Control.LayoutPreset] enum. This is code equivalent of using the Layout menu in 2D editor. + Sets the offsets to a [code]preset[/code] from [enum Control.LayoutPreset] enum. This is the code equivalent to using the Layout menu in the 2D editor. Use parameter [code]resize_mode[/code] with constants from [enum Control.LayoutPresetMode] to better determine the resulting size of the [Control]. Constant size will be ignored if used with presets that change size, e.g. [code]PRESET_LEFT_WIDE[/code]. Use parameter [code]margin[/code] to determine the gap between the [Control] and the edges. </description> @@ -1229,11 +1229,13 @@ <signal name="mouse_entered"> <description> Emitted when the mouse enters the control's [code]Rect[/code] area, provided its [member mouse_filter] lets the event reach it. + [b]Note:[/b] [signal mouse_entered] will not be emitted if the mouse enters a child [Control] node before entering the parent's [code]Rect[/code] area, at least until the mouse is moved to reach the parent's [code]Rect[/code] area. </description> </signal> <signal name="mouse_exited"> <description> Emitted when the mouse leaves the control's [code]Rect[/code] area, provided its [member mouse_filter] lets the event reach it. + [b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a child [Control] node, even if the mouse cursor is still inside the parent's [code]Rect[/code] area. </description> </signal> <signal name="resized"> diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml index dae8d83f0c..ff92f6c5ef 100644 --- a/doc/classes/Directory.xml +++ b/doc/classes/Directory.xml @@ -159,7 +159,7 @@ <argument index="1" name="show_hidden" type="bool" default="false"> </argument> <description> - Initializes the stream used to list all files and directories using the [method get_next] function, closing the current opened stream if needed. Once the stream has been processed, it should typically be closed with [method list_dir_end]. + Initializes the stream used to list all files and directories using the [method get_next] function, closing the currently opened stream if needed. Once the stream has been processed, it should typically be closed with [method list_dir_end]. If [code]show_navigational[/code] is [code]true[/code], [code].[/code] and [code]..[/code] are included too. If [code]show_hidden[/code] is [code]true[/code], hidden files are included too. </description> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 17b51d5cbe..5c9bcc5014 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -7,16 +7,6 @@ <tutorials> </tutorials> <methods> - <method name="alert"> - <return type="void"> - </return> - <argument index="0" name="text" type="String"> - </argument> - <argument index="1" name="title" type="String" default=""Alert!""> - </argument> - <description> - </description> - </method> <method name="clipboard_get" qualifiers="const"> <return type="String"> </return> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index a532e9bc2b..1722b278f8 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -126,7 +126,7 @@ <return type="int"> </return> <description> - Gets the order of this importer to be run when importing resources. Higher values will be called later. Use this to ensure the importer runs after the dependencies are already imported. + Gets the order of this importer to be run when importing resources. Importers with [i]lower[/i] import orders will be called first, and higher values will be called later. Use this to ensure the importer runs after the dependencies are already imported. The default import order is [code]0[/code] unless overridden by a specific importer. See [enum ResourceImporter.ImportOrder] for some predefined values. </description> </method> <method name="_get_importer_name" qualifiers="virtual"> diff --git a/doc/classes/EditorNode3DGizmo.xml b/doc/classes/EditorNode3DGizmo.xml index 221b5e44d6..d4d1e4a652 100644 --- a/doc/classes/EditorNode3DGizmo.xml +++ b/doc/classes/EditorNode3DGizmo.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorNode3DGizmo" inherits="Node3DGizmo" version="4.0"> <brief_description> - Custom gizmo for editing Node3D objects. + Gizmo for editing Node3D objects. </brief_description> <description> - Custom gizmo that is used for providing custom visualization and editing (handles) for Node3D objects. See [EditorNode3DGizmoPlugin] for more information. + Gizmo that is used for providing custom visualization and editing (handles and subgizmos) for Node3D objects. Can be overridden to create custom gizmos, but for simple gizmos creating a [EditorNode3DGizmoPlugin] is usually recommended. </description> <tutorials> </tutorials> @@ -12,64 +12,119 @@ <method name="_commit_handle" qualifiers="virtual"> <return type="void"> </return> - <argument index="0" name="index" type="int"> + <argument index="0" name="id" type="int"> </argument> <argument index="1" name="restore" type="Variant"> </argument> <argument index="2" name="cancel" type="bool" default="false"> </argument> <description> - Commit a handle being edited (handles must have been previously added by [method add_handles]). - If the [code]cancel[/code] parameter is [code]true[/code], an option to restore the edited value to the original is provided. + Override this method to commit a handle being edited (handles must have been previously added by [method add_handles]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo". + If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. + </description> + </method> + <method name="_commit_subgizmos" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="ids" type="PackedInt32Array"> + </argument> + <argument index="1" name="restore" type="Array"> + </argument> + <argument index="2" name="cancel" type="bool" default="false"> + </argument> + <description> + Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo". + If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action. </description> </method> <method name="_get_handle_name" qualifiers="virtual"> <return type="String"> </return> - <argument index="0" name="index" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> - Gets the name of an edited handle (handles must have been previously added by [method add_handles]). + Override this method to return the name of an edited handle (handles must have been previously added by [method add_handles]). Handles can be named for reference to the user when editing. </description> </method> <method name="_get_handle_value" qualifiers="virtual"> <return type="Variant"> </return> - <argument index="0" name="index" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> - Gets actual value of a handle. This value can be anything and used for eventually undoing the motion when calling [method _commit_handle]. + Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. + </description> + </method> + <method name="_get_subgizmo_transform" qualifiers="virtual"> + <return type="Transform3D"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + Override this method to return the current transform of a subgizmo. This transform will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_subgizmos]. </description> </method> <method name="_is_handle_highlighted" qualifiers="virtual"> <return type="bool"> </return> - <argument index="0" name="index" type="int"> + <argument index="0" name="id" type="int"> </argument> <description> - Returns [code]true[/code] if the handle at index [code]index[/code] is highlighted by being hovered with the mouse. + Override this method to return [code]true[/code] whenever the given handle should be highlighted in the editor. </description> </method> <method name="_redraw" qualifiers="virtual"> <return type="void"> </return> <description> - This function is called when the [Node3D] this gizmo refers to changes (the [method Node3D.update_gizmo] is called). + Override this method to add all the gizmo elements whenever a gizmo update is requested. It's common to call [method clear] at the beginning of this method and then add visual elements depending on the node's properties. </description> </method> <method name="_set_handle" qualifiers="virtual"> <return type="void"> </return> - <argument index="0" name="index" type="int"> + <argument index="0" name="id" type="int"> </argument> <argument index="1" name="camera" type="Camera3D"> </argument> <argument index="2" name="point" type="Vector2"> </argument> <description> - This function is used when the user drags a gizmo handle (previously added with [method add_handles]) in screen coordinates. - The [Camera3D] is also provided so screen coordinates can be converted to raycasts. + Override this method to update the node properties when the user drags a gizmo handle (previously added with [method add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. + </description> + </method> + <method name="_set_subgizmo_transform" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="transform" type="Transform3D"> + </argument> + <description> + Override this method to update the node properties during subgizmo editing (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). The [code]transform[/code] is given in the Node3D's local coordinate system. + </description> + </method> + <method name="_subgizmos_intersect_frustum" qualifiers="virtual"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="camera" type="Camera3D"> + </argument> + <argument index="1" name="frustum" type="Array"> + </argument> + <description> + Override this method to allow selecting subgizmos using mouse drag box selection. Given a [code]camera[/code] and a [code]frustum[/code], this method should return which subgizmos are contained within the frustum. The [code]frustum[/code] argument consists of an [code]Array[/code] with all the [code]Plane[/code]s that make up the selection frustum. The returned value should contain a list of unique subgizmo identifiers, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. + </description> + </method> + <method name="_subgizmos_intersect_ray" qualifiers="virtual"> + <return type="int"> + </return> + <argument index="0" name="camera" type="Camera3D"> + </argument> + <argument index="1" name="point" type="Vector2"> + </argument> + <description> + Override this method to allow selecting subgizmos using mouse clicks. Given a [code]camera[/code] and a [code]point[/code] in screen coordinates, this method should return which subgizmo should be selected. The returned value should be a unique subgizmo identifier, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. </description> </method> <method name="add_collision_segments"> @@ -78,7 +133,7 @@ <argument index="0" name="segments" type="PackedVector3Array"> </argument> <description> - Adds the specified [code]segments[/code] to the gizmo's collision shape for picking. Call this function during [method _redraw]. + Adds the specified [code]segments[/code] to the gizmo's collision shape for picking. Call this method during [method _redraw]. </description> </method> <method name="add_collision_triangles"> @@ -87,7 +142,7 @@ <argument index="0" name="triangles" type="TriangleMesh"> </argument> <description> - Adds collision triangles to the gizmo for picking. A [TriangleMesh] can be generated from a regular [Mesh] too. Call this function during [method _redraw]. + Adds collision triangles to the gizmo for picking. A [TriangleMesh] can be generated from a regular [Mesh] too. Call this method during [method _redraw]. </description> </method> <method name="add_handles"> @@ -97,13 +152,15 @@ </argument> <argument index="1" name="material" type="Material"> </argument> - <argument index="2" name="billboard" type="bool" default="false"> + <argument index="2" name="ids" type="PackedInt32Array"> </argument> - <argument index="3" name="secondary" type="bool" default="false"> + <argument index="3" name="billboard" type="bool" default="false"> + </argument> + <argument index="4" name="secondary" type="bool" default="false"> </argument> <description> - Adds a list of handles (points) which can be used to deform the object being edited. - There are virtual functions which will be called upon editing of these handles. Call this function during [method _redraw]. + Adds a list of handles (points) which can be used to edit the properties of the gizmo's Node3D. The [code]ids[/code] argument can be used to specify a custom identifier for each handle, if an empty [code]Array[/code] is passed, the ids will be assigned automatically from the [code]handles[/code] argument order. + There are virtual methods which will be called upon editing of these handles. Call this method during [method _redraw]. </description> </method> <method name="add_lines"> @@ -118,7 +175,7 @@ <argument index="3" name="modulate" type="Color" default="Color(1, 1, 1, 1)"> </argument> <description> - Adds lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. Call this function during [method _redraw]. + Adds lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. Call this method during [method _redraw]. </description> </method> <method name="add_mesh"> @@ -126,14 +183,14 @@ </return> <argument index="0" name="mesh" type="ArrayMesh"> </argument> - <argument index="1" name="billboard" type="bool" default="false"> + <argument index="1" name="material" type="Material" default="null"> </argument> - <argument index="2" name="skeleton" type="SkinReference" default="null"> + <argument index="2" name="transform" type="Transform3D" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)"> </argument> - <argument index="3" name="material" type="Material" default="null"> + <argument index="3" name="skeleton" type="SkinReference" default="null"> </argument> <description> - Adds a mesh to the gizmo with the specified [code]billboard[/code] state, [code]skeleton[/code] and [code]material[/code]. If [code]billboard[/code] is [code]true[/code], the mesh will rotate to always face the camera. Call this function during [method _redraw]. + Adds a mesh to the gizmo with the specified [code]material[/code], local [code]transform[/code] and [code]skeleton[/code]. Call this method during [method _redraw]. </description> </method> <method name="add_unscaled_billboard"> @@ -146,7 +203,7 @@ <argument index="2" name="modulate" type="Color" default="Color(1, 1, 1, 1)"> </argument> <description> - Adds an unscaled billboard for visualization. Call this function during [method _redraw]. + Adds an unscaled billboard for visualization and selection. Call this method during [method _redraw]. </description> </method> <method name="clear"> @@ -170,6 +227,22 @@ Returns the Node3D node associated with this gizmo. </description> </method> + <method name="get_subgizmo_selection" qualifiers="const"> + <return type="PackedInt32Array"> + </return> + <description> + Returns a list of the currently selected subgizmos. Can be used to highlight selected elements during [method _redraw]. + </description> + </method> + <method name="is_subgizmo_selected" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="arg0" type="int"> + </argument> + <description> + Returns [code]true[/code] if the given subgizmo is currently selected. Can be used to highlight selected elements during [method _redraw]. + </description> + </method> <method name="set_hidden"> <return type="void"> </return> diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml index 41c94cbbc6..10d6bd8bc8 100644 --- a/doc/classes/EditorNode3DGizmoPlugin.xml +++ b/doc/classes/EditorNode3DGizmoPlugin.xml @@ -14,7 +14,7 @@ <return type="bool"> </return> <description> - Override this method to define whether the gizmo can be hidden or not. Returns [code]true[/code] if not overridden. + Override this method to define whether the gizmos handled by this plugin can be hidden or not. Returns [code]true[/code] if not overridden. </description> </method> <method name="_commit_handle" qualifiers="virtual"> @@ -22,14 +22,31 @@ </return> <argument index="0" name="gizmo" type="EditorNode3DGizmo"> </argument> - <argument index="1" name="index" type="int"> + <argument index="1" name="id" type="int"> </argument> <argument index="2" name="restore" type="Variant"> </argument> <argument index="3" name="cancel" type="bool" default="false"> </argument> <description> - Override this method to commit gizmo handles. Called for this plugin's active gizmos. + Override this method to commit a handle being edited (handles must have been previously added by [method EditorNode3DGizmo.add_handles] during [method _redraw]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo". + If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. Called for this plugin's active gizmos. + </description> + </method> + <method name="_commit_subgizmos" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="gizmo" type="EditorNode3DGizmo"> + </argument> + <argument index="1" name="ids" type="PackedInt32Array"> + </argument> + <argument index="2" name="restore" type="Array"> + </argument> + <argument index="3" name="cancel" type="bool" default="false"> + </argument> + <description> + Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo". + If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action. Called for this plugin's active gizmos. </description> </method> <method name="_create_gizmo" qualifiers="virtual"> @@ -53,7 +70,7 @@ </return> <argument index="0" name="gizmo" type="EditorNode3DGizmo"> </argument> - <argument index="1" name="index" type="int"> + <argument index="1" name="id" type="int"> </argument> <description> Override this method to provide gizmo's handle names. Called for this plugin's active gizmos. @@ -64,18 +81,29 @@ </return> <argument index="0" name="gizmo" type="EditorNode3DGizmo"> </argument> - <argument index="1" name="index" type="int"> + <argument index="1" name="id" type="int"> </argument> <description> - Gets actual value of a handle from gizmo. Called for this plugin's active gizmos. + Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. Called for this plugin's active gizmos. </description> </method> <method name="_get_priority" qualifiers="virtual"> <return type="int"> </return> <description> - Override this method to set the gizmo's priority. Higher values correspond to higher priority. If a gizmo with higher priority conflicts with another gizmo, only the gizmo with higher priority will be used. - All built-in editor gizmos return a priority of [code]-1[/code]. If not overridden, this method will return [code]0[/code], which means custom gizmos will automatically override built-in gizmos. + Override this method to set the gizmo's priority. Gizmos with higher priority will have precedence when processing inputs like handles or subgizmos selection. + All built-in editor gizmos return a priority of [code]-1[/code]. If not overridden, this method will return [code]0[/code], which means custom gizmos will automatically get higher priority than built-in gizmos. + </description> + </method> + <method name="_get_subgizmo_transform" qualifiers="virtual"> + <return type="Transform3D"> + </return> + <argument index="0" name="gizmo" type="EditorNode3DGizmo"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <description> + Override this method to return the current transform of a subgizmo. This transform will be requested at the start of an edit and used in the [code]restore[/code] argument in [method _commit_subgizmos]. Called for this plugin's active gizmos. </description> </method> <method name="_has_gizmo" qualifiers="virtual"> @@ -92,10 +120,10 @@ </return> <argument index="0" name="gizmo" type="EditorNode3DGizmo"> </argument> - <argument index="1" name="index" type="int"> + <argument index="1" name="id" type="int"> </argument> <description> - Gets whether a handle is highlighted or not. Called for this plugin's active gizmos. + Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. Called for this plugin's active gizmos. </description> </method> <method name="_is_selectable_when_hidden" qualifiers="virtual"> @@ -111,7 +139,7 @@ <argument index="0" name="gizmo" type="EditorNode3DGizmo"> </argument> <description> - Callback to redraw the provided gizmo. Called for this plugin's active gizmos. + Override this method to add all the gizmo elements whenever a gizmo update is requested. It's common to call [method EditorNode3DGizmo.clear] at the beginning of this method and then add visual elements depending on the node's properties. </description> </method> <method name="_set_handle" qualifiers="virtual"> @@ -119,14 +147,53 @@ </return> <argument index="0" name="gizmo" type="EditorNode3DGizmo"> </argument> - <argument index="1" name="index" type="int"> + <argument index="1" name="id" type="int"> </argument> <argument index="2" name="camera" type="Camera3D"> </argument> <argument index="3" name="point" type="Vector2"> </argument> <description> - Update the value of a handle after it has been updated. Called for this plugin's active gizmos. + Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorNode3DGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. Called for this plugin's active gizmos. + </description> + </method> + <method name="_set_subgizmo_transform" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="gizmo" type="EditorNode3DGizmo"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <argument index="2" name="transform" type="Transform3D"> + </argument> + <description> + Override this method to update the node properties during subgizmo editing (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). The [code]transform[/code] is given in the Node3D's local coordinate system. Called for this plugin's active gizmos. + </description> + </method> + <method name="_subgizmos_intersect_frustum" qualifiers="virtual"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="gizmo" type="EditorNode3DGizmo"> + </argument> + <argument index="1" name="camera" type="Camera3D"> + </argument> + <argument index="2" name="frustum" type="Array"> + </argument> + <description> + Override this method to allow selecting subgizmos using mouse drag box selection. Given a [code]camera[/code] and a [code]frustum[/code], this method should return which subgizmos are contained within the frustum. The [code]frustum[/code] argument consists of an [code]Array[/code] with all the [code]Plane[/code]s that make up the selection frustum. The returned value should contain a list of unique subgizmo identifiers, these identifiers can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. Called for this plugin's active gizmos. + </description> + </method> + <method name="_subgizmos_intersect_ray" qualifiers="virtual"> + <return type="int"> + </return> + <argument index="0" name="gizmo" type="EditorNode3DGizmo"> + </argument> + <argument index="1" name="camera" type="Camera3D"> + </argument> + <argument index="2" name="point" type="Vector2"> + </argument> + <description> + Override this method to allow selecting subgizmos using mouse clicks. Given a [code]camera[/code] and a [code]point[/code] in screen coordinates, this method should return which subgizmo should be selected. The returned value should be a unique subgizmo identifier, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. Called for this plugin's active gizmos. </description> </method> <method name="add_material"> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index 753227513b..efd1d30565 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -404,7 +404,7 @@ </argument> <description> Adds a custom type, which will appear in the list of nodes or resources. An icon can be optionally passed. - When given node or resource is selected, the base type will be instantiated (e.g. "Node3D", "Control", "Resource"), then the script will be loaded and set to this object. + When a given node or resource is selected, the base type will be instantiated (e.g. "Node3D", "Control", "Resource"), then the script will be loaded and set to this object. You can use the virtual method [method _handles] to check if your custom object is being edited by checking the script or using the [code]is[/code] keyword. During run-time, this will be a simple object with a script so this function does not need to be called then. </description> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index c0a8407ece..3fa7894fdc 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -170,7 +170,7 @@ The number of fixed iterations per second. This controls how often physics simulation and [method Node._physics_process] methods are run. This value should generally always be set to [code]60[/code] or above, as Godot doesn't interpolate the physics step. As a result, values lower than [code]60[/code] will look stuttery. This value can be increased to make input more reactive or work around tunneling issues, but keep in mind doing so will increase CPU usage. </member> <member name="physics_jitter_fix" type="float" setter="set_physics_jitter_fix" getter="get_physics_jitter_fix" default="0.5"> - Controls how much physics ticks are synchronized with real time. For 0 or less, the ticks are synchronized. Such values are recommended for network games, where clock synchronization matters. Higher values cause higher deviation of in-game clock and real clock, but allows smoothing out framerate jitters. The default value of 0.5 should be fine for most; values above 2 could cause the game to react to dropped frames with a noticeable delay and are not recommended. + Controls how much physics ticks are synchronized with real time. For 0 or less, the ticks are synchronized. Such values are recommended for network games, where clock synchronization matters. Higher values cause higher deviation of the in-game clock and real clock but smooth out framerate jitters. The default value of 0.5 should be fine for most; values above 2 could cause the game to react to dropped frames with a noticeable delay and are not recommended. [b]Note:[/b] For best results, when using a custom physics interpolation solution, the physics jitter fix should be disabled by setting [member physics_jitter_fix] to [code]0[/code]. </member> <member name="print_error_messages" type="bool" setter="set_print_error_messages" getter="is_printing_error_messages" default="true"> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 167b90ea73..fd80841a63 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -241,7 +241,7 @@ <argument index="0" name="renormalize" type="bool" default="false"> </argument> <description> - Generates mipmaps for the image. Mipmaps are precalculated and lower resolution copies of the image. Mipmaps are automatically used if the image needs to be scaled down when rendered. This improves image quality and the performance of the rendering. Returns an error if the image is compressed, in a custom format or if the image's width/height is 0. + Generates mipmaps for the image. Mipmaps are precalculated lower-resolution copies of the image that are automatically used if the image needs to be scaled down when rendered. They help improve image quality and performance when rendering. This method returns an error if the image is compressed, in a custom format, or if the image's width/height is [code]0[/code]. </description> </method> <method name="get_data" qualifiers="const"> @@ -710,7 +710,7 @@ </constant> <constant name="INTERPOLATE_TRILINEAR" value="3" enum="Interpolation"> Performs bilinear separately on the two most-suited mipmap levels, then linearly interpolates between them. - It's slower than [constant INTERPOLATE_BILINEAR], but produces higher-quality results with much less aliasing artifacts. + It's slower than [constant INTERPOLATE_BILINEAR], but produces higher-quality results with far fewer aliasing artifacts. If the image does not have mipmaps, they will be generated and used internally, but no mipmaps will be generated on the resulting image. [b]Note:[/b] If you intend to scale multiple copies of the original image, it's better to call [method generate_mipmaps]] on it in advance, to avoid wasting processing power in generating them again and again. On the other hand, if the image already has mipmaps, they will be used, and a new set will be generated for the resulting image. diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index b970070659..c340895130 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -208,7 +208,7 @@ <argument index="4" name="deadzone" type="float" default="-1.0"> </argument> <description> - Get vector input by specifying four actions, two for the X axis and two for the Y axis, negative and positive. + Gets an input vector by specifying four actions for the positive and negative X and Y axes. This method is useful when getting vector input, such as from a joystick, directional pad, arrows, or WASD. The vector has its length limited to 1 and has a circular deadzone, which is useful for using vector input as movement. By default, the deadzone is automatically calculated from the average of the action deadzones. However, you can override the deadzone to be whatever you want (on the range of 0 to 1). </description> diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index ca22567ad5..9e96f11ccc 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -4,7 +4,7 @@ Displays plain text in a line or wrapped inside a rectangle. For formatted text, use [RichTextLabel]. </brief_description> <description> - Label displays plain text on the screen. It gives you control over the horizontal and vertical alignment, and can wrap the text inside the node's bounding rectangle. It doesn't support bold, italics or other formatting. For that, use [RichTextLabel] instead. + Label displays plain text on the screen. It gives you control over the horizontal and vertical alignment and can wrap the text inside the node's bounding rectangle. It doesn't support bold, italics, or other formatting. For that, use [RichTextLabel] instead. [b]Note:[/b] Contrarily to most other [Control]s, Label's [member Control.mouse_filter] defaults to [constant Control.MOUSE_FILTER_IGNORE] (i.e. it doesn't react to mouse input events). This implies that a label won't display any configured [member Control.hint_tooltip], unless you change its mouse filter. </description> <tutorials> diff --git a/doc/classes/MethodTweener.xml b/doc/classes/MethodTweener.xml index 42b91abf93..3badeb164b 100644 --- a/doc/classes/MethodTweener.xml +++ b/doc/classes/MethodTweener.xml @@ -4,7 +4,7 @@ Interpolates an abstract value and supplies it to a method called over time. </brief_description> <description> - [MethodTweener] is similar to a combination of [CallbackTweener] and [PropertyTweener]. It calls a method providing an interpolated value as a paramater. See [method Tween.tween_method] for more usage information. + [MethodTweener] is similar to a combination of [CallbackTweener] and [PropertyTweener]. It calls a method providing an interpolated value as a parameter. See [method Tween.tween_method] for more usage information. [b]Note:[/b] [method Tween.tween_method] is the only correct way to create [MethodTweener]. Any [MethodTweener] created manually will not function correctly. </description> <tutorials> diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index 14e03a2186..8cb331a578 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -13,6 +13,29 @@ <link title="All 3D Demos">https://github.com/godotengine/godot-demo-projects/tree/master/3d</link> </tutorials> <methods> + <method name="add_gizmo"> + <return type="void"> + </return> + <argument index="0" name="gizmo" type="Node3DGizmo"> + </argument> + <description> + Attach a gizmo to this [code]Node3D[/code]. + </description> + </method> + <method name="clear_gizmos"> + <return type="void"> + </return> + <description> + Clear all gizmos attached to this [code]Node3D[/code]. + </description> + </method> + <method name="clear_subgizmo_selection"> + <return type="void"> + </return> + <description> + Clears subgizmo selection for this node in the editor. Useful when subgizmo IDs become invalid after a property change. + </description> + </method> <method name="force_update_transform"> <return type="void"> </return> @@ -20,6 +43,13 @@ Forces the transform to update. Transform changes in physics are not instant for performance reasons. Transforms are accumulated and then set. Use this if you need an up-to-date transform when doing physics operations. </description> </method> + <method name="get_gizmos" qualifiers="const"> + <return type="Array"> + </return> + <description> + Returns all the gizmos attached to this [code]Node3D[/code]. + </description> + </method> <method name="get_parent_node_3d" qualifiers="const"> <return type="Node3D"> </return> @@ -276,18 +306,15 @@ Changes the node's position by the given offset [Vector3] in local space. </description> </method> - <method name="update_gizmo"> + <method name="update_gizmos"> <return type="void"> </return> <description> - Updates the [Node3DGizmo] of this node. + Updates all the [Node3DGizmo]s attached to this node. </description> </method> </methods> <members> - <member name="gizmo" type="Node3DGizmo" setter="set_gizmo" getter="get_gizmo"> - The [Node3DGizmo] for this node. Used for example in [EditorNode3DGizmo] as custom visualization and editing handles in Editor. - </member> <member name="global_transform" type="Transform3D" setter="set_global_transform" getter="get_global_transform"> World3D space (global) [Transform3D] of this node. </member> @@ -308,7 +335,7 @@ Local space [Transform3D] of this node, with respect to the parent node. </member> <member name="visibility_parent" type="NodePath" setter="set_visibility_parent" getter="get_visibility_parent" default="NodePath("")"> - Defines the visibility range parent for this node and its subtree. The visibility parent must be a GeometryInstance3D. Any visual instance will only be visible if the visibility parent (and all of its visibility ancestors) is hidden by being closer to the camera than its own [member GeometryInstance3D.visibility_range_begin]. Nodes hidden via the [member Node3D.visible] property are essentially removed from the visibility dependency tree, so dependant instances will not take the hidden node or its ancestors into account. + Defines the visibility range parent for this node and its subtree. The visibility parent must be a GeometryInstance3D. Any visual instance will only be visible if the visibility parent (and all of its visibility ancestors) is hidden by being closer to the camera than its own [member GeometryInstance3D.visibility_range_begin]. Nodes hidden via the [member Node3D.visible] property are essentially removed from the visibility dependency tree, so dependent instances will not take the hidden node or its ancestors into account. </member> <member name="visible" type="bool" setter="set_visible" getter="is_visible" default="true"> If [code]true[/code], this node is drawn. The node is only visible if all of its antecedents are visible as well (in other words, [method is_visible_in_tree] must return [code]true[/code]). @@ -324,7 +351,7 @@ <constants> <constant name="NOTIFICATION_TRANSFORM_CHANGED" value="2000"> Node3D nodes receives this notification when their global transform changes. This means that either the current or a parent node changed its transform. - In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform]. The notification is also sent if the node is in the editor context and it has a valid gizmo. + In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform]. The notification is also sent if the node is in the editor context and it has at least one valid gizmo. </constant> <constant name="NOTIFICATION_ENTER_WORLD" value="41"> Node3D nodes receives this notification when they are registered to new [World3D] resource. diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index a9396306f4..679a51935d 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -10,6 +10,17 @@ <link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link> </tutorials> <methods> + <method name="alert"> + <return type="void"> + </return> + <argument index="0" name="text" type="String"> + </argument> + <argument index="1" name="title" type="String" default=""Alert!""> + </argument> + <description> + Displays a modal dialog box using the host OS' facilities. Execution is blocked until the dialog is closed. + </description> + </method> <method name="can_use_threads" qualifiers="const"> <return type="bool"> </return> @@ -54,7 +65,7 @@ <argument index="0" name="msec" type="int"> </argument> <description> - Delay execution of the current thread by [code]msec[/code] milliseconds. [code]usec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_msec] will do nothing and will print an error message. + Delay execution of the current thread by [code]msec[/code] milliseconds. [code]msec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_msec] will do nothing and will print an error message. </description> </method> <method name="delay_usec" qualifiers="const"> @@ -228,7 +239,7 @@ <return type="PackedStringArray"> </return> <description> - With this function you can get the list of dangerous permissions that have been granted to the Android application. + With this function, you can get the list of dangerous permissions that have been granted to the Android application. [b]Note:[/b] This method is implemented on Android. </description> </method> @@ -250,7 +261,7 @@ [code]language[/code] - 2 or 3-letter [url=https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes]language code[/url], in lower case. [code]Script[/code] - optional, 4-letter [url=https://en.wikipedia.org/wiki/ISO_15924]script code[/url], in title case. [code]COUNTRY[/code] - optional, 2 or 3-letter [url=https://en.wikipedia.org/wiki/ISO_3166-1]country code[/url], in upper case. - [code]VARIANT[/code] - optional, language variant, region and sort order. Variant can have any number of underscored key words. + [code]VARIANT[/code] - optional, language variant, region and sort order. Variant can have any number of underscored keywords. [code]extra[/code] - optional, semicolon separated list of additional key words. Currency, calendar, sort order and numbering system information. </description> </method> @@ -321,7 +332,7 @@ </return> <description> Returns a string that is unique to the device. - [b]Note:[/b] This string may change without notice if the user reinstalls/upgrades their operating system or changes their hardware. This means it should generally not be used to encrypt persistent data as the data saved prior to an unexpected ID change would become inaccessible. The returned string may also be falsified using external programs, so do not rely on the string returned by [method get_unique_id] for security purposes. + [b]Note:[/b] This string may change without notice if the user reinstalls/upgrades their operating system or changes their hardware. This means it should generally not be used to encrypt persistent data as the data saved before an unexpected ID change would become inaccessible. The returned string may also be falsified using external programs, so do not rely on the string returned by [method get_unique_id] for security purposes. [b]Note:[/b] Returns an empty string on HTML5 and UWP, as this method isn't implemented on those platforms yet. </description> </method> @@ -353,7 +364,7 @@ <argument index="0" name="tag_name" type="String"> </argument> <description> - Returns [code]true[/code] if the feature for the given feature tag is supported in the currently running instance, depending on platform, build etc. Can be used to check whether you're currently running a debug build, on a certain platform or arch, etc. Refer to the [url=https://docs.godotengine.org/en/latest/getting_started/workflow/export/feature_tags.html]Feature Tags[/url] documentation for more details. + Returns [code]true[/code] if the feature for the given feature tag is supported in the currently running instance, depending on the platform, build, etc. Can be used to check whether you're currently running a debug build, on a certain platform or arch, etc. Refer to the [url=https://docs.godotengine.org/en/latest/getting_started/workflow/export/feature_tags.html]Feature Tags[/url] documentation for more details. [b]Note:[/b] Tag names are case-sensitive. </description> </method> @@ -455,7 +466,7 @@ <return type="bool"> </return> <description> - With this function you can request dangerous permissions since normal permissions are automatically granted at install time in Android application. + With this function, you can request dangerous permissions since normal permissions are automatically granted at install time in Android applications. [b]Note:[/b] This method is implemented on Android. </description> </method> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index cdf76a3a59..fe7529bceb 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -400,7 +400,7 @@ <method name="get_meta" qualifiers="const"> <return type="Variant"> </return> - <argument index="0" name="name" type="String"> + <argument index="0" name="name" type="StringName"> </argument> <description> Returns the object's metadata entry for the given [code]name[/code]. @@ -454,7 +454,7 @@ <method name="has_meta" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="name" type="String"> + <argument index="0" name="name" type="StringName"> </argument> <description> Returns [code]true[/code] if a metadata entry is found with the given [code]name[/code]. @@ -543,7 +543,7 @@ <method name="remove_meta"> <return type="void"> </return> - <argument index="0" name="name" type="String"> + <argument index="0" name="name" type="StringName"> </argument> <description> Removes a given entry from the object's metadata. See also [method set_meta]. @@ -619,7 +619,7 @@ <method name="set_meta"> <return type="void"> </return> - <argument index="0" name="name" type="String"> + <argument index="0" name="name" type="StringName"> </argument> <argument index="1" name="value" type="Variant"> </argument> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index 0652cf0aa1..82bfa14ded 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -515,6 +515,42 @@ Returns the slice of the [PackedByteArray] between indices (inclusive) as a new [PackedByteArray]. Any negative index is considered to be from the end of the array. </description> </method> + <method name="to_float32_array" qualifiers="const"> + <return type="PackedFloat32Array"> + </return> + <description> + Returns a copy of the data converted to a [PackedFloat32Array], where each block of 4 bytes has been converted to a 32-bit float (C++ [code]float[/code]). + The size of the new array will be [code]byte_array.size() / 4[/code]. + If the original data can't be converted to 32-bit floats, the resulting data is undefined. + </description> + </method> + <method name="to_float64_array" qualifiers="const"> + <return type="PackedFloat64Array"> + </return> + <description> + Returns a copy of the data converted to a [PackedFloat64Array], where each block of 8 bytes has been converted to a 64-bit float (C++ [code]double[/code], Godot [float]). + The size of the new array will be [code]byte_array.size() / 8[/code]. + If the original data can't be converted to 64-bit floats, the resulting data is undefined. + </description> + </method> + <method name="to_int32_array" qualifiers="const"> + <return type="PackedInt32Array"> + </return> + <description> + Returns a copy of the data converted to a [PackedInt32Array], where each block of 4 bytes has been converted to a signed 32-bit integer (C++ [code]int32_t[/code]). + The size of the new array will be [code]byte_array.size() / 4[/code]. + If the original data can't be converted to signed 32-bit integers, the resulting data is undefined. + </description> + </method> + <method name="to_int64_array" qualifiers="const"> + <return type="PackedInt64Array"> + </return> + <description> + Returns a copy of the data converted to a [PackedInt64Array], where each block of 4 bytes has been converted to a signed 64-bit integer (C++ [code]int64_t[/code], Godot [int]). + The size of the new array will be [code]byte_array.size() / 8[/code]. + If the original data can't be converted to signed 64-bit integers, the resulting data is undefined. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index ab97c9a695..663aeeb21d 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -201,6 +201,8 @@ <return type="PackedByteArray"> </return> <description> + Returns a copy of the data converted to a [PackedByteArray], where each element have been encoded as 4 bytes. + The size of the new array will be [code]float32_array.size() * 4[/code]. </description> </method> </methods> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index ad20801b01..bf2200f5bb 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -201,6 +201,8 @@ <return type="PackedByteArray"> </return> <description> + Returns a copy of the data converted to a [PackedByteArray], where each element have been encoded as 8 bytes. + The size of the new array will be [code]float64_array.size() * 8[/code]. </description> </method> </methods> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index ff4729082e..c587126d50 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -201,6 +201,8 @@ <return type="PackedByteArray"> </return> <description> + Returns a copy of the data converted to a [PackedByteArray], where each element have been encoded as 4 bytes. + The size of the new array will be [code]int32_array.size() * 4[/code]. </description> </method> </methods> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 195b12b129..a9ebc80601 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -201,6 +201,8 @@ <return type="PackedByteArray"> </return> <description> + Returns a copy of the data converted to a [PackedByteArray], where each element have been encoded as 8 bytes. + The size of the new array will be [code]int64_array.size() * 8[/code]. </description> </method> </methods> diff --git a/doc/classes/ResourceImporter.xml b/doc/classes/ResourceImporter.xml index 59900b1b73..03d47ee518 100644 --- a/doc/classes/ResourceImporter.xml +++ b/doc/classes/ResourceImporter.xml @@ -1,13 +1,22 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ResourceImporter" inherits="RefCounted" version="4.0"> <brief_description> + Base class for the implementation of core resource importers. </brief_description> <description> + This is the base class for the resource importers implemented in core. To implement your own resource importers using editor plugins, see [EditorImportPlugin]. </description> <tutorials> + <link title="Import plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/import_plugins.html</link> </tutorials> <methods> </methods> <constants> + <constant name="IMPORT_ORDER_DEFAULT" value="0" enum="ImportOrder"> + The default import order. + </constant> + <constant name="IMPORT_ORDER_SCENE" value="100" enum="ImportOrder"> + The import order for scenes, which ensures scenes are imported [i]after[/i] all other core resources such as textures. Custom importers should generally have an import order lower than [code]100[/code] to avoid issues when importing scenes that rely on custom resources. + </constant> </constants> </class> diff --git a/doc/classes/ResourceUID.xml b/doc/classes/ResourceUID.xml new file mode 100644 index 0000000000..9fe61d8008 --- /dev/null +++ b/doc/classes/ResourceUID.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="ResourceUID" inherits="Object" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_id"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="path" type="String"> + </argument> + <description> + </description> + </method> + <method name="create_id" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_id_path" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="has_id" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="id_to_text" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="remove_id"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_id"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="path" type="String"> + </argument> + <description> + </description> + </method> + <method name="text_to_id" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="text_id" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + <constant name="INVALID_ID" value="-1"> + </constant> + </constants> +</class> diff --git a/doc/classes/RootMotionView.xml b/doc/classes/RootMotionView.xml index be8d8d0078..e31ea9265e 100644 --- a/doc/classes/RootMotionView.xml +++ b/doc/classes/RootMotionView.xml @@ -1,23 +1,32 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="RootMotionView" inherits="VisualInstance3D" version="4.0"> <brief_description> + Editor-only helper for setting up root motion in [AnimationTree]. </brief_description> <description> + [i]Root motion[/i] refers to an animation technique where a mesh's skeleton is used to give impulse to a character. When working with 3D animations, a popular technique is for animators to use the root skeleton bone to give motion to the rest of the skeleton. This allows animating characters in a way where steps actually match the floor below. It also allows precise interaction with objects during cinematics. See also [AnimationTree]. + [b]Note:[/b] [RootMotionView] is only visible in the editor. It will be hidden automatically in the running project, and will also be converted to a plain [Node] in the running project. This means a script attached to a [RootMotionView] node [i]must[/i] have [code]extends Node[/code] instead of [code]extends RootMotionView[/code]. Additionally, it must not be a [code]@tool[/code] script. </description> <tutorials> + <link title="Using AnimationTree - Root motion">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html#root-motion</link> </tutorials> <methods> </methods> <members> <member name="animation_path" type="NodePath" setter="set_animation_path" getter="get_animation_path"> + Path to an [AnimationTree] node to use as a basis for root motion. </member> <member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size"> + The grid's cell size in 3D units. </member> <member name="color" type="Color" setter="set_color" getter="get_color"> + The grid's color. </member> <member name="radius" type="float" setter="set_radius" getter="get_radius"> + The grid's radius in 3D units. The grid's opacity will fade gradually as the distance from the origin increases until this [member radius] is reached. </member> <member name="zero_y" type="bool" setter="set_zero_y" getter="get_zero_y"> + If [code]true[/code], the grid's points will all be on the same Y coordinate ([i]local[/i] Y = 0). If [code]false[/code], the points' original Y coordinate is preserved. </member> </members> <constants> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index bf51b4dfa7..9930665d26 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -132,7 +132,7 @@ <return type="Array"> </return> <description> - Returns an array of currently exising [Tween]s in the [SceneTree] (both running and paused). + Returns an array of currently existing [Tween]s in the [SceneTree] (both running and paused). </description> </method> <method name="has_group" qualifiers="const"> diff --git a/doc/classes/Skeleton2D.xml b/doc/classes/Skeleton2D.xml index 6665a4a9f6..1ae39dfc07 100644 --- a/doc/classes/Skeleton2D.xml +++ b/doc/classes/Skeleton2D.xml @@ -73,7 +73,7 @@ </argument> <description> Sets the local pose transform, [code]pose[/code], for the bone at [code]bone_idx[/code]. - [code]amount[/code] is the interpolation strengh that will be used when applying the pose, and [code]persistent[/code] determines if the applied pose will remain. + [code]amount[/code] is the interpolation strength that will be used when applying the pose, and [code]persistent[/code] determines if the applied pose will remain. [b]Note:[/b] The pose transform needs to be a local transform relative to the [Bone2D] node at [code]bone_idx[/code]! </description> </method> diff --git a/doc/classes/SkeletonModification2D.xml b/doc/classes/SkeletonModification2D.xml index 8596dac76e..dfd0256d9b 100644 --- a/doc/classes/SkeletonModification2D.xml +++ b/doc/classes/SkeletonModification2D.xml @@ -14,7 +14,7 @@ <return type="void"> </return> <description> - Used for drawing [b]editor-only[/b] modification gizmos. This function will only be called in the Godot editor and can be overriden to draw custom gizmos. + Used for drawing [b]editor-only[/b] modification gizmos. This function will only be called in the Godot editor and can be overridden to draw custom gizmos. [b]Note:[/b] You will need to use the Skeleton2D from [method SkeletonModificationStack2D.get_skeleton] and it's draw functions, as the [SkeletonModification2D] resource cannot draw on its own. </description> </method> @@ -96,7 +96,7 @@ If [code]true[/code], the modification's [method _execute] function will be called by the [SkeletonModificationStack2D]. </member> <member name="execution_mode" type="int" setter="set_execution_mode" getter="get_execution_mode" default="0"> - The execution mode for the modification. This tells the modification stack when to execute the modification. Some modifications have settings that are only availible in certain execution modes. + The execution mode for the modification. This tells the modification stack when to execute the modification. Some modifications have settings that are only available in certain execution modes. </member> </members> <constants> diff --git a/doc/classes/SkeletonModification2DCCDIK.xml b/doc/classes/SkeletonModification2DCCDIK.xml index 014d366a42..1a74905df2 100644 --- a/doc/classes/SkeletonModification2DCCDIK.xml +++ b/doc/classes/SkeletonModification2DCCDIK.xml @@ -4,7 +4,7 @@ A modification that uses CCDIK to manipulate a series of bones to reach a target in 2D. </brief_description> <description> - This [SkeletonModification2D] uses an algorithm called [b]C[/b]yclic [b]C[/b]oordinate [b]D[/b]escent [b]I[/b]nverse [b]K[/b]inematics, or CCDIK, to maniuplate a chain of bones in a [Skeleton2D] so it reaches a defined target. + This [SkeletonModification2D] uses an algorithm called [b]C[/b]yclic [b]C[/b]oordinate [b]D[/b]escent [b]I[/b]nverse [b]K[/b]inematics, or CCDIK, to manipulate a chain of bones in a [Skeleton2D] so it reaches a defined target. CCDIK works by rotating a set of bones, typically called a "bone chain", on a single axis. Each bone is rotated to face the target from the tip (by default), which over a chain of bones allow it to rotate properly to reach the target. Because the bones only rotate on a single axis, CCDIK [i]can[/i] look more robotic than other IK solvers. [b]Note:[/b] The CCDIK modifier has [code]ccdik_joints[/code], which are the data objects that hold the data for each joint in the CCDIK chain. This is different from a bone! CCDIK joints hold the data needed for each bone in the bone chain used by CCDIK. CCDIK also fully supports angle constraints, allowing for more control over how a solution is met. diff --git a/doc/classes/SkeletonModification2DJiggle.xml b/doc/classes/SkeletonModification2DJiggle.xml index ae46acd0d0..da25191dc0 100644 --- a/doc/classes/SkeletonModification2DJiggle.xml +++ b/doc/classes/SkeletonModification2DJiggle.xml @@ -69,7 +69,7 @@ <argument index="0" name="joint_idx" type="int"> </argument> <description> - Returns a boolean that indiciates whether the joint at [code]joint_idx[/code] is overriding the default Jiggle joint data defined in the modification. + Returns a boolean that indicates whether the joint at [code]joint_idx[/code] is overriding the default Jiggle joint data defined in the modification. </description> </method> <method name="get_jiggle_joint_stiffness" qualifiers="const"> @@ -87,7 +87,7 @@ <argument index="0" name="joint_idx" type="int"> </argument> <description> - Returns a boolean that indiciates whether the joint at [code]joint_idx[/code] is using gravity or not. + Returns a boolean that indicates whether the joint at [code]joint_idx[/code] is using gravity or not. </description> </method> <method name="get_use_colliders" qualifiers="const"> @@ -206,19 +206,19 @@ </methods> <members> <member name="damping" type="float" setter="set_damping" getter="get_damping" default="0.75"> - The default amount of dampening applied to the Jiggle joints, if they are not overriden. Higher values lead to more of the calculated velocity being applied. + The default amount of dampening applied to the Jiggle joints, if they are not overridden. Higher values lead to more of the calculated velocity being applied. </member> <member name="gravity" type="Vector2" setter="set_gravity" getter="get_gravity" default="Vector2(0, 6)"> - The default amount of gravity applied to the Jiggle joints, if they are not overriden. + The default amount of gravity applied to the Jiggle joints, if they are not overridden. </member> <member name="jiggle_data_chain_length" type="int" setter="set_jiggle_data_chain_length" getter="get_jiggle_data_chain_length" default="0"> The amount of Jiggle joints in the Jiggle modification. </member> <member name="mass" type="float" setter="set_mass" getter="get_mass" default="0.75"> - The default amount of mass assigned to the Jiggle joints, if they are not overriden. Higher values lead to faster movements and more overshooting. + The default amount of mass assigned to the Jiggle joints, if they are not overridden. Higher values lead to faster movements and more overshooting. </member> <member name="stiffness" type="float" setter="set_stiffness" getter="get_stiffness" default="3.0"> - The default amount of stiffness assigned to the Jiggle joints, if they are not overriden. Higher values act more like springs, quickly moving into the correct position. + The default amount of stiffness assigned to the Jiggle joints, if they are not overridden. Higher values act more like springs, quickly moving into the correct position. </member> <member name="target_nodepath" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> The NodePath to the node that is the target for the Jiggle modification. This node is what the Jiggle chain will attempt to rotate the bone chain to. diff --git a/doc/classes/SkeletonModification2DTwoBoneIK.xml b/doc/classes/SkeletonModification2DTwoBoneIK.xml index 554515556b..0eecfa635c 100644 --- a/doc/classes/SkeletonModification2DTwoBoneIK.xml +++ b/doc/classes/SkeletonModification2DTwoBoneIK.xml @@ -4,7 +4,7 @@ A modification that rotates two bones using the law of cosigns to reach the target. </brief_description> <description> - This [SkeletonModification2D] uses an algorithm typically called TwoBoneIK. This algorithm works by leveraging the law of cosigns and the lengths of the bones to figure out what rotation the bones currently have, and what rotation they need to make a complete triangle, where the first bone, the second bone, and the target form the three verticies of the triangle. Because the algorithm works by making a triangle, it can only opperate on two bones. + This [SkeletonModification2D] uses an algorithm typically called TwoBoneIK. This algorithm works by leveraging the law of cosigns and the lengths of the bones to figure out what rotation the bones currently have, and what rotation they need to make a complete triangle, where the first bone, the second bone, and the target form the three vertices of the triangle. Because the algorithm works by making a triangle, it can only operate on two bones. TwoBoneIK is great for arms, legs, and really any joints that can be represented by just two bones that bend to reach a target. This solver is more lightweight than [SkeletonModification2DFABRIK], but gives similar, natural looking results. </description> <tutorials> diff --git a/doc/classes/SkeletonModificationStack2D.xml b/doc/classes/SkeletonModificationStack2D.xml index 35b899fe08..4ffd2c33fb 100644 --- a/doc/classes/SkeletonModificationStack2D.xml +++ b/doc/classes/SkeletonModificationStack2D.xml @@ -54,7 +54,7 @@ <return type="bool"> </return> <description> - Returns a boolean that indiciates whether the modification stack is setup and can execute. + Returns a boolean that indicates whether the modification stack is setup and can execute. </description> </method> <method name="get_modification" qualifiers="const"> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index e51bf42bdb..8d5f8f951c 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -127,7 +127,7 @@ <return type="Vector2"> </return> <description> - Gets the caret pixel draw poistion. + Gets the caret pixel draw position. </description> </method> <method name="get_first_non_whitespace_column" qualifiers="const"> diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml index 253822cf32..4efb0a3309 100644 --- a/doc/classes/Tween.xml +++ b/doc/classes/Tween.xml @@ -125,7 +125,7 @@ <return type="Tween"> </return> <description> - Makes the next [Tweener] run parallely to the previous one. Example: + Makes the next [Tweener] run parallelly to the previous one. Example: [codeblock] var tween = create_tween() tween.tween_property(...) @@ -175,7 +175,7 @@ <argument index="0" name="parallel" type="bool" default="true"> </argument> <description> - If [code]parallel[/code] is [code]true[/code], the [Tweener]s appended after this method will by default run simultanously, as opposed to sequentially. + If [code]parallel[/code] is [code]true[/code], the [Tweener]s appended after this method will by default run simultaneously, as opposed to sequentially. </description> </method> <method name="set_pause_mode"> diff --git a/doc/classes/Tweener.xml b/doc/classes/Tweener.xml index 5cd502ced9..a3279502e0 100644 --- a/doc/classes/Tweener.xml +++ b/doc/classes/Tweener.xml @@ -13,7 +13,7 @@ <signals> <signal name="finished"> <description> - Emited when the [Tweener] has just finished its job. + Emitted when the [Tweener] has just finished its job. </description> </signal> </signals> diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 6ea55219bb..f07c654bd6 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -111,7 +111,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { } } - if (is_backup_save_enabled() && (p_mode_flags & WRITE) && !(p_mode_flags & READ)) { + if (is_backup_save_enabled() && (p_mode_flags == WRITE)) { save_path = path; path = path + ".tmp"; } diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index efeaf32ff7..e01c6a0e0f 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -269,11 +269,11 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IPAddress p_ip, Str break; // IPv6 uses index. } - for (List<IPAddress>::Element *F = c.ip_addresses.front(); F; F = F->next()) { - if (!F->get().is_ipv4()) { + for (const IPAddress &F : c.ip_addresses) { + if (!F.is_ipv4()) { continue; // Wrong IP type } - if_ip = F->get(); + if_ip = F; break; } break; diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index a5c61bbea5..f6a3e93b55 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -139,10 +139,6 @@ void OS_Unix::finalize_core() { NetSocketPosix::cleanup(); } -void OS_Unix::alert(const String &p_alert, const String &p_title) { - fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data()); -} - String OS_Unix::get_stdin_string(bool p_block) { if (p_block) { char buff[1024]; diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 6c79d984e9..bf82019d38 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -52,7 +52,6 @@ protected: public: OS_Unix(); - virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); virtual String get_stdin_string(bool p_block) override; //virtual void set_mouse_show(bool p_show); diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub index 14b9d63204..6a2a57d18c 100644 --- a/drivers/vulkan/SCsub +++ b/drivers/vulkan/SCsub @@ -105,7 +105,7 @@ elif env["builtin_vulkan"]: else: # Always build VMA. thirdparty_dir = "#thirdparty/vulkan" - env.Prepend(CPPPATH=[thirdparty_dir]) + env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"]) # Build Vulkan loader library env_thirdparty = env.Clone() diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 5bf3bbf8a4..8d3362c7aa 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -6037,7 +6037,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma specialization_info.resize(pipeline_stages.size()); specialization_map_entries.resize(pipeline_stages.size()); for (int i = 0; i < shader->specialization_constants.size(); i++) { - //see if overriden + //see if overridden const Shader::SpecializationConstant &sc = shader->specialization_constants[i]; data_ptr[i] = sc.constant.int_value; //just copy the 32 bits @@ -6181,7 +6181,7 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<Pi specialization_constant_data.resize(shader->specialization_constants.size()); uint32_t *data_ptr = specialization_constant_data.ptrw(); for (int i = 0; i < shader->specialization_constants.size(); i++) { - //see if overriden + //see if overridden const Shader::SpecializationConstant &sc = shader->specialization_constants[i]; data_ptr[i] = sc.constant.int_value; //just copy the 32 bits @@ -8542,8 +8542,8 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) { } else { WARN_PRINT(vformat("%d RIDs of type \"%s\" were leaked.", owned.size(), p_type)); } - for (List<RID>::Element *E = owned.front(); E; E = E->next()) { - free(E->get()); + for (const RID &E : owned) { + free(E); } } } @@ -8764,13 +8764,13 @@ void RenderingDeviceVulkan::finalize() { List<RID>::Element *N = E->next(); if (texture_is_shared(E->get())) { free(E->get()); - owned.erase(E->get()); + owned.erase(E); } E = N; } //free non shared second, this will avoid an error trying to free unexisting textures due to dependencies. - for (List<RID>::Element *E = owned.front(); E; E = E->next()) { - free(E->get()); + for (const RID &E : owned) { + free(E); } } } diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 8b95ff43b8..3b3582eaa3 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -652,8 +652,8 @@ class RenderingDeviceVulkan : public RenderingDevice { // Basically, you can mix and match pools as you // like, but you'll run into fragmentation issues. // Because of this, the recommended approach is to - // create a a pool for every descriptor set type, - // as this prevents fragmentation. + // create a pool for every descriptor set type, as + // this prevents fragmentation. // // This is implemented here as a having a list of // pools (each can contain up to 64 sets) for each diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index d6deda7b5d..f504bad60d 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -108,7 +108,7 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { } #endif - if (is_backup_save_enabled() && p_mode_flags & WRITE && !(p_mode_flags & READ)) { + if (is_backup_save_enabled() && p_mode_flags == WRITE) { save_path = path; path = path + ".tmp"; } diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 05db9045bd..1e3140e202 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -898,8 +898,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { } // 6-(undo) reinsert overlapped keys - for (List<AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) { - AnimMoveRestore &amr = E->get(); + for (const AnimMoveRestore &amr : to_restore) { undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, 1); } @@ -1091,9 +1090,9 @@ void AnimationBezierTrackEdit::duplicate_selection() { //reselect duplicated selection.clear(); - for (List<Pair<int, float>>::Element *E = new_selection_values.front(); E; E = E->next()) { - int track = E->get().first; - float time = E->get().second; + for (const Pair<int, float> &E : new_selection_values) { + int track = E.first; + float time = E.second; int existing_idx = animation->track_find_key(track, time, true); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 174f19280a..91835c1866 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -598,12 +598,12 @@ public: if (ap) { List<StringName> anims; ap->get_animation_list(&anims); - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { + for (const StringName &E : anims) { if (animations != String()) { animations += ","; } - animations += String(E->get()); + animations += String(E); } } } @@ -702,8 +702,8 @@ public: for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { int key = 0; - for (List<float>::Element *F = E->value().front(); F; F = F->next()) { - float key_ofs = F->get(); + for (float &F : E->value()) { + float key_ofs = F; if (from != key_ofs) { key++; continue; @@ -728,8 +728,8 @@ public: bool change_notify_deserved = false; for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { int track = E->key(); - for (List<float>::Element *F = E->value().front(); F; F = F->next()) { - float key_ofs = F->get(); + for (float &F : E->value()) { + float key_ofs = F; int key = animation->track_find_key(track, key_ofs, true); ERR_FAIL_COND_V(key == -1, false); @@ -986,8 +986,8 @@ public: bool _get(const StringName &p_name, Variant &r_ret) const { for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { int track = E->key(); - for (List<float>::Element *F = E->value().front(); F; F = F->next()) { - float key_ofs = F->get(); + for (float &F : E->value()) { + float key_ofs = F; int key = animation->track_find_key(track, key_ofs, true); ERR_CONTINUE(key == -1); @@ -1137,8 +1137,8 @@ public: same_key_type = false; } - for (List<float>::Element *F = E->value().front(); F; F = F->next()) { - int key = animation->track_find_key(track, F->get(), true); + for (float &F : E->value()) { + int key = animation->track_find_key(track, F, true); ERR_FAIL_COND(key == -1); if (first_key < 0) { first_key = key; @@ -3356,9 +3356,9 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) { } insert_frame = Engine::get_singleton()->get_frames_drawn(); - for (List<InsertData>::Element *E = insert_data.front(); E; E = E->next()) { + for (const InsertData &E : insert_data) { //prevent insertion of multiple tracks - if (E->get().path == p_id.path) { + if (E.path == p_id.path) { return; //already inserted a track for this on this frame } } @@ -3843,9 +3843,9 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b List<PropertyInfo> pinfo; property_info_base.get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().name == leftover_path[leftover_path.size() - 1]) { - return E->get(); + for (const PropertyInfo &E : pinfo) { + if (E.name == leftover_path[leftover_path.size() - 1]) { + return E; } } @@ -4675,21 +4675,21 @@ void AnimationTrackEditor::_add_method_key(const String &p_method) { List<MethodInfo> minfo; base->get_method_list(&minfo); - for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) { - if (E->get().name == p_method) { + for (const MethodInfo &E : minfo) { + if (E.name == p_method) { Dictionary d; d["method"] = p_method; Array params; - int first_defarg = E->get().arguments.size() - E->get().default_arguments.size(); + int first_defarg = E.arguments.size() - E.default_arguments.size(); - for (int i = 0; i < E->get().arguments.size(); i++) { + for (int i = 0; i < E.arguments.size(); i++) { if (i >= first_defarg) { - Variant arg = E->get().default_arguments[i - first_defarg]; + Variant arg = E.default_arguments[i - first_defarg]; params.push_back(arg); } else { Callable::CallError ce; Variant arg; - Variant::construct(E->get().arguments[i].type, arg, nullptr, 0, ce); + Variant::construct(E.arguments[i].type, arg, nullptr, 0, ce); params.push_back(arg); } } @@ -4936,8 +4936,7 @@ void AnimationTrackEditor::_move_selection_commit() { } // 6 - (undo) reinsert overlapped keys - for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) { - _AnimMoveRestore &amr = E->get(); + for (_AnimMoveRestore &amr : to_restore) { undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition); } @@ -5151,9 +5150,9 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) { //reselect duplicated Map<SelectedKey, KeyInfo> new_selection; - for (List<Pair<int, float>>::Element *E = new_selection_values.front(); E; E = E->next()) { - int track = E->get().first; - float time = E->get().second; + for (const Pair<int, float> &E : new_selection_values) { + int track = E.first; + float time = E.second; int existing_idx = animation->track_find_key(track, time, true); @@ -5462,8 +5461,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } // 6-(undo) reinsert overlapped keys - for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) { - _AnimMoveRestore &amr = E->get(); + for (_AnimMoveRestore &amr : to_restore) { undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition); } @@ -5543,8 +5541,8 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { if (cleanup_all->is_pressed()) { List<StringName> names; AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - _cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E->get())); + for (const StringName &E : names) { + _cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E)); } } else { _cleanup_animation(animation); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index b0ec346afe..03695419cb 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -854,9 +854,7 @@ void CodeTextEditor::_complete_request() { return; } - for (List<ScriptCodeCompletionOption>::Element *E = entries.front(); E; E = E->next()) { - ScriptCodeCompletionOption &e = E->get(); - + for (const ScriptCodeCompletionOption &e : entries) { Color font_color = completion_font_color; if (e.insert_text.begins_with("\"") || e.insert_text.begins_with("\'")) { font_color = completion_string_color; diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index c439d6a1d4..c773f51342 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -944,9 +944,7 @@ void ConnectionsDock::update_tree() { node_signals2.sort(); } - for (List<MethodInfo>::Element *E = node_signals2.front(); E; E = E->next()) { - MethodInfo &mi = E->get(); - + for (MethodInfo &mi : node_signals2) { StringName signal_name = mi.name; String signaldesc = "("; PackedStringArray argnames; @@ -1025,8 +1023,8 @@ void ConnectionsDock::update_tree() { List<Object::Connection> connections; selectedNode->get_signal_connection_list(signal_name, &connections); - for (List<Object::Connection>::Element *F = connections.front(); F; F = F->next()) { - Connection cn = F->get(); + for (const Object::Connection &F : connections) { + Connection cn = F; if (!(cn.flags & CONNECT_PERSIST)) { continue; } diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index bfbd697409..3389b53317 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -447,8 +447,7 @@ Variant CreateDialog::instance_selected() { List<PropertyInfo> pinfo; ((Object *)obj)->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - PropertyInfo pi = E->get(); + for (const PropertyInfo &pi : pinfo) { if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) { Object *prop = ClassDB::instantiate(pi.class_name); ((Object *)obj)->set(pi.name, prop); diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index a629bf6159..a1eb71235c 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -56,8 +56,8 @@ bool EditorDebuggerRemoteObject::_get(const StringName &p_name, Variant &r_ret) void EditorDebuggerRemoteObject::_get_property_list(List<PropertyInfo> *p_list) const { p_list->clear(); //sorry, no want category - for (const List<PropertyInfo>::Element *E = prop_list.front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (const PropertyInfo &E : prop_list) { + p_list->push_back(E); } } diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 6b015e1fda..fa9c9f61f5 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -588,8 +588,8 @@ EditorProfiler::EditorProfiler() { hb->add_child(memnew(Label(TTR("Measure:")))); display_mode = memnew(OptionButton); - display_mode->add_item(TTR("Frame Time (sec)")); - display_mode->add_item(TTR("Average Time (sec)")); + display_mode->add_item(TTR("Frame Time (ms)")); + display_mode->add_item(TTR("Average Time (ms)")); display_mode->add_item(TTR("Frame %")); display_mode->add_item(TTR("Physics Frame %")); display_mode->connect("item_selected", callable_mp(this, &EditorProfiler::_combo_changed)); @@ -601,6 +601,7 @@ EditorProfiler::EditorProfiler() { display_time = memnew(OptionButton); display_time->add_item(TTR("Inclusive")); display_time->add_item(TTR("Self")); + display_time->set_tooltip(TTR("Inclusive: Includes time from other functions called by this function.\nUse this to spot bottlenecks.\n\nSelf: Only count the time spent in the function itself, not in other functions called by that function.\nUse this to find individual functions to optimize.")); display_time->connect("item_selected", callable_mp(this, &EditorProfiler::_combo_changed)); hb->add_child(display_time); diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index a61e9bd73e..f17ad0d36c 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -365,13 +365,13 @@ void EditorVisualProfiler::_update_frame(bool p_focus_selected) { } TreeItem *category = variables->create_item(parent); - for (List<TreeItem *>::Element *E = stack.front(); E; E = E->next()) { - float total_cpu = E->get()->get_metadata(1); - float total_gpu = E->get()->get_metadata(2); + for (TreeItem *E : stack) { + float total_cpu = E->get_metadata(1); + float total_gpu = E->get_metadata(2); total_cpu += cpu_time; total_gpu += gpu_time; - E->get()->set_metadata(1, cpu_time); - E->get()->set_metadata(2, gpu_time); + E->set_metadata(1, cpu_time); + E->set_metadata(2, gpu_time); } category->set_icon(0, track_icon); @@ -392,11 +392,11 @@ void EditorVisualProfiler::_update_frame(bool p_focus_selected) { } } - for (List<TreeItem *>::Element *E = categories.front(); E; E = E->next()) { - float total_cpu = E->get()->get_metadata(1); - float total_gpu = E->get()->get_metadata(2); - E->get()->set_text(1, _get_time_as_text(total_cpu)); - E->get()->set_text(2, _get_time_as_text(total_gpu)); + for (TreeItem *E : categories) { + float total_cpu = E->get_metadata(1); + float total_gpu = E->get_metadata(2); + E->set_text(1, _get_time_as_text(total_cpu)); + E->set_text(2, _get_time_as_text(total_gpu)); } if (ensure_selected) { diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 06b02cceb4..9856fbec74 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -347,13 +347,13 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da uint64_t total = 0; - for (List<DebuggerMarshalls::ResourceInfo>::Element *E = usage.infos.front(); E; E = E->next()) { + for (const DebuggerMarshalls::ResourceInfo &E : usage.infos) { TreeItem *it = vmem_tree->create_item(root); - String type = E->get().type; - int bytes = E->get().vram; - it->set_text(0, E->get().path); + String type = E.type; + int bytes = E.vram; + it->set_text(0, E.path); it->set_text(1, type); - it->set_text(2, E->get().format); + it->set_text(2, E.format); it->set_text(3, String::humanize_size(bytes)); total += bytes; diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index c18b8743cd..069ae2c7f2 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -55,8 +55,8 @@ void DependencyEditor::_load_pressed(Object *p_item, int p_cell, int p_button) { search->clear_filters(); List<String> ext; ResourceLoader::get_recognized_extensions_for_type(ti->get_metadata(0), &ext); - for (List<String>::Element *E = ext.front(); E; E = E->next()) { - search->add_filter("*" + E->get()); + for (const String &E : ext) { + search->add_filter("*" + E); } search->popup_file_dialog(); } @@ -120,13 +120,13 @@ void DependencyEditor::_fix_all() { Map<String, Map<String, String>> candidates; - for (List<String>::Element *E = missing.front(); E; E = E->next()) { - String base = E->get().get_file(); + for (const String &E : missing) { + String base = E.get_file(); if (!candidates.has(base)) { candidates[base] = Map<String, String>(); } - candidates[base][E->get()] = ""; + candidates[base][E] = ""; } _fix_and_find(EditorFileSystem::get_singleton()->get_filesystem(), candidates); @@ -166,10 +166,8 @@ void DependencyEditor::_update_list() { bool broken = false; - for (List<String>::Element *E = deps.front(); E; E = E->next()) { + for (const String &n : deps) { TreeItem *item = tree->create_item(root); - - String n = E->get(); String path; String type; @@ -180,6 +178,15 @@ void DependencyEditor::_update_list() { path = n; type = "Resource"; } + + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(path); + if (uid != ResourceUID::INVALID_ID) { + // dependency is in uid format, obtain proper path + ERR_CONTINUE(!ResourceUID::get_singleton()->has_id(uid)); + + path = ResourceUID::get_singleton()->get_id_path(uid); + } + String name = path.get_file(); Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(type); @@ -741,9 +748,9 @@ void OrphanResourcesDialog::_find_to_delete(TreeItem *p_item, List<String> &path void OrphanResourcesDialog::_delete_confirm() { DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - for (List<String>::Element *E = paths.front(); E; E = E->next()) { - da->remove(E->get()); - EditorFileSystem::get_singleton()->update_file(E->get()); + for (const String &E : paths) { + da->remove(E); + EditorFileSystem::get_singleton()->update_file(E); } memdelete(da); refresh(); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index befafec6cb..cbd4a1b916 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -266,20 +266,20 @@ void DocTools::generate(bool p_basic_types) { } List<PropertyInfo>::Element *EO = own_properties.front(); - for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { + for (const PropertyInfo &E : properties) { bool inherited = EO == nullptr; - if (EO && EO->get() == E->get()) { + if (EO && EO->get() == E) { inherited = false; EO = EO->next(); } - if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL) { + if (E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP || E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_INTERNAL) { continue; } DocData::PropertyDoc prop; - prop.name = E->get().name; + prop.name = E.name; prop.overridden = inherited; @@ -288,20 +288,20 @@ void DocTools::generate(bool p_basic_types) { if (name == "ProjectSettings") { // Special case for project settings, so that settings are not taken from the current project's settings - if (E->get().name == "script" || !ProjectSettings::get_singleton()->is_builtin_setting(E->get().name)) { + if (E.name == "script" || !ProjectSettings::get_singleton()->is_builtin_setting(E.name)) { continue; } - if (E->get().usage & PROPERTY_USAGE_EDITOR) { - if (!ProjectSettings::get_singleton()->get_ignore_value_in_docs(E->get().name)) { - default_value = ProjectSettings::get_singleton()->property_get_revert(E->get().name); + if (E.usage & PROPERTY_USAGE_EDITOR) { + if (!ProjectSettings::get_singleton()->get_ignore_value_in_docs(E.name)) { + default_value = ProjectSettings::get_singleton()->property_get_revert(E.name); default_value_valid = true; } } } else { - default_value = get_documentation_default_value(name, E->get().name, default_value_valid); + default_value = get_documentation_default_value(name, E.name, default_value_valid); if (inherited) { bool base_default_value_valid = false; - Variant base_default_value = get_documentation_default_value(ClassDB::get_parent_class(name), E->get().name, base_default_value_valid); + Variant base_default_value = get_documentation_default_value(ClassDB::get_parent_class(name), E.name, base_default_value_valid); if (!default_value_valid || !base_default_value_valid || default_value == base_default_value) { continue; } @@ -309,13 +309,13 @@ void DocTools::generate(bool p_basic_types) { } //used to track uninitialized values using valgrind - //print_line("getting default value for " + String(name) + "." + String(E->get().name)); + //print_line("getting default value for " + String(name) + "." + String(E.name)); if (default_value_valid && default_value.get_type() != Variant::OBJECT) { prop.default_value = default_value.get_construct_string().replace("\n", ""); } - StringName setter = ClassDB::get_property_setter(name, E->get().name); - StringName getter = ClassDB::get_property_getter(name, E->get().name); + StringName setter = ClassDB::get_property_setter(name, E.name); + StringName getter = ClassDB::get_property_getter(name, E.name); prop.setter = setter; prop.getter = getter; @@ -353,10 +353,10 @@ void DocTools::generate(bool p_basic_types) { } if (!found_type) { - if (E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { - prop.type = E->get().hint_string; + if (E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_RESOURCE_TYPE) { + prop.type = E.hint_string; } else { - prop.type = Variant::get_type_name(E->get().type); + prop.type = Variant::get_type_name(E.type); } } @@ -367,62 +367,62 @@ void DocTools::generate(bool p_basic_types) { ClassDB::get_method_list(name, &method_list, true); method_list.sort(); - for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { - if (E->get().name == "" || (E->get().name[0] == '_' && !(E->get().flags & METHOD_FLAG_VIRTUAL))) { + for (const MethodInfo &E : method_list) { + if (E.name == "" || (E.name[0] == '_' && !(E.flags & METHOD_FLAG_VIRTUAL))) { continue; //hidden, don't count } - if (skip_setter_getter_methods && setters_getters.has(E->get().name)) { + if (skip_setter_getter_methods && setters_getters.has(E.name)) { // Don't skip parametric setters and getters, i.e. method which require // one or more parameters to define what property should be set or retrieved. // E.g. CPUParticles3D::set_param(Parameter param, float value). - if (E->get().arguments.size() == 0 /* getter */ || (E->get().arguments.size() == 1 && E->get().return_val.type == Variant::NIL /* setter */)) { + if (E.arguments.size() == 0 /* getter */ || (E.arguments.size() == 1 && E.return_val.type == Variant::NIL /* setter */)) { continue; } } DocData::MethodDoc method; - method.name = E->get().name; + method.name = E.name; - if (E->get().flags & METHOD_FLAG_VIRTUAL) { + if (E.flags & METHOD_FLAG_VIRTUAL) { method.qualifiers = "virtual"; } - if (E->get().flags & METHOD_FLAG_CONST) { + if (E.flags & METHOD_FLAG_CONST) { if (method.qualifiers != "") { method.qualifiers += " "; } method.qualifiers += "const"; } - if (E->get().flags & METHOD_FLAG_VARARG) { + if (E.flags & METHOD_FLAG_VARARG) { if (method.qualifiers != "") { method.qualifiers += " "; } method.qualifiers += "vararg"; } - if (E->get().flags & METHOD_FLAG_STATIC) { + if (E.flags & METHOD_FLAG_STATIC) { if (method.qualifiers != "") { method.qualifiers += " "; } method.qualifiers += "static"; } - for (int i = -1; i < E->get().arguments.size(); i++) { + for (int i = -1; i < E.arguments.size(); i++) { if (i == -1) { #ifdef DEBUG_METHODS_ENABLED - DocData::return_doc_from_retinfo(method, E->get().return_val); + DocData::return_doc_from_retinfo(method, E.return_val); #endif } else { - const PropertyInfo &arginfo = E->get().arguments[i]; + const PropertyInfo &arginfo = E.arguments[i]; DocData::ArgumentDoc argument; DocData::argument_doc_from_arginfo(argument, arginfo); - int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size()); + int darg_idx = i - (E.arguments.size() - E.default_arguments.size()); if (darg_idx >= 0) { - Variant default_arg = E->get().default_arguments[darg_idx]; + Variant default_arg = E.default_arguments[darg_idx]; argument.default_value = default_arg.get_construct_string(); } @@ -455,12 +455,12 @@ void DocTools::generate(bool p_basic_types) { List<String> constant_list; ClassDB::get_integer_constant_list(name, &constant_list, true); - for (List<String>::Element *E = constant_list.front(); E; E = E->next()) { + for (const String &E : constant_list) { DocData::ConstantDoc constant; - constant.name = E->get(); - constant.value = itos(ClassDB::get_integer_constant(name, E->get())); + constant.name = E; + constant.value = itos(ClassDB::get_integer_constant(name, E)); constant.is_value_valid = true; - constant.enumeration = ClassDB::get_integer_constant_enum(name, E->get()); + constant.enumeration = ClassDB::get_integer_constant_enum(name, E); c.constants.push_back(constant); } @@ -469,53 +469,53 @@ void DocTools::generate(bool p_basic_types) { { List<StringName> l; Theme::get_default()->get_constant_list(cname, &l); - for (List<StringName>::Element *E = l.front(); E; E = E->next()) { + for (const StringName &E : l) { DocData::PropertyDoc pd; - pd.name = E->get(); + pd.name = E; pd.type = "int"; - pd.default_value = itos(Theme::get_default()->get_constant(E->get(), cname)); + pd.default_value = itos(Theme::get_default()->get_constant(E, cname)); c.theme_properties.push_back(pd); } l.clear(); Theme::get_default()->get_color_list(cname, &l); - for (List<StringName>::Element *E = l.front(); E; E = E->next()) { + for (const StringName &E : l) { DocData::PropertyDoc pd; - pd.name = E->get(); + pd.name = E; pd.type = "Color"; - pd.default_value = Variant(Theme::get_default()->get_color(E->get(), cname)).get_construct_string(); + pd.default_value = Variant(Theme::get_default()->get_color(E, cname)).get_construct_string(); c.theme_properties.push_back(pd); } l.clear(); Theme::get_default()->get_icon_list(cname, &l); - for (List<StringName>::Element *E = l.front(); E; E = E->next()) { + for (const StringName &E : l) { DocData::PropertyDoc pd; - pd.name = E->get(); + pd.name = E; pd.type = "Texture2D"; c.theme_properties.push_back(pd); } l.clear(); Theme::get_default()->get_font_list(cname, &l); - for (List<StringName>::Element *E = l.front(); E; E = E->next()) { + for (const StringName &E : l) { DocData::PropertyDoc pd; - pd.name = E->get(); + pd.name = E; pd.type = "Font"; c.theme_properties.push_back(pd); } l.clear(); Theme::get_default()->get_font_size_list(cname, &l); - for (List<StringName>::Element *E = l.front(); E; E = E->next()) { + for (const StringName &E : l) { DocData::PropertyDoc pd; - pd.name = E->get(); + pd.name = E; pd.type = "int"; c.theme_properties.push_back(pd); } l.clear(); Theme::get_default()->get_stylebox_list(cname, &l); - for (List<StringName>::Element *E = l.front(); E; E = E->next()) { + for (const StringName &E : l) { DocData::PropertyDoc pd; - pd.name = E->get(); + pd.name = E; pd.type = "StyleBox"; c.theme_properties.push_back(pd); } @@ -621,8 +621,7 @@ void DocTools::generate(bool p_basic_types) { method_list.push_back(mi); } - for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { - MethodInfo &mi = E->get(); + for (const MethodInfo &mi : method_list) { DocData::MethodDoc method; method.name = mi.name; @@ -675,8 +674,7 @@ void DocTools::generate(bool p_basic_types) { List<PropertyInfo> properties; v.get_property_list(&properties); - for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - PropertyInfo pi = E->get(); + for (const PropertyInfo &pi : properties) { DocData::PropertyDoc property; property.name = pi.name; property.type = Variant::get_type_name(pi.type); @@ -688,10 +686,10 @@ void DocTools::generate(bool p_basic_types) { List<StringName> constants; Variant::get_constants_for_type(Variant::Type(i), &constants); - for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { + for (const StringName &E : constants) { DocData::ConstantDoc constant; - constant.name = E->get(); - Variant value = Variant::get_constant_value(Variant::Type(i), E->get()); + constant.name = E; + Variant value = Variant::get_constant_value(Variant::Type(i), E); constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string(); constant.is_value_valid = true; c.constants.push_back(constant); @@ -723,9 +721,8 @@ void DocTools::generate(bool p_basic_types) { Engine::get_singleton()->get_singletons(&singletons); //servers (this is kind of hackish) - for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { + for (const Engine::Singleton &s : singletons) { DocData::PropertyDoc pd; - Engine::Singleton &s = E->get(); if (!s.ptr) { continue; } @@ -743,13 +740,13 @@ void DocTools::generate(bool p_basic_types) { List<StringName> utility_functions; Variant::get_utility_function_list(&utility_functions); utility_functions.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { + for (const StringName &E : utility_functions) { DocData::MethodDoc md; - md.name = E->get(); + md.name = E; //return - if (Variant::has_utility_function_return_value(E->get())) { + if (Variant::has_utility_function_return_value(E)) { PropertyInfo pi; - pi.type = Variant::get_utility_function_return_type(E->get()); + pi.type = Variant::get_utility_function_return_type(E); if (pi.type == Variant::NIL) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } @@ -758,13 +755,13 @@ void DocTools::generate(bool p_basic_types) { md.return_type = ad.type; } - if (Variant::is_utility_function_vararg(E->get())) { + if (Variant::is_utility_function_vararg(E)) { md.qualifiers = "vararg"; } else { - for (int i = 0; i < Variant::get_utility_function_argument_count(E->get()); i++) { + for (int i = 0; i < Variant::get_utility_function_argument_count(E); i++) { PropertyInfo pi; - pi.type = Variant::get_utility_function_argument_type(E->get(), i); - pi.name = Variant::get_utility_function_argument_name(E->get(), i); + pi.type = Variant::get_utility_function_argument_type(E, i); + pi.name = Variant::get_utility_function_argument_name(E, i); if (pi.type == Variant::NIL) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } @@ -793,8 +790,7 @@ void DocTools::generate(bool p_basic_types) { List<MethodInfo> minfo; lang->get_public_functions(&minfo); - for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) { - MethodInfo &mi = E->get(); + for (const MethodInfo &mi : minfo) { DocData::MethodDoc md; md.name = mi.name; @@ -813,7 +809,7 @@ void DocTools::generate(bool p_basic_types) { int darg_idx = j - (mi.arguments.size() - mi.default_arguments.size()); if (darg_idx >= 0) { - Variant default_arg = E->get().default_arguments[darg_idx]; + Variant default_arg = mi.default_arguments[darg_idx]; ad.default_value = default_arg.get_construct_string(); } @@ -827,10 +823,10 @@ void DocTools::generate(bool p_basic_types) { List<Pair<String, Variant>> cinfo; lang->get_public_constants(&cinfo); - for (List<Pair<String, Variant>>::Element *E = cinfo.front(); E; E = E->next()) { + for (const Pair<String, Variant> &E : cinfo) { DocData::ConstantDoc cd; - cd.name = E->get().first; - cd.value = E->get().second; + cd.name = E.first; + cd.value = E.second; cd.is_value_valid = true; c.constants.push_back(cd); } diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index d94ac21837..4a19f007d4 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -920,15 +920,15 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { List<StringName> effects; ClassDB::get_inheriters_from_class("AudioEffect", &effects); effects.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = effects.front(); E; E = E->next()) { - if (!ClassDB::can_instantiate(E->get())) { + for (const StringName &E : effects) { + if (!ClassDB::can_instantiate(E)) { continue; } - Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(E->get()); - String name = E->get().operator String().replace("AudioEffect", ""); + Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(E); + String name = E.operator String().replace("AudioEffect", ""); effect_options->add_item(name); - effect_options->set_item_metadata(effect_options->get_item_count() - 1, E->get()); + effect_options->set_item_metadata(effect_options->get_item_count() - 1, E); effect_options->set_item_icon(effect_options->get_item_count() - 1, icon); } @@ -1331,8 +1331,8 @@ EditorAudioBuses::EditorAudioBuses() { file_dialog = memnew(EditorFileDialog); List<String> ext; ResourceLoader::get_recognized_extensions_for_type("AudioBusLayout", &ext); - for (List<String>::Element *E = ext.front(); E; E = E->next()) { - file_dialog->add_filter("*." + E->get() + "; Audio Bus Layout"); + for (const String &E : ext) { + file_dialog->add_filter("*." + E + "; Audio Bus Layout"); } add_child(file_dialog); file_dialog->connect("file_selected", callable_mp(this, &EditorAudioBuses::_file_dialog_callback)); diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index c6d52107cd..fad76682b5 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -46,12 +46,11 @@ void EditorAutoloadSettings::_notification(int p_what) { ResourceLoader::get_recognized_extensions_for_type("Script", &afn); ResourceLoader::get_recognized_extensions_for_type("PackedScene", &afn); - for (List<String>::Element *E = afn.front(); E; E = E->next()) { - file_dialog->add_filter("*." + E->get()); + for (const String &E : afn) { + file_dialog->add_filter("*." + E); } - for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) { - AutoLoadInfo &info = E->get(); + for (const AutoLoadInfo &info : autoload_cache) { if (info.node && info.in_editor) { get_tree()->get_root()->call_deferred(SNAME("add_child"), info.node); } @@ -102,8 +101,8 @@ bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, Strin for (int i = 0; i < ScriptServer::get_language_count(); i++) { List<String> keywords; ScriptServer::get_language(i)->get_reserved_words(&keywords); - for (List<String>::Element *E = keywords.front(); E; E = E->next()) { - if (E->get() == p_name) { + for (const String &E : keywords) { + if (E == p_name) { if (r_error) { *r_error = TTR("Invalid name.") + "\n" + TTR("Keyword cannot be used as an autoload name."); } @@ -379,8 +378,7 @@ void EditorAutoloadSettings::update_autoload() { Map<String, AutoLoadInfo> to_remove; List<AutoLoadInfo *> to_add; - for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) { - AutoLoadInfo &info = E->get(); + for (const AutoLoadInfo &info : autoload_cache) { to_remove.insert(info.name, info); } @@ -392,9 +390,7 @@ void EditorAutoloadSettings::update_autoload() { List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (const PropertyInfo &pi : props) { if (!pi.name.begins_with("autoload/")) { continue; } @@ -483,9 +479,7 @@ void EditorAutoloadSettings::update_autoload() { // Load new/changed autoloads List<Node *> nodes_to_add; - for (List<AutoLoadInfo *>::Element *E = to_add.front(); E; E = E->next()) { - AutoLoadInfo *info = E->get(); - + for (AutoLoadInfo *info : to_add) { info->node = _create_autoload(info->path); ERR_CONTINUE(!info->node); @@ -518,8 +512,8 @@ void EditorAutoloadSettings::update_autoload() { } } - for (List<Node *>::Element *E = nodes_to_add.front(); E; E = E->next()) { - get_tree()->get_root()->add_child(E->get()); + for (Node *E : nodes_to_add) { + get_tree()->get_root()->add_child(E); } updating_autoload = false; @@ -649,8 +643,8 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant & int i = 0; - for (List<AutoLoadInfo>::Element *F = autoload_cache.front(); F; F = F->next()) { - orders.write[i++] = F->get().order; + for (const AutoLoadInfo &F : autoload_cache) { + orders.write[i++] = F.order; } orders.sort(); @@ -661,9 +655,9 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant & i = 0; - for (List<AutoLoadInfo>::Element *F = autoload_cache.front(); F; F = F->next()) { - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", "autoload/" + F->get().name, orders[i++]); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", "autoload/" + F->get().name, F->get().order); + for (const AutoLoadInfo &F : autoload_cache) { + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", "autoload/" + F.name, orders[i++]); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", "autoload/" + F.name, F.order); } orders.clear(); @@ -764,9 +758,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() { // Make first cache List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (const PropertyInfo &pi : props) { if (!pi.name.begins_with("autoload/")) { continue; } @@ -799,9 +791,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() { autoload_cache.push_back(info); } - for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) { - AutoLoadInfo &info = E->get(); - + for (AutoLoadInfo &info : autoload_cache) { info.node = _create_autoload(info.path); if (info.node) { @@ -904,8 +894,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() { } EditorAutoloadSettings::~EditorAutoloadSettings() { - for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) { - AutoLoadInfo &info = E->get(); + for (const AutoLoadInfo &info : autoload_cache) { if (info.node && !info.in_editor) { memdelete(info.node); } diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 3529a4fbdc..c62e5b75b2 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -299,13 +299,13 @@ void EditorData::copy_object_params(Object *p_object) { List<PropertyInfo> pinfo; p_object->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_EDITOR) || E->get().name == "script" || E->get().name == "scripts") { + for (const PropertyInfo &E : pinfo) { + if (!(E.usage & PROPERTY_USAGE_EDITOR) || E.name == "script" || E.name == "scripts") { continue; } PropertyData pd; - pd.name = E->get().name; + pd.name = E.name; pd.value = p_object->get(pd.name); clipboard.push_back(pd); } @@ -404,9 +404,9 @@ void EditorData::restore_editor_global_states() { void EditorData::paste_object_params(Object *p_object) { ERR_FAIL_NULL(p_object); undo_redo.create_action(TTR("Paste Params")); - for (List<PropertyData>::Element *E = clipboard.front(); E; E = E->next()) { - String name = E->get().name; - undo_redo.add_do_property(p_object, name, E->get().value); + for (const PropertyData &E : clipboard) { + String name = E.name; + undo_redo.add_do_property(p_object, name, E.value); undo_redo.add_undo_property(p_object, name, p_object->get(name)); } undo_redo.commit_action(); @@ -616,8 +616,8 @@ bool EditorData::check_and_update_scene(int p_idx) { //transfer selection List<Node *> new_selection; - for (List<Node *>::Element *E = edited_scene.write[p_idx].selection.front(); E; E = E->next()) { - NodePath p = edited_scene[p_idx].root->get_path_to(E->get()); + for (const Node *E : edited_scene.write[p_idx].selection) { + NodePath p = edited_scene[p_idx].root->get_path_to(E); Node *new_node = new_scene->get_node(p); if (new_node) { new_selection.push_back(new_node); @@ -841,8 +841,8 @@ Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, p_history->history = es.history_stored; p_selection->clear(); - for (List<Node *>::Element *E = es.selection.front(); E; E = E->next()) { - p_selection->add_node(E->get()); + for (Node *E : es.selection) { + p_selection->add_node(E); } set_editor_states(es.editor_states); @@ -964,9 +964,9 @@ void EditorData::script_class_save_icon_paths() { _script_class_icon_paths.get_key_list(&keys); Dictionary d; - for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { - if (ScriptServer::is_global_class(E->get())) { - d[E->get()] = _script_class_icon_paths[E->get()]; + for (const StringName &E : keys) { + if (ScriptServer::is_global_class(E)) { + d[E] = _script_class_icon_paths[E]; } } @@ -996,8 +996,8 @@ void EditorData::script_class_load_icon_paths() { List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - String name = E->get().operator String(); + for (const Variant &E : keys) { + String name = E.operator String(); _script_class_icon_paths[name] = d[name]; String path = ScriptServer::get_global_class_path(name); @@ -1038,8 +1038,8 @@ void EditorSelection::add_node(Node *p_node) { changed = true; nl_changed = true; Object *meta = nullptr; - for (List<Object *>::Element *E = editor_plugins.front(); E; E = E->next()) { - meta = E->get()->call("_get_editor_data", p_node); + for (Object *E : editor_plugins) { + meta = E->call("_get_editor_data", p_node); if (meta) { break; } @@ -1076,8 +1076,8 @@ bool EditorSelection::is_selected(Node *p_node) const { Array EditorSelection::_get_transformable_selected_nodes() { Array ret; - for (List<Node *>::Element *E = selected_node_list.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const Node *E : selected_node_list) { + ret.push_back(E); } return ret; diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index fc483b46b7..b374f56f6d 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -80,9 +80,9 @@ bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const { } void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const { - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (platform->get_option_visibility(E->get().name, values)) { - p_list->push_back(E->get()); + for (const PropertyInfo &E : properties) { + if (platform->get_option_visibility(E.name, values)) { + p_list->push_back(E); } } } @@ -436,9 +436,9 @@ Ref<EditorExportPreset> EditorExportPlatform::create_preset() { List<ExportOption> options; get_export_options(&options); - for (List<ExportOption>::Element *E = options.front(); E; E = E->next()) { - preset->properties.push_back(E->get().option); - preset->values[E->get().option.name] = E->get().default_value; + for (const ExportOption &E : options) { + preset->properties.push_back(E.option); + preset->values[E.option.name] = E.default_value; } return preset; @@ -679,9 +679,9 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai platform->get_preset_features(p_preset, &feature_list); FeatureContainers result; - for (List<String>::Element *E = feature_list.front(); E; E = E->next()) { - result.features.insert(E->get()); - result.features_pv.push_back(E->get()); + for (const String &E : feature_list) { + result.features.insert(E); + result.features_pv.push_back(E); } if (p_preset->get_custom_features() != String()) { @@ -752,9 +752,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (const PropertyInfo &pi : props) { if (!pi.name.begins_with("autoload/")) { continue; } @@ -899,8 +897,8 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Set<String> remap_features; - for (List<String>::Element *F = remaps.front(); F; F = F->next()) { - String remap = F->get(); + for (const String &F : remaps) { + String remap = F; String feature = remap.get_slice(".", 1); if (features.has(feature)) { remap_features.insert(feature); @@ -913,8 +911,8 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & err = OK; - for (List<String>::Element *F = remaps.front(); F; F = F->next()) { - String remap = F->get(); + for (const String &F : remaps) { + String remap = F; if (remap == "path") { String remapped_path = config->get_value("remap", remap); Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); @@ -1050,6 +1048,13 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & return err; } } + if (FileAccess::exists(ResourceUID::CACHE_FILE)) { + Vector<uint8_t> array = FileAccess::get_file_as_array(ResourceUID::CACHE_FILE); + err = p_func(p_udata, ResourceUID::CACHE_FILE, array, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } + } // Store text server data if it is supported. if (TS->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { @@ -1362,7 +1367,7 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags if (breakpoints.size()) { r_flags.push_back("--breakpoints"); String bpoints; - for (const List<String>::Element *E = breakpoints.front(); E; E = E->next()) { + for (List<String>::Element *E = breakpoints.front(); E; E = E->next()) { bpoints += E->get().replace(" ", "%20"); if (E->next()) { bpoints += ","; @@ -1436,8 +1441,8 @@ void EditorExport::_save() { String option_section = "preset." + itos(i) + ".options"; - for (const List<PropertyInfo>::Element *E = preset->get_properties().front(); E; E = E->next()) { - config->set_value(option_section, E->get().name, preset->get(E->get().name)); + for (const PropertyInfo &E : preset->get_properties()) { + config->set_value(option_section, E.name, preset->get(E.name)); } } @@ -1642,10 +1647,10 @@ void EditorExport::load_config() { config->get_section_keys(option_section, &options); - for (List<String>::Element *E = options.front(); E; E = E->next()) { - Variant value = config->get_value(option_section, E->get()); + for (const String &E : options) { + Variant value = config->get_value(option_section, E); - preset->set(E->get(), value); + preset->set(E, value); } add_export_preset(preset); @@ -1684,11 +1689,11 @@ void EditorExport::update_export_presets() { preset->properties.clear(); preset->values.clear(); - for (List<EditorExportPlatform::ExportOption>::Element *E = options.front(); E; E = E->next()) { - preset->properties.push_back(E->get().option); + for (const EditorExportPlatform::ExportOption &E : options) { + preset->properties.push_back(E.option); - StringName option_name = E->get().option.name; - preset->values[option_name] = previous_values.has(option_name) ? previous_values[option_name] : E->get().default_value; + StringName option_name = E.option.name; + preset->values[option_name] = previous_values.has(option_name) ? previous_values[option_name] : E.default_value; } } } diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index e36cc7bc2e..22f44a54bb 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -527,9 +527,8 @@ void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const S ClassDB::get_direct_inheriters_from_class(p_class, &child_classes); child_classes.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = child_classes.front(); E; E = E->next()) { - String name = E->get(); - if (name.begins_with("Editor") || ClassDB::get_api_type(name) != ClassDB::API_CORE) { + for (const StringName &name : child_classes) { + if (String(name).begins_with("Editor") || ClassDB::get_api_type(name) != ClassDB::API_CORE) { continue; } _fill_classes_from(class_item, name, p_selected); @@ -597,9 +596,9 @@ void EditorFeatureProfileManager::_class_list_item_selected() { TreeItem *properties = property_list->create_item(root); properties->set_text(0, TTR("Class Properties:")); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String name = E->get().name; - if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) { + for (const PropertyInfo &E : props) { + String name = E.name; + if (!(E.usage & PROPERTY_USAGE_EDITOR)) { continue; } TreeItem *property = property_list->create_item(properties); @@ -609,7 +608,7 @@ void EditorFeatureProfileManager::_class_list_item_selected() { property->set_checked(0, !edited->is_class_property_disabled(class_name, name)); property->set_text(0, name.capitalize()); property->set_metadata(0, name); - String icon_type = Variant::get_type_name(E->get().type); + String icon_type = Variant::get_type_name(E.type); property->set_icon(0, EditorNode::get_singleton()->get_class_icon(icon_type)); } } diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index ed2edb5a5d..5ccbed1b49 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -830,8 +830,8 @@ void EditorFileDialog::update_file_list() { while (!files.is_empty()) { bool match = patterns.is_empty(); - for (List<String>::Element *E = patterns.front(); E; E = E->next()) { - if (files.front()->get().matchn(E->get())) { + for (const String &E : patterns) { + if (files.front()->get().matchn(E)) { match = true; break; } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 82a71c0e0c..78861eff9d 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -43,7 +43,7 @@ EditorFileSystem *EditorFileSystem::singleton = nullptr; //the name is the version, to keep compatibility with different versions of Godot -#define CACHE_FILE_NAME "filesystem_cache6" +#define CACHE_FILE_NAME "filesystem_cache7" void EditorFileSystemDirectory::sort_files() { files.sort_custom<FileInfoSort>(); @@ -116,7 +116,26 @@ String EditorFileSystemDirectory::get_file_path(int p_idx) const { Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, files.size(), Vector<String>()); - return files[p_idx]->deps; + Vector<String> deps; + + for (int i = 0; i < files[p_idx]->deps.size(); i++) { + String dep = files[p_idx]->deps[i]; + int sep_idx = dep.find("::"); //may contain type information, unwanted + if (sep_idx != -1) { + dep = dep.substr(0, sep_idx); + } + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(dep); + if (uid != ResourceUID::INVALID_ID) { + //return proper dependency resource from uid + if (ResourceUID::get_singleton()->has_id(uid)) { + dep = ResourceUID::get_singleton()->get_id_path(uid); + } else { + continue; + } + } + deps.push_back(dep); + } + return deps; } bool EditorFileSystemDirectory::get_file_import_is_valid(int p_idx) const { @@ -234,7 +253,7 @@ void EditorFileSystem::_scan_filesystem() { } else { Vector<String> split = l.split("::"); - ERR_CONTINUE(split.size() != 8); + ERR_CONTINUE(split.size() != 9); String name = split[0]; String file; @@ -243,15 +262,16 @@ void EditorFileSystem::_scan_filesystem() { FileCache fc; fc.type = split[1]; - fc.modification_time = split[2].to_int(); - fc.import_modification_time = split[3].to_int(); - fc.import_valid = split[4].to_int() != 0; - fc.import_group_file = split[5].strip_edges(); - fc.script_class_name = split[6].get_slice("<>", 0); - fc.script_class_extends = split[6].get_slice("<>", 1); - fc.script_class_icon_path = split[6].get_slice("<>", 2); - - String deps = split[7].strip_edges(); + fc.uid = split[2].to_int(); + fc.modification_time = split[3].to_int(); + fc.import_modification_time = split[4].to_int(); + fc.import_valid = split[5].to_int() != 0; + fc.import_group_file = split[6].strip_edges(); + fc.script_class_name = split[7].get_slice("<>", 0); + fc.script_class_extends = split[7].get_slice("<>", 1); + fc.script_class_icon_path = split[7].get_slice("<>", 2); + + String deps = split[8].strip_edges(); if (deps.length()) { Vector<String> dp = deps.split("<>"); for (int i = 0; i < dp.size(); i++) { @@ -368,6 +388,7 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo Vector<String> dest_files; String dest_md5 = ""; int version = 0; + bool found_uid = false; while (true) { assign = Variant(); @@ -395,6 +416,8 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo version = value; } else if (assign == "importer") { importer_name = value; + } else if (assign == "uid") { + found_uid = true; } else if (!p_only_imported_files) { if (assign == "source_file") { source_file = value; @@ -414,6 +437,10 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo return false; //keep mode, do not reimport } + if (!found_uid) { + return true; //UUID not found, old format, reimport. + } + Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name); if (importer->get_format_version() > version) { @@ -457,8 +484,8 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo memdelete(md5s); //imported files are gone, reimport - for (List<String>::Element *E = to_check.front(); E; E = E->next()) { - if (!FileAccess::exists(E->get())) { + for (const String &E : to_check) { + if (!FileAccess::exists(E)) { return true; } } @@ -497,9 +524,7 @@ bool EditorFileSystem::_update_scan_actions() { Vector<String> reimports; Vector<String> reloads; - for (List<ItemAction>::Element *E = scan_actions.front(); E; E = E->next()) { - ItemAction &ia = E->get(); - + for (const ItemAction &ia : scan_actions) { switch (ia.action) { case ItemAction::ACTION_NONE: { } break; @@ -582,6 +607,9 @@ bool EditorFileSystem::_update_scan_actions() { if (reimports.size()) { reimport_files(reimports); + } else { + //reimport files will update the uid cache file so if nothing was reimported, update it manually + ResourceUID::get_singleton()->update_cache(); } if (first_scan) { @@ -756,6 +784,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess if (fc && fc->modification_time == mt && fc->import_modification_time == import_mt && !_test_for_reimport(path, true)) { fi->type = fc->type; + fi->uid = fc->uid; fi->deps = fc->deps; fi->modified_time = fc->modification_time; fi->import_modified_time = fc->import_modification_time; @@ -781,8 +810,14 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess //note: I think this should not happen any longer.. } + if (fc->uid == ResourceUID::INVALID_ID) { + // imported files should always have a UUID, so attempt to fetch it. + fi->uid = ResourceLoader::get_resource_uid(path); + } + } else { fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path); + fi->uid = ResourceFormatImporter::get_singleton()->get_resource_uid(path); fi->import_group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(path); fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path); fi->modified_time = 0; @@ -799,6 +834,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess if (fc && fc->modification_time == mt) { //not imported, so just update type if changed fi->type = fc->type; + fi->uid = fc->uid; fi->modified_time = fc->modification_time; fi->deps = fc->deps; fi->import_modified_time = 0; @@ -809,6 +845,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess } else { //new or modified time fi->type = ResourceLoader::get_resource_type(path); + fi->uid = ResourceLoader::get_resource_uid(path); fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path); fi->deps = _get_dependencies(path); fi->modified_time = mt; @@ -817,6 +854,14 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess } } + if (fi->uid != ResourceUID::INVALID_ID) { + if (ResourceUID::get_singleton()->has_id(fi->uid)) { + ResourceUID::get_singleton()->set_id(fi->uid, path); + } else { + ResourceUID::get_singleton()->add_id(fi->uid, path); + } + } + for (int i = 0; i < ScriptServer::get_language_count(); i++) { ScriptLanguage *lang = ScriptServer::get_language(i); if (lang->supports_documentation() && fi->type == lang->get_type()) { @@ -1027,8 +1072,8 @@ void EditorFileSystem::_delete_internal_files(String p_file) { List<String> paths; ResourceFormatImporter::get_singleton()->get_internal_resource_path_list(p_file, &paths); DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - for (List<String>::Element *E = paths.front(); E; E = E->next()) { - da->remove(E->get()); + for (const String &E : paths) { + da->remove(E); } da->remove(p_file + ".import"); memdelete(da); @@ -1181,7 +1226,7 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir, if (p_dir->files[i]->import_group_file != String()) { group_file_cache.insert(p_dir->files[i]->import_group_file); } - String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->import_group_file + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path; + String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->uid) + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->import_group_file + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path; s += "::"; for (int j = 0; j < p_dir->files[i]->deps.size(); j++) { if (j > 0) { @@ -1368,8 +1413,8 @@ Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) { ResourceLoader::get_dependencies(p_path, &deps); Vector<String> ret; - for (List<String>::Element *E = deps.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const String &E : deps) { + ret.push_back(E); } return ret; @@ -1462,6 +1507,11 @@ void EditorFileSystem::update_file(const String &p_file) { //was removed _delete_internal_files(p_file); if (cpos != -1) { // Might've never been part of the editor file system (*.* files deleted in Open dialog). + if (fs->files[cpos]->uid != ResourceUID::INVALID_ID) { + if (ResourceUID::get_singleton()->has_id(fs->files[cpos]->uid)) { + ResourceUID::get_singleton()->remove_id(fs->files[cpos]->uid); + } + } memdelete(fs->files[cpos]); fs->files.remove(cpos); } @@ -1472,6 +1522,7 @@ void EditorFileSystem::update_file(const String &p_file) { } String type = ResourceLoader::get_resource_type(p_file); + ResourceUID::ID uid = ResourceLoader::get_resource_uid(p_file); if (cpos == -1) { // The file did not exist, it was added. @@ -1504,12 +1555,22 @@ void EditorFileSystem::update_file(const String &p_file) { } fs->files[cpos]->type = type; + fs->files[cpos]->uid = uid; fs->files[cpos]->script_class_name = _get_global_script_class(type, p_file, &fs->files[cpos]->script_class_extends, &fs->files[cpos]->script_class_icon_path); fs->files[cpos]->import_group_file = ResourceLoader::get_import_group_file(p_file); fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file); fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); + if (uid != ResourceUID::INVALID_ID) { + if (ResourceUID::get_singleton()->has_id(uid)) { + ResourceUID::get_singleton()->set_id(uid, p_file); + } else { + ResourceUID::get_singleton()->add_id(uid, p_file); + } + + ResourceUID::get_singleton()->update_cache(); + } // Update preview EditorResourcePreview::get_singleton()->check_for_invalidation(p_file); @@ -1532,7 +1593,6 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector ERR_CONTINUE(file_importer_name == String()); if (importer_name != String() && importer_name != file_importer_name) { - print_line("one importer '" + importer_name + "' the other '" + file_importer_name + "'."); EditorNode::get_singleton()->show_warning(vformat(TTR("There are multiple importers for different types pointing to file %s, import aborted"), p_group_file)); ERR_FAIL_V(ERR_FILE_CORRUPT); } @@ -1549,15 +1609,14 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector List<ResourceImporter::ImportOption> options; importer->get_import_options(&options); //set default values - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - source_file_options[p_files[i]][E->get().option.name] = E->get().default_value; + for (const ResourceImporter::ImportOption &E : options) { + source_file_options[p_files[i]][E.option.name] = E.default_value; } if (config->has_section("params")) { List<String> sk; config->get_section_keys("params", &sk); - for (List<String>::Element *E = sk.front(); E; E = E->next()) { - String param = E->get(); + for (const String ¶m : sk) { Variant value = config->get_value("params", param); //override with whathever is in file source_file_options[p_files[i]][param] = value; @@ -1631,9 +1690,9 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector List<ResourceImporter::ImportOption> options; importer->get_import_options(&options); //set default values - for (List<ResourceImporter::ImportOption>::Element *F = options.front(); F; F = F->next()) { - String base = F->get().option.name; - Variant v = F->get().default_value; + for (const ResourceImporter::ImportOption &F : options) { + String base = F.option.name; + Variant v = F.default_value; if (source_file_options[file].has(base)) { v = source_file_options[file][base]; } @@ -1702,6 +1761,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName params = *p_custom_options; } + ResourceUID::ID uid = ResourceUID::INVALID_ID; + if (FileAccess::exists(p_file + ".import")) { //use existing if (p_custom_options == nullptr) { @@ -1712,12 +1773,20 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName if (cf->has_section("params")) { List<String> sk; cf->get_section_keys("params", &sk); - for (List<String>::Element *E = sk.front(); E; E = E->next()) { - params[E->get()] = cf->get_value("params", E->get()); + for (const String &E : sk) { + params[E] = cf->get_value("params", E); } } - if (p_custom_importer == String() && cf->has_section("remap")) { - importer_name = cf->get_value("remap", "importer"); + + if (cf->has_section("remap")) { + if (p_custom_importer == String()) { + importer_name = cf->get_value("remap", "importer"); + } + + if (cf->has_section_key("remap", "uid")) { + String uidt = cf->get_value("remap", "uid"); + uid = ResourceUID::get_singleton()->text_to_id(uidt); + } } } } @@ -1754,9 +1823,9 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName List<ResourceImporter::ImportOption> opts; importer->get_import_options(&opts); - for (List<ResourceImporter::ImportOption>::Element *E = opts.front(); E; E = E->next()) { - if (!params.has(E->get().option.name)) { //this one is not present - params[E->get().option.name] = E->get().default_value; + for (const ResourceImporter::ImportOption &E : opts) { + if (!params.has(E.option.name)) { //this one is not present + params[E.option.name] = E.default_value; } } @@ -1766,8 +1835,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName List<Variant> v; d.get_key_list(&v); - for (List<Variant>::Element *E = v.front(); E; E = E->next()) { - params[E->get()] = d[E->get()]; + for (const Variant &E : v) { + params[E] = d[E]; } } @@ -1800,6 +1869,12 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName f->store_line("type=\"" + importer->get_resource_type() + "\""); } + if (uid == ResourceUID::INVALID_ID) { + uid = ResourceUID::get_singleton()->create_id(); + } + + f->store_line("uid=\"" + ResourceUID::get_singleton()->id_to_text(uid) + "\""); //store in readable format + Vector<String> dest_paths; if (err == OK) { @@ -1807,10 +1882,10 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName //no path } else if (import_variants.size()) { //import with variants - for (List<String>::Element *E = import_variants.front(); E; E = E->next()) { - String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension(); + for (const String &E : import_variants) { + String path = base_path.c_escape() + "." + E + "." + importer->get_save_extension(); - f->store_line("path." + E->get() + "=\"" + path + "\""); + f->store_line("path." + E + "=\"" + path + "\""); dest_paths.push_back(path); } } else { @@ -1833,9 +1908,9 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName if (gen_files.size()) { Array genf; - for (List<String>::Element *E = gen_files.front(); E; E = E->next()) { - genf.push_back(E->get()); - dest_paths.push_back(E->get()); + for (const String &E : gen_files) { + genf.push_back(E); + dest_paths.push_back(E); } String value; @@ -1859,8 +1934,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName //store options in provided order, to avoid file changing. Order is also important because first match is accepted first. - for (List<ResourceImporter::ImportOption>::Element *E = opts.front(); E; E = E->next()) { - String base = E->get().option.name; + for (const ResourceImporter::ImportOption &E : opts) { + String base = E.option.name; String value; VariantWriter::write_to_string(params[base], value); f->store_line(base + "=" + value); @@ -1885,8 +1960,15 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import"); fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->type = importer->get_resource_type(); + fs->files[cpos]->uid = uid; fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); + if (ResourceUID::get_singleton()->has_id(uid)) { + ResourceUID::get_singleton()->set_id(uid, p_file); + } else { + ResourceUID::get_singleton()->add_id(uid, p_file); + } + //if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it //to reload properly if (ResourceCache::has(p_file)) { @@ -1937,11 +2019,18 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { Set<String> groups_to_reimport; for (int i = 0; i < p_files.size(); i++) { - String group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(p_files[i]); + String file = p_files[i]; + + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(file); + if (uid != ResourceUID::INVALID_ID && ResourceUID::get_singleton()->has_id(uid)) { + file = ResourceUID::get_singleton()->get_id_path(uid); + } + + String group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(file); - if (group_file_cache.has(p_files[i])) { + if (group_file_cache.has(file)) { //maybe the file itself is a group! - groups_to_reimport.insert(p_files[i]); + groups_to_reimport.insert(file); //groups do not belong to grups group_file = String(); } else if (group_file != String()) { @@ -1950,15 +2039,15 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { } else { //it's a regular file ImportFile ifile; - ifile.path = p_files[i]; - ResourceFormatImporter::get_singleton()->get_import_order_threads_and_importer(p_files[i], ifile.order, ifile.threaded, ifile.importer); + ifile.path = file; + ResourceFormatImporter::get_singleton()->get_import_order_threads_and_importer(file, ifile.order, ifile.threaded, ifile.importer); reimport_files.push_back(ifile); } //group may have changed, so also update group reference EditorFileSystemDirectory *fs = nullptr; int cpos = -1; - if (_find_file(p_files[i], &fs, cpos)) { + if (_find_file(file, &fs, cpos)) { fs->files.write[cpos]->import_group_file = group_file; } } @@ -2023,6 +2112,8 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { } } + ResourceUID::get_singleton()->update_cache(); //after reimporting, update the cache + _save_filesystem_cache(); importing = false; if (!is_scanning()) { @@ -2080,9 +2171,8 @@ void EditorFileSystem::_move_group_files(EditorFileSystemDirectory *efd, const S List<String> sk; config->get_section_keys("params", &sk); - for (List<String>::Element *E = sk.front(); E; E = E->next()) { + for (const String ¶m : sk) { //not very clean, but should work - String param = E->get(); String value = config->get_value("params", param); if (value == p_group_file) { config->set_value("params", param, p_new_location); @@ -2108,6 +2198,30 @@ void EditorFileSystem::move_group_file(const String &p_path, const String &p_new } } +ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate) { + if (!p_path.is_resource_file() || p_path.begins_with("res://.godot")) { + //saved externally (configuration file) or internal file, do not assign an ID. + return ResourceUID::INVALID_ID; + } + + EditorFileSystemDirectory *fs = nullptr; + int cpos = -1; + + if (!singleton->_find_file(p_path, &fs, cpos)) { + if (p_generate) { + return ResourceUID::get_singleton()->create_id(); //just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple. + } else { + return ResourceUID::INVALID_ID; + } + } else if (fs->files[cpos]->uid != ResourceUID::INVALID_ID) { + return fs->files[cpos]->uid; + } else if (p_generate) { + return ResourceUID::get_singleton()->create_id(); //just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple. + } else { + return ResourceUID::INVALID_ID; + } +} + void EditorFileSystem::_bind_methods() { ClassDB::bind_method(D_METHOD("get_filesystem"), &EditorFileSystem::get_filesystem); ClassDB::bind_method(D_METHOD("is_scanning"), &EditorFileSystem::is_scanning); @@ -2131,14 +2245,14 @@ void EditorFileSystem::_update_extensions() { List<String> extensionsl; ResourceLoader::get_recognized_extensions_for_type("", &extensionsl); - for (List<String>::Element *E = extensionsl.front(); E; E = E->next()) { - valid_extensions.insert(E->get()); + for (const String &E : extensionsl) { + valid_extensions.insert(E); } extensionsl.clear(); ResourceFormatImporter::get_singleton()->get_recognized_extensions(&extensionsl); - for (List<String>::Element *E = extensionsl.front(); E; E = E->next()) { - import_extensions.insert(E->get()); + for (const String &E : extensionsl) { + import_extensions.insert(E); } } @@ -2169,8 +2283,11 @@ EditorFileSystem::EditorFileSystem() { scan_changes_pending = false; revalidate_import_files = false; import_threads.init(); + ResourceUID::get_singleton()->clear(); //will be updated on scan + ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path); } EditorFileSystem::~EditorFileSystem() { import_threads.finish(); + ResourceSaver::set_get_resource_id_for_path(nullptr); } diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 37eee13c16..9dce29d09c 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -55,6 +55,7 @@ class EditorFileSystemDirectory : public Object { struct FileInfo { String file; StringName type; + ResourceUID::ID uid = ResourceUID::INVALID_ID; uint64_t modified_time = 0; uint64_t import_modified_time = 0; bool import_valid = false; @@ -159,6 +160,7 @@ class EditorFileSystem : public Node { /* Used for reading the filesystem cache file */ struct FileCache { String type; + ResourceUID::ID uid = ResourceUID::INVALID_ID; uint64_t modification_time = 0; uint64_t import_modification_time = 0; Vector<String> deps; @@ -251,6 +253,8 @@ class EditorFileSystem : public Node { void _reimport_thread(uint32_t p_index, ImportThreadData *p_import_data); + static ResourceUID::ID _resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 5d6c415d39..29e3236ac2 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -109,10 +109,10 @@ void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p List<PropertyInfo> plist; p_node->get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_EDITOR) { - if (E->get().type == Variant::OBJECT) { - RES res = p_node->get(E->get().name); + for (const PropertyInfo &E : plist) { + if (E.usage & PROPERTY_USAGE_EDITOR) { + if (E.type == Variant::OBJECT) { + RES res = p_node->get(E.name); if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) { Vector<String> res_unfolds = _get_unfolds(res.ptr()); resource_folds.push_back(res->get_path()); @@ -228,41 +228,41 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) { Set<String> unfold_group; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_CATEGORY) { + for (const PropertyInfo &E : plist) { + if (E.usage & PROPERTY_USAGE_CATEGORY) { group = ""; group_base = ""; } - if (E->get().usage & PROPERTY_USAGE_GROUP) { - group = E->get().name; - group_base = E->get().hint_string; + if (E.usage & PROPERTY_USAGE_GROUP) { + group = E.name; + group_base = E.hint_string; if (group_base.ends_with("_")) { group_base = group_base.substr(0, group_base.length() - 1); } } //can unfold - if (E->get().usage & PROPERTY_USAGE_EDITOR) { + if (E.usage & PROPERTY_USAGE_EDITOR) { if (group != "") { //group - if (group_base == String() || E->get().name.begins_with(group_base)) { - bool can_revert = EditorPropertyRevert::can_property_revert(p_object, E->get().name); + if (group_base == String() || E.name.begins_with(group_base)) { + bool can_revert = EditorPropertyRevert::can_property_revert(p_object, E.name); if (can_revert) { unfold_group.insert(group); } } } else { //path - int last = E->get().name.rfind("/"); + int last = E.name.rfind("/"); if (last != -1) { - bool can_revert = EditorPropertyRevert::can_property_revert(p_object, E->get().name); + bool can_revert = EditorPropertyRevert::can_property_revert(p_object, E.name); if (can_revert) { - unfold_group.insert(E->get().name.substr(0, last)); + unfold_group.insert(E.name.substr(0, last)); } } } - if (E->get().type == Variant::OBJECT) { - RES res = p_object->get(E->get().name); - print_line("res: " + String(E->get().name) + " valid " + itos(res.is_valid())); + if (E.type == Variant::OBJECT) { + RES res = p_object->get(E.name); + print_line("res: " + String(E.name) + " valid " + itos(res.is_valid())); if (res.is_valid()) { print_line("path " + res->get_path()); } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 9fa2007597..cdbe505441 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1508,9 +1508,9 @@ String EditorInspector::get_selected_path() const { } void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<EditorInspectorPlugin> ped) { - for (List<EditorInspectorPlugin::AddedEditor>::Element *F = ped->added_editors.front(); F; F = F->next()) { - EditorProperty *ep = Object::cast_to<EditorProperty>(F->get().property_editor); - current_vbox->add_child(F->get().property_editor); + for (const EditorInspectorPlugin::AddedEditor &F : ped->added_editors) { + EditorProperty *ep = Object::cast_to<EditorProperty>(F.property_editor); + current_vbox->add_child(F.property_editor); if (ep) { ep->object = object; @@ -1524,19 +1524,19 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED); ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED); - if (F->get().properties.size()) { - if (F->get().properties.size() == 1) { + if (F.properties.size()) { + if (F.properties.size() == 1) { //since it's one, associate: - ep->property = F->get().properties[0]; + ep->property = F.properties[0]; ep->property_usage = 0; } - if (F->get().label != String()) { - ep->set_label(F->get().label); + if (F.label != String()) { + ep->set_label(F.label); } - for (int i = 0; i < F->get().properties.size(); i++) { - String prop = F->get().properties[i]; + for (int i = 0; i < F.properties.size(); i++) { + String prop = F.properties[i]; if (!editor_property_map.has(prop)) { editor_property_map[prop] = List<EditorProperty *>(); @@ -1648,8 +1648,7 @@ void EditorInspector::update_tree() { Color sscolor = get_theme_color(SNAME("prop_subsection"), SNAME("Editor")); - for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { - Ref<EditorInspectorPlugin> ped = E->get(); + for (Ref<EditorInspectorPlugin> ped : valid_plugins) { ped->parse_begin(object); _parse_added_editors(main_vbox, ped); } @@ -1746,8 +1745,7 @@ void EditorInspector::update_tree() { category->set_tooltip(p.name + "::" + (class_descr_cache[type2] == "" ? "" : class_descr_cache[type2])); } - for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { - Ref<EditorInspectorPlugin> ped = E->get(); + for (Ref<EditorInspectorPlugin> ped : valid_plugins) { ped->parse_category(object, p.name); _parse_added_editors(main_vbox, ped); } @@ -1948,36 +1946,35 @@ void EditorInspector::update_tree() { doc_hint = descr; } - for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { - Ref<EditorInspectorPlugin> ped = E->get(); + for (Ref<EditorInspectorPlugin> ped : valid_plugins) { bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage, wide_editors); List<EditorInspectorPlugin::AddedEditor> editors = ped->added_editors; //make a copy, since plugins may be used again in a sub-inspector ped->added_editors.clear(); - for (List<EditorInspectorPlugin::AddedEditor>::Element *F = editors.front(); F; F = F->next()) { - EditorProperty *ep = Object::cast_to<EditorProperty>(F->get().property_editor); + for (const EditorInspectorPlugin::AddedEditor &F : editors) { + EditorProperty *ep = Object::cast_to<EditorProperty>(F.property_editor); if (ep) { //set all this before the control gets the ENTER_TREE notification ep->object = object; - if (F->get().properties.size()) { - if (F->get().properties.size() == 1) { + if (F.properties.size()) { + if (F.properties.size() == 1) { //since it's one, associate: - ep->property = F->get().properties[0]; + ep->property = F.properties[0]; ep->property_usage = p.usage; //and set label? } - if (F->get().label != String()) { - ep->set_label(F->get().label); + if (F.label != String()) { + ep->set_label(F.label); } else { - //use existin one + // Use the existing one. ep->set_label(name); } - for (int i = 0; i < F->get().properties.size(); i++) { - String prop = F->get().properties[i]; + for (int i = 0; i < F.properties.size(); i++) { + String prop = F.properties[i]; if (!editor_property_map.has(prop)) { editor_property_map[prop] = List<EditorProperty *>(); @@ -1995,7 +1992,7 @@ void EditorInspector::update_tree() { ep->set_deletable(deletable_properties); } - current_vbox->add_child(F->get().property_editor); + current_vbox->add_child(F.property_editor); if (ep) { ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed)); @@ -2031,8 +2028,7 @@ void EditorInspector::update_tree() { } } - for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { - Ref<EditorInspectorPlugin> ped = E->get(); + for (Ref<EditorInspectorPlugin> ped : valid_plugins) { ped->parse_end(); _parse_added_editors(main_vbox, ped); } @@ -2045,10 +2041,10 @@ void EditorInspector::update_property(const String &p_prop) { return; } - for (List<EditorProperty *>::Element *E = editor_property_map[p_prop].front(); E; E = E->next()) { - E->get()->update_property(); - E->get()->update_reload_status(); - E->get()->update_cache(); + for (EditorProperty *E : editor_property_map[p_prop]) { + E->update_property(); + E->update_reload_status(); + E->update_cache(); } } @@ -2157,24 +2153,24 @@ bool EditorInspector::is_using_folding() { } void EditorInspector::collapse_all_folding() { - for (List<EditorInspectorSection *>::Element *E = sections.front(); E; E = E->next()) { - E->get()->fold(); + for (EditorInspectorSection *E : sections) { + E->fold(); } for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { - for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { - E->get()->collapse_all_folding(); + for (EditorProperty *E : F->get()) { + E->collapse_all_folding(); } } } void EditorInspector::expand_all_folding() { - for (List<EditorInspectorSection *>::Element *E = sections.front(); E; E = E->next()) { - E->get()->unfold(); + for (EditorInspectorSection *E : sections) { + E->unfold(); } for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { - for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { - E->get()->expand_all_folding(); + for (EditorProperty *E : F->get()) { + E->expand_all_folding(); } } } @@ -2239,9 +2235,9 @@ void EditorInspector::_edit_request_change(Object *p_object, const String &p_pro void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field) { if (autoclear && editor_property_map.has(p_name)) { - for (List<EditorProperty *>::Element *E = editor_property_map[p_name].front(); E; E = E->next()) { - if (E->get()->is_checkable()) { - E->get()->set_checked(true); + for (EditorProperty *E : editor_property_map[p_name]) { + if (E->is_checkable()) { + E->set_checked(true); } } } @@ -2308,8 +2304,8 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo } if (editor_property_map.has(p_name)) { - for (List<EditorProperty *>::Element *E = editor_property_map[p_name].front(); E; E = E->next()) { - E->get()->update_reload_status(); + for (EditorProperty *E : editor_property_map[p_name]) { + E->update_reload_status(); } } } @@ -2395,10 +2391,10 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { Variant to_create; List<PropertyInfo> pinfo; object->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().name == p_path) { + for (const PropertyInfo &E : pinfo) { + if (E.name == p_path) { Callable::CallError ce; - Variant::construct(E->get().type, to_create, nullptr, 0, ce); + Variant::construct(E.type, to_create, nullptr, 0, ce); break; } } @@ -2406,10 +2402,10 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { } if (editor_property_map.has(p_path)) { - for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) { - E->get()->update_property(); - E->get()->update_reload_status(); - E->get()->update_cache(); + for (EditorProperty *E : editor_property_map[p_path]) { + E->update_property(); + E->update_reload_status(); + E->update_cache(); } } @@ -2426,9 +2422,9 @@ void EditorInspector::_property_selected(const String &p_path, int p_focusable) if (F->key() == property_selected) { continue; } - for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { - if (E->get()->is_selected()) { - E->get()->deselect(); + for (EditorProperty *E : F->get()) { + if (E->is_selected()) { + E->deselect(); } } } @@ -2485,11 +2481,11 @@ void EditorInspector::_notification(int p_what) { refresh_countdown -= get_process_delta_time(); if (refresh_countdown <= 0) { for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { - for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { - if (!E->get()->is_cache_valid()) { - E->get()->update_property(); - E->get()->update_reload_status(); - E->get()->update_cache(); + for (EditorProperty *E : F->get()) { + if (!E->is_cache_valid()) { + E->update_property(); + E->update_reload_status(); + E->update_cache(); } } } @@ -2508,10 +2504,10 @@ void EditorInspector::_notification(int p_what) { while (pending.size()) { StringName prop = pending.front()->get(); if (editor_property_map.has(prop)) { - for (List<EditorProperty *>::Element *E = editor_property_map[prop].front(); E; E = E->next()) { - E->get()->update_property(); - E->get()->update_reload_status(); - E->get()->update_cache(); + for (EditorProperty *E : editor_property_map[prop]) { + E->update_property(); + E->update_reload_status(); + E->update_cache(); } } pending.erase(pending.front()); @@ -2599,8 +2595,7 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li } Set<StringName> added; - for (List<Ref<Script>>::Element *E = classes.front(); E; E = E->next()) { - Ref<Script> s = E->get(); + for (Ref<Script> s : classes) { String path = s->get_path(); String name = EditorNode::get_editor_data().script_class_get_name(path); if (name.is_empty()) { diff --git a/editor/editor_layouts_dialog.cpp b/editor/editor_layouts_dialog.cpp index 16538a2376..0c8660c216 100644 --- a/editor/editor_layouts_dialog.cpp +++ b/editor/editor_layouts_dialog.cpp @@ -92,8 +92,8 @@ void EditorLayoutsDialog::_post_popup() { List<String> layouts; config.ptr()->get_sections(&layouts); - for (List<String>::Element *E = layouts.front(); E; E = E->next()) { - layout_names->add_item(**E); + for (const String &E : layouts) { + layout_names->add_item(E); } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6bdf428f81..267854d7ec 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -797,8 +797,8 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) { } if (changed.size()) { - for (List<Ref<Resource>>::Element *E = changed.front(); E; E = E->next()) { - E->get()->reload_from_file(); + for (Ref<Resource> E : changed) { + E->reload_from_file(); } } } @@ -914,8 +914,8 @@ void EditorNode::_resources_reimported(const Vector<String> &p_resources) { } } - for (List<String>::Element *E = scenes.front(); E; E = E->next()) { - reload_scene(E->get()); + for (const String &E : scenes) { + reload_scene(E); } scene_tabs->set_current_tab(current_tab); @@ -926,7 +926,7 @@ void EditorNode::_sources_changed(bool p_exist) { waiting_for_first_scan = false; // Reload the global shader variables, but this time - // loading texures, as they are now properly imported. + // loading textures, as they are now properly imported. RenderingServer::get_singleton()->global_variables_load_settings(true); // Start preview thread now that it's safe. @@ -1143,13 +1143,13 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String file->clear_filters(); List<String> preferred; - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (p_resource->is_class("Script") && (E->get() == "tres" || E->get() == "res")) { + for (const String &E : extensions) { + if (p_resource->is_class("Script") && (E == "tres" || E == "res")) { //this serves no purpose and confused people continue; } - file->add_filter("*." + E->get() + " ; " + E->get().to_upper()); - preferred.push_back(E->get()); + file->add_filter("*." + E + " ; " + E.to_upper()); + preferred.push_back(E); } // Lowest priority extension List<String>::Element *res_element = preferred.find("res"); @@ -1259,10 +1259,10 @@ void EditorNode::_get_scene_metadata(const String &p_file) { cf->get_section_keys("editor_states", &esl); Dictionary md; - for (List<String>::Element *E = esl.front(); E; E = E->next()) { - Variant st = cf->get_value("editor_states", E->get()); + for (const String &E : esl) { + Variant st = cf->get_value("editor_states", E); if (st.get_type() != Variant::NIL) { - md[E->get()] = st; + md[E] = st; } } @@ -1295,8 +1295,8 @@ void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) { List<Variant> keys; md.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - cf->set_value("editor_states", E->get(), md[E->get()]); + for (const Variant &E : keys) { + cf->set_value("editor_states", E, md[E]); } Error err = cf->save(path); @@ -1334,14 +1334,14 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> bool ret_changed = false; List<PropertyInfo> pi; obj->get_property_list(&pi); - for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : pi) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - switch (E->get().type) { + switch (E.type) { case Variant::OBJECT: { - RES res = obj->get(E->get().name); + RES res = obj->get(E.name); if (_find_and_save_resource(res, processed, flags)) { ret_changed = true; @@ -1349,7 +1349,7 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> } break; case Variant::ARRAY: { - Array varray = obj->get(E->get().name); + Array varray = obj->get(E.name); int len = varray.size(); for (int i = 0; i < len; i++) { const Variant &v = varray.get(i); @@ -1361,11 +1361,11 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> } break; case Variant::DICTIONARY: { - Dictionary d = obj->get(E->get().name); + Dictionary d = obj->get(E.name); List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *F = keys.front(); F; F = F->next()) { - Variant v = d[F->get()]; + for (const Variant &F : keys) { + Variant v = d[F]; RES res = v; if (_find_and_save_resource(res, processed, flags)) { ret_changed = true; @@ -1520,9 +1520,9 @@ static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Reso p_resource->get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().type == Variant::OBJECT && E->get().usage & PROPERTY_USAGE_STORAGE && !(E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)) { - RES res = p_resource->get(E->get().name); + for (const PropertyInfo &E : plist) { + if (E.type == Variant::OBJECT && E.usage & PROPERTY_USAGE_STORAGE && !(E.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)) { + RES res = p_resource->get(E.name); if (res.is_null()) { continue; } @@ -1551,12 +1551,11 @@ int EditorNode::_save_external_resources() { int saved = 0; List<Ref<Resource>> cached; ResourceCache::get_cached_resources(&cached); - for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) { - Ref<Resource> res = E->get(); + for (Ref<Resource> res : cached) { if (!res->get_path().is_resource_file()) { continue; } - //not only check if this resourec is edited, check contained subresources too + //not only check if this resource is edited, check contained subresources too if (_find_edited_resources(res, edited_subresources)) { ResourceSaver::save(res->get_path(), res, flg); saved++; @@ -1642,8 +1641,8 @@ void EditorNode::_save_scene(String p_file, int idx) { editor_data.save_editor_external_data(); - for (List<Ref<AnimatedValuesBackup>>::Element *E = anim_backups.front(); E; E = E->next()) { - E->get()->restore(); + for (Ref<AnimatedValuesBackup> E : anim_backups) { + E->restore(); } if (err == OK) { @@ -1884,8 +1883,8 @@ void EditorNode::_dialog_action(String p_file) { // erase List<String> keys; config->get_section_keys(p_file, &keys); - for (List<String>::Element *E = keys.front(); E; E = E->next()) { - config->set_value(p_file, E->get(), Variant()); + for (const String &E : keys) { + config->set_value(p_file, E, Variant()); } config->save(EditorSettings::get_singleton()->get_editor_layouts_config()); @@ -2533,8 +2532,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { Ref<MeshLibrary> ml(memnew(MeshLibrary)); ResourceSaver::get_recognized_extensions(ml, &extensions); file_export_lib->clear_filters(); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - file_export_lib->add_filter("*." + E->get()); + for (const String &E : extensions) { + file_export_lib->add_filter("*." + E); } file_export_lib->popup_file_dialog(); @@ -4055,11 +4054,11 @@ void EditorNode::_build_icon_type_cache() { List<StringName> tl; StringName ei = "EditorIcons"; theme_base->get_theme()->get_icon_list(ei, &tl); - for (List<StringName>::Element *E = tl.front(); E; E = E->next()) { - if (!ClassDB::class_exists(E->get())) { + for (const StringName &E : tl) { + if (!ClassDB::class_exists(E)) { continue; } - icon_type_cache[E->get()] = theme_base->get_theme()->get_icon(E->get(), ei); + icon_type_cache[E] = theme_base->get_theme()->get_icon(E, ei); } } @@ -4784,9 +4783,7 @@ void EditorNode::_update_layouts_menu() { List<String> layouts; config.ptr()->get_sections(&layouts); - for (List<String>::Element *E = layouts.front(); E; E = E->next()) { - String layout = E->get(); - + for (const String &layout : layouts) { if (layout == TTR("Default")) { editor_layouts->remove_item(editor_layouts->get_item_index(SETTINGS_LAYOUT_DEFAULT)); overridden_default_layout = editor_layouts->get_item_count(); @@ -5343,9 +5340,9 @@ void EditorNode::reload_scene(const String &p_path) { List<Ref<Resource>> cached; ResourceCache::get_cached_resources(&cached); List<Ref<Resource>> to_clear; //clear internal resources from previous scene from being used - for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) { - if (E->get()->get_path().begins_with(p_path + "::")) { //subresources of existing scene - to_clear.push_back(E->get()); + for (Ref<Resource> E : cached) { + if (E->get_path().begins_with(p_path + "::")) { //subresources of existing scene + to_clear.push_back(E); } } @@ -6741,8 +6738,8 @@ EditorNode::EditorNode() { file_script->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); List<String> sexts; ResourceLoader::get_recognized_extensions_for_type("Script", &sexts); - for (List<String>::Element *E = sexts.front(); E; E = E->next()) { - file_script->add_filter("*." + E->get()); + for (const String &E : sexts) { + file_script->add_filter("*." + E); } gui_base->add_child(file_script); file_script->connect("file_selected", callable_mp(this, &EditorNode::_dialog_action)); diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp index a31b9fd0c7..f3b3eedccc 100644 --- a/editor/editor_path.cpp +++ b/editor/editor_path.cpp @@ -40,15 +40,15 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { List<PropertyInfo> pinfo; p_obj->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) { + for (const PropertyInfo &E : pinfo) { + if (!(E.usage & PROPERTY_USAGE_EDITOR)) { continue; } - if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE) { + if (E.hint != PROPERTY_HINT_RESOURCE_TYPE) { continue; } - Variant value = p_obj->get(E->get().name); + Variant value = p_obj->get(E.name); if (value.get_type() != Variant::OBJECT) { continue; } @@ -60,7 +60,7 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(obj); String proper_name = ""; - Vector<String> name_parts = E->get().name.split("/"); + Vector<String> name_parts = E.name.split("/"); for (int i = 0; i < name_parts.size(); i++) { if (i > 0) { diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 8bb6c590dc..7d809ea656 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -221,8 +221,8 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } Set<String> valid_extensions; - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - valid_extensions.insert(E->get()); + for (const String &E : extensions) { + valid_extensions.insert(E); } if (!file_dialog) { @@ -260,9 +260,8 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { List<PropertyInfo> property_list; edited_resource->get_property_list(&property_list); List<Pair<String, Variant>> propvalues; - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { + for (const PropertyInfo &pi : property_list) { Pair<String, Variant> p; - PropertyInfo &pi = E->get(); if (pi.usage & PROPERTY_USAGE_STORAGE) { p.first = pi.name; p.second = edited_resource->get(pi.name); @@ -276,8 +275,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { Ref<Resource> unique_resource = Ref<Resource>(Object::cast_to<Resource>(inst)); ERR_FAIL_COND(unique_resource.is_null()); - for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { - Pair<String, Variant> &p = E->get(); + for (const Pair<String, Variant> &p : propvalues) { unique_resource->set(p.first, p.second); } @@ -467,13 +465,13 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, Set<String> * List<StringName> inheriters; ClassDB::get_inheriters_from_class(base, &inheriters); - for (List<StringName>::Element *E = inheriters.front(); E; E = E->next()) { - p_vector->insert(E->get()); + for (const StringName &E : inheriters) { + p_vector->insert(E); } - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - if (EditorNode::get_editor_data().script_class_is_parent(E->get(), base)) { - p_vector->insert(E->get()); + for (const StringName &E : global_classes) { + if (EditorNode::get_editor_data().script_class_is_parent(E, base)) { + p_vector->insert(E); } } diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 5e6d2ab69c..4fadbf5922 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -228,8 +228,8 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L } printf("Running: %s", exec.utf8().get_data()); - for (List<String>::Element *E = args.front(); E; E = E->next()) { - printf(" %s", E->get().utf8().get_data()); + for (const String &E : args) { + printf(" %s", E.utf8().get_data()); }; printf("\n"); @@ -250,8 +250,8 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L } bool EditorRun::has_child_process(OS::ProcessID p_pid) const { - for (const List<OS::ProcessID>::Element *E = pids.front(); E; E = E->next()) { - if (E->get() == p_pid) { + for (const OS::ProcessID &E : pids) { + if (E == p_pid) { return true; } } @@ -267,8 +267,8 @@ void EditorRun::stop_child_process(OS::ProcessID p_pid) { void EditorRun::stop() { if (status != STATUS_STOP && pids.size() > 0) { - for (List<OS::ProcessID>::Element *E = pids.front(); E; E = E->next()) { - OS::get_singleton()->kill(E->get()); + for (const OS::ProcessID &E : pids) { + OS::get_singleton()->kill(E); } } diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 1209df50ed..751cc7a574 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -76,8 +76,7 @@ class SectionedInspectorFilter : public Object { List<PropertyInfo> pinfo; edited->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - PropertyInfo pi = E->get(); + for (PropertyInfo &pi : pinfo) { int sp = pi.name.find("/"); if (pi.name == "resource_path" || pi.name == "resource_name" || pi.name == "resource_local_to_scene" || pi.name.begins_with("script/") || pi.name.begins_with("_global_script")) { //skip resource stuff @@ -221,9 +220,7 @@ void SectionedInspector::update_category_list() { filter = search_box->get_text(); } - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - PropertyInfo pi = E->get(); - + for (PropertyInfo &pi : pinfo) { if (pi.usage & PROPERTY_USAGE_CATEGORY) { continue; } else if (!(pi.usage & PROPERTY_USAGE_EDITOR) || (restrict_to_basic && !(pi.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 0667d7116f..a52b14643e 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -759,8 +759,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { List<String> keys; p_extra_config->get_section_keys("presets", &keys); - for (List<String>::Element *E = keys.front(); E; E = E->next()) { - String key = E->get(); + for (const String &key : keys) { Variant val = p_extra_config->get_value("presets", key); set(key, val); } @@ -815,8 +814,7 @@ bool EditorSettings::_save_text_editor_theme(String p_file) { props.get_key_list(&keys); keys.sort(); - for (const List<String>::Element *E = keys.front(); E; E = E->next()) { - const String &key = E->get(); + for (const String &key : keys) { if (key.begins_with("text_editor/highlighting/") && key.find("color") >= 0) { cf->set_value(theme_section, key.replace("text_editor/highlighting/", ""), ((Color)props[key].variant).to_html()); } @@ -1015,15 +1013,13 @@ void EditorSettings::setup_network() { String selected = "127.0.0.1"; // Check that current remote_host is a valid interface address and populate hints. - for (List<IPAddress>::Element *E = local_ip.front(); E; E = E->next()) { - String ip = E->get(); - + for (const IPAddress &ip : local_ip) { // link-local IPv6 addresses don't work, skipping them - if (ip.begins_with("fe80:0:0:0:")) { // fe80::/64 + if (String(ip).begins_with("fe80:0:0:0:")) { // fe80::/64 continue; } // Same goes for IPv4 link-local (APIPA) addresses. - if (ip.begins_with("169.254.")) { // 169.254.0.0/16 + if (String(ip).begins_with("169.254.")) { // 169.254.0.0/16 continue; } // Select current IP (found) @@ -1303,8 +1299,8 @@ void EditorSettings::list_text_editor_themes() { memdelete(d); custom_themes.sort(); - for (List<String>::Element *E = custom_themes.front(); E; E = E->next()) { - themes += "," + E->get(); + for (const String &E : custom_themes) { + themes += "," + E; } } add_property_hint(PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, themes)); @@ -1332,8 +1328,7 @@ void EditorSettings::load_text_editor_theme() { List<String> keys; cf->get_section_keys("color_theme", &keys); - for (List<String>::Element *E = keys.front(); E; E = E->next()) { - String key = E->get(); + for (const String &key : keys) { String val = cf->get_value("color_theme", key); // don't load if it's not already there! @@ -1434,7 +1429,7 @@ float EditorSettings::get_auto_display_scale() const { return DisplayServer::get_singleton()->screen_get_max_scale(); #else const int screen = DisplayServer::get_singleton()->window_get_current_screen(); - // Use the smallest dimension to use a correct display scale on portait displays. + // Use the smallest dimension to use a correct display scale on portrait displays. const int smallest_dimension = MIN(DisplayServer::get_singleton()->screen_get_size(screen).x, DisplayServer::get_singleton()->screen_get_size(screen).y); if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && smallest_dimension >= 1400) { // hiDPI display. @@ -1585,8 +1580,8 @@ void EditorSettings::set_builtin_action_override(const String &p_name, const Arr int event_idx = 0; // Check equality of each event. - for (List<Ref<InputEvent>>::Element *E = builtin_events.front(); E; E = E->next()) { - if (!E->get()->is_match(p_events[event_idx])) { + for (Ref<InputEvent> E : builtin_events) { + if (!E->is_match(p_events[event_idx])) { same_as_builtin = false; break; } @@ -1615,8 +1610,8 @@ const Array EditorSettings::get_builtin_action_overrides(const String &p_name) c Array event_array; List<Ref<InputEvent>> events_list = AO->get(); - for (List<Ref<InputEvent>>::Element *E = events_list.front(); E; E = E->next()) { - event_array.push_back(E->get()); + for (Ref<InputEvent> E : events_list) { + event_array.push_back(E); } return event_array; } diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 49c2a84e18..dbbbb03864 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -135,9 +135,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory _sort_file_info_list(file_list); // Build the tree. - for (List<FileInfo>::Element *E = file_list.front(); E; E = E->next()) { - FileInfo fi = E->get(); - + for (const FileInfo &fi : file_list) { TreeItem *file_item = tree->create_item(subdirectory_item); file_item->set_text(0, fi.name); file_item->set_structured_text_bidi_override(0, STRUCTURED_TEXT_FILE); @@ -869,8 +867,8 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { // Fills the ItemList control node from the FileInfos. String main_scene = ProjectSettings::get_singleton()->get("application/run/main_scene"); String oi = "Object"; - for (List<FileInfo>::Element *E = file_list.front(); E; E = E->next()) { - FileInfo *finfo = &(E->get()); + for (FileInfo &E : file_list) { + FileInfo *finfo = &(E); String fname = finfo->name; String fpath = finfo->path; String ftype = finfo->type; @@ -966,8 +964,8 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit List<String> importer_exts; ResourceImporterScene::get_singleton()->get_recognized_extensions(&importer_exts); String extension = fpath.get_extension(); - for (List<String>::Element *E = importer_exts.front(); E; E = E->next()) { - if (extension.nocasecmp_to(E->get()) == 0) { + for (const String &E : importer_exts) { + if (extension.nocasecmp_to(E) == 0) { is_imported = true; break; } @@ -1239,9 +1237,7 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> List<Ref<Resource>> cached; ResourceCache::get_cached_resources(&cached); - for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) { - Ref<Resource> r = E->get(); - + for (Ref<Resource> r : cached) { String base_path = r->get_path(); String extra_path; int sep_pos = r->get_path().find("::"); @@ -1317,16 +1313,16 @@ void FileSystemDock::_update_project_settings_after_move(const Map<String, Strin // Also search for the file in autoload, as they are stored differently from normal files. List<PropertyInfo> property_list; ProjectSettings::get_singleton()->get_property_list(&property_list); - for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { - if (E->get().name.begins_with("autoload/")) { + for (const PropertyInfo &E : property_list) { + if (E.name.begins_with("autoload/")) { // If the autoload resource paths has a leading "*", it indicates that it is a Singleton, // so we have to handle both cases when updating. - String autoload = GLOBAL_GET(E->get().name); + String autoload = GLOBAL_GET(E.name); String autoload_singleton = autoload.substr(1, autoload.length()); if (p_renames.has(autoload)) { - ProjectSettings::get_singleton()->set_setting(E->get().name, p_renames[autoload]); + ProjectSettings::get_singleton()->set_setting(E.name, p_renames[autoload]); } else if (autoload.begins_with("*") && p_renames.has(autoload_singleton)) { - ProjectSettings::get_singleton()->set_setting(E->get().name, "*" + p_renames[autoload_singleton]); + ProjectSettings::get_singleton()->set_setting(E.name, "*" + p_renames[autoload_singleton]); } } } @@ -1417,8 +1413,8 @@ void FileSystemDock::_make_scene_confirm() { ResourceSaver::get_recognized_extensions(sd, &extensions); bool extension_correct = false; - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get() == extension) { + for (const String &E : extensions) { + if (E == extension) { extension_correct = true; break; } diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 0a39768b9a..113306fc8a 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -240,8 +240,7 @@ void GroupDialog::_group_renamed() { List<Node *> nodes; scene_tree->get_nodes_in_group(selected_group, &nodes); bool removed_all = true; - for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) { - Node *node = E->get(); + for (Node *node : nodes) { if (_can_edit(node, selected_group)) { undo_redo->add_do_method(node, "remove_from_group", selected_group); undo_redo->add_undo_method(node, "remove_from_group", name); @@ -286,11 +285,11 @@ void GroupDialog::_load_groups(Node *p_current) { List<Node::GroupInfo> gi; p_current->get_groups(&gi); - for (List<Node::GroupInfo>::Element *E = gi.front(); E; E = E->next()) { - if (!E->get().persistent) { + for (const Node::GroupInfo &E : gi) { + if (!E.persistent) { continue; } - _add_group(E->get().name); + _add_group(E.name); } for (int i = 0; i < p_current->get_child_count(); i++) { @@ -311,10 +310,10 @@ void GroupDialog::_delete_group_pressed(Object *p_item, int p_column, int p_id) List<Node *> nodes; scene_tree->get_nodes_in_group(name, &nodes); bool removed_all = true; - for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) { - if (_can_edit(E->get(), name)) { - undo_redo->add_do_method(E->get(), "remove_from_group", name); - undo_redo->add_undo_method(E->get(), "add_to_group", name, true); + for (Node *E : nodes) { + if (_can_edit(E, name)) { + undo_redo->add_do_method(E, "remove_from_group", name); + undo_redo->add_undo_method(E, "add_to_group", name, true); } else { removed_all = false; } @@ -628,8 +627,7 @@ void GroupsEditor::update_tree() { TreeItem *root = tree->create_item(); - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { - Node::GroupInfo gi = E->get(); + for (const GroupInfo &gi : groups) { if (!gi.persistent) { continue; } diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index ddf89f077b..b615c73422 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -894,8 +894,8 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor surftool->add_vertex(vertex_array[k].vertex); } - for (List<int>::Element *E = indices_list.front(); E; E = E->next()) { - surftool->add_index(E->get()); + for (int &E : indices_list) { + surftool->add_index(E); } if (!normal_src) { diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 01603c0a6a..8b6bd8066f 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -438,17 +438,16 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in Node3D *scene = memnew(Node3D); - for (List<Ref<Mesh>>::Element *E = meshes.front(); E; E = E->next()) { + for (Ref<Mesh> m : meshes) { Ref<EditorSceneImporterMesh> mesh; mesh.instantiate(); - Ref<Mesh> m = E->get(); for (int i = 0; i < m->get_surface_count(); i++) { mesh->add_surface(m->surface_get_primitive_type(i), m->surface_get_arrays(i), Array(), Dictionary(), m->surface_get_material(i)); } EditorSceneImporterMeshNode3D *mi = memnew(EditorSceneImporterMeshNode3D); mi->set_mesh(mesh); - mi->set_name(E->get()->get_name()); + mi->set_name(m->get_name()); scene->add_child(mi); mi->set_owner(scene); } diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index c14b948dae..e9160f0414 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -312,8 +312,8 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E List<StringName> anims; ap->get_animation_list(&anims); - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { - Ref<Animation> anim = ap->get_animation(E->get()); + for (const StringName &E : anims) { + Ref<Animation> anim = ap->get_animation(E); ERR_CONTINUE(anim.is_null()); for (int i = 0; i < anim->get_track_count(); i++) { NodePath path = anim->track_get_path(i); @@ -328,14 +328,14 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E } } - String animname = E->get(); + String animname = E; const int loop_string_count = 3; static const char *loop_strings[loop_string_count] = { "loops", "loop", "cycle" }; for (int i = 0; i < loop_string_count; i++) { if (_teststr(animname, loop_strings[i])) { anim->set_loop(true); animname = _fixstr(animname, loop_strings[i]); - ap->rename_animation(E->get(), animname); + ap->rename_animation(E, animname); } } } @@ -659,9 +659,9 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< } int idx = 0; - for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) { + for (const Ref<Shape3D> &E : shapes) { CollisionShape3D *cshape = memnew(CollisionShape3D); - cshape->set_shape(E->get()); + cshape->set_shape(E); base->add_child(cshape); cshape->set_owner(base->get_owner()); @@ -712,9 +712,9 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< //fill node settings for this node with default values List<ImportOption> iopts; get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts); - for (List<ImportOption>::Element *E = iopts.front(); E; E = E->next()) { - if (!node_settings.has(E->get().option.name)) { - node_settings[E->get().option.name] = E->get().default_value; + for (const ImportOption &E : iopts) { + if (!node_settings.has(E.option.name)) { + node_settings[E.option.name] = E.default_value; } } } @@ -756,8 +756,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< } else { List<StringName> anims; ap->get_animation_list(&anims); - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { - String name = E->get(); + for (const StringName &name : anims) { Ref<Animation> anim = ap->get_animation(name); if (p_animation_data.has(name)) { Dictionary anim_settings = p_animation_data[name]; @@ -765,9 +764,9 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< //fill with default values List<ImportOption> iopts; get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts); - for (List<ImportOption>::Element *F = iopts.front(); F; F = F->next()) { - if (!anim_settings.has(F->get().option.name)) { - anim_settings[F->get().option.name] = F->get().default_value; + for (const ImportOption &F : iopts) { + if (!anim_settings.has(F.option.name)) { + anim_settings[F.option.name] = F.default_value; } } } @@ -936,8 +935,8 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ void ResourceImporterScene::_optimize_animations(AnimationPlayer *anim, float p_max_lin_error, float p_max_ang_error, float p_max_angle) { List<StringName> anim_names; anim->get_animation_list(&anim_names); - for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) { - Ref<Animation> a = anim->get_animation(E->get()); + for (const StringName &E : anim_names) { + Ref<Animation> a = anim->get_animation(E); a->optimize(p_max_lin_error, p_max_ang_error, Math::deg2rad(p_max_angle)); } } @@ -1046,11 +1045,11 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in String script_ext_hint; - for (List<String>::Element *E = script_extentions.front(); E; E = E->next()) { + for (const String &E : script_extentions) { if (script_ext_hint != "") { script_ext_hint += ","; } - script_ext_hint += "*." + E->get(); + script_ext_hint += "*." + E; } r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "nodes/root_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001"), 1.0)); @@ -1089,9 +1088,9 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { - importer = E->get(); + for (const String &F : extensions) { + if (F.to_lower() == ext) { + importer = E; break; } } @@ -1119,9 +1118,9 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { - importer = E->get(); + for (const String &F : extensions) { + if (F.to_lower() == ext) { + importer = E; break; } } @@ -1291,9 +1290,9 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } void ResourceImporterScene::_add_shapes(Node *p_node, const List<Ref<Shape3D>> &p_shapes) { - for (const List<Ref<Shape3D>>::Element *E = p_shapes.front(); E; E = E->next()) { + for (const Ref<Shape3D> &E : p_shapes) { CollisionShape3D *cshape = memnew(CollisionShape3D); - cshape->set_shape(E->get()); + cshape->set_shape(E); p_node->add_child(cshape); cshape->set_owner(p_node->get_owner()); @@ -1311,8 +1310,8 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) { List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { + for (const String &F : extensions) { + if (F.to_lower() == ext) { importer = E->get(); break; } @@ -1351,8 +1350,8 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { + for (const String &F : extensions) { + if (F.to_lower() == ext) { importer = E->get(); break; } diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index c6e5836a23..781beff689 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -155,7 +155,8 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override; - virtual int get_import_order() const override { return 100; } //after everything + // Import scenes *after* everything else (such as textures). + virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; } Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> &collision_map); Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 5dc494d6df..19a8f209bb 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -71,9 +71,9 @@ class SceneImportSettingsData : public Object { return false; } void _get_property_list(List<PropertyInfo> *p_list) const { - for (const List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - if (ResourceImporterScene::get_singleton()->get_internal_option_visibility(category, E->get().option.name, current)) { - p_list->push_back(E->get().option); + for (const ResourceImporter::ImportOption &E : options) { + if (ResourceImporterScene::get_singleton()->get_internal_option_visibility(category, E.option.name, current)) { + p_list->push_back(E.option); } } } @@ -305,8 +305,8 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) { if (anim_node) { List<StringName> animations; anim_node->get_animation_list(&animations); - for (List<StringName>::Element *E = animations.front(); E; E = E->next()) { - _fill_animation(scene_tree, anim_node->get_animation(E->get()), E->get(), item); + for (const StringName &E : animations) { + _fill_animation(scene_tree, anim_node->get_animation(E), E, item); } } @@ -394,8 +394,8 @@ void SceneImportSettings::_load_default_subresource_settings(Map<StringName, Var d = d[p_import_id]; List<ResourceImporterScene::ImportOption> options; ResourceImporterScene::get_singleton()->get_internal_import_options(p_category, &options); - for (List<ResourceImporterScene::ImportOption>::Element *E = options.front(); E; E = E->next()) { - String key = E->get().option.name; + for (const ResourceImporterScene::ImportOption &E : options) { + String key = E.option.name; if (d.has(key)) { settings[key] = d[key]; } @@ -440,12 +440,12 @@ void SceneImportSettings::open_settings(const String &p_path) { if (err == OK) { List<String> keys; config->get_section_keys("params", &keys); - for (List<String>::Element *E = keys.front(); E; E = E->next()) { - Variant value = config->get_value("params", E->get()); - if (E->get() == "_subresources") { + for (const String &E : keys) { + Variant value = config->get_value("params", E); + if (E == "_subresources") { base_subresource_settings = value; } else { - defaults[E->get()] = value; + defaults[E] = value; } } } @@ -605,13 +605,13 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) { scene_import_settings_data->defaults.clear(); scene_import_settings_data->current.clear(); - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - scene_import_settings_data->defaults[E->get().option.name] = E->get().default_value; + for (const ResourceImporter::ImportOption &E : options) { + scene_import_settings_data->defaults[E.option.name] = E.default_value; //needed for visibility toggling (fails if something is missing) - if (scene_import_settings_data->settings->has(E->get().option.name)) { - scene_import_settings_data->current[E->get().option.name] = (*scene_import_settings_data->settings)[E->get().option.name]; + if (scene_import_settings_data->settings->has(E.option.name)) { + scene_import_settings_data->current[E.option.name] = (*scene_import_settings_data->settings)[E.option.name]; } else { - scene_import_settings_data->current[E->get().option.name] = E->get().default_value; + scene_import_settings_data->current[E.option.name] = E.default_value; } } scene_import_settings_data->options = options; diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index f8e93df382..0d14347225 100644 --- a/editor/import/scene_importer_mesh.cpp +++ b/editor/import/scene_importer_mesh.cpp @@ -79,11 +79,11 @@ void EditorSceneImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const List<Variant> lods; p_lods.get_key_list(&lods); - for (List<Variant>::Element *E = lods.front(); E; E = E->next()) { - ERR_CONTINUE(!E->get().is_num()); + for (const Variant &E : lods) { + ERR_CONTINUE(!E.is_num()); Surface::LOD lod; - lod.distance = E->get(); - lod.indices = p_lods[E->get()]; + lod.distance = E; + lod.indices = p_lods[E]; ERR_CONTINUE(lod.indices.size() == 0); s.lods.push_back(lod); } diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp index 8c506e938d..7c06ef4516 100644 --- a/editor/import_defaults_editor.cpp +++ b/editor/import_defaults_editor.cpp @@ -61,9 +61,9 @@ protected: if (importer.is_null()) { return; } - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (importer->get_option_visibility(E->get().name, values)) { - p_list->push_back(E->get()); + for (const PropertyInfo &E : properties) { + if (importer->get_option_visibility(E.name, values)) { + p_list->push_back(E); } } } @@ -106,9 +106,9 @@ void ImportDefaultsEditor::_update_importer() { List<Ref<ResourceImporter>> importer_list; ResourceFormatImporter::get_singleton()->get_importers(&importer_list); Ref<ResourceImporter> importer; - for (List<Ref<ResourceImporter>>::Element *E = importer_list.front(); E; E = E->next()) { - if (E->get()->get_visible_name() == importers->get_item_text(importers->get_selected())) { - importer = E->get(); + for (Ref<ResourceImporter> E : importer_list) { + if (E->get_visible_name() == importers->get_item_text(importers->get_selected())) { + importer = E; break; } } @@ -125,14 +125,14 @@ void ImportDefaultsEditor::_update_importer() { d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); } - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - settings->properties.push_back(E->get().option); - if (d.has(E->get().option.name)) { - settings->values[E->get().option.name] = d[E->get().option.name]; + for (const ResourceImporter::ImportOption &E : options) { + settings->properties.push_back(E.option); + if (d.has(E.option.name)) { + settings->values[E.option.name] = d[E.option.name]; } else { - settings->values[E->get().option.name] = E->get().default_value; + settings->values[E.option.name] = E.default_value; } - settings->default_values[E->get().option.name] = E->get().default_value; + settings->default_values[E.option.name] = E.default_value; } save_defaults->set_disabled(false); @@ -166,8 +166,8 @@ void ImportDefaultsEditor::clear() { List<Ref<ResourceImporter>> importer_list; ResourceFormatImporter::get_singleton()->get_importers(&importer_list); Vector<String> names; - for (List<Ref<ResourceImporter>>::Element *E = importer_list.front(); E; E = E->next()) { - String vn = E->get()->get_visible_name(); + for (Ref<ResourceImporter> E : importer_list) { + String vn = E->get_visible_name(); names.push_back(vn); } names.sort(); diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 4110912ff3..1f8fefbe6e 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -65,14 +65,14 @@ public: return false; } void _get_property_list(List<PropertyInfo> *p_list) const { - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (!importer->get_option_visibility(E->get().name, values)) { + for (const PropertyInfo &E : properties) { + if (!importer->get_option_visibility(E.name, values)) { continue; } - PropertyInfo pi = E->get(); + PropertyInfo pi = E; if (checking) { pi.usage |= PROPERTY_USAGE_CHECKABLE; - if (checked.has(E->get().name)) { + if (checked.has(E.name)) { pi.usage |= PROPERTY_USAGE_CHECKED; } } @@ -111,18 +111,18 @@ void ImportDock::set_edit_path(const String &p_path) { ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_path.get_extension(), &importers); List<Pair<String, String>> importer_names; - for (List<Ref<ResourceImporter>>::Element *E = importers.front(); E; E = E->next()) { - importer_names.push_back(Pair<String, String>(E->get()->get_visible_name(), E->get()->get_importer_name())); + for (Ref<ResourceImporter> E : importers) { + importer_names.push_back(Pair<String, String>(E->get_visible_name(), E->get_importer_name())); } importer_names.sort_custom<PairSort<String, String>>(); import_as->clear(); - for (List<Pair<String, String>>::Element *E = importer_names.front(); E; E = E->next()) { - import_as->add_item(E->get().first); - import_as->set_item_metadata(import_as->get_item_count() - 1, E->get().second); - if (E->get().second == importer_name) { + for (const Pair<String, String> &E : importer_names) { + import_as->add_item(E.first); + import_as->set_item_metadata(import_as->get_item_count() - 1, E.second); + if (E.second == importer_name) { import_as->select(import_as->get_item_count() - 1); } } @@ -153,12 +153,12 @@ void ImportDock::_update_options(const Ref<ConfigFile> &p_config) { params->checking = params->paths.size() > 1; params->checked.clear(); - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - params->properties.push_back(E->get().option); - if (p_config.is_valid() && p_config->has_section_key("params", E->get().option.name)) { - params->values[E->get().option.name] = p_config->get_value("params", E->get().option.name); + for (const ResourceImporter::ImportOption &E : options) { + params->properties.push_back(E.option); + if (p_config.is_valid() && p_config->has_section_key("params", E.option.name)) { + params->values[E.option.name] = p_config->get_value("params", E.option.name); } else { - params->values[E->get().option.name] = E->get().default_value; + params->values[E.option.name] = E.default_value; } } @@ -201,17 +201,17 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { List<String> keys; config->get_section_keys("params", &keys); - for (List<String>::Element *E = keys.front(); E; E = E->next()) { - if (!value_frequency.has(E->get())) { - value_frequency[E->get()] = Dictionary(); + for (const String &E : keys) { + if (!value_frequency.has(E)) { + value_frequency[E] = Dictionary(); } - Variant value = config->get_value("params", E->get()); + Variant value = config->get_value("params", E); - if (value_frequency[E->get()].has(value)) { - value_frequency[E->get()][value] = int(value_frequency[E->get()][value]) + 1; + if (value_frequency[E].has(value)) { + value_frequency[E][value] = int(value_frequency[E][value]) + 1; } else { - value_frequency[E->get()][value] = 1; + value_frequency[E][value] = 1; } } } @@ -226,25 +226,25 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { params->checking = true; params->checked.clear(); - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - params->properties.push_back(E->get().option); + for (const ResourceImporter::ImportOption &E : options) { + params->properties.push_back(E.option); - if (value_frequency.has(E->get().option.name)) { - Dictionary d = value_frequency[E->get().option.name]; + if (value_frequency.has(E.option.name)) { + Dictionary d = value_frequency[E.option.name]; int freq = 0; List<Variant> v; d.get_key_list(&v); Variant value; - for (List<Variant>::Element *F = v.front(); F; F = F->next()) { - int f = d[F->get()]; + for (const Variant &F : v) { + int f = d[F]; if (f > freq) { - value = F->get(); + value = F; } } - params->values[E->get().option.name] = value; + params->values[E.option.name] = value; } else { - params->values[E->get().option.name] = E->get().default_value; + params->values[E.option.name] = E.default_value; } } @@ -254,18 +254,18 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_paths[0].get_extension(), &importers); List<Pair<String, String>> importer_names; - for (List<Ref<ResourceImporter>>::Element *E = importers.front(); E; E = E->next()) { - importer_names.push_back(Pair<String, String>(E->get()->get_visible_name(), E->get()->get_importer_name())); + for (Ref<ResourceImporter> E : importers) { + importer_names.push_back(Pair<String, String>(E->get_visible_name(), E->get_importer_name())); } importer_names.sort_custom<PairSort<String, String>>(); import_as->clear(); - for (List<Pair<String, String>>::Element *E = importer_names.front(); E; E = E->next()) { - import_as->add_item(E->get().first); - import_as->set_item_metadata(import_as->get_item_count() - 1, E->get().second); - if (E->get().second == params->importer->get_importer_name()) { + for (const Pair<String, String> &E : importer_names) { + import_as->add_item(E.first); + import_as->set_item_metadata(import_as->get_item_count() - 1, E.second); + if (E.second == params->importer->get_importer_name()) { import_as->select(import_as->get_item_count() - 1); } } @@ -345,8 +345,8 @@ void ImportDock::_preset_selected(int p_idx) { case ITEM_SET_AS_DEFAULT: { Dictionary d; - for (const List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) { - d[E->get().name] = params->values[E->get().name]; + for (const PropertyInfo &E : params->properties) { + d[E.name] = params->values[E.name]; } ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), d); @@ -363,10 +363,10 @@ void ImportDock::_preset_selected(int p_idx) { if (params->checking) { params->checked.clear(); } - for (List<Variant>::Element *E = v.front(); E; E = E->next()) { - params->values[E->get()] = d[E->get()]; + for (const Variant &E : v) { + params->values[E] = d[E]; if (params->checking) { - params->checked.insert(E->get()); + params->checked.insert(E); } } params->update(); @@ -384,10 +384,10 @@ void ImportDock::_preset_selected(int p_idx) { if (params->checking) { params->checked.clear(); } - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - params->values[E->get().option.name] = E->get().default_value; + for (const ResourceImporter::ImportOption &E : options) { + params->values[E.option.name] = E.default_value; if (params->checking) { - params->checked.insert(E->get().option.name); + params->checked.insert(E.option.name); } } params->update(); @@ -486,9 +486,9 @@ void ImportDock::_reimport() { if (params->checking && config->get_value("remap", "importer") == params->importer->get_importer_name()) { //update only what is edited (checkboxes) if the importer is the same - for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) { - if (params->checked.has(E->get().name)) { - config->set_value("params", E->get().name, params->values[E->get().name]); + for (const PropertyInfo &E : params->properties) { + if (params->checked.has(E.name)) { + config->set_value("params", E.name, params->values[E.name]); } } } else { @@ -498,8 +498,8 @@ void ImportDock::_reimport() { config->erase_section("params"); } - for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) { - config->set_value("params", E->get().name, params->values[E->get().name]); + for (const PropertyInfo &E : params->properties) { + config->set_value("params", E.name, params->values[E.name]); } } diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index ab307500e7..1973494a2a 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -87,12 +87,12 @@ void InspectorDock::_menu_option(int p_option) { List<PropertyInfo> props; current->get_property_list(&props); Map<RES, RES> duplicates; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant v = current->get(E->get().name); + Variant v = current->get(E.name); if (v.is_ref()) { REF ref = v; if (ref.is_valid()) { @@ -103,8 +103,8 @@ void InspectorDock::_menu_option(int p_option) { } res = duplicates[res]; - current->set(E->get().name, res); - editor->get_inspector()->update_property(E->get().name); + current->set(E.name, res); + editor->get_inspector()->update_property(E.name); } } } diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index f51decd9dc..b32ea67d4d 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -43,15 +43,15 @@ void LocalizationEditor::_notification(int p_what) { List<String> tfn; ResourceLoader::get_recognized_extensions_for_type("Translation", &tfn); - for (List<String>::Element *E = tfn.front(); E; E = E->next()) { - translation_file_open->add_filter("*." + E->get()); + for (const String &E : tfn) { + translation_file_open->add_filter("*." + E); } List<String> rfn; ResourceLoader::get_recognized_extensions_for_type("Resource", &rfn); - for (List<String>::Element *E = rfn.front(); E; E = E->next()) { - translation_res_file_open_dialog->add_filter("*." + E->get()); - translation_res_option_file_open_dialog->add_filter("*." + E->get()); + for (const String &E : rfn) { + translation_res_file_open_dialog->add_filter("*." + E); + translation_res_option_file_open_dialog->add_filter("*." + E); } _update_pot_file_extensions(); @@ -430,8 +430,8 @@ void LocalizationEditor::_update_pot_file_extensions() { pot_file_open_dialog->clear_filters(); List<String> translation_parse_file_extensions; EditorTranslationParser::get_singleton()->get_recognized_extensions(&translation_parse_file_extensions); - for (List<String>::Element *E = translation_parse_file_extensions.front(); E; E = E->next()) { - pot_file_open_dialog->add_filter("*." + E->get()); + for (const String &E : translation_parse_file_extensions) { + pot_file_open_dialog->add_filter("*." + E); } } @@ -560,8 +560,8 @@ void LocalizationEditor::update_translations() { List<Variant> rk; remaps.get_key_list(&rk); Vector<String> keys; - for (List<Variant>::Element *E = rk.front(); E; E = E->next()) { - keys.push_back(E->get()); + for (const Variant &E : rk) { + keys.push_back(E); } keys.sort(); diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp index b714109af7..fd4a4334fc 100644 --- a/editor/multi_node_edit.cpp +++ b/editor/multi_node_edit.cpp @@ -52,12 +52,12 @@ bool MultiNodeEdit::_set_impl(const StringName &p_name, const Variant &p_value, UndoRedo *ur = EditorNode::get_undo_redo(); ur->create_action(TTR("MultiNode Set") + " " + String(name), UndoRedo::MERGE_ENDS); - for (const List<NodePath>::Element *E = nodes.front(); E; E = E->next()) { - if (!es->has_node(E->get())) { + for (const NodePath &E : nodes) { + if (!es->has_node(E)) { continue; } - Node *n = es->get_node(E->get()); + Node *n = es->get_node(E); if (!n) { continue; } @@ -98,12 +98,12 @@ bool MultiNodeEdit::_get(const StringName &p_name, Variant &r_ret) const { name = "script"; } - for (const List<NodePath>::Element *E = nodes.front(); E; E = E->next()) { - if (!es->has_node(E->get())) { + for (const NodePath &E : nodes) { + if (!es->has_node(E)) { continue; } - const Node *n = es->get_node(E->get()); + const Node *n = es->get_node(E); if (!n) { continue; } @@ -130,12 +130,12 @@ void MultiNodeEdit::_get_property_list(List<PropertyInfo> *p_list) const { List<PLData *> data_list; - for (const List<NodePath>::Element *E = nodes.front(); E; E = E->next()) { - if (!es->has_node(E->get())) { + for (const NodePath &E : nodes) { + if (!es->has_node(E)) { continue; } - Node *n = es->get_node(E->get()); + Node *n = es->get_node(E); if (!n) { continue; } @@ -143,30 +143,30 @@ void MultiNodeEdit::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> plist; n->get_property_list(&plist, true); - for (List<PropertyInfo>::Element *F = plist.front(); F; F = F->next()) { - if (F->get().name == "script") { + for (const PropertyInfo &F : plist) { + if (F.name == "script") { continue; //added later manually, since this is intercepted before being set (check Variant Object::get() ) } - if (!usage.has(F->get().name)) { + if (!usage.has(F.name)) { PLData pld; pld.uses = 0; - pld.info = F->get(); - usage[F->get().name] = pld; - data_list.push_back(usage.getptr(F->get().name)); + pld.info = F; + usage[F.name] = pld; + data_list.push_back(usage.getptr(F.name)); } // Make sure only properties with the same exact PropertyInfo data will appear - if (usage[F->get().name].info == F->get()) { - usage[F->get().name].uses++; + if (usage[F.name].info == F) { + usage[F.name].uses++; } } nc++; } - for (List<PLData *>::Element *E = data_list.front(); E; E = E->next()) { - if (nc == E->get()->uses) { - p_list->push_back(E->get()->info); + for (const PLData *E : data_list) { + if (nc == E->uses) { + p_list->push_back(E->info); } } diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp index 35b27b25aa..5fe466140b 100644 --- a/editor/plugin_config_dialog.cpp +++ b/editor/plugin_config_dialog.cpp @@ -150,7 +150,7 @@ void PluginConfigDialog::_on_required_text_changed(const String &) { if (script_edit->get_text().get_extension() != ext) { is_valid = false; script_validation->set_texture(invalid_icon); - script_validation->set_tooltip(vformat(TTR("Script extension must match chosen langauge extension (.%s)."), ext)); + script_validation->set_tooltip(vformat(TTR("Script extension must match chosen language extension (.%s)."), ext)); } if (script_edit->get_text().get_basename().is_empty()) { is_valid = false; diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 9e58332e41..ad2d9866fa 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -72,22 +72,22 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven List<StringName> names; ap->get_animation_list(&names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E->get()); - animations_to_add.push_back(E->get()); + for (const StringName &E : names) { + animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E); + animations_to_add.push_back(E); } } } - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - String name = String(E->get()).replace_first("AnimationNode", ""); + for (const StringName &E : classes) { + String name = String(E).replace_first("AnimationNode", ""); if (name == "Animation") { continue; } int idx = menu->get_item_count(); menu->add_item(vformat("Add %s", name), idx); - menu->set_item_metadata(idx, E->get()); + menu->set_item_metadata(idx, E); } Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard(); @@ -373,8 +373,8 @@ void AnimationNodeBlendSpace1DEditor::_add_menu_type(int p_index) { open_file->clear_filters(); List<String> filters; ResourceLoader::get_recognized_extensions_for_type("AnimationRootNode", &filters); - for (List<String>::Element *E = filters.front(); E; E = E->next()) { - open_file->add_filter("*." + E->get()); + for (const String &E : filters) { + open_file->add_filter("*." + E); } open_file->popup_file_dialog(); return; diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index bbf88bbd8f..49fcac512b 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -96,21 +96,21 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven if (ap) { List<StringName> names; ap->get_animation_list(&names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E->get()); - animations_to_add.push_back(E->get()); + for (const StringName &E : names) { + animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E); + animations_to_add.push_back(E); } } } - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - String name = String(E->get()).replace_first("AnimationNode", ""); + for (const StringName &E : classes) { + String name = String(E).replace_first("AnimationNode", ""); if (name == "Animation") { continue; // nope } int idx = menu->get_item_count(); menu->add_item(vformat("Add %s", name), idx); - menu->set_item_metadata(idx, E->get()); + menu->set_item_metadata(idx, E); } Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard(); @@ -295,8 +295,8 @@ void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) { open_file->clear_filters(); List<String> filters; ResourceLoader::get_recognized_extensions_for_type("AnimationRootNode", &filters); - for (List<String>::Element *E = filters.front(); E; E = E->next()) { - open_file->add_filter("*." + E->get()); + for (const String &E : filters) { + open_file->add_filter("*." + E); } open_file->popup_file_dialog(); return; diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 7930bc1e1c..c94014944c 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -121,21 +121,21 @@ void AnimationNodeBlendTreeEditor::_update_graph() { List<StringName> nodes; blend_tree->get_node_list(&nodes); - for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { + for (const StringName &E : nodes) { GraphNode *node = memnew(GraphNode); graph->add_child(node); - Ref<AnimationNode> agnode = blend_tree->get_node(E->get()); + Ref<AnimationNode> agnode = blend_tree->get_node(E); - node->set_position_offset(blend_tree->get_node_position(E->get()) * EDSCALE); + node->set_position_offset(blend_tree->get_node_position(E) * EDSCALE); node->set_title(agnode->get_caption()); - node->set_name(E->get()); + node->set_name(E); int base = 0; - if (String(E->get()) != "output") { + if (String(E) != "output") { LineEdit *name = memnew(LineEdit); - name->set_text(E->get()); + name->set_text(E); name->set_expand_to_text_length_enabled(true); node->add_child(name); node->set_slot(0, false, 0, Color(), true, 0, get_theme_color(SNAME("font_color"), SNAME("Label"))); @@ -143,7 +143,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out), varray(name, agnode), CONNECT_DEFERRED); base = 1; node->set_show_close_button(true); - node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_request), varray(E->get()), CONNECT_DEFERRED); + node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_request), varray(E), CONNECT_DEFERRED); } for (int i = 0; i < agnode->get_input_count(); i++) { @@ -155,12 +155,12 @@ void AnimationNodeBlendTreeEditor::_update_graph() { List<PropertyInfo> pinfo; agnode->get_parameter_list(&pinfo); - for (List<PropertyInfo>::Element *F = pinfo.front(); F; F = F->next()) { - if (!(F->get().usage & PROPERTY_USAGE_EDITOR)) { + for (const PropertyInfo &F : pinfo) { + if (!(F.usage & PROPERTY_USAGE_EDITOR)) { continue; } - String base_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E->get()) + "/" + F->get().name; - EditorProperty *prop = EditorInspector::instantiate_property_editor(AnimationTreeEditor::get_singleton()->get_tree(), F->get().type, base_path, F->get().hint, F->get().hint_string, F->get().usage); + String base_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E) + "/" + F.name; + EditorProperty *prop = EditorInspector::instantiate_property_editor(AnimationTreeEditor::get_singleton()->get_tree(), F.type, base_path, F.hint, F.hint_string, F.usage); if (prop) { prop->set_object_and_property(AnimationTreeEditor::get_singleton()->get_tree(), base_path); prop->update_property(); @@ -171,7 +171,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { } } - node->connect("dragged", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_dragged), varray(E->get())); + node->connect("dragged", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_dragged), varray(E)); if (AnimationTreeEditor::get_singleton()->can_edit(agnode)) { node->add_child(memnew(HSeparator)); @@ -179,7 +179,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { open_in_editor->set_text(TTR("Open Editor")); open_in_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); node->add_child(open_in_editor); - open_in_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_open_in_editor), varray(E->get()), CONNECT_DEFERRED); + open_in_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_open_in_editor), varray(E), CONNECT_DEFERRED); open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER); } @@ -189,7 +189,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { edit_filters->set_text(TTR("Edit Filters")); edit_filters->set_icon(get_theme_icon(SNAME("AnimationFilter"), SNAME("EditorIcons"))); node->add_child(edit_filters); - edit_filters->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_edit_filters), varray(E->get()), CONNECT_DEFERRED); + edit_filters->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_edit_filters), varray(E), CONNECT_DEFERRED); edit_filters->set_h_size_flags(SIZE_SHRINK_CENTER); } @@ -212,9 +212,9 @@ void AnimationNodeBlendTreeEditor::_update_graph() { List<StringName> anims; ap->get_animation_list(&anims); - for (List<StringName>::Element *F = anims.front(); F; F = F->next()) { - mb->get_popup()->add_item(F->get()); - options.push_back(F->get()); + for (const StringName &F : anims) { + mb->get_popup()->add_item(F); + options.push_back(F); } if (ap->has_animation(anim->get_animation())) { @@ -225,10 +225,10 @@ void AnimationNodeBlendTreeEditor::_update_graph() { pb->set_percent_visible(false); pb->set_custom_minimum_size(Vector2(0, 14) * EDSCALE); - animations[E->get()] = pb; + animations[E] = pb; node->add_child(pb); - mb->get_popup()->connect("index_pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_anim_selected), varray(options, E->get()), CONNECT_DEFERRED); + mb->get_popup()->connect("index_pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_anim_selected), varray(options, E), CONNECT_DEFERRED); } Ref<StyleBoxFlat> sb = node->get_theme_stylebox(SNAME("frame"), SNAME("GraphNode")); @@ -246,10 +246,10 @@ void AnimationNodeBlendTreeEditor::_update_graph() { List<AnimationNodeBlendTree::NodeConnection> connections; blend_tree->get_node_connections(&connections); - for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = connections.front(); E; E = E->next()) { - StringName from = E->get().output_node; - StringName to = E->get().input_node; - int to_idx = E->get().input_index; + for (const AnimationNodeBlendTree::NodeConnection &E : connections) { + StringName from = E.output_node; + StringName to = E.input_node; + int to_idx = E.input_index; graph->connect_node(from, 0, to, to_idx); } @@ -274,8 +274,8 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { open_file->clear_filters(); List<String> filters; ResourceLoader::get_recognized_extensions_for_type("AnimationNode", &filters); - for (List<String>::Element *E = filters.front(); E; E = E->next()) { - open_file->add_filter("*." + E->get()); + for (const String &E : filters) { + open_file->add_filter("*." + E); } open_file->popup_file_dialog(); return; @@ -394,9 +394,9 @@ void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) { List<AnimationNodeBlendTree::NodeConnection> conns; blend_tree->get_node_connections(&conns); - for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().output_node == p_which || E->get().input_node == p_which) { - undo_redo->add_undo_method(blend_tree.ptr(), "connect_node", E->get().input_node, E->get().input_index, E->get().output_node); + for (const AnimationNodeBlendTree::NodeConnection &E : conns) { + if (E.output_node == p_which || E.input_node == p_which) { + undo_redo->add_undo_method(blend_tree.ptr(), "connect_node", E.input_node, E.input_index, E.output_node); } } @@ -423,8 +423,8 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request() { undo_redo->create_action(TTR("Delete Node(s)")); - for (List<StringName>::Element *F = to_erase.front(); F; F = F->next()) { - _delete_request(F->get()); + for (const StringName &F : to_erase) { + _delete_request(F); } undo_redo->commit_action(); @@ -517,8 +517,8 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano List<StringName> animations; player->get_animation_list(&animations); - for (List<StringName>::Element *E = animations.front(); E; E = E->next()) { - Ref<Animation> anim = player->get_animation(E->get()); + for (const StringName &E : animations) { + Ref<Animation> anim = player->get_animation(E); for (int i = 0; i < anim->get_track_count(); i++) { String track_path = anim->track_get_path(i); paths.insert(track_path); @@ -718,13 +718,13 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { List<AnimationNodeBlendTree::NodeConnection> conns; blend_tree->get_node_connections(&conns); - for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = conns.front(); E; E = E->next()) { + for (const AnimationNodeBlendTree::NodeConnection &E : conns) { float activity = 0; - StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E->get().input_node; + StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node; if (AnimationTreeEditor::get_singleton()->get_tree() && !AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) { - activity = AnimationTreeEditor::get_singleton()->get_tree()->get_connection_activity(path, E->get().input_index); + activity = AnimationTreeEditor::get_singleton()->get_tree()->get_connection_activity(path, E.input_index); } - graph->set_connection_activity(E->get().output_node, 0, E->get().input_node, E->get().input_index, activity); + graph->set_connection_activity(E.output_node, 0, E.input_node, E.input_index, activity); } AnimationTree *graph_player = AnimationTreeEditor::get_singleton()->get_tree(); @@ -741,7 +741,7 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { Ref<Animation> anim = player->get_animation(an->get_animation()); if (anim.is_valid()) { E->get()->set_max(anim->get_length()); - //StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E->get().input_node; + //StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node; StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E->key()) + "/time"; E->get()->set_value(AnimationTreeEditor::get_singleton()->get_tree()->get(time_path)); } @@ -828,10 +828,10 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima List<AnimationNodeBlendTree::NodeConnection> connections; blend_tree->get_node_connections(&connections); - for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = connections.front(); E; E = E->next()) { - StringName from = E->get().output_node; - StringName to = E->get().input_node; - int to_idx = E->get().input_index; + for (const AnimationNodeBlendTree::NodeConnection &E : connections) { + StringName from = E.output_node; + StringName to = E.input_node; + int to_idx = E.input_index; graph->connect_node(from, 0, to, to_idx); } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index cbce5bb3f5..4ba9147955 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -350,8 +350,8 @@ void AnimationPlayerEditor::_animation_load() { List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("Animation", &extensions); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - file->add_filter("*." + E->get() + " ; " + E->get().to_upper()); + for (const String &E : extensions) { + file->add_filter("*." + E + " ; " + E.to_upper()); } file->popup_file_dialog(); @@ -584,8 +584,7 @@ void AnimationPlayerEditor::_animation_blend() { blend_editor.next->clear(); blend_editor.next->add_item("", i); - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { - String to = E->get(); + for (const StringName &to : anims) { TreeItem *blend = blend_editor.tree->create_item(root); blend->set_editable(0, false); blend->set_editable(1, true); @@ -830,20 +829,20 @@ void AnimationPlayerEditor::_update_player() { } int active_idx = -1; - for (List<StringName>::Element *E = animlist.front(); E; E = E->next()) { + for (const StringName &E : animlist) { Ref<Texture2D> icon; - if (E->get() == player->get_autoplay()) { - if (E->get() == "RESET") { + if (E == player->get_autoplay()) { + if (E == "RESET") { icon = autoplay_reset_icon; } else { icon = autoplay_icon; } - } else if (E->get() == "RESET") { + } else if (E == "RESET") { icon = reset_icon; } - animation->add_icon_item(icon, E->get()); + animation->add_icon_item(icon, E); - if (player->get_assigned_animation() == E->get()) { + if (player->get_assigned_animation() == E) { active_idx = animation->get_item_count() - 1; } } @@ -966,9 +965,9 @@ void AnimationPlayerEditor::_animation_duplicate() { Ref<Animation> new_anim = memnew(Animation); List<PropertyInfo> plist; anim->get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE) { - new_anim->set(E->get().name, anim->get(E->get().name)); + for (const PropertyInfo &E : plist) { + if (E.usage & PROPERTY_USAGE_STORAGE) { + new_anim->set(E.name, anim->get(E.name)); } } new_anim->set_path(""); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 8abe20c3c9..a1f96f21bf 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -93,21 +93,21 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (ap) { List<StringName> names; ap->get_animation_list(&names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E->get()); - animations_to_add.push_back(E->get()); + for (const StringName &E : names) { + animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E); + animations_to_add.push_back(E); } } } - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - String name = String(E->get()).replace_first("AnimationNode", ""); + for (const StringName &E : classes) { + String name = String(E).replace_first("AnimationNode", ""); if (name == "Animation") { continue; // nope } int idx = menu->get_item_count(); menu->add_item(vformat("Add %s", name), idx); - menu->set_item_metadata(idx, E->get()); + menu->set_item_metadata(idx, E); } Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard(); @@ -318,24 +318,24 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv float best_d_x = 1e20; float best_d_y = 1e20; - for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { - if (E->get() == selected_node) { + for (const StringName &E : nodes) { + if (E == selected_node) { continue; } - Vector2 npos = state_machine->get_node_position(E->get()); + Vector2 npos = state_machine->get_node_position(E); float d_x = ABS(npos.x - cpos.x); if (d_x < MIN(5, best_d_x)) { drag_ofs.x -= cpos.x - npos.x; best_d_x = d_x; - snap_x = E->get(); + snap_x = E; } float d_y = ABS(npos.y - cpos.y); if (d_y < MIN(5, best_d_y)) { drag_ofs.y -= cpos.y - npos.y; best_d_y = d_y; - snap_y = E->get(); + snap_y = E; } } } @@ -409,8 +409,8 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) { open_file->clear_filters(); List<String> filters; ResourceLoader::get_recognized_extensions_for_type("AnimationRootNode", &filters); - for (List<String>::Element *E = filters.front(); E; E = E->next()) { - open_file->add_filter("*." + E->get()); + for (const String &E : filters) { + open_file->add_filter("*." + E); } open_file->popup_file_dialog(); return; @@ -606,11 +606,11 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } //pre pass nodes so we know the rectangles - for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { - Ref<AnimationNode> anode = state_machine->get_node(E->get()); - String name = E->get(); + for (const StringName &E : nodes) { + Ref<AnimationNode> anode = state_machine->get_node(E); + String name = E; bool needs_editor = EditorNode::get_singleton()->item_has_editor(anode.ptr()); - Ref<StyleBox> sb = E->get() == selected_node ? style_selected : style; + Ref<StyleBox> sb = E == selected_node ? style_selected : style; Size2 s = sb->get_minimum_size(); int strsize = font->get_string_size(name, font_size).width; @@ -622,8 +622,8 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } Vector2 offset; - offset += state_machine->get_node_position(E->get()) * EDSCALE; - if (selected_node == E->get() && dragging_selected) { + offset += state_machine->get_node_position(E) * EDSCALE; + if (selected_node == E && dragging_selected) { offset += drag_ofs; } offset -= s / 2; @@ -633,7 +633,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { NodeRect nr; nr.node = Rect2(offset, s); - nr.node_name = E->get(); + nr.node_name = E; scroll_range = scroll_range.merge(nr.node); //merge with range diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 9c28e023dd..cd84be0c25 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -215,8 +215,8 @@ Vector<String> AnimationTreeEditor::get_animation_list() { List<StringName> anims; ap->get_animation_list(&anims); Vector<String> ret; - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const StringName &E : anims) { + ret.push_back(E); } return ret; diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index bbc8107cf6..785bab42cf 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -603,12 +603,11 @@ void EditorAssetLibrary::_notification(int p_what) { void EditorAssetLibrary::_update_repository_options() { Dictionary default_urls; - default_urls["godotengine.org"] = "https://godotengine.org/asset-library/api"; - default_urls["localhost"] = "http://127.0.0.1/asset-library/api"; + default_urls["godotengine.org (Official)"] = "https://godotengine.org/asset-library/api"; Dictionary available_urls = _EDITOR_DEF("asset_library/available_urls", default_urls, true); repository->clear(); Array keys = available_urls.keys(); - for (int i = 0; i < available_urls.size(); i++) { + for (int i = 0; i < keys.size(); i++) { String key = keys[i]; repository->add_item(key); repository->set_item_metadata(i, available_urls[key]); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index d5ef13e426..869a582d96 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -301,8 +301,8 @@ void CanvasItemEditor::_snap_other_nodes( // Check if the element is in the exception bool exception = false; - for (List<const CanvasItem *>::Element *E = p_exceptions.front(); E; E = E->next()) { - if (E->get() == p_current) { + for (const CanvasItem *&E : p_exceptions) { + if (E == p_current) { exception = true; break; } @@ -399,8 +399,8 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig if ((is_snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) { Transform2D to_snap_transform = Transform2D(); List<const CanvasItem *> exceptions = List<const CanvasItem *>(); - for (List<CanvasItem *>::Element *E = p_other_nodes_exceptions.front(); E; E = E->next()) { - exceptions.push_back(E->get()); + for (const CanvasItem *E : p_other_nodes_exceptions) { + exceptions.push_back(E); } if (p_self_canvas_item) { exceptions.push_back(p_self_canvas_item); @@ -527,8 +527,7 @@ Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_li Rect2 rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().position + canvas_item->_edit_get_rect().size / 2), Size2()); // Expand with the other ones - for (List<CanvasItem *>::Element *E = p_list.front(); E; E = E->next()) { - CanvasItem *canvas_item2 = E->get(); + for (CanvasItem *canvas_item2 : p_list) { Transform2D xform = canvas_item2->get_global_transform_with_canvas(); Rect2 current_rect = canvas_item2->_edit_get_rect(); @@ -760,9 +759,9 @@ List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retreive_lock if (remove_canvas_item_if_parent_in_selection) { List<CanvasItem *> filtered_selection; - for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { - if (!selection.find(E->get()->get_parent())) { - filtered_selection.push_back(E->get()); + for (CanvasItem *E : selection) { + if (!selection.find(E->get_parent())) { + filtered_selection.push_back(E); } } return filtered_selection; @@ -800,8 +799,7 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 } void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones) { - for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : p_canvas_items) { CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); if (se) { se->undo_state = canvas_item->_edit_get_state(); @@ -816,8 +814,7 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items } void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones) { - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : drag_selection) { CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); canvas_item->_edit_set_state(se->undo_state); } @@ -825,8 +822,7 @@ void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_it void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones) { List<CanvasItem *> modified_canvas_items; - for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : p_canvas_items) { Dictionary old_state = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item)->undo_state; Dictionary new_state = canvas_item->_edit_get_state(); @@ -840,17 +836,16 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite } undo_redo->create_action(action_name); - for (List<CanvasItem *>::Element *E = modified_canvas_items.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : modified_canvas_items) { CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); if (se) { undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state); if (commit_bones) { - for (List<Dictionary>::Element *F = se->pre_drag_bones_undo_state.front(); F; F = F->next()) { + for (const Dictionary &F : se->pre_drag_bones_undo_state) { canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent()); undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); - undo_redo->add_undo_method(canvas_item, "_edit_set_state", F->get()); + undo_redo->add_undo_method(canvas_item, "_edit_set_state", F); } } } @@ -1304,8 +1299,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { // Filters the selection with nodes that allow setting the pivot drag_selection = List<CanvasItem *>(); - for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : selection) { if (canvas_item->_edit_use_pivot()) { drag_selection.push_back(canvas_item); } @@ -1321,8 +1315,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { } else { new_pos = snap_point(drag_from, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, nullptr, drag_selection); } - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : drag_selection) { canvas_item->_edit_set_pivot(canvas_item->get_global_transform_with_canvas().affine_inverse().xform(new_pos)); } @@ -1343,8 +1336,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { } else { new_pos = snap_point(drag_to, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL); } - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : drag_selection) { canvas_item->_edit_set_pivot(canvas_item->get_global_transform_with_canvas().affine_inverse().xform(new_pos)); } return true; @@ -1387,8 +1379,8 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { List<CanvasItem *> selection = _get_edited_canvas_items(); // Remove not movable nodes - for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { - if (!_is_node_movable(E->get(), true)) { + for (CanvasItem *E : selection) { + if (!_is_node_movable(E, true)) { selection.erase(E); } } @@ -1414,8 +1406,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { // Rotate the node if (m.is_valid()) { _restore_canvas_item_state(drag_selection); - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : drag_selection) { drag_to = transform.affine_inverse().xform(m->get_position()); //Rotate the opposite way if the canvas item's compounded scale has an uneven number of negative elements bool opposite = (canvas_item->get_global_transform().get_scale().sign().dot(canvas_item->get_transform().get_scale().sign()) == 0); @@ -2046,8 +2037,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } int index = 0; - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : drag_selection) { Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); @@ -2162,8 +2152,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } int index = 0; - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : drag_selection) { Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); @@ -2375,8 +2364,8 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (selitems.size() == 1 && editor_selection->get_selected_node_list().is_empty()) { editor->push_item(selitems[0]); } - for (List<CanvasItem *>::Element *E = selitems.front(); E; E = E->next()) { - editor_selection->add_node(E->get()); + for (CanvasItem *E : selitems) { + editor_selection->add_node(E); } } @@ -3248,8 +3237,8 @@ void CanvasItemEditor::_draw_selection() { List<CanvasItem *> selection = _get_edited_canvas_items(true, false); bool single = selection.size() == 1; - for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); + for (CanvasItem *E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); bool item_locked = canvas_item->has_meta("_edit_lock_"); @@ -3566,9 +3555,9 @@ void CanvasItemEditor::_draw_hover() { Point2 pos = transform.xform(hovering_results[i].position) - Point2(0, item_size.y) + (Point2(node_icon->get_size().x, -node_icon->get_size().y) / 4); // Rectify the position to avoid overlapping items - for (List<Rect2>::Element *E = previous_rects.front(); E; E = E->next()) { - if (E->get().intersects(Rect2(pos, item_size))) { - pos.y = E->get().get_position().y - item_size.y; + for (const Rect2 &E : previous_rects) { + if (E.intersects(Rect2(pos, item_size))) { + pos.y = E.get_position().y - item_size.y; } } @@ -3642,14 +3631,14 @@ void CanvasItemEditor::_draw_viewport() { all_locked = false; all_group = false; } else { - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - if (Object::cast_to<CanvasItem>(E->get()) && !Object::cast_to<CanvasItem>(E->get())->has_meta("_edit_lock_")) { + for (Node *E : selection) { + if (Object::cast_to<CanvasItem>(E) && !Object::cast_to<CanvasItem>(E)->has_meta("_edit_lock_")) { all_locked = false; break; } } - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - if (Object::cast_to<CanvasItem>(E->get()) && !Object::cast_to<CanvasItem>(E->get())->has_meta("_edit_group_")) { + for (Node *E : selection) { + if (Object::cast_to<CanvasItem>(E) && !Object::cast_to<CanvasItem>(E)->has_meta("_edit_group_")) { all_group = false; break; } @@ -3716,8 +3705,7 @@ void CanvasItemEditor::_notification(int p_what) { // Update the viewport if the canvas_item changes List<CanvasItem *> selection = _get_edited_canvas_items(true); - for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); + for (CanvasItem *canvas_item : selection) { CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); Rect2 rect; @@ -3932,8 +3920,8 @@ void CanvasItemEditor::_selection_changed() { int nbValidControls = 0; int nbAnchorsMode = 0; List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Control *control = Object::cast_to<Control>(E->get()); + for (Node *E : selection) { + Control *control = Object::cast_to<Control>(E); if (!control) { continue; } @@ -4101,8 +4089,8 @@ void CanvasItemEditor::_set_anchors_and_offsets_preset(Control::LayoutPreset p_p undo_redo->create_action(TTR("Change Anchors and Offsets")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Control *control = Object::cast_to<Control>(E->get()); + for (Node *E : selection) { + Control *control = Object::cast_to<Control>(E); if (control) { undo_redo->add_do_method(control, "set_anchors_preset", p_preset); switch (p_preset) { @@ -4142,8 +4130,8 @@ void CanvasItemEditor::_set_anchors_and_offsets_to_keep_ratio() { undo_redo->create_action(TTR("Change Anchors and Offsets")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Control *control = Object::cast_to<Control>(E->get()); + for (Node *E : selection) { + Control *control = Object::cast_to<Control>(E); if (control) { Point2 top_left_anchor = _position_to_anchor(control, Point2()); Point2 bottom_right_anchor = _position_to_anchor(control, control->get_size()); @@ -4169,8 +4157,8 @@ void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) { List<Node *> selection = editor_selection->get_selected_node_list(); undo_redo->create_action(TTR("Change Anchors")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Control *control = Object::cast_to<Control>(E->get()); + for (Node *E : selection) { + Control *control = Object::cast_to<Control>(E); if (control) { undo_redo->add_do_method(control, "set_anchors_preset", p_preset); undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state()); @@ -4295,15 +4283,15 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, } if (has_chain && ik_chain.size()) { - for (List<Node2D *>::Element *F = ik_chain.front(); F; F = F->next()) { + for (Node2D *&F : ik_chain) { if (key_pos) { - AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F->get(), "position", F->get()->get_position(), p_on_existing); + AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F, "position", F->get_position(), p_on_existing); } if (key_rot) { - AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F->get(), "rotation", F->get()->get_rotation(), p_on_existing); + AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F, "rotation", F->get_rotation(), p_on_existing); } if (key_scale) { - AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F->get(), "scale", F->get()->get_scale(), p_on_existing); + AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F, "scale", F->get_scale(), p_on_existing); } } } @@ -4327,8 +4315,8 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) { List<CanvasItem *> selection = _get_edited_canvas_items(false, false); - for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { - Control *control = Object::cast_to<Control>(E->get()); + for (CanvasItem *E : selection) { + Control *control = Object::cast_to<Control>(E); if (!control || Object::cast_to<Container>(control->get_parent())) { continue; } @@ -4441,13 +4429,13 @@ void CanvasItemEditor::_popup_callback(int p_op) { } break; case SKELETON_SHOW_BONES: { List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + for (Node *E : selection) { // Add children nodes so they are processed - for (int child = 0; child < E->get()->get_child_count(); child++) { - selection.push_back(E->get()->get_child(child)); + for (int child = 0; child < E->get_child_count(); child++) { + selection.push_back(E->get_child(child)); } - Bone2D *bone_2d = Object::cast_to<Bone2D>(E->get()); + Bone2D *bone_2d = Object::cast_to<Bone2D>(E); if (!bone_2d || !bone_2d->is_inside_tree()) { continue; } @@ -4477,8 +4465,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->create_action(TTR("Lock Selected")); List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); + for (Node *E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); if (!canvas_item || !canvas_item->is_inside_tree()) { continue; } @@ -4499,8 +4487,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->create_action(TTR("Unlock Selected")); List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); + for (Node *E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); if (!canvas_item || !canvas_item->is_inside_tree()) { continue; } @@ -4521,8 +4509,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->create_action(TTR("Group Selected")); List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); + for (Node *E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); if (!canvas_item || !canvas_item->is_inside_tree()) { continue; } @@ -4543,8 +4531,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->create_action(TTR("Ungroup Selected")); List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); + for (Node *E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); if (!canvas_item || !canvas_item->is_inside_tree()) { continue; } @@ -4711,14 +4699,14 @@ void CanvasItemEditor::_popup_callback(int p_op) { } undo_redo->create_action(TTR("Paste Pose")); - for (List<PoseClipboard>::Element *E = pose_clipboard.front(); E; E = E->next()) { - Node2D *n2d = Object::cast_to<Node2D>(ObjectDB::get_instance(E->get().id)); + for (const PoseClipboard &E : pose_clipboard) { + Node2D *n2d = Object::cast_to<Node2D>(ObjectDB::get_instance(E.id)); if (!n2d) { continue; } - undo_redo->add_do_method(n2d, "set_position", E->get().pos); - undo_redo->add_do_method(n2d, "set_rotation", E->get().rot); - undo_redo->add_do_method(n2d, "set_scale", E->get().scale); + undo_redo->add_do_method(n2d, "set_position", E.pos); + undo_redo->add_do_method(n2d, "set_rotation", E.rot); + undo_redo->add_do_method(n2d, "set_scale", E.scale); undo_redo->add_undo_method(n2d, "set_position", n2d->get_position()); undo_redo->add_undo_method(n2d, "set_rotation", n2d->get_rotation()); undo_redo->add_undo_method(n2d, "set_scale", n2d->get_scale()); @@ -5325,7 +5313,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { select_button->set_pressed(true); select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q)); select_button->set_shortcut_context(this); - select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.")); + select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("RMB: Add node at position clicked.")); hb->add_child(memnew(VSeparator)); @@ -5819,14 +5807,14 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & String property = "texture"; List<PropertyInfo> props; child->get_property_list(&props); - for (const List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().name == "config/texture") { // Particles2D + for (const PropertyInfo &E : props) { + if (E.name == "config/texture") { // Particles2D property = "config/texture"; break; - } else if (E->get().name == "texture/texture") { // Polygon2D + } else if (E.name == "texture/texture") { // Polygon2D property = "texture/texture"; break; - } else if (E->get().name == "normal") { // TouchScreenButton + } else if (E.name == "normal") { // TouchScreenButton property = "normal"; break; } diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 45adbe29de..2c2adc2672 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -31,6 +31,7 @@ #include "collision_shape_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/os/keyboard.h" #include "scene/resources/capsule_shape_2d.h" #include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" @@ -97,7 +98,7 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const { case RECTANGLE_SHAPE: { Ref<RectangleShape2D> rect = node->get_shape(); - if (idx < 3) { + if (idx < 8) { return rect->get_size().abs(); } @@ -176,16 +177,26 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } break; case RECTANGLE_SHAPE: { - if (idx < 3) { + if (idx < 8) { Ref<RectangleShape2D> rect = node->get_shape(); + Vector2 size = (Point2)original; - Vector2 size = rect->get_size(); - if (idx == 2) { - size = p_point * 2; + if (RECT_HANDLES[idx].x != 0) { + size.x = p_point.x * RECT_HANDLES[idx].x * 2; + } + if (RECT_HANDLES[idx].y != 0) { + size.y = p_point.y * RECT_HANDLES[idx].y * 2; + } + + if (Input::get_singleton()->is_key_pressed(KEY_ALT)) { + rect->set_size(size.abs()); + node->set_global_position(original_transform.get_origin()); } else { - size[idx] = p_point[idx] * 2; + rect->set_size(((Point2)original + (size - (Point2)original) * 0.5).abs()); + Point2 pos = original_transform.affine_inverse().xform(original_transform.get_origin()); + pos += (size - (Point2)original) * 0.5 * RECT_HANDLES[idx] * 0.5; + node->set_global_position(original_transform.xform(pos)); } - rect->set_size(size.abs()); canvas_item_editor->update_viewport(); } @@ -280,8 +291,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { Ref<RectangleShape2D> rect = node->get_shape(); undo_redo->add_do_method(rect.ptr(), "set_size", rect->get_size()); + undo_redo->add_do_method(node, "set_global_transform", node->get_global_transform()); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(rect.ptr(), "set_size", p_org); + undo_redo->add_undo_method(node, "set_global_transform", original_transform); undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; @@ -342,6 +355,8 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e } original = get_handle_value(edit_handle); + original_transform = node->get_global_transform(); + last_point = original; pressed = true; return true; @@ -369,13 +384,26 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e } Vector2 cpoint = canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position())); - cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + cpoint = original_transform.affine_inverse().xform(cpoint); + last_point = cpoint; set_handle(edit_handle, cpoint); return true; } + Ref<InputEventKey> k = p_event; + + if (k.is_valid()) { + if (edit_handle == -1 || !pressed || k->is_echo()) { + return false; + } + + if (shape_type == RECTANGLE_SHAPE && k->get_keycode() == KEY_ALT) { + set_handle(edit_handle, last_point); // Update handle when Alt key is toggled. + } + } + return false; } @@ -492,15 +520,12 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla case RECTANGLE_SHAPE: { Ref<RectangleShape2D> shape = node->get_shape(); - handles.resize(3); + handles.resize(8); Vector2 ext = shape->get_size() / 2; - handles.write[0] = Point2(ext.x, 0); - handles.write[1] = Point2(0, ext.y); - handles.write[2] = Point2(ext.x, ext.y); - - p_overlay->draw_texture(h, gt.xform(handles[0]) - size); - p_overlay->draw_texture(h, gt.xform(handles[1]) - size); - p_overlay->draw_texture(h, gt.xform(handles[2]) - size); + for (int i = 0; i < handles.size(); i++) { + handles.write[i] = RECT_HANDLES[i] * ext; + p_overlay->draw_texture(h, gt.xform(handles[i]) - size); + } } break; diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 054db1a61b..7db6bd22aa 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -52,6 +52,17 @@ class CollisionShape2DEditor : public Control { SEGMENT_SHAPE }; + const Point2 RECT_HANDLES[8] = { + Point2(1, 0), + Point2(1, 1), + Point2(0, 1), + Point2(-1, 1), + Point2(-1, 0), + Point2(-1, -1), + Point2(0, -1), + Point2(1, -1), + }; + EditorNode *editor; UndoRedo *undo_redo; CanvasItemEditor *canvas_item_editor; @@ -63,6 +74,8 @@ class CollisionShape2DEditor : public Control { int edit_handle; bool pressed; Variant original; + Transform2D original_transform; + Point2 last_point; Variant get_handle_value(int idx) const; void set_handle(int idx, Point2 &p_point); diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index c4deb296fb..6f246c1661 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -253,8 +253,8 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) { file = memnew(EditorFileDialog); List<String> ext; ImageLoader::get_recognized_extensions(&ext); - for (List<String>::Element *E = ext.front(); E; E = E->next()) { - file->add_filter("*." + E->get() + "; " + E->get().to_upper()); + for (const String &E : ext) { + file->add_filter("*." + E + "; " + E.to_upper()); } file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); toolbar->add_child(file); diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index a233d66d82..81c340e9a4 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -490,11 +490,11 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size Set<String> control_flow_keywords; Set<String> keywords; - for (List<String>::Element *E = kwors.front(); E; E = E->next()) { - if (scr->get_language()->is_control_flow_keyword(E->get())) { - control_flow_keywords.insert(E->get()); + for (const String &E : kwors) { + if (scr->get_language()->is_control_flow_keyword(E)) { + control_flow_keywords.insert(E); } else { - keywords.insert(E->get()); + keywords.insert(E); } } diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index cc5793a1f9..5184e837ce 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -361,8 +361,8 @@ GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin(EditorNode *p_node) { file = memnew(EditorFileDialog); List<String> ext; ImageLoader::get_recognized_extensions(&ext); - for (List<String>::Element *E = ext.front(); E; E = E->next()) { - file->add_filter("*." + E->get() + "; " + E->get().to_upper()); + for (const String &E : ext) { + file->add_filter("*." + E + "; " + E.to_upper()); } file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); toolbar->add_child(file); diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 7105d351b0..94966d4fe6 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -265,15 +265,15 @@ Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p List<PropertyInfo> params; RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); - for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) { + for (const PropertyInfo &E : params) { // Texture parameter has to be treated specially since StandardMaterial3D saved it // as RID but ShaderMaterial needs Texture itself - Ref<Texture2D> texture = mat->get_texture_by_name(E->get().name); + Ref<Texture2D> texture = mat->get_texture_by_name(E.name); if (texture.is_valid()) { - smat->set_shader_param(E->get().name, texture); + smat->set_shader_param(E.name, texture); } else { - Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E->get().name); - smat->set_shader_param(E->get().name, value); + Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); + smat->set_shader_param(E.name, value); } } @@ -309,9 +309,9 @@ Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_ List<PropertyInfo> params; RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); - for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) { - Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E->get().name); - smat->set_shader_param(E->get().name, value); + for (const PropertyInfo &E : params) { + Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); + smat->set_shader_param(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -346,9 +346,9 @@ Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p List<PropertyInfo> params; RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); - for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) { - Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E->get().name); - smat->set_shader_param(E->get().name, value); + for (const PropertyInfo &E : params) { + Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); + smat->set_shader_param(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -383,9 +383,9 @@ Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> List<PropertyInfo> params; RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); - for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) { - Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E->get().name); - smat->set_shader_param(E->get().name, value); + for (const PropertyInfo &E : params) { + Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); + smat->set_shader_param(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -420,9 +420,9 @@ Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> & List<PropertyInfo> params; RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); - for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) { - Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E->get().name); - smat->set_shader_param(E->get().name, value); + for (const PropertyInfo &E : params) { + Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); + smat->set_shader_param(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -457,9 +457,9 @@ Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> & List<PropertyInfo> params; RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms); - for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) { - Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E->get().name); - smat->set_shader_param(E->get().name, value); + for (const PropertyInfo &E : params) { + Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); + smat->set_shader_param(E.name, value); } smat->set_render_priority(mat->get_render_priority()); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 91415f4883..9ee1fcb325 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -90,8 +90,8 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->create_action(TTR("Create Static Trimesh Body")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - MeshInstance3D *instance = Object::cast_to<MeshInstance3D>(E->get()); + for (Node *E : selection) { + MeshInstance3D *instance = Object::cast_to<MeshInstance3D>(E); if (!instance) { continue; } diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 15b6a0f3a0..b3f92c9d95 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -122,23 +122,23 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, List<uint32_t> shapes; sb->get_shape_owners(&shapes); - for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) { - if (sb->is_shape_owner_disabled(E->get())) { + for (uint32_t &E : shapes) { + if (sb->is_shape_owner_disabled(E)) { continue; } - //Transform3D shape_transform = sb->shape_owner_get_transform(E->get()); + //Transform3D shape_transform = sb->shape_owner_get_transform(E); //shape_transform.set_origin(shape_transform.get_origin() - phys_offset); - for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) { - Ref<Shape3D> collision = sb->shape_owner_get_shape(E->get(), k); + for (int k = 0; k < sb->shape_owner_get_shape_count(E); k++) { + Ref<Shape3D> collision = sb->shape_owner_get_shape(E, k); if (!collision.is_valid()) { continue; } MeshLibrary::ShapeData shape_data; shape_data.shape = collision; - shape_data.local_transform = sb->get_transform() * sb->shape_owner_get_transform(E->get()); + shape_data.local_transform = sb->get_transform() * sb->shape_owner_get_transform(E); collisions.push_back(shape_data); } } diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 74fb38b66b..2138f943da 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -33,7 +33,9 @@ #include "core/math/convex_hull.h" #include "core/math/geometry_2d.h" #include "core/math/geometry_3d.h" +#include "editor/plugins/node_3d_editor_plugin.h" #include "scene/3d/audio_stream_player_3d.h" +#include "scene/3d/camera_3d.h" #include "scene/3d/collision_polygon_3d.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/cpu_particles_3d.h" @@ -106,58 +108,122 @@ void EditorNode3DGizmo::clear() { void EditorNode3DGizmo::redraw() { if (get_script_instance() && get_script_instance()->has_method("_redraw")) { get_script_instance()->call("_redraw"); - return; + } else { + ERR_FAIL_COND(!gizmo_plugin); + gizmo_plugin->redraw(this); } - ERR_FAIL_COND(!gizmo_plugin); - gizmo_plugin->redraw(this); + if (Node3DEditor::get_singleton()->is_current_selected_gizmo(this)) { + Node3DEditor::get_singleton()->update_transform_gizmo(); + } } -String EditorNode3DGizmo::get_handle_name(int p_idx) const { +String EditorNode3DGizmo::get_handle_name(int p_id) const { if (get_script_instance() && get_script_instance()->has_method("_get_handle_name")) { - return get_script_instance()->call("_get_handle_name", p_idx); + return get_script_instance()->call("_get_handle_name", p_id); } ERR_FAIL_COND_V(!gizmo_plugin, ""); - return gizmo_plugin->get_handle_name(this, p_idx); + return gizmo_plugin->get_handle_name(this, p_id); } -bool EditorNode3DGizmo::is_handle_highlighted(int p_idx) const { +bool EditorNode3DGizmo::is_handle_highlighted(int p_id) const { if (get_script_instance() && get_script_instance()->has_method("_is_handle_highlighted")) { - return get_script_instance()->call("_is_handle_highlighted", p_idx); + return get_script_instance()->call("_is_handle_highlighted", p_id); } ERR_FAIL_COND_V(!gizmo_plugin, false); - return gizmo_plugin->is_handle_highlighted(this, p_idx); + return gizmo_plugin->is_handle_highlighted(this, p_id); } -Variant EditorNode3DGizmo::get_handle_value(int p_idx) { +Variant EditorNode3DGizmo::get_handle_value(int p_id) const { if (get_script_instance() && get_script_instance()->has_method("_get_handle_value")) { - return get_script_instance()->call("_get_handle_value", p_idx); + return get_script_instance()->call("_get_handle_value", p_id); } ERR_FAIL_COND_V(!gizmo_plugin, Variant()); - return gizmo_plugin->get_handle_value(this, p_idx); + return gizmo_plugin->get_handle_value(this, p_id); } -void EditorNode3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const { if (get_script_instance() && get_script_instance()->has_method("_set_handle")) { - get_script_instance()->call("_set_handle", p_idx, p_camera, p_point); + get_script_instance()->call("_set_handle", p_id, p_camera, p_point); return; } ERR_FAIL_COND(!gizmo_plugin); - gizmo_plugin->set_handle(this, p_idx, p_camera, p_point); + gizmo_plugin->set_handle(this, p_id, p_camera, p_point); } -void EditorNode3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { +void EditorNode3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) const { if (get_script_instance() && get_script_instance()->has_method("_commit_handle")) { - get_script_instance()->call("_commit_handle", p_idx, p_restore, p_cancel); + get_script_instance()->call("_commit_handle", p_id, p_restore, p_cancel); + return; + } + + ERR_FAIL_COND(!gizmo_plugin); + gizmo_plugin->commit_handle(this, p_id, p_restore, p_cancel); +} + +int EditorNode3DGizmo::subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const { + if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_ray")) { + return get_script_instance()->call("_subgizmos_intersect_ray", p_camera, p_point); + } + + ERR_FAIL_COND_V(!gizmo_plugin, -1); + return gizmo_plugin->subgizmos_intersect_ray(this, p_camera, p_point); +} + +Vector<int> EditorNode3DGizmo::subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const { + if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_frustum")) { + Array frustum; + for (int i = 0; i < p_frustum.size(); i++) { + frustum[i] = p_frustum[i]; + } + return get_script_instance()->call("_subgizmos_intersect_frustum", p_camera, frustum); + } + + ERR_FAIL_COND_V(!gizmo_plugin, Vector<int>()); + return gizmo_plugin->subgizmos_intersect_frustum(this, p_camera, p_frustum); +} + +Transform3D EditorNode3DGizmo::get_subgizmo_transform(int p_id) const { + if (get_script_instance() && get_script_instance()->has_method("_get_subgizmo_transform")) { + return get_script_instance()->call("_get_subgizmo_transform", p_id); + } + + ERR_FAIL_COND_V(!gizmo_plugin, Transform3D()); + return gizmo_plugin->get_subgizmo_transform(this, p_id); +} + +void EditorNode3DGizmo::set_subgizmo_transform(int p_id, Transform3D p_transform) const { + if (get_script_instance() && get_script_instance()->has_method("_set_subgizmo_transform")) { + get_script_instance()->call("_set_subgizmo_transform", p_id, p_transform); return; } ERR_FAIL_COND(!gizmo_plugin); - gizmo_plugin->commit_handle(this, p_idx, p_restore, p_cancel); + gizmo_plugin->set_subgizmo_transform(this, p_id, p_transform); +} + +void EditorNode3DGizmo::commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) const { + if (get_script_instance() && get_script_instance()->has_method("_commit_subgizmos")) { + Array ids; + for (int i = 0; i < p_ids.size(); i++) { + ids[i] = p_ids[i]; + } + + Array restore; + for (int i = 0; i < p_restore.size(); i++) { + restore[i] = p_restore[i]; + } + + get_script_instance()->call("_commit_subgizmos", ids, restore, p_cancel); + return; + } + + ERR_FAIL_COND(!gizmo_plugin); + gizmo_plugin->commit_subgizmos(this, p_ids, p_restore, p_cancel); } void EditorNode3DGizmo::set_spatial_node(Node3D *p_node) { @@ -180,17 +246,17 @@ void EditorNode3DGizmo::Instance::create_instance(Node3D *p_base, bool p_hidden) RS::get_singleton()->instance_geometry_set_flag(instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); } -void EditorNode3DGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const Ref<SkinReference> &p_skin_reference, const Ref<Material> &p_material) { +void EditorNode3DGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) { ERR_FAIL_COND(!spatial_node); Instance ins; - ins.billboard = p_billboard; ins.mesh = p_mesh; ins.skin_reference = p_skin_reference; ins.material = p_material; + ins.xform = p_xform; if (valid) { ins.create_instance(spatial_node, hidden); - RS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform()); + RS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform() * ins.xform); if (ins.material.is_valid()) { RS::get_singleton()->instance_geometry_set_material_override(ins.instance, p_material->get_rid()); } @@ -245,7 +311,6 @@ void EditorNode3DGizmo::add_vertices(const Vector<Vector3> &p_vertices, const Re } } - ins.billboard = p_billboard; ins.mesh = mesh; if (valid) { ins.create_instance(spatial_node, hidden); @@ -307,8 +372,6 @@ void EditorNode3DGizmo::add_unscaled_billboard(const Ref<Material> &p_material, mesh->set_custom_aabb(AABB(Vector3(-selectable_icon_size, -selectable_icon_size, -selectable_icon_size) * 100.0f, Vector3(selectable_icon_size, selectable_icon_size, selectable_icon_size) * 200.0f)); ins.mesh = mesh; - ins.unscaled = true; - ins.billboard = true; if (valid) { ins.create_instance(spatial_node, hidden); RS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform()); @@ -331,7 +394,7 @@ void EditorNode3DGizmo::add_collision_segments(const Vector<Vector3> &p_lines) { } } -void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard, bool p_secondary) { +void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, const Vector<int> &p_ids, bool p_billboard, bool p_secondary) { billboard_handle = p_billboard; if (!is_selected() || !is_editable()) { @@ -340,8 +403,16 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< ERR_FAIL_COND(!spatial_node); - Instance ins; + if (p_ids.is_empty()) { + ERR_FAIL_COND_MSG((!handles.is_empty() && !handle_ids.is_empty()) || (!secondary_handles.is_empty() && !secondary_handle_ids.is_empty()), "Fail"); + } else { + ERR_FAIL_COND_MSG(handles.size() != handle_ids.size() || secondary_handles.size() != secondary_handle_ids.size(), "Fail"); + } + bool is_current_hover_gizmo = Node3DEditor::get_singleton()->get_current_hover_gizmo() == this; + int current_hover_handle = Node3DEditor::get_singleton()->get_current_hover_gizmo_handle(); + + Instance ins; Ref<ArrayMesh> mesh = memnew(ArrayMesh); Array a; @@ -357,7 +428,8 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< col = Color(0, 0, 1, 0.9); } - if (Node3DEditor::get_singleton()->get_over_gizmo_handle() != i) { + int id = p_ids.is_empty() ? i : p_ids[i]; + if (!is_current_hover_gizmo || current_hover_handle != id) { col.a = 0.8; } @@ -379,29 +451,31 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< } ins.mesh = mesh; - ins.billboard = p_billboard; ins.extra_margin = true; if (valid) { ins.create_instance(spatial_node, hidden); RS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform()); } instances.push_back(ins); - if (!p_secondary) { - int chs = handles.size(); - handles.resize(chs + p_handles.size()); - for (int i = 0; i < p_handles.size(); i++) { - handles.write[i + chs] = p_handles[i]; - } - } else { - int chs = secondary_handles.size(); - secondary_handles.resize(chs + p_handles.size()); - for (int i = 0; i < p_handles.size(); i++) { - secondary_handles.write[i + chs] = p_handles[i]; + + Vector<Vector3> &h = p_secondary ? secondary_handles : handles; + int current_size = h.size(); + h.resize(current_size + p_handles.size()); + for (int i = 0; i < p_handles.size(); i++) { + h.write[current_size + i] = p_handles[i]; + } + + if (!p_ids.is_empty()) { + Vector<int> &ids = p_secondary ? secondary_handle_ids : handle_ids; + current_size = ids.size(); + ids.resize(current_size + p_ids.size()); + for (int i = 0; i < p_ids.size(); i++) { + ids.write[current_size + i] = p_ids[i]; } } } -void EditorNode3DGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position) { +void EditorNode3DGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position, const Transform3D &p_xform) { ERR_FAIL_COND(!spatial_node); BoxMesh box_mesh; @@ -419,8 +493,7 @@ void EditorNode3DGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size, Ref<ArrayMesh> m = memnew(ArrayMesh); m->add_surface_from_arrays(box_mesh.surface_get_primitive_type(0), arrays); - m->surface_set_material(0, p_material); - add_mesh(m); + add_mesh(m, p_material, p_xform); } bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) { @@ -485,13 +558,15 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector Transform3D it = t.affine_inverse(); Vector<Plane> transformed_frustum; + int plane_count = p_frustum.size(); + transformed_frustum.resize(plane_count); - for (int i = 0; i < p_frustum.size(); i++) { - transformed_frustum.push_back(it.xform(p_frustum[i])); + for (int i = 0; i < plane_count; i++) { + transformed_frustum.write[i] = it.xform(p_frustum[i]); } - Vector<Vector3> convex_points = Geometry3D::compute_convex_mesh_points(p_frustum.ptr(), p_frustum.size()); - if (collision_mesh->inside_convex_shape(transformed_frustum.ptr(), transformed_frustum.size(), convex_points.ptr(), convex_points.size(), mesh_scale)) { + Vector<Vector3> convex_points = Geometry3D::compute_convex_mesh_points(transformed_frustum.ptr(), plane_count); + if (collision_mesh->inside_convex_shape(transformed_frustum.ptr(), plane_count, convex_points.ptr(), convex_points.size(), mesh_scale)) { return true; } } @@ -499,64 +574,71 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector return false; } -bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) { - ERR_FAIL_COND_V(!spatial_node, false); - ERR_FAIL_COND_V(!valid, false); +void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id) { + r_id = -1; - if (hidden && !gizmo_plugin->is_selectable_when_hidden()) { - return false; + ERR_FAIL_COND(!spatial_node); + ERR_FAIL_COND(!valid); + + if (hidden) { + return; } - if (r_gizmo_handle && !hidden) { - Transform3D t = spatial_node->get_global_transform(); - if (billboard_handle) { - t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1)); - } + Transform3D camera_xform = p_camera->get_global_transform(); + Transform3D t = spatial_node->get_global_transform(); + if (billboard_handle) { + t.set_look_at(t.origin, t.origin - camera_xform.basis.get_axis(2), camera_xform.basis.get_axis(1)); + } - float min_d = 1e20; - int idx = -1; + float min_d = 1e20; - for (int i = 0; i < secondary_handles.size(); i++) { - Vector3 hpos = t.xform(secondary_handles[i]); - Vector2 p = p_camera->unproject_position(hpos); + for (int i = 0; i < secondary_handles.size(); i++) { + Vector3 hpos = t.xform(secondary_handles[i]); + Vector2 p = p_camera->unproject_position(hpos); - if (p.distance_to(p_point) < HANDLE_HALF_SIZE) { - real_t dp = p_camera->get_transform().origin.distance_to(hpos); - if (dp < min_d) { - r_pos = t.xform(hpos); - r_normal = p_camera->get_transform().basis.get_axis(2); - min_d = dp; - idx = i + handles.size(); + if (p.distance_to(p_point) < HANDLE_HALF_SIZE) { + real_t dp = p_camera->get_transform().origin.distance_to(hpos); + if (dp < min_d) { + min_d = dp; + if (secondary_handle_ids.is_empty()) { + r_id = i; + } else { + r_id = secondary_handle_ids[i]; } } } + } - if (p_sec_first && idx != -1) { - *r_gizmo_handle = idx; - return true; - } + if (r_id != -1 && p_shift_pressed) { + return; + } - min_d = 1e20; + min_d = 1e20; - for (int i = 0; i < handles.size(); i++) { - Vector3 hpos = t.xform(handles[i]); - Vector2 p = p_camera->unproject_position(hpos); + for (int i = 0; i < handles.size(); i++) { + Vector3 hpos = t.xform(handles[i]); + Vector2 p = p_camera->unproject_position(hpos); - if (p.distance_to(p_point) < HANDLE_HALF_SIZE) { - real_t dp = p_camera->get_transform().origin.distance_to(hpos); - if (dp < min_d) { - r_pos = t.xform(hpos); - r_normal = p_camera->get_transform().basis.get_axis(2); - min_d = dp; - idx = i; + if (p.distance_to(p_point) < HANDLE_HALF_SIZE) { + real_t dp = p_camera->get_transform().origin.distance_to(hpos); + if (dp < min_d) { + min_d = dp; + if (handle_ids.is_empty()) { + r_id = i; + } else { + r_id = handle_ids[i]; } } } + } +} - if (idx >= 0) { - *r_gizmo_handle = idx; - return true; - } +bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal) { + ERR_FAIL_COND_V(!spatial_node, false); + ERR_FAIL_COND_V(!valid, false); + + if (hidden && !gizmo_plugin->is_selectable_when_hidden()) { + return false; } if (selectable_icon_size > 0.0f) { @@ -674,6 +756,25 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, return false; } +bool EditorNode3DGizmo::is_subgizmo_selected(int p_id) const { + Node3DEditor *ed = Node3DEditor::get_singleton(); + ERR_FAIL_COND_V(!ed, false); + return ed->is_current_selected_gizmo(this) && ed->is_subgizmo_selected(p_id); +} + +Vector<int> EditorNode3DGizmo::get_subgizmo_selection() const { + Vector<int> ret; + + Node3DEditor *ed = Node3DEditor::get_singleton(); + ERR_FAIL_COND_V(!ed, ret); + + if (ed->is_current_selected_gizmo(this)) { + ret = ed->get_subgizmo_selection(); + } + + return ret; +} + void EditorNode3DGizmo::create() { ERR_FAIL_COND(!spatial_node); ERR_FAIL_COND(valid); @@ -690,7 +791,7 @@ void EditorNode3DGizmo::transform() { ERR_FAIL_COND(!spatial_node); ERR_FAIL_COND(!valid); for (int i = 0; i < instances.size(); i++) { - RS::get_singleton()->instance_set_transform(instances[i].instance, spatial_node->get_global_transform()); + RS::get_singleton()->instance_set_transform(instances[i].instance, spatial_node->get_global_transform() * instances[i].xform); } } @@ -724,38 +825,46 @@ void EditorNode3DGizmo::set_plugin(EditorNode3DGizmoPlugin *p_plugin) { void EditorNode3DGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard", "modulate"), &EditorNode3DGizmo::add_lines, DEFVAL(false), DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton", "material"), &EditorNode3DGizmo::add_mesh, DEFVAL(false), DEFVAL(Ref<SkinReference>()), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "material", "transform", "skeleton"), &EditorNode3DGizmo::add_mesh, DEFVAL(Variant()), DEFVAL(Transform3D()), DEFVAL(Ref<SkinReference>())); ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorNode3DGizmo::add_collision_segments); ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles"), &EditorNode3DGizmo::add_collision_triangles); ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale", "modulate"), &EditorNode3DGizmo::add_unscaled_billboard, DEFVAL(1), DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("add_handles", "handles", "material", "billboard", "secondary"), &EditorNode3DGizmo::add_handles, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_handles", "handles", "material", "ids", "billboard", "secondary"), &EditorNode3DGizmo::add_handles, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorNode3DGizmo::_set_spatial_node); ClassDB::bind_method(D_METHOD("get_spatial_node"), &EditorNode3DGizmo::get_spatial_node); ClassDB::bind_method(D_METHOD("get_plugin"), &EditorNode3DGizmo::get_plugin); ClassDB::bind_method(D_METHOD("clear"), &EditorNode3DGizmo::clear); ClassDB::bind_method(D_METHOD("set_hidden", "hidden"), &EditorNode3DGizmo::set_hidden); + ClassDB::bind_method(D_METHOD("is_subgizmo_selected"), &EditorNode3DGizmo::is_subgizmo_selected); + ClassDB::bind_method(D_METHOD("get_subgizmo_selection"), &EditorNode3DGizmo::get_subgizmo_selection); BIND_VMETHOD(MethodInfo("_redraw")); - BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_handle_name", PropertyInfo(Variant::INT, "index"))); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_handle_highlighted", PropertyInfo(Variant::INT, "index"))); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_handle_name", PropertyInfo(Variant::INT, "id"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_handle_highlighted", PropertyInfo(Variant::INT, "id"))); - MethodInfo hvget(Variant::NIL, "_get_handle_value", PropertyInfo(Variant::INT, "index")); + MethodInfo hvget(Variant::NIL, "_get_handle_value", PropertyInfo(Variant::INT, "id")); hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; BIND_VMETHOD(hvget); - BIND_VMETHOD(MethodInfo("_set_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point"))); - MethodInfo cm = MethodInfo("_commit_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel")); + BIND_VMETHOD(MethodInfo("_set_handle", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point"))); + MethodInfo cm = MethodInfo("_commit_handle", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel")); cm.default_arguments.push_back(false); BIND_VMETHOD(cm); + + BIND_VMETHOD(MethodInfo(Variant::INT, "_subgizmos_intersect_ray", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point"))); + BIND_VMETHOD(MethodInfo(Variant::PACKED_INT32_ARRAY, "_subgizmos_intersect_frustum", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::ARRAY, "frustum"))); + BIND_VMETHOD(MethodInfo(Variant::TRANSFORM3D, "_get_subgizmo_transform", PropertyInfo(Variant::INT, "id"))); + BIND_VMETHOD(MethodInfo("_set_subgizmo_transform", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::TRANSFORM3D, "transform"))); + MethodInfo cs = MethodInfo("_commit_subgizmos", PropertyInfo(Variant::PACKED_INT32_ARRAY, "ids"), PropertyInfo(Variant::ARRAY, "restore"), PropertyInfo(Variant::BOOL, "cancel")); + cs.default_arguments.push_back(false); + BIND_VMETHOD(cs); } EditorNode3DGizmo::EditorNode3DGizmo() { valid = false; billboard_handle = false; hidden = false; - base = nullptr; selected = false; - instantiated = false; spatial_node = nullptr; gizmo_plugin = nullptr; selectable_icon_size = -1.0f; @@ -768,10 +877,362 @@ EditorNode3DGizmo::~EditorNode3DGizmo() { clear(); } -Vector3 EditorNode3DGizmo::get_handle_pos(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, handles.size(), Vector3()); +///// + +void EditorNode3DGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) { + Color instantiated_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instantiated", Color(0.7, 0.7, 0.7, 0.6)); + + Vector<Ref<StandardMaterial3D>> mats; + + for (int i = 0; i < 4; i++) { + bool selected = i % 2 == 1; + bool instantiated = i < 2; + + Ref<StandardMaterial3D> material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - return handles[p_idx]; + Color color = instantiated ? instantiated_color : p_color; + + if (!selected) { + color.a *= 0.3; + } + + material->set_albedo(color); + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN + 1); + material->set_cull_mode(StandardMaterial3D::CULL_DISABLED); + + if (p_use_vertex_color) { + material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + } + + if (p_billboard) { + material->set_billboard_mode(StandardMaterial3D::BILLBOARD_ENABLED); + } + + if (p_on_top && selected) { + material->set_on_top_of_alpha(); + } + + mats.push_back(material); + } + + materials[p_name] = mats; +} + +void EditorNode3DGizmoPlugin::create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top, const Color &p_albedo) { + Color instantiated_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instantiated", Color(0.7, 0.7, 0.7, 0.6)); + + Vector<Ref<StandardMaterial3D>> icons; + + for (int i = 0; i < 4; i++) { + bool selected = i % 2 == 1; + bool instantiated = i < 2; + + Ref<StandardMaterial3D> icon = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + + Color color = instantiated ? instantiated_color : p_albedo; + + if (!selected) { + color.a *= 0.85; + } + + icon->set_albedo(color); + + icon->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + icon->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + icon->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + icon->set_cull_mode(StandardMaterial3D::CULL_DISABLED); + icon->set_depth_draw_mode(StandardMaterial3D::DEPTH_DRAW_DISABLED); + icon->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + icon->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, p_texture); + icon->set_flag(StandardMaterial3D::FLAG_FIXED_SIZE, true); + icon->set_billboard_mode(StandardMaterial3D::BILLBOARD_ENABLED); + icon->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN); + + if (p_on_top && selected) { + icon->set_on_top_of_alpha(); + } + + icons.push_back(icon); + } + + materials[p_name] = icons; +} + +void EditorNode3DGizmoPlugin::create_handle_material(const String &p_name, bool p_billboard, const Ref<Texture2D> &p_icon) { + Ref<StandardMaterial3D> handle_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + + handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); + Ref<Texture2D> handle_t = p_icon != nullptr ? p_icon : Node3DEditor::get_singleton()->get_theme_icon(SNAME("Editor3DHandle"), SNAME("EditorIcons")); + handle_material->set_point_size(handle_t->get_width()); + handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle_t); + handle_material->set_albedo(Color(1, 1, 1)); + handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + handle_material->set_on_top_of_alpha(); + if (p_billboard) { + handle_material->set_billboard_mode(StandardMaterial3D::BILLBOARD_ENABLED); + handle_material->set_on_top_of_alpha(); + } + handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + + materials[p_name] = Vector<Ref<StandardMaterial3D>>(); + materials[p_name].push_back(handle_material); +} + +void EditorNode3DGizmoPlugin::add_material(const String &p_name, Ref<StandardMaterial3D> p_material) { + materials[p_name] = Vector<Ref<StandardMaterial3D>>(); + materials[p_name].push_back(p_material); +} + +Ref<StandardMaterial3D> EditorNode3DGizmoPlugin::get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo) { + ERR_FAIL_COND_V(!materials.has(p_name), Ref<StandardMaterial3D>()); + ERR_FAIL_COND_V(materials[p_name].size() == 0, Ref<StandardMaterial3D>()); + + if (p_gizmo.is_null() || materials[p_name].size() == 1) { + return materials[p_name][0]; + } + + int index = (p_gizmo->is_selected() ? 1 : 0) + (p_gizmo->is_editable() ? 2 : 0); + + Ref<StandardMaterial3D> mat = materials[p_name][index]; + + if (current_state == ON_TOP && p_gizmo->is_selected()) { + mat->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + } else { + mat->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, false); + } + + return mat; +} + +String EditorNode3DGizmoPlugin::get_gizmo_name() const { + if (get_script_instance() && get_script_instance()->has_method("_get_gizmo_name")) { + return get_script_instance()->call("_get_gizmo_name"); + } + return TTR("Nameless gizmo"); +} + +int EditorNode3DGizmoPlugin::get_priority() const { + if (get_script_instance() && get_script_instance()->has_method("_get_priority")) { + return get_script_instance()->call("_get_priority"); + } + return 0; +} + +Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::get_gizmo(Node3D *p_spatial) { + if (get_script_instance() && get_script_instance()->has_method("_get_gizmo")) { + return get_script_instance()->call("_get_gizmo", p_spatial); + } + + Ref<EditorNode3DGizmo> ref = create_gizmo(p_spatial); + + if (ref.is_null()) { + return ref; + } + + ref->set_plugin(this); + ref->set_spatial_node(p_spatial); + ref->set_hidden(current_state == HIDDEN); + + current_gizmos.push_back(ref.ptr()); + return ref; +} + +void EditorNode3DGizmoPlugin::_bind_methods() { +#define GIZMO_REF PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "EditorNode3DGizmo") + + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); + BIND_VMETHOD(MethodInfo(GIZMO_REF, "_create_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); + + ClassDB::bind_method(D_METHOD("create_material", "name", "color", "billboard", "on_top", "use_vertex_color"), &EditorNode3DGizmoPlugin::create_material, DEFVAL(false), DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("create_icon_material", "name", "texture", "on_top", "color"), &EditorNode3DGizmoPlugin::create_icon_material, DEFVAL(false), DEFVAL(Color(1, 1, 1, 1))); + ClassDB::bind_method(D_METHOD("create_handle_material", "name", "billboard", "texture"), &EditorNode3DGizmoPlugin::create_handle_material, DEFVAL(false), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("add_material", "name", "material"), &EditorNode3DGizmoPlugin::add_material); + + ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorNode3DGizmoPlugin::get_material, DEFVAL(Ref<EditorNode3DGizmo>())); + + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_gizmo_name")); + BIND_VMETHOD(MethodInfo(Variant::INT, "_get_priority")); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_can_be_hidden")); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_selectable_when_hidden")); + + BIND_VMETHOD(MethodInfo("_redraw", GIZMO_REF)); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_handle_name", GIZMO_REF, PropertyInfo(Variant::INT, "id"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_handle_highlighted", GIZMO_REF, PropertyInfo(Variant::INT, "id"))); + + MethodInfo hvget(Variant::NIL, "_get_handle_value", GIZMO_REF, PropertyInfo(Variant::INT, "id")); + hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + BIND_VMETHOD(hvget); + + BIND_VMETHOD(MethodInfo("_set_handle", GIZMO_REF, PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point"))); + MethodInfo cm = MethodInfo("_commit_handle", GIZMO_REF, PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel")); + cm.default_arguments.push_back(false); + BIND_VMETHOD(cm); + + BIND_VMETHOD(MethodInfo(Variant::INT, "_subgizmos_intersect_ray", GIZMO_REF, PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point"))); + BIND_VMETHOD(MethodInfo(Variant::PACKED_INT32_ARRAY, "_subgizmos_intersect_frustum", GIZMO_REF, PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::ARRAY, "frustum"))); + BIND_VMETHOD(MethodInfo(Variant::TRANSFORM3D, "_get_subgizmo_transform", GIZMO_REF, PropertyInfo(Variant::INT, "id"))); + BIND_VMETHOD(MethodInfo("_set_subgizmo_transform", GIZMO_REF, PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::TRANSFORM3D, "transform"))); + MethodInfo cs = MethodInfo("_commit_subgizmos", GIZMO_REF, PropertyInfo(Variant::PACKED_INT32_ARRAY, "ids"), PropertyInfo(Variant::ARRAY, "restore"), PropertyInfo(Variant::BOOL, "cancel")); + cs.default_arguments.push_back(false); + BIND_VMETHOD(cs); + +#undef GIZMO_REF +} + +bool EditorNode3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + if (get_script_instance() && get_script_instance()->has_method("_has_gizmo")) { + return get_script_instance()->call("_has_gizmo", p_spatial); + } + return false; +} + +Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::create_gizmo(Node3D *p_spatial) { + if (get_script_instance() && get_script_instance()->has_method("_create_gizmo")) { + return get_script_instance()->call("_create_gizmo", p_spatial); + } + + Ref<EditorNode3DGizmo> ref; + if (has_gizmo(p_spatial)) { + ref.instantiate(); + } + return ref; +} + +bool EditorNode3DGizmoPlugin::can_be_hidden() const { + if (get_script_instance() && get_script_instance()->has_method("_can_be_hidden")) { + return get_script_instance()->call("_can_be_hidden"); + } + return true; +} + +bool EditorNode3DGizmoPlugin::is_selectable_when_hidden() const { + if (get_script_instance() && get_script_instance()->has_method("_is_selectable_when_hidden")) { + return get_script_instance()->call("_is_selectable_when_hidden"); + } + return false; +} + +void EditorNode3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + if (get_script_instance() && get_script_instance()->has_method("_redraw")) { + Ref<EditorNode3DGizmo> ref(p_gizmo); + get_script_instance()->call("_redraw", ref); + } +} + +bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const { + if (get_script_instance() && get_script_instance()->has_method("_is_handle_highlighted")) { + return get_script_instance()->call("_is_handle_highlighted", p_gizmo, p_id); + } + return false; +} + +String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + if (get_script_instance() && get_script_instance()->has_method("_get_handle_name")) { + return get_script_instance()->call("_get_handle_name", p_gizmo, p_id); + } + return ""; +} + +Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { + if (get_script_instance() && get_script_instance()->has_method("_get_handle_value")) { + return get_script_instance()->call("_get_handle_value", p_gizmo, p_id); + } + return Variant(); +} + +void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { + if (get_script_instance() && get_script_instance()->has_method("_set_handle")) { + get_script_instance()->call("_set_handle", p_gizmo, p_id, p_camera, p_point); + } +} + +void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { + if (get_script_instance() && get_script_instance()->has_method("_commit_handle")) { + get_script_instance()->call("_commit_handle", p_gizmo, p_id, p_restore, p_cancel); + } +} + +int EditorNode3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const { + if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_ray")) { + return get_script_instance()->call("_subgizmos_intersect_ray", p_camera, p_point); + } + return -1; +} + +Vector<int> EditorNode3DGizmoPlugin::subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const { + if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_frustum")) { + Array frustum; + for (int i = 0; i < p_frustum.size(); i++) { + frustum[i] = p_frustum[i]; + } + return get_script_instance()->call("_subgizmos_intersect_frustum", p_camera, frustum); + } + + return Vector<int>(); +} + +Transform3D EditorNode3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const { + if (get_script_instance() && get_script_instance()->has_method("_get_subgizmo_transform")) { + return get_script_instance()->call("_get_subgizmo_transform", p_id); + } + + return Transform3D(); +} + +void EditorNode3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) const { + if (get_script_instance() && get_script_instance()->has_method("_set_subgizmo_transform")) { + get_script_instance()->call("_set_subgizmo_transform", p_id, p_transform); + } +} + +void EditorNode3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) const { + if (get_script_instance() && get_script_instance()->has_method("_commit_subgizmos")) { + Array ids; + for (int i = 0; i < p_ids.size(); i++) { + ids[i] = p_ids[i]; + } + + Array restore; + for (int i = 0; i < p_restore.size(); i++) { + restore[i] = p_restore[i]; + } + + get_script_instance()->call("_commit_subgizmos", ids, restore, p_cancel); + } +} + +void EditorNode3DGizmoPlugin::set_state(int p_state) { + current_state = p_state; + for (int i = 0; i < current_gizmos.size(); ++i) { + current_gizmos[i]->set_hidden(current_state == HIDDEN); + } +} + +int EditorNode3DGizmoPlugin::get_state() const { + return current_state; +} + +void EditorNode3DGizmoPlugin::unregister_gizmo(EditorNode3DGizmo *p_gizmo) { + current_gizmos.erase(p_gizmo); +} + +EditorNode3DGizmoPlugin::EditorNode3DGizmoPlugin() { + current_state = VISIBLE; +} + +EditorNode3DGizmoPlugin::~EditorNode3DGizmoPlugin() { + for (int i = 0; i < current_gizmos.size(); ++i) { + current_gizmos[i]->set_plugin(nullptr); + current_gizmos[i]->get_spatial_node()->remove_gizmo(current_gizmos[i]); + } + if (Node3DEditor::get_singleton()) { + Node3DEditor::get_singleton()->update_all_gizmos(); + } } //// light gizmo @@ -802,20 +1263,20 @@ int Light3DGizmoPlugin::get_priority() const { return -1; } -String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - if (p_idx == 0) { +String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + if (p_id == 0) { return "Radius"; } else { return "Aperture"; } } -Variant Light3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant Light3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); - if (p_idx == 0) { + if (p_id == 0) { return light->get_param(Light3D::PARAM_RANGE); } - if (p_idx == 1) { + if (p_id == 1) { return light->get_param(Light3D::PARAM_SPOT_ANGLE); } @@ -849,7 +1310,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec return Math::rad2deg(a); } -void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); Transform3D gt = light->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -858,7 +1319,7 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer Vector3 ray_dir = p_camera->project_ray_normal(p_point); Vector3 s[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; - if (p_idx == 0) { + if (p_id == 0) { if (Object::cast_to<SpotLight3D>(light)) { Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(0, 0, -4096), s[0], s[1], ra, rb); @@ -887,24 +1348,24 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer } } - } else if (p_idx == 1) { + } else if (p_id == 1) { float a = _find_closest_angle_to_half_pi_arc(s[0], s[1], light->get_param(Light3D::PARAM_RANGE), gt); light->set_param(Light3D::PARAM_SPOT_ANGLE, CLAMP(a, 0.01, 89.99)); } } -void Light3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); if (p_cancel) { - light->set_param(p_idx == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore); + light->set_param(p_id == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore); - } else if (p_idx == 0) { + } else if (p_id == 0) { UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); ur->create_action(TTR("Change Light Radius")); ur->add_do_method(light, "set_param", Light3D::PARAM_RANGE, light->get_param(Light3D::PARAM_RANGE)); ur->add_undo_method(light, "set_param", Light3D::PARAM_RANGE, p_restore); ur->commit_action(); - } else if (p_idx == 1) { + } else if (p_id == 1) { UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); ur->create_action(TTR("Change Light Radius")); ur->add_do_method(light, "set_param", Light3D::PARAM_SPOT_ANGLE, light->get_param(Light3D::PARAM_SPOT_ANGLE)); @@ -996,7 +1457,7 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> handles; handles.push_back(Vector3(r, 0, 0)); - p_gizmo->add_handles(handles, get_material("handles_billboard"), true); + p_gizmo->add_handles(handles, get_material("handles_billboard"), Vector<int>(), true); } if (Object::cast_to<SpotLight3D>(light)) { @@ -1068,16 +1529,16 @@ int AudioStreamPlayer3DGizmoPlugin::get_priority() const { return -1; } -String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { return "Emission Radius"; } -Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); return player->get_emission_angle(); } -void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); Transform3D gt = player->get_global_transform(); @@ -1114,7 +1575,7 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int } } -void AudioStreamPlayer3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); if (p_cancel) { @@ -1203,7 +1664,7 @@ int Camera3DGizmoPlugin::get_priority() const { return -1; } -String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { @@ -1213,7 +1674,7 @@ String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, in } } -Variant Camera3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { @@ -1223,7 +1684,7 @@ Variant Camera3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_ } } -void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); Transform3D gt = camera->get_global_transform(); @@ -1252,7 +1713,7 @@ void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Came } } -void Camera3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { @@ -1761,7 +2222,7 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } Ref<ArrayMesh> m = surface_tool->commit(); - p_gizmo->add_mesh(m, false, skel->register_skin(Ref<Skin>())); + p_gizmo->add_mesh(m, Ref<Material>(), Transform3D(), skel->register_skin(Ref<Skin>())); } //// @@ -2102,23 +2563,23 @@ void SoftBody3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_collision_triangles(tm); } -String SoftBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String SoftBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { return "SoftBody3D pin point"; } -Variant SoftBody3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant SoftBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); - return Variant(soft_body->is_point_pinned(p_idx)); + return Variant(soft_body->is_point_pinned(p_id)); } -void SoftBody3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void SoftBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); - soft_body->pin_point_toggle(p_idx); + soft_body->pin_point_toggle(p_id); } -bool SoftBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int idx) const { +bool SoftBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const { SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); - return soft_body->is_point_pinned(idx); + return soft_body->is_point_pinned(p_id); } /////////// @@ -2143,8 +2604,8 @@ int VisibleOnScreenNotifier3DGizmoPlugin::get_priority() const { return -1; } -String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - switch (p_idx) { +String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + switch (p_id) { case 0: return "Size X"; case 1: @@ -2162,20 +2623,20 @@ String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DG return ""; } -Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); return notifier->get_aabb(); } -void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); Transform3D gt = notifier->get_global_transform(); Transform3D gi = gt.affine_inverse(); - bool move = p_idx >= 3; - p_idx = p_idx % 3; + bool move = p_id >= 3; + p_id = p_id % 3; AABB aabb = notifier->get_aabb(); Vector3 ray_from = p_camera->project_ray_origin(p_point); @@ -2186,25 +2647,25 @@ void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo Vector3 ofs = aabb.position + aabb.size * 0.5; Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; if (move) { Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } - aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5; + aabb.position[p_id] = d - 1.0 - aabb.size[p_id] * 0.5; notifier->set_aabb(aabb); } else { Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx] - ofs[p_idx]; + float d = ra[p_id] - ofs[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -2213,13 +2674,13 @@ void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo d = 0.001; } //resize - aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d; - aabb.size[p_idx] = d * 2; + aabb.position[p_id] = (aabb.position[p_id] + aabb.size[p_id] * 0.5) - d; + aabb.size[p_id] = d * 2; notifier->set_aabb(aabb); } } -void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); if (p_cancel) { @@ -2335,8 +2796,8 @@ bool GPUParticles3DGizmoPlugin::is_selectable_when_hidden() const { return true; } -String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - switch (p_idx) { +String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + switch (p_id) { case 0: return "Size X"; case 1: @@ -2354,19 +2815,19 @@ String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_giz return ""; } -Variant GPUParticles3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant GPUParticles3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); return particles->get_visibility_aabb(); } -void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); Transform3D gt = particles->get_global_transform(); Transform3D gi = gt.affine_inverse(); - bool move = p_idx >= 3; - p_idx = p_idx % 3; + bool move = p_id >= 3; + p_id = p_id % 3; AABB aabb = particles->get_visibility_aabb(); Vector3 ray_from = p_camera->project_ray_origin(p_point); @@ -2377,25 +2838,25 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx Vector3 ofs = aabb.position + aabb.size * 0.5; Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; if (move) { Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } - aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5; + aabb.position[p_id] = d - 1.0 - aabb.size[p_id] * 0.5; particles->set_visibility_aabb(aabb); } else { Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx] - ofs[p_idx]; + float d = ra[p_id] - ofs[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -2404,13 +2865,13 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx d = 0.001; } //resize - aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d; - aabb.size[p_idx] = d * 2; + aabb.position[p_id] = (aabb.position[p_id] + aabb.size[p_id] * 0.5) - d; + aabb.size[p_id] = d * 2; particles->set_visibility_aabb(aabb); } } -void GPUParticles3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); if (p_cancel) { @@ -2475,8 +2936,6 @@ void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { //// -//// - GPUParticlesCollision3DGizmoPlugin::GPUParticlesCollision3DGizmoPlugin() { Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particle_collision", Color(0.5, 0.7, 1)); create_material("shape_material", gizmo_color); @@ -2498,7 +2957,7 @@ int GPUParticlesCollision3DGizmoPlugin::get_priority() const { return -1; } -String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { const Node3D *cs = p_gizmo->get_spatial_node(); if (Object::cast_to<GPUParticlesCollisionSphere>(cs) || Object::cast_to<GPUParticlesAttractorSphere>(cs)) { @@ -2512,7 +2971,7 @@ String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGiz return ""; } -Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { const Node3D *cs = p_gizmo->get_spatial_node(); if (Object::cast_to<GPUParticlesCollisionSphere>(cs) || Object::cast_to<GPUParticlesAttractorSphere>(cs)) { @@ -2526,7 +2985,7 @@ Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(EditorNode3DGizmo * return Variant(); } -void GPUParticlesCollision3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { Node3D *sn = p_gizmo->get_spatial_node(); Transform3D gt = sn->get_global_transform(); @@ -2554,10 +3013,10 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, if (Object::cast_to<GPUParticlesCollisionBox>(sn) || Object::cast_to<GPUParticlesAttractorBox>(sn) || Object::cast_to<GPUParticlesAttractorVectorField>(sn) || Object::cast_to<GPUParticlesCollisionSDF>(sn) || Object::cast_to<GPUParticlesCollisionHeightField>(sn)) { Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -2567,12 +3026,12 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, } Vector3 he = sn->call("get_extents"); - he[p_idx] = d; + he[p_id] = d; sn->call("set_extents", he); } } -void GPUParticlesCollision3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { Node3D *sn = p_gizmo->get_spatial_node(); if (Object::cast_to<GPUParticlesCollisionSphere>(sn) || Object::cast_to<GPUParticlesAttractorSphere>(sn)) { @@ -2762,8 +3221,8 @@ int ReflectionProbeGizmoPlugin::get_priority() const { return -1; } -String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - switch (p_idx) { +String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + switch (p_id) { case 0: return "Extents X"; case 1: @@ -2781,18 +3240,18 @@ String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gi return ""; } -Variant ReflectionProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); return AABB(probe->get_extents(), probe->get_origin_offset()); } -void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); Transform3D gt = probe->get_global_transform(); Transform3D gi = gt.affine_inverse(); - if (p_idx < 3) { + if (p_id < 3) { Vector3 extents = probe->get_extents(); Vector3 ray_from = p_camera->project_ray_origin(p_point); @@ -2801,11 +3260,11 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -2814,13 +3273,13 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id d = 0.001; } - extents[p_idx] = d; + extents[p_id] = d; probe->set_extents(extents); } else { - p_idx -= 3; + p_id -= 3; Vector3 origin = probe->get_origin_offset(); - origin[p_idx] = 0; + origin[p_id] = 0; Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -2828,22 +3287,22 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb); // Adjust the actual position to account for the gizmo handle position - float d = ra[p_idx] + 0.25; + float d = ra[p_id] + 0.25; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } - origin[p_idx] = d; + origin[p_id] = d; probe->set_origin_offset(origin); } } -void ReflectionProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); AABB restore = p_restore; @@ -2947,8 +3406,8 @@ int DecalGizmoPlugin::get_priority() const { return -1; } -String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - switch (p_idx) { +String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + switch (p_id) { case 0: return "Extents X"; case 1: @@ -2960,12 +3419,12 @@ String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p return ""; } -Variant DecalGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); return decal->get_extents(); } -void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); Transform3D gt = decal->get_global_transform(); @@ -2979,11 +3438,11 @@ void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3 Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -2992,11 +3451,11 @@ void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3 d = 0.001; } - extents[p_idx] = d; + extents[p_id] = d; decal->set_extents(extents); } -void DecalGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); Vector3 restore = p_restore; @@ -3055,7 +3514,6 @@ void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Ref<Material> material = get_material("decal_material", p_gizmo); p_gizmo->add_lines(lines, material); - p_gizmo->add_handles(handles, get_material("handles")); } @@ -3088,8 +3546,8 @@ int VoxelGIGizmoPlugin::get_priority() const { return -1; } -String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - switch (p_idx) { +String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + switch (p_id) { case 0: return "Extents X"; case 1: @@ -3101,12 +3559,12 @@ String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int return ""; } -Variant VoxelGIGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); return probe->get_extents(); } -void VoxelGIGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); Transform3D gt = probe->get_global_transform(); @@ -3120,11 +3578,11 @@ void VoxelGIGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -3133,11 +3591,11 @@ void VoxelGIGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer d = 0.001; } - extents[p_idx] = d; + extents[p_id] = d; probe->set_extents(extents); } -void VoxelGIGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); Vector3 restore = p_restore; @@ -3257,18 +3715,18 @@ LightmapGIGizmoPlugin::LightmapGIGizmoPlugin() { create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoLightmapGI"), SNAME("EditorIcons"))); } -String LightmapGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String LightmapGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { return ""; } -Variant LightmapGIGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant LightmapGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { return Variant(); } -void LightmapGIGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void LightmapGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { } -void LightmapGIGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void LightmapGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { } bool LightmapGIGizmoPlugin::has_gizmo(Node3D *p_spatial) { @@ -3439,18 +3897,18 @@ LightmapProbeGizmoPlugin::LightmapProbeGizmoPlugin() { create_material("lightprobe_lines", gizmo_color); } -String LightmapProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String LightmapProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { return ""; } -Variant LightmapProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant LightmapProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { return Variant(); } -void LightmapProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void LightmapProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { } -void LightmapProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void LightmapProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { } bool LightmapProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) { @@ -3555,8 +4013,7 @@ void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { List<uint32_t> owners; co->get_shape_owners(&owners); - for (List<uint32_t>::Element *E = owners.front(); E; E = E->next()) { - uint32_t owner_id = E->get(); + for (uint32_t &owner_id : owners) { Transform3D xform = co->shape_owner_get_transform(owner_id); Object *owner = co->shape_owner_get_owner(owner_id); // Exclude CollisionShape3D and CollisionPolygon3D as they have their gizmo. @@ -3570,7 +4027,7 @@ void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { SurfaceTool st; st.append_from(s->get_debug_mesh(), 0, xform); - p_gizmo->add_mesh(st.commit(), false, Ref<SkinReference>(), material); + p_gizmo->add_mesh(st.commit(), material); p_gizmo->add_collision_segments(s->get_debug_mesh_lines()); } } @@ -3600,7 +4057,7 @@ int CollisionShape3DGizmoPlugin::get_priority() const { return -1; } -String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { const CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -3617,11 +4074,11 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g } if (Object::cast_to<CapsuleShape3D>(*s)) { - return p_idx == 0 ? "Radius" : "Height"; + return p_id == 0 ? "Radius" : "Height"; } if (Object::cast_to<CylinderShape3D>(*s)) { - return p_idx == 0 ? "Radius" : "Height"; + return p_id == 0 ? "Radius" : "Height"; } if (Object::cast_to<RayShape3D>(*s)) { @@ -3631,7 +4088,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g return ""; } -Variant CollisionShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -3651,12 +4108,12 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo if (Object::cast_to<CapsuleShape3D>(*s)) { Ref<CapsuleShape3D> cs2 = s; - return p_idx == 0 ? cs2->get_radius() : cs2->get_height(); + return p_id == 0 ? cs2->get_radius() : cs2->get_height(); } if (Object::cast_to<CylinderShape3D>(*s)) { Ref<CylinderShape3D> cs2 = s; - return p_idx == 0 ? cs2->get_radius() : cs2->get_height(); + return p_id == 0 ? cs2->get_radius() : cs2->get_height(); } if (Object::cast_to<RayShape3D>(*s)) { @@ -3667,7 +4124,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo return Variant(); } -void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -3717,11 +4174,11 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i if (Object::cast_to<BoxShape3D>(*s)) { Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; Ref<BoxShape3D> bs = s; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -3731,18 +4188,18 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i } Vector3 he = bs->get_size(); - he[p_idx] = d * 2; + he[p_id] = d * 2; bs->set_size(he); } if (Object::cast_to<CapsuleShape3D>(*s)) { Vector3 axis; - axis[p_idx == 0 ? 0 : 2] = 1.0; + axis[p_id == 0 ? 0 : 2] = 1.0; Ref<CapsuleShape3D> cs2 = s; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = axis.dot(ra); - if (p_idx == 1) { + if (p_id == 1) { d -= cs2->get_radius(); } @@ -3754,16 +4211,16 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i d = 0.001; } - if (p_idx == 0) { + if (p_id == 0) { cs2->set_radius(d); - } else if (p_idx == 1) { + } else if (p_id == 1) { cs2->set_height(d * 2.0); } } if (Object::cast_to<CylinderShape3D>(*s)) { Vector3 axis; - axis[p_idx == 0 ? 0 : 1] = 1.0; + axis[p_id == 0 ? 0 : 1] = 1.0; Ref<CylinderShape3D> cs2 = s; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); @@ -3776,15 +4233,15 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i d = 0.001; } - if (p_idx == 0) { + if (p_id == 0) { cs2->set_radius(d); - } else if (p_idx == 1) { + } else if (p_id == 1) { cs2->set_height(d * 2.0); } } } -void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -3823,7 +4280,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int if (Object::cast_to<CapsuleShape3D>(*s)) { Ref<CapsuleShape3D> ss = s; if (p_cancel) { - if (p_idx == 0) { + if (p_id == 0) { ss->set_radius(p_restore); } else { ss->set_height(p_restore); @@ -3832,7 +4289,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int } UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); - if (p_idx == 0) { + if (p_id == 0) { ur->create_action(TTR("Change Capsule Shape Radius")); ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); ur->add_undo_method(ss.ptr(), "set_radius", p_restore); @@ -3848,7 +4305,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int if (Object::cast_to<CylinderShape3D>(*s)) { Ref<CylinderShape3D> ss = s; if (p_cancel) { - if (p_idx == 0) { + if (p_id == 0) { ss->set_radius(p_restore); } else { ss->set_height(p_restore); @@ -3857,7 +4314,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int } UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); - if (p_idx == 0) { + if (p_id == 0) { ur->create_action(TTR("Change Cylinder Shape Radius")); ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); ur->add_undo_method(ss.ptr(), "set_radius", p_restore); @@ -4153,7 +4610,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (Object::cast_to<ConcavePolygonShape3D>(*s)) { Ref<ConcavePolygonShape3D> cs2 = s; Ref<ArrayMesh> mesh = cs2->get_debug_mesh(); - p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), material); + p_gizmo->add_mesh(mesh, material); p_gizmo->add_collision_segments(cs2->get_debug_mesh_lines()); } @@ -4174,7 +4631,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Ref<HeightMapShape3D> hms = s; Ref<ArrayMesh> mesh = hms->get_debug_mesh(); - p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), material); + p_gizmo->add_mesh(mesh, material); } } @@ -4289,9 +4746,7 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector3 *tw = tmeshfaces.ptrw(); int tidx = 0; - for (List<Face3>::Element *E = faces.front(); E; E = E->next()) { - const Face3 &f = E->get(); - + for (const Face3 &f : faces) { for (int j = 0; j < 3; j++) { tw[tidx++] = f.vertex[j]; _EdgeKey ek; diff --git a/editor/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index 6f071859ec..61ee3a95a9 100644 --- a/editor/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -28,13 +28,156 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPATIAL_EDITOR_GIZMOS_H -#define SPATIAL_EDITOR_GIZMOS_H +#ifndef NODE_3D_EDITOR_GIZMOS_H +#define NODE_3D_EDITOR_GIZMOS_H -#include "editor/plugins/node_3d_editor_plugin.h" -#include "scene/3d/camera_3d.h" +#include "core/templates/ordered_hash_map.h" +#include "scene/3d/node_3d.h" +#include "scene/3d/skeleton_3d.h" class Camera3D; +class Timer; +class EditorNode3DGizmoPlugin; + +class EditorNode3DGizmo : public Node3DGizmo { + GDCLASS(EditorNode3DGizmo, Node3DGizmo); + + struct Instance { + RID instance; + Ref<ArrayMesh> mesh; + Ref<Material> material; + Ref<SkinReference> skin_reference; + bool extra_margin = false; + Transform3D xform; + + void create_instance(Node3D *p_base, bool p_hidden = false); + }; + + bool selected; + + Vector<Vector3> collision_segments; + Ref<TriangleMesh> collision_mesh; + + Vector<Vector3> handles; + Vector<int> handle_ids; + Vector<Vector3> secondary_handles; + Vector<int> secondary_handle_ids; + + float selectable_icon_size; + bool billboard_handle; + + bool valid; + bool hidden; + Vector<Instance> instances; + Node3D *spatial_node; + + void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Node3D>(p_node)); } + +protected: + static void _bind_methods(); + + EditorNode3DGizmoPlugin *gizmo_plugin; + +public: + void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); + void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); + void add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>()); + void add_collision_segments(const Vector<Vector3> &p_lines); + void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); + void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1, const Color &p_modulate = Color(1, 1, 1)); + void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, const Vector<int> &p_ids = Vector<int>(), bool p_billboard = false, bool p_secondary = false); + void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D()); + + virtual bool is_handle_highlighted(int p_id) const; + virtual String get_handle_name(int p_id) const; + virtual Variant get_handle_value(int p_id) const; + virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const; + virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) const; + + virtual int subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const; + virtual Vector<int> subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const; + virtual Transform3D get_subgizmo_transform(int p_id) const; + virtual void set_subgizmo_transform(int p_id, Transform3D p_transform) const; + virtual void commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) const; + + void set_selected(bool p_selected) { selected = p_selected; } + bool is_selected() const { return selected; } + + void set_spatial_node(Node3D *p_node); + Node3D *get_spatial_node() const { return spatial_node; } + Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; } + bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum); + void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id); + bool intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal); + bool is_subgizmo_selected(int p_id) const; + Vector<int> get_subgizmo_selection() const; + + virtual void clear() override; + virtual void create() override; + virtual void transform() override; + virtual void redraw() override; + virtual void free() override; + + virtual bool is_editable() const; + + void set_hidden(bool p_hidden); + void set_plugin(EditorNode3DGizmoPlugin *p_plugin); + + EditorNode3DGizmo(); + ~EditorNode3DGizmo(); +}; + +class EditorNode3DGizmoPlugin : public Resource { + GDCLASS(EditorNode3DGizmoPlugin, Resource); + +public: + static const int VISIBLE = 0; + static const int HIDDEN = 1; + static const int ON_TOP = 2; + +protected: + int current_state; + List<EditorNode3DGizmo *> current_gizmos; + HashMap<String, Vector<Ref<StandardMaterial3D>>> materials; + + static void _bind_methods(); + virtual bool has_gizmo(Node3D *p_spatial); + virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial); + +public: + void create_material(const String &p_name, const Color &p_color, bool p_billboard = false, bool p_on_top = false, bool p_use_vertex_color = false); + void create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1)); + void create_handle_material(const String &p_name, bool p_billboard = false, const Ref<Texture2D> &p_texture = nullptr); + void add_material(const String &p_name, Ref<StandardMaterial3D> p_material); + + Ref<StandardMaterial3D> get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo = Ref<EditorNode3DGizmo>()); + + virtual String get_gizmo_name() const; + virtual int get_priority() const; + virtual bool can_be_hidden() const; + virtual bool is_selectable_when_hidden() const; + + virtual void redraw(EditorNode3DGizmo *p_gizmo); + virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const; + virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const; + virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const; + virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const; + virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const; + + virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const; + virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const; + virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const; + virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) const; + virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) const; + + Ref<EditorNode3DGizmo> get_gizmo(Node3D *p_spatial); + void set_state(int p_state); + int get_state() const; + void unregister_gizmo(EditorNode3DGizmo *p_gizmo); + + EditorNode3DGizmoPlugin(); + virtual ~EditorNode3DGizmoPlugin(); +}; class Light3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(Light3DGizmoPlugin, EditorNode3DGizmoPlugin); @@ -44,10 +187,10 @@ public: String get_gizmo_name() const override; int get_priority() const override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; void redraw(EditorNode3DGizmo *p_gizmo) override; Light3DGizmoPlugin(); @@ -61,10 +204,10 @@ public: String get_gizmo_name() const override; int get_priority() const override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; void redraw(EditorNode3DGizmo *p_gizmo) override; AudioStreamPlayer3DGizmoPlugin(); @@ -78,10 +221,10 @@ public: String get_gizmo_name() const override; int get_priority() const override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; void redraw(EditorNode3DGizmo *p_gizmo) override; Camera3DGizmoPlugin(); @@ -210,10 +353,10 @@ public: bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) override; - bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int idx) const override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; + bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const override; SoftBody3DGizmoPlugin(); }; @@ -227,10 +370,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; VisibleOnScreenNotifier3DGizmoPlugin(); }; @@ -257,10 +400,10 @@ public: bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; GPUParticles3DGizmoPlugin(); }; @@ -274,10 +417,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; GPUParticlesCollision3DGizmoPlugin(); }; @@ -291,10 +434,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; ReflectionProbeGizmoPlugin(); }; @@ -308,10 +451,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; DecalGizmoPlugin(); }; @@ -325,10 +468,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; VoxelGIGizmoPlugin(); }; @@ -342,10 +485,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; LightmapGIGizmoPlugin(); }; @@ -359,10 +502,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; LightmapProbeGizmoPlugin(); }; @@ -388,10 +531,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override; CollisionShape3DGizmoPlugin(); }; @@ -489,4 +632,4 @@ public: Joint3DGizmoPlugin(); }; -#endif // SPATIAL_EDITOR_GIZMOS_H +#endif // NODE_3D_EDITOR_GIZMOS_H diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 7290a39463..b69d57188c 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -35,20 +35,20 @@ #include "core/math/camera_matrix.h" #include "core/math/math_funcs.h" #include "core/os/keyboard.h" -#include "core/string/print_string.h" #include "core/templates/sort_array.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" -#include "editor/editor_scale.h" #include "editor/editor_settings.h" -#include "editor/node_3d_editor_gizmos.h" #include "editor/plugins/animation_player_editor_plugin.h" +#include "editor/plugins/node_3d_editor_gizmos.h" #include "editor/plugins/script_editor_plugin.h" #include "scene/3d/camera_3d.h" #include "scene/3d/collision_shape_3d.h" +#include "scene/3d/light_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/visual_instance_3d.h" +#include "scene/3d/world_environment.h" #include "scene/gui/center_container.h" #include "scene/gui/subviewport_container.h" #include "scene/resources/packed_scene.h" @@ -58,7 +58,6 @@ #define GIZMO_ARROW_SIZE 0.35 #define GIZMO_RING_HALF_WIDTH 0.1 -#define GIZMO_SCALE_DEFAULT 0.15 #define GIZMO_PLANE_SIZE 0.2 #define GIZMO_PLANE_DST 0.3 #define GIZMO_CIRCLE_SIZE 1.1 @@ -436,16 +435,29 @@ Vector3 Node3DEditorViewport::_get_ray(const Vector2 &p_pos) const { } void Node3DEditorViewport::_clear_selected() { - editor_selection->clear(); -} - -void Node3DEditorViewport::_select_clicked(bool p_append, bool p_single, bool p_allow_locked) { - if (clicked.is_null()) { - return; + _edit.gizmo = Ref<EditorNode3DGizmo>(); + _edit.gizmo_handle = -1; + _edit.gizmo_initial_value = Variant(); + + Node3D *selected = spatial_editor->get_single_selected_node(); + Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; + + if (se && se->gizmo.is_valid()) { + se->subgizmos.clear(); + se->gizmo->redraw(); + se->gizmo.unref(); + spatial_editor->update_transform_gizmo(); + } else { + editor_selection->clear(); + Node3DEditor::get_singleton()->edit(nullptr); } +} - Node *node = Object::cast_to<Node>(ObjectDB::get_instance(clicked)); +void Node3DEditorViewport::_select_clicked(bool p_allow_locked) { + Node *node = Object::cast_to<Node3D>(ObjectDB::get_instance(clicked)); Node3D *selected = Object::cast_to<Node3D>(node); + clicked = ObjectID(); + if (!selected) { return; } @@ -462,43 +474,27 @@ void Node3DEditorViewport::_select_clicked(bool p_append, bool p_single, bool p_ } if (p_allow_locked || !_is_node_locked(selected)) { - _select(selected, clicked_wants_append, true); - } -} - -void Node3DEditorViewport::_select(Node *p_node, bool p_append, bool p_single) { - // Add or remove a single node from the selection - if (p_append && p_single) { - if (editor_selection->is_selected(p_node)) { - // Already in the selection, remove it from the selected nodes - editor_selection->remove_node(p_node); + if (clicked_wants_append) { + if (editor_selection->is_selected(selected)) { + editor_selection->remove_node(selected); + } else { + editor_selection->add_node(selected); + } } else { - // Add the item to the selection - editor_selection->add_node(p_node); - } - } else if (p_append && !p_single) { - // Add the item to the selection - editor_selection->add_node(p_node); - } else { - // No append; single select - editor_selection->clear(); - editor_selection->add_node(p_node); - // Reselect - if (Engine::get_singleton()->is_editor_hint()) { - editor->call("edit_node", p_node); + if (!editor_selection->is_selected(selected)) { + editor_selection->clear(); + editor_selection->add_node(selected); + editor->edit_node(selected); + } } - } - if (editor_selection->get_selected_node_list().size() == 1) { - editor->push_item(editor_selection->get_selected_node_list()[0]); + if (editor_selection->get_selected_node_list().size() == 1) { + editor->edit_node(editor_selection->get_selected_node_list()[0]); + } } } -ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle, bool p_alt_select) { - if (r_gizmo_handle) { - *r_gizmo_handle = -1; - } - +ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) { Vector3 ray = _get_ray(p_pos); Vector3 pos = _get_ray_pos(p_pos); Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink(); @@ -514,7 +510,6 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b ObjectID closest; Node *item = nullptr; float closest_dist = 1e20; - int selected_handle = -1; for (int i = 0; i < instances.size(); i++) { Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i])); @@ -523,38 +518,40 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b continue; } - Ref<EditorNode3DGizmo> seg = spat->get_gizmo(); + Vector<Ref<Node3DGizmo>> gizmos = spat->get_gizmos(); - if ((!seg.is_valid()) || found_gizmos.has(seg)) { - continue; - } + for (int j = 0; j < gizmos.size(); j++) { + Ref<EditorNode3DGizmo> seg = gizmos[j]; - found_gizmos.insert(seg); - Vector3 point; - Vector3 normal; + if ((!seg.is_valid()) || found_gizmos.has(seg)) { + continue; + } - int handle = -1; - bool inters = seg->intersect_ray(camera, shrinked_pos, point, normal, &handle, p_alt_select); + found_gizmos.insert(seg); + Vector3 point; + Vector3 normal; - if (!inters) { - continue; - } + bool inters = seg->intersect_ray(camera, shrinked_pos, point, normal); - float dist = pos.distance_to(point); + if (!inters) { + continue; + } - if (dist < 0) { - continue; - } + float dist = pos.distance_to(point); - if (dist < closest_dist) { - item = Object::cast_to<Node>(spat); - if (item != edited_scene) { - item = edited_scene->get_deepest_editable_node(item); + if (dist < 0) { + continue; } - closest = item->get_instance_id(); - closest_dist = dist; - selected_handle = handle; + if (dist < closest_dist) { + item = Object::cast_to<Node>(spat); + if (item != edited_scene) { + item = edited_scene->get_deepest_editable_node(item); + } + + closest = item->get_instance_id(); + closest_dist = dist; + } } } @@ -562,23 +559,15 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b return ObjectID(); } - if (!editor_selection->is_selected(item) || (r_gizmo_handle && selected_handle >= 0)) { - if (r_gizmo_handle) { - *r_gizmo_handle = selected_handle; - } - } - return closest; } -void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select, bool p_include_locked_nodes) { +void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked_nodes) { Vector3 ray = _get_ray(p_pos); Vector3 pos = _get_ray_pos(p_pos); Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world_3d()->get_scenario()); - Set<Ref<EditorNode3DGizmo>> found_gizmos; - - r_includes_current = false; + Set<Node3D *> found_nodes; for (int i = 0; i < instances.size(); i++) { Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i])); @@ -587,53 +576,48 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_inclu continue; } - Ref<EditorNode3DGizmo> seg = spat->get_gizmo(); - - if (!seg.is_valid()) { + if (found_nodes.has(spat)) { continue; } - if (found_gizmos.has(seg)) { + if (!p_include_locked_nodes && _is_node_locked(spat)) { continue; } - found_gizmos.insert(seg); - Vector3 point; - Vector3 normal; + Vector<Ref<Node3DGizmo>> gizmos = spat->get_gizmos(); + for (int j = 0; j < gizmos.size(); j++) { + Ref<EditorNode3DGizmo> seg = gizmos[j]; - int handle = -1; - bool inters = seg->intersect_ray(camera, p_pos, point, normal, nullptr, p_alt_select); + if (!seg.is_valid()) { + continue; + } - if (!inters) { - continue; - } + Vector3 point; + Vector3 normal; - float dist = pos.distance_to(point); + bool inters = seg->intersect_ray(camera, p_pos, point, normal); - if (dist < 0) { - continue; - } + if (!inters) { + continue; + } - if (!p_include_locked_nodes && _is_node_locked(spat)) { - continue; - } + float dist = pos.distance_to(point); - if (editor_selection->is_selected(spat)) { - r_includes_current = true; - } + if (dist < 0) { + continue; + } - _RayResult res; - res.item = spat; - res.depth = dist; - res.handle = handle; - results.push_back(res); - } + found_nodes.insert(spat); - if (results.is_empty()) { - return; + _RayResult res; + res.item = spat; + res.depth = dist; + r_results.push_back(res); + break; + } } - results.sort(); + r_results.sort(); } Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { @@ -656,6 +640,9 @@ Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { void Node3DEditorViewport::_select_region() { if (cursor.region_begin == cursor.region_end) { + if (!clicked_wants_append) { + _clear_selected(); + } return; //nothing really } @@ -702,7 +689,66 @@ void Node3DEditorViewport::_select_region() { far.d += get_zfar(); frustum.push_back(far); + if (spatial_editor->get_single_selected_node()) { + Node3D *single_selected = spatial_editor->get_single_selected_node(); + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(single_selected); + + Ref<EditorNode3DGizmo> old_gizmo; + if (!clicked_wants_append) { + se->subgizmos.clear(); + old_gizmo = se->gizmo; + se->gizmo.unref(); + } + + bool found_subgizmos = false; + Vector<Ref<Node3DGizmo>> gizmos = single_selected->get_gizmos(); + for (int j = 0; j < gizmos.size(); j++) { + Ref<EditorNode3DGizmo> seg = gizmos[j]; + if (!seg.is_valid()) { + continue; + } + + if (se->gizmo.is_valid() && se->gizmo != seg) { + continue; + } + + Vector<int> subgizmos = seg->subgizmos_intersect_frustum(camera, frustum); + if (!subgizmos.is_empty()) { + se->gizmo = seg; + for (int i = 0; i < subgizmos.size(); i++) { + int subgizmo_id = subgizmos[i]; + if (!se->subgizmos.has(subgizmo_id)) { + se->subgizmos.insert(subgizmo_id, se->gizmo->get_subgizmo_transform(subgizmo_id)); + } + } + found_subgizmos = true; + break; + } + } + + if (!clicked_wants_append || found_subgizmos) { + if (se->gizmo.is_valid()) { + se->gizmo->redraw(); + } + + if (old_gizmo != se->gizmo && old_gizmo.is_valid()) { + old_gizmo->redraw(); + } + + spatial_editor->update_transform_gizmo(); + } + + if (found_subgizmos) { + return; + } + } + + if (!clicked_wants_append) { + _clear_selected(); + } + Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world_3d()->get_scenario()); + Set<Node3D *> found_nodes; Vector<Node *> selected; Node *edited_scene = get_tree()->get_edited_scene_root(); @@ -713,6 +759,12 @@ void Node3DEditorViewport::_select_region() { continue; } + if (found_nodes.has(sp)) { + continue; + } + + found_nodes.insert(sp); + Node *item = Object::cast_to<Node>(sp); if (item != edited_scene) { item = edited_scene->get_deepest_editable_node(item); @@ -731,28 +783,31 @@ void Node3DEditorViewport::_select_region() { item = sel; } - if (selected.find(item) != -1) { - continue; - } - if (_is_node_locked(item)) { continue; } - Ref<EditorNode3DGizmo> seg = sp->get_gizmo(); + Vector<Ref<Node3DGizmo>> gizmos = sp->get_gizmos(); + for (int j = 0; j < gizmos.size(); j++) { + Ref<EditorNode3DGizmo> seg = gizmos[j]; + if (!seg.is_valid()) { + continue; + } - if (!seg.is_valid()) { - continue; + if (seg->intersect_frustum(camera, frustum)) { + selected.push_back(item); + } } + } - if (seg->intersect_frustum(camera, frustum)) { - selected.push_back(item); + for (int i = 0; i < selected.size(); i++) { + if (!editor_selection->is_selected(selected[i])) { + editor_selection->add_node(selected[i]); } } - bool single = selected.size() == 1; - for (int i = 0; i < selected.size(); i++) { - _select(selected[i], true, single); + if (editor_selection->get_selected_node_list().size() == 1) { + editor->edit_node(editor_selection->get_selected_node_list()[0]); } } @@ -779,21 +834,34 @@ void Node3DEditorViewport::_compute_edit(const Point2 &p_point) { spatial_editor->update_transform_gizmo(); _edit.center = spatial_editor->get_gizmo_transform().origin; - List<Node *> &selection = editor_selection->get_selected_node_list(); + Node3D *selected = spatial_editor->get_single_selected_node(); + Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); - if (!sp) { - continue; + if (se && se->gizmo.is_valid()) { + for (Map<int, Transform3D>::Element *E = se->subgizmos.front(); E; E = E->next()) { + int subgizmo_id = E->key(); + se->subgizmos[subgizmo_id] = se->gizmo->get_subgizmo_transform(subgizmo_id); } + se->original_local = selected->get_transform(); + se->original = selected->get_global_transform(); + } else { + List<Node *> &selection = editor_selection->get_selected_node_list(); - Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!se) { - continue; - } + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node3D *sp = Object::cast_to<Node3D>(E->get()); + if (!sp) { + continue; + } + + Node3DEditorSelectedItem *sel_item = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + + if (!sel_item) { + continue; + } - se->original = se->sp->get_global_gizmo_transform(); - se->original_local = se->sp->get_local_gizmo_transform(); + sel_item->original_local = sel_item->sp->get_local_gizmo_transform(); + sel_item->original = sel_item->sp->get_global_gizmo_transform(); + } } } @@ -829,7 +897,7 @@ static int _get_key_modifier(Ref<InputEventWithModifiers> e) { return 0; } -bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only) { +bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only) { if (!spatial_editor->is_gizmo_visible()) { return false; } @@ -1015,6 +1083,88 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high return false; } +void Node3DEditorViewport::_transform_gizmo_apply(Node3D *p_node, const Transform3D &p_transform, bool p_local) { + if (p_transform.basis.determinant() == 0) { + return; + } + + if (p_local) { + p_node->set_transform(p_transform); + } else { + p_node->set_global_transform(p_transform); + } +} + +Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local) { + switch (p_mode) { + case TRANSFORM_SCALE: { + if (p_local) { + Basis g = p_original.basis.orthonormalized(); + Vector3 local_motion = g.inverse().xform(p_motion); + + if (_edit.snap || spatial_editor->is_snap_enabled()) { + local_motion.snap(Vector3(p_extra, p_extra, p_extra)); + } + + Vector3 local_scale = p_original_local.basis.get_scale() * (local_motion + Vector3(1, 1, 1)); + Transform3D local_t = p_original_local; + local_t.basis.set_euler_scale(p_original_local.basis.get_rotation_euler(), local_scale); + return local_t; + } else { + Transform3D base = Transform3D(Basis(), _edit.center); + if (_edit.snap || spatial_editor->is_snap_enabled()) { + p_motion.snap(Vector3(p_extra, p_extra, p_extra)); + } + + Transform3D r; + r.basis.scale(p_motion + Vector3(1, 1, 1)); + return base * (r * (base.inverse() * p_original)); + } + } + case TRANSFORM_TRANSLATE: { + if (p_local) { + if (_edit.snap || spatial_editor->is_snap_enabled()) { + Basis g = p_original.basis.orthonormalized(); + Vector3 local_motion = g.inverse().xform(p_motion); + local_motion.snap(Vector3(p_extra, p_extra, p_extra)); + + p_motion = g.xform(local_motion); + } + + } else { + if (_edit.snap || spatial_editor->is_snap_enabled()) { + p_motion.snap(Vector3(p_extra, p_extra, p_extra)); + } + } + + // Apply translation + Transform3D t = p_original; + t.origin += p_motion; + return t; + } + case TRANSFORM_ROTATE: { + if (p_local) { + Basis rot = Basis(p_motion, p_extra); + + Vector3 scale = p_original_local.basis.get_scale(); + Vector3 euler = (p_original_local.get_basis().orthonormalized() * rot).get_euler(); + Transform3D t; + t.basis.set_euler_scale(euler, scale); + t.origin = p_original_local.origin; + return t; + } else { + Transform3D r; + r.basis.rotate(p_motion, p_extra); + Transform3D base = Transform3D(Basis(), _edit.center); + return base * r * base.inverse() * p_original; + } + } + default: { + ERR_FAIL_V_MSG(Transform3D(), "Invalid mode in '_compute_transform'"); + } + } +} + void Node3DEditorViewport::_surface_mouse_enter() { if (!surface->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) { surface->grab_focus(); @@ -1038,7 +1188,7 @@ bool Node3DEditorViewport ::_is_node_locked(const Node *p_node) { } void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { - _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->is_shift_pressed(), spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); + _find_items_at_pos(b->get_position(), selection_results, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); Node *scene = editor->get_edited_scene(); @@ -1058,10 +1208,8 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { selection_results.clear(); if (clicked.is_valid()) { - _select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); - clicked = ObjectID(); + _select_clicked(spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); } - } else if (!selection_results.is_empty()) { NodePath root_path = get_tree()->get_edited_scene_root()->get_path(); StringName root_name = root_path.get_name(root_path.get_name_count() - 1); @@ -1179,8 +1327,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -1190,7 +1338,20 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - sp->set_global_transform(se->original); + if (se->gizmo.is_valid()) { + Vector<int> ids; + Vector<Transform3D> restore; + + for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { + ids.push_back(GE->key()); + restore.push_back(GE->value()); + } + + se->gizmo->commit_subgizmos(ids, restore, true); + spatial_editor->update_transform_gizmo(); + } else { + sp->set_global_transform(se->original); + } } surface->update(); set_message(TTR("Transform Aborted."), 3); @@ -1271,28 +1432,65 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { can_select_gizmos = view_menu->get_popup()->is_item_checked(idx); } - if (can_select_gizmos && spatial_editor->get_selected()) { - Ref<EditorNode3DGizmo> seg = spatial_editor->get_selected()->get_gizmo(); - if (seg.is_valid()) { - int handle = -1; - Vector3 point; - Vector3 normal; - bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, b->is_shift_pressed()); - if (inters && handle != -1) { + if (can_select_gizmos && spatial_editor->get_single_selected_node()) { + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(spatial_editor->get_single_selected_node()); + Vector<Ref<Node3DGizmo>> gizmos = spatial_editor->get_single_selected_node()->get_gizmos(); + + bool intersected_handle = false; + for (int i = 0; i < gizmos.size(); i++) { + Ref<EditorNode3DGizmo> seg = gizmos[i]; + + if ((!seg.is_valid())) { + continue; + } + + int subgizmo_id = seg->subgizmos_intersect_ray(camera, _edit.mouse_pos); + if (subgizmo_id != -1) { + ERR_CONTINUE(!se); + if (b->is_shift_pressed()) { + if (se->subgizmos.has(subgizmo_id)) { + se->subgizmos.erase(subgizmo_id); + } else { + se->subgizmos.insert(subgizmo_id, seg->get_subgizmo_transform(subgizmo_id)); + } + } else { + se->subgizmos.clear(); + se->subgizmos.insert(subgizmo_id, seg->get_subgizmo_transform(subgizmo_id)); + } + + if (se->subgizmos.is_empty()) { + se->gizmo = Ref<EditorNode3DGizmo>(); + } else { + se->gizmo = seg; + } + + seg->redraw(); + spatial_editor->update_transform_gizmo(); + intersected_handle = true; + break; + } + + int gizmo_handle = -1; + seg->handles_intersect_ray(camera, _edit.mouse_pos, b->is_shift_pressed(), gizmo_handle); + if (gizmo_handle != -1) { _edit.gizmo = seg; - _edit.gizmo_handle = handle; - _edit.gizmo_initial_value = seg->get_handle_value(handle); + _edit.gizmo_handle = gizmo_handle; + _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle); + intersected_handle = true; break; } } + + if (intersected_handle) { + break; + } } - if (_gizmo_select(_edit.mouse_pos)) { + if (_transform_gizmo_select(_edit.mouse_pos)) { break; } clicked = ObjectID(); - clicked_includes_current = false; if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) { /* HANDLE ROTATION */ @@ -1325,40 +1523,19 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { break; } - // todo scale - - int gizmo_handle = -1; - - clicked = _select_ray(b->get_position(), b->is_shift_pressed(), clicked_includes_current, &gizmo_handle, b->is_shift_pressed()); + clicked = _select_ray(b->get_position()); //clicking is always deferred to either move or release clicked_wants_append = b->is_shift_pressed(); if (clicked.is_null()) { - if (!clicked_wants_append) { - _clear_selected(); - } - //default to regionselect cursor.region_select = true; cursor.region_begin = b->get_position(); cursor.region_end = b->get_position(); } - if (clicked.is_valid() && gizmo_handle >= 0) { - Node3D *spa = Object::cast_to<Node3D>(ObjectDB::get_instance(clicked)); - if (spa) { - Ref<EditorNode3DGizmo> seg = spa->get_gizmo(); - if (seg.is_valid()) { - _edit.gizmo = seg; - _edit.gizmo_handle = gizmo_handle; - _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle); - break; - } - } - } - surface->update(); } else { if (_edit.gizmo.is_valid()) { @@ -1366,47 +1543,57 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { _edit.gizmo = Ref<EditorNode3DGizmo>(); break; } + if (clicked.is_valid()) { - _select_clicked(clicked_wants_append, true); - // Processing was deferred. - clicked = ObjectID(); + _select_clicked(false); } if (cursor.region_select) { - if (!clicked_wants_append) { - _clear_selected(); - } - _select_region(); cursor.region_select = false; surface->update(); } if (_edit.mode != TRANSFORM_NONE) { - static const char *_transform_name[4] = { "None", "Rotate", "Translate", "Scale" }; - undo_redo->create_action(_transform_name[_edit.mode]); + Node3D *selected = spatial_editor->get_single_selected_node(); + Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; - List<Node *> &selection = editor_selection->get_selected_node_list(); + if (se && se->gizmo.is_valid()) { + Vector<int> ids; + Vector<Transform3D> restore; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); - if (!sp) { - continue; + for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { + ids.push_back(GE->key()); + restore.push_back(GE->value()); } - Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!se) { - continue; - } + se->gizmo->commit_subgizmos(ids, restore, false); + spatial_editor->update_transform_gizmo(); + } else { + static const char *_transform_name[4] = { "None", "Rotate", "Translate", "Scale" }; + undo_redo->create_action(_transform_name[_edit.mode]); + + List<Node *> &selection = editor_selection->get_selected_node_list(); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node3D *sp = Object::cast_to<Node3D>(E->get()); + if (!sp) { + continue; + } - undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); - undo_redo->add_undo_method(sp, "set_global_transform", se->original); + Node3DEditorSelectedItem *sel_item = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (!sel_item) { + continue; + } + + undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); + undo_redo->add_undo_method(sp, "set_global_transform", sel_item->original); + } + undo_redo->commit_action(); } - undo_redo->commit_action(); _edit.mode = TRANSFORM_NONE; set_message(""); } - surface->update(); } @@ -1421,31 +1608,39 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (m.is_valid()) { _edit.mouse_pos = m->get_position(); - if (spatial_editor->get_selected()) { - Ref<EditorNode3DGizmo> seg = spatial_editor->get_selected()->get_gizmo(); - if (seg.is_valid()) { - int selected_handle = -1; - - int handle = -1; - Vector3 point; - Vector3 normal; - bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, false); - if (inters && handle != -1) { - selected_handle = handle; + if (spatial_editor->get_single_selected_node()) { + Vector<Ref<Node3DGizmo>> gizmos = spatial_editor->get_single_selected_node()->get_gizmos(); + + Ref<EditorNode3DGizmo> found_gizmo; + int found_handle = -1; + + for (int i = 0; i < gizmos.size(); i++) { + Ref<EditorNode3DGizmo> seg = gizmos[i]; + if (!seg.is_valid()) { + continue; } - if (selected_handle != spatial_editor->get_over_gizmo_handle()) { - spatial_editor->set_over_gizmo_handle(selected_handle); - spatial_editor->get_selected()->update_gizmo(); - if (selected_handle != -1) { - spatial_editor->select_gizmo_highlight_axis(-1); - } + seg->handles_intersect_ray(camera, _edit.mouse_pos, false, found_handle); + + if (found_handle != -1) { + found_gizmo = seg; + break; } } + + if (found_gizmo.is_valid()) { + spatial_editor->select_gizmo_highlight_axis(-1); + } + + if (found_gizmo != spatial_editor->get_current_hover_gizmo() || found_handle != spatial_editor->get_current_hover_gizmo_handle()) { + spatial_editor->set_current_hover_gizmo(found_gizmo); + spatial_editor->set_current_hover_gizmo_handle(found_handle); + spatial_editor->get_single_selected_node()->update_gizmos(); + } } - if (spatial_editor->get_over_gizmo_handle() == -1 && !(m->get_button_mask() & 1) && !_edit.gizmo.is_valid()) { - _gizmo_select(_edit.mouse_pos, true); + if (spatial_editor->get_current_hover_gizmo().is_null() && !(m->get_button_mask() & 1) && !_edit.gizmo.is_valid()) { + _transform_gizmo_select(_edit.mouse_pos, true); } NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); @@ -1469,11 +1664,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } else { const bool movement_threshold_passed = _edit.original_mouse_pos.distance_to(_edit.mouse_pos) > 8 * EDSCALE; if (clicked.is_valid() && movement_threshold_passed) { - if (!clicked_includes_current) { - _select_clicked(clicked_wants_append, true); - // Processing was deferred. - } - _compute_edit(_edit.mouse_pos); clicked = ObjectID(); @@ -1568,8 +1758,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { motion = Vector3(scale, scale, scale); } - List<Node *> &selection = editor_selection->get_selected_node_list(); - // Disable local transformation for TRANSFORM_VIEW bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); @@ -1582,8 +1770,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { set_message(TTR("Scaling: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " + String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")"); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + List<Node *> &selection = editor_selection->get_selected_node_list(); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -1597,44 +1786,22 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - Transform3D original = se->original; - Transform3D original_local = se->original_local; - Transform3D base = Transform3D(Basis(), _edit.center); - Transform3D t; - Vector3 local_scale; - - if (local_coords) { - Basis g = original.basis.orthonormalized(); - Vector3 local_motion = g.inverse().xform(motion); - - if (_edit.snap || spatial_editor->is_snap_enabled()) { - local_motion.snap(Vector3(snap, snap, snap)); - } - - local_scale = original_local.basis.get_scale() * (local_motion + Vector3(1, 1, 1)); - - // Prevent scaling to 0 it would break the gizmo - Basis check = original_local.basis; - check.scale(local_scale); - if (check.determinant() != 0) { - // Apply scale - sp->set_scale(local_scale); + if (se->gizmo.is_valid()) { + for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { + Transform3D xform = GE->get(); + Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords); + if (!local_coords) { + new_xform = se->original.inverse() * new_xform; + } + se->gizmo->set_subgizmo_transform(GE->key(), new_xform); } - } else { - if (_edit.snap || spatial_editor->is_snap_enabled()) { - motion.snap(Vector3(snap, snap, snap)); - } - - Transform3D r; - r.basis.scale(motion + Vector3(1, 1, 1)); - t = base * (r * (base.inverse() * original)); - - // Apply scale - sp->set_global_transform(t); + Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords); + _transform_gizmo_apply(se->sp, new_xform, local_coords); } } + spatial_editor->update_transform_gizmo(); surface->update(); } break; @@ -1691,8 +1858,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } - List<Node *> &selection = editor_selection->get_selected_node_list(); - // Disable local transformation for TRANSFORM_VIEW bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); @@ -1704,8 +1869,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { set_message(TTR("Translating: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " + String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")"); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + List<Node *> &selection = editor_selection->get_selected_node_list(); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -1719,30 +1885,20 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - Transform3D original = se->original; - Transform3D t; - - if (local_coords) { - if (_edit.snap || spatial_editor->is_snap_enabled()) { - Basis g = original.basis.orthonormalized(); - Vector3 local_motion = g.inverse().xform(motion); - local_motion.snap(Vector3(snap, snap, snap)); - - motion = g.xform(local_motion); + if (se->gizmo.is_valid()) { + for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { + Transform3D xform = GE->get(); + Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords); + new_xform = se->original.inverse() * new_xform; + se->gizmo->set_subgizmo_transform(GE->key(), new_xform); } - } else { - if (_edit.snap || spatial_editor->is_snap_enabled()) { - motion.snap(Vector3(snap, snap, snap)); - } + Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords); + _transform_gizmo_apply(se->sp, new_xform, false); } - - // Apply translation - t = original; - t.origin += motion; - sp->set_global_transform(t); } + spatial_editor->update_transform_gizmo(); surface->update(); } break; @@ -1796,12 +1952,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals))); angle = Math::deg2rad(angle); - List<Node *> &selection = editor_selection->get_selected_node_list(); - bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + List<Node *> &selection = editor_selection->get_selected_node_list(); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -1815,32 +1970,24 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - Transform3D t; - - if (local_coords) { - Transform3D original_local = se->original_local; - Basis rot = Basis(axis, angle); - - t.basis = original_local.get_basis().orthonormalized() * rot; - t.origin = original_local.origin; - - // Apply rotation - sp->set_transform(t); - sp->set_scale(original_local.basis.get_scale()); // re-apply original scale + Vector3 compute_axis = local_coords ? axis : plane.normal; + if (se->gizmo.is_valid()) { + for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { + Transform3D xform = GE->get(); + Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords); + if (!local_coords) { + new_xform = se->original.inverse() * new_xform; + } + se->gizmo->set_subgizmo_transform(GE->key(), new_xform); + } } else { - Transform3D original = se->original; - Transform3D r; - Transform3D base = Transform3D(Basis(), _edit.center); - - r.basis.rotate(plane.normal, angle); - t = base * r * base.inverse() * original; - - // Apply rotation - sp->set_global_transform(t); + Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords); + _transform_gizmo_apply(se->sp, new_xform, local_coords); } } + spatial_editor->update_transform_gizmo(); surface->update(); } break; @@ -2039,8 +2186,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -2905,8 +3052,8 @@ void Node3DEditorViewport::_menu_option(int p_option) { undo_redo->create_action(TTR("Align Transform with View")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -2941,8 +3088,8 @@ void Node3DEditorViewport::_menu_option(int p_option) { List<Node *> &selection = editor_selection->get_selected_node_list(); undo_redo->create_action(TTR("Align Rotation with View")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -3310,8 +3457,7 @@ void Node3DEditorViewport::_selection_result_pressed(int p_result) { clicked = selection_results[p_result].item->get_instance_id(); if (clicked.is_valid()) { - _select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); - clicked = ObjectID(); + _select_clicked(spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); } } @@ -3595,8 +3741,8 @@ void Node3DEditorViewport::focus_selection() { List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -3606,6 +3752,13 @@ void Node3DEditorViewport::focus_selection() { continue; } + if (se->gizmo.is_valid()) { + for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { + center += se->gizmo->get_subgizmo_transform(GE->key()).origin; + count++; + } + } + center += sp->get_global_gizmo_transform().origin; count++; } @@ -3644,34 +3797,39 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const continue; } - Ref<EditorNode3DGizmo> seg = mesh_instance->get_gizmo(); + Vector<Ref<Node3DGizmo>> gizmos = mesh_instance->get_gizmos(); - if ((!seg.is_valid()) || found_gizmos.has(seg)) { - continue; - } + for (int j = 0; j < gizmos.size(); j++) { + Ref<EditorNode3DGizmo> seg = gizmos[j]; - found_gizmos.insert(seg); + if ((!seg.is_valid()) || found_gizmos.has(seg)) { + continue; + } - Vector3 hit_point; - Vector3 hit_normal; - bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, nullptr, false); + found_gizmos.insert(seg); - if (!inters) { - continue; - } + Vector3 hit_point; + Vector3 hit_normal; + bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal); - float dist = world_pos.distance_to(hit_point); + if (!inters) { + continue; + } - if (dist < 0) { - continue; - } + float dist = world_pos.distance_to(hit_point); + + if (dist < 0) { + continue; + } - if (dist < closest_dist) { - closest_dist = dist; - point = hit_point; - normal = hit_normal; + if (dist < closest_dist) { + closest_dist = dist; + point = hit_point; + normal = hit_normal; + } } } + Vector3 offset = Vector3(); for (int i = 0; i < 3; i++) { if (normal[i] > 0.0) { @@ -3972,9 +4130,8 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito _edit.mode = TRANSFORM_NONE; _edit.plane = TRANSFORM_VIEW; - _edit.edited_gizmo = 0; _edit.snap = true; - _edit.gizmo_handle = 0; + _edit.gizmo_handle = -1; index = p_index; editor = p_editor; @@ -3982,7 +4139,6 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito editor_selection = editor->get_editor_selection(); undo_redo = editor->get_undo_redo(); - clicked_includes_current = false; orthogonal = false; auto_orthogonal = false; lock_rotation = false; @@ -4005,7 +4161,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito surface->set_anchors_and_offsets_preset(Control::PRESET_WIDE); surface->set_clip_contents(true); camera = memnew(Camera3D); - camera->set_disable_gizmo(true); + camera->set_disable_gizmos(true); camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + p_index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER) | (1 << MISC_TOOL_LAYER)); viewport->add_child(camera); camera->make_current(); @@ -4574,43 +4730,54 @@ void Node3DEditor::select_gizmo_highlight_axis(int p_axis) { } void Node3DEditor::update_transform_gizmo() { - List<Node *> &selection = editor_selection->get_selected_node_list(); - AABB center; - bool first = true; + int count = 0; + bool local_gizmo_coords = are_local_coords_enabled(); + Vector3 gizmo_center; Basis gizmo_basis; - bool local_gizmo_coords = are_local_coords_enabled(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); - if (!sp) { - continue; - } + Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; - Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!se) { - continue; + if (se && se->gizmo.is_valid()) { + for (Map<int, Transform3D>::Element *E = se->subgizmos.front(); E; E = E->next()) { + Transform3D xf = se->sp->get_global_transform() * se->gizmo->get_subgizmo_transform(E->key()); + gizmo_center += xf.origin; + if (count == 0 && local_gizmo_coords) { + gizmo_basis = xf.basis; + gizmo_basis.orthonormalize(); + } + count++; } + } else { + List<Node *> &selection = editor_selection->get_selected_node_list(); + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node3D *sp = Object::cast_to<Node3D>(E->get()); + if (!sp) { + continue; + } + + if (sp->has_meta("_edit_lock_")) { + continue; + } - Transform3D xf = se->sp->get_global_gizmo_transform(); + Node3DEditorSelectedItem *sel_item = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (!sel_item) { + continue; + } - if (first) { - center.position = xf.origin; - first = false; - if (local_gizmo_coords) { + Transform3D xf = sel_item->sp->get_global_transform(); + gizmo_center += xf.origin; + if (count == 0 && local_gizmo_coords) { gizmo_basis = xf.basis; gizmo_basis.orthonormalize(); } - } else { - center.expand_to(xf.origin); - gizmo_basis = Basis(); + count++; } } - Vector3 pcenter = center.position + center.size * 0.5; - gizmo.visible = !first; - gizmo.transform.origin = pcenter; - gizmo.transform.basis = gizmo_basis; + gizmo.visible = count > 0; + gizmo.transform.origin = (count > 0) ? gizmo_center / count : Vector3(); + gizmo.transform.basis = (count == 1) ? gizmo_basis : Basis(); for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { viewports[i]->update_transform_gizmo_view(); @@ -4621,7 +4788,7 @@ void _update_all_gizmos(Node *p_node) { for (int i = p_node->get_child_count() - 1; 0 <= i; --i) { Node3D *spatial_node = Object::cast_to<Node3D>(p_node->get_child(i)); if (spatial_node) { - spatial_node->update_gizmo(); + spatial_node->update_gizmos(); } _update_all_gizmos(p_node->get_child(i)); @@ -4940,22 +5107,38 @@ void Node3DEditor::set_state(const Dictionary &p_state) { void Node3DEditor::edit(Node3D *p_spatial) { if (p_spatial != selected) { if (selected) { - Ref<EditorNode3DGizmo> seg = selected->get_gizmo(); - if (seg.is_valid()) { + Vector<Ref<Node3DGizmo>> gizmos = selected->get_gizmos(); + for (int i = 0; i < gizmos.size(); i++) { + Ref<EditorNode3DGizmo> seg = gizmos[i]; + if (!seg.is_valid()) { + continue; + } seg->set_selected(false); - selected->update_gizmo(); } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected); + if (se) { + se->gizmo.unref(); + se->subgizmos.clear(); + } + + selected->update_gizmos(); } selected = p_spatial; - over_gizmo_handle = -1; + current_hover_gizmo = Ref<EditorNode3DGizmo>(); + current_hover_gizmo_handle = -1; if (selected) { - Ref<EditorNode3DGizmo> seg = selected->get_gizmo(); - if (seg.is_valid()) { + Vector<Ref<Node3DGizmo>> gizmos = selected->get_gizmos(); + for (int i = 0; i < gizmos.size(); i++) { + Ref<EditorNode3DGizmo> seg = gizmos[i]; + if (!seg.is_valid()) { + continue; + } seg->set_selected(true); - selected->update_gizmo(); } + selected->update_gizmos(); } } } @@ -4993,8 +5176,8 @@ void Node3DEditor::_xform_dialog_action() { List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (!sp) { continue; } @@ -5230,8 +5413,8 @@ void Node3DEditor::_menu_item_pressed(int p_option) { List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *spatial = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *spatial = Object::cast_to<Node3D>(E); if (!spatial || !spatial->is_inside_tree()) { continue; } @@ -5255,8 +5438,8 @@ void Node3DEditor::_menu_item_pressed(int p_option) { List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *spatial = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *spatial = Object::cast_to<Node3D>(E); if (!spatial || !spatial->is_inside_tree()) { continue; } @@ -5280,8 +5463,8 @@ void Node3DEditor::_menu_item_pressed(int p_option) { List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *spatial = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *spatial = Object::cast_to<Node3D>(E); if (!spatial || !spatial->is_inside_tree()) { continue; } @@ -5304,8 +5487,8 @@ void Node3DEditor::_menu_item_pressed(int p_option) { undo_redo->create_action(TTR("Ungroup Selected")); List<Node *> &selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *spatial = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *spatial = Object::cast_to<Node3D>(E); if (!spatial || !spatial->is_inside_tree()) { continue; } @@ -6027,13 +6210,27 @@ void Node3DEditor::update_grid() { _init_grid(); } -bool Node3DEditor::is_any_freelook_active() const { - for (unsigned int i = 0; i < VIEWPORTS_COUNT; ++i) { - if (viewports[i]->is_freelook_active()) { - return true; +void Node3DEditor::_selection_changed() { + _refresh_menu_icons(); + if (selected && editor_selection->get_selected_node_list().size() != 1) { + Vector<Ref<Node3DGizmo>> gizmos = selected->get_gizmos(); + for (int i = 0; i < gizmos.size(); i++) { + Ref<EditorNode3DGizmo> seg = gizmos[i]; + if (!seg.is_valid()) { + continue; + } + seg->set_selected(false); + } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected); + if (se) { + se->gizmo.unref(); + se->subgizmos.clear(); } + selected->update_gizmos(); + selected = nullptr; } - return false; + update_transform_gizmo(); } void Node3DEditor::_refresh_menu_icons() { @@ -6046,14 +6243,14 @@ void Node3DEditor::_refresh_menu_icons() { all_locked = false; all_grouped = false; } else { - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - if (Object::cast_to<Node3D>(E->get()) && !Object::cast_to<Node3D>(E->get())->has_meta("_edit_lock_")) { + for (Node *E : selection) { + if (Object::cast_to<Node3D>(E) && !Object::cast_to<Node3D>(E)->has_meta("_edit_lock_")) { all_locked = false; break; } } - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - if (Object::cast_to<Node3D>(E->get()) && !Object::cast_to<Node3D>(E->get())->has_meta("_edit_group_")) { + for (Node *E : selection) { + if (Object::cast_to<Node3D>(E) && !Object::cast_to<Node3D>(E)->has_meta("_edit_group_")) { all_grouped = false; break; } @@ -6106,8 +6303,8 @@ void Node3DEditor::snap_selected_nodes_to_floor() { List<Node *> &selection = editor_selection->get_selected_node_list(); Dictionary snap_data; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); if (sp) { Vector3 from = Vector3(); Vector3 position_offset = Vector3(); @@ -6325,7 +6522,7 @@ void Node3DEditor::_notification(int p_what) { get_tree()->connect("node_removed", callable_mp(this, &Node3DEditor::_node_removed)); get_tree()->connect("node_added", callable_mp(this, &Node3DEditor::_node_added)); EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); - editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); + editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_selection_changed)); editor->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false)); editor->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true)); @@ -6384,6 +6581,34 @@ void Node3DEditor::_notification(int p_what) { } } +bool Node3DEditor::is_subgizmo_selected(int p_id) { + Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; + if (se) { + return se->subgizmos.has(p_id); + } + return false; +} + +bool Node3DEditor::is_current_selected_gizmo(const EditorNode3DGizmo *p_gizmo) { + Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; + if (se) { + return se->gizmo == p_gizmo; + } + return false; +} + +Vector<int> Node3DEditor::get_subgizmo_selection() { + Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; + + Vector<int> ret; + if (se) { + for (Map<int, Transform3D>::Element *E = se->subgizmos.front(); E; E = E->next()) { + ret.push_back(E->key()); + } + } + return ret; +} + void Node3DEditor::add_control_to_menu_panel(Control *p_control) { hbc_menu->add_child(p_control); } @@ -6411,23 +6636,43 @@ void Node3DEditor::_request_gizmo(Object *p_obj) { if (!sp) { return; } - if (editor->get_edited_scene() && (sp == editor->get_edited_scene() || (sp->get_owner() && editor->get_edited_scene()->is_ancestor_of(sp)))) { - Ref<EditorNode3DGizmo> seg; + bool is_selected = (sp == selected); + + if (editor->get_edited_scene() && (sp == editor->get_edited_scene() || (sp->get_owner() && editor->get_edited_scene()->is_ancestor_of(sp)))) { for (int i = 0; i < gizmo_plugins_by_priority.size(); ++i) { - seg = gizmo_plugins_by_priority.write[i]->get_gizmo(sp); + Ref<EditorNode3DGizmo> seg = gizmo_plugins_by_priority.write[i]->get_gizmo(sp); if (seg.is_valid()) { - sp->set_gizmo(seg); + sp->add_gizmo(seg); - if (sp == selected) { - seg->set_selected(true); - selected->update_gizmo(); + if (is_selected != seg->is_selected()) { + seg->set_selected(is_selected); } - - break; } } + sp->update_gizmos(); + } +} + +void Node3DEditor::_clear_subgizmo_selection(Object *p_obj) { + Node3D *sp = nullptr; + if (p_obj) { + sp = Object::cast_to<Node3D>(p_obj); + } else { + sp = selected; + } + + if (!sp) { + return; + } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (se) { + se->subgizmos.clear(); + se->gizmo.unref(); + sp->update_gizmos(); + update_transform_gizmo(); } } @@ -6516,7 +6761,13 @@ void Node3DEditor::_node_removed(Node *p_node) { } if (p_node == selected) { + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected); + if (se) { + se->gizmo.unref(); + se->subgizmos.clear(); + } selected = nullptr; + update_transform_gizmo(); } } @@ -6554,6 +6805,7 @@ void Node3DEditor::_bind_methods() { ClassDB::bind_method("_unhandled_key_input", &Node3DEditor::_unhandled_key_input); ClassDB::bind_method("_get_editor_data", &Node3DEditor::_get_editor_data); ClassDB::bind_method("_request_gizmo", &Node3DEditor::_request_gizmo); + ClassDB::bind_method("_clear_subgizmo_selection", &Node3DEditor::_clear_subgizmo_selection); ClassDB::bind_method("_refresh_menu_icons", &Node3DEditor::_refresh_menu_icons); ADD_SIGNAL(MethodInfo("transform_key_request")); @@ -6769,8 +7021,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), KEY_Q)); tool_button[TOOL_MODE_SELECT]->set_shortcut_context(this); - tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Show list of all nodes at position clicked, including locked.")); - + tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.")); hbc_menu->add_child(memnew(VSeparator)); tool_button[TOOL_MODE_MOVE] = memnew(Button); @@ -7130,7 +7381,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::FLOAT, "editors/3d/manipulator_gizmo_opacity", PROPERTY_HINT_RANGE, "0,1,0.01")); EDITOR_DEF("editors/3d/navigation/show_viewport_rotation_gizmo", true); - over_gizmo_handle = -1; + current_hover_gizmo_handle = -1; { //sun popup @@ -7444,303 +7695,3 @@ Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) { Node3DEditorPlugin::~Node3DEditorPlugin() { } - -void EditorNode3DGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) { - Color instantiated_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instantiated", Color(0.7, 0.7, 0.7, 0.6)); - - Vector<Ref<StandardMaterial3D>> mats; - - for (int i = 0; i < 4; i++) { - bool selected = i % 2 == 1; - bool instantiated = i < 2; - - Ref<StandardMaterial3D> material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - - Color color = instantiated ? instantiated_color : p_color; - - if (!selected) { - color.a *= 0.3; - } - - material->set_albedo(color); - material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN + 1); - material->set_cull_mode(StandardMaterial3D::CULL_DISABLED); - - if (p_use_vertex_color) { - material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - } - - if (p_billboard) { - material->set_billboard_mode(StandardMaterial3D::BILLBOARD_ENABLED); - } - - if (p_on_top && selected) { - material->set_on_top_of_alpha(); - } - - mats.push_back(material); - } - - materials[p_name] = mats; -} - -void EditorNode3DGizmoPlugin::create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top, const Color &p_albedo) { - Color instantiated_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instantiated", Color(0.7, 0.7, 0.7, 0.6)); - - Vector<Ref<StandardMaterial3D>> icons; - - for (int i = 0; i < 4; i++) { - bool selected = i % 2 == 1; - bool instantiated = i < 2; - - Ref<StandardMaterial3D> icon = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - - Color color = instantiated ? instantiated_color : p_albedo; - - if (!selected) { - color.a *= 0.85; - } - - icon->set_albedo(color); - - icon->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - icon->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - icon->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - icon->set_cull_mode(StandardMaterial3D::CULL_DISABLED); - icon->set_depth_draw_mode(StandardMaterial3D::DEPTH_DRAW_DISABLED); - icon->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - icon->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, p_texture); - icon->set_flag(StandardMaterial3D::FLAG_FIXED_SIZE, true); - icon->set_billboard_mode(StandardMaterial3D::BILLBOARD_ENABLED); - icon->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN); - - if (p_on_top && selected) { - icon->set_on_top_of_alpha(); - } - - icons.push_back(icon); - } - - materials[p_name] = icons; -} - -void EditorNode3DGizmoPlugin::create_handle_material(const String &p_name, bool p_billboard, const Ref<Texture2D> &p_icon) { - Ref<StandardMaterial3D> handle_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - - handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); - Ref<Texture2D> handle_t = p_icon != nullptr ? p_icon : Node3DEditor::get_singleton()->get_theme_icon(SNAME("Editor3DHandle"), SNAME("EditorIcons")); - handle_material->set_point_size(handle_t->get_width()); - handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle_t); - handle_material->set_albedo(Color(1, 1, 1)); - handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - handle_material->set_on_top_of_alpha(); - if (p_billboard) { - handle_material->set_billboard_mode(StandardMaterial3D::BILLBOARD_ENABLED); - handle_material->set_on_top_of_alpha(); - } - handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - - materials[p_name] = Vector<Ref<StandardMaterial3D>>(); - materials[p_name].push_back(handle_material); -} - -void EditorNode3DGizmoPlugin::add_material(const String &p_name, Ref<StandardMaterial3D> p_material) { - materials[p_name] = Vector<Ref<StandardMaterial3D>>(); - materials[p_name].push_back(p_material); -} - -Ref<StandardMaterial3D> EditorNode3DGizmoPlugin::get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo) { - ERR_FAIL_COND_V(!materials.has(p_name), Ref<StandardMaterial3D>()); - ERR_FAIL_COND_V(materials[p_name].size() == 0, Ref<StandardMaterial3D>()); - - if (p_gizmo.is_null() || materials[p_name].size() == 1) { - return materials[p_name][0]; - } - - int index = (p_gizmo->is_selected() ? 1 : 0) + (p_gizmo->is_editable() ? 2 : 0); - - Ref<StandardMaterial3D> mat = materials[p_name][index]; - - if (current_state == ON_TOP && p_gizmo->is_selected()) { - mat->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); - } else { - mat->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, false); - } - - return mat; -} - -String EditorNode3DGizmoPlugin::get_gizmo_name() const { - if (get_script_instance() && get_script_instance()->has_method("_get_gizmo_name")) { - return get_script_instance()->call("_get_gizmo_name"); - } - return TTR("Nameless gizmo"); -} - -int EditorNode3DGizmoPlugin::get_priority() const { - if (get_script_instance() && get_script_instance()->has_method("_get_priority")) { - return get_script_instance()->call("_get_priority"); - } - return 0; -} - -Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::get_gizmo(Node3D *p_spatial) { - if (get_script_instance() && get_script_instance()->has_method("get_gizmo")) { - return get_script_instance()->call("get_gizmo", p_spatial); - } - - Ref<EditorNode3DGizmo> ref = create_gizmo(p_spatial); - - if (ref.is_null()) { - return ref; - } - - ref->set_plugin(this); - ref->set_spatial_node(p_spatial); - ref->set_hidden(current_state == HIDDEN); - - current_gizmos.push_back(ref.ptr()); - return ref; -} - -void EditorNode3DGizmoPlugin::_bind_methods() { -#define GIZMO_REF PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "EditorNode3DGizmo") - - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); - BIND_VMETHOD(MethodInfo(GIZMO_REF, "_create_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); - - ClassDB::bind_method(D_METHOD("create_material", "name", "color", "billboard", "on_top", "use_vertex_color"), &EditorNode3DGizmoPlugin::create_material, DEFVAL(false), DEFVAL(false), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("create_icon_material", "name", "texture", "on_top", "color"), &EditorNode3DGizmoPlugin::create_icon_material, DEFVAL(false), DEFVAL(Color(1, 1, 1, 1))); - ClassDB::bind_method(D_METHOD("create_handle_material", "name", "billboard", "texture"), &EditorNode3DGizmoPlugin::create_handle_material, DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("add_material", "name", "material"), &EditorNode3DGizmoPlugin::add_material); - - ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorNode3DGizmoPlugin::get_material, DEFVAL(Ref<EditorNode3DGizmo>())); - - BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_gizmo_name")); - BIND_VMETHOD(MethodInfo(Variant::INT, "_get_priority")); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_can_be_hidden")); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_selectable_when_hidden")); - - BIND_VMETHOD(MethodInfo("_redraw", GIZMO_REF)); - BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_handle_name", GIZMO_REF, PropertyInfo(Variant::INT, "index"))); - - MethodInfo hvget(Variant::NIL, "_get_handle_value", GIZMO_REF, PropertyInfo(Variant::INT, "index")); - hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; - BIND_VMETHOD(hvget); - - BIND_VMETHOD(MethodInfo("_set_handle", GIZMO_REF, PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point"))); - MethodInfo cm = MethodInfo("_commit_handle", GIZMO_REF, PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel")); - cm.default_arguments.push_back(false); - BIND_VMETHOD(cm); - - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_handle_highlighted", GIZMO_REF, PropertyInfo(Variant::INT, "index"))); - -#undef GIZMO_REF -} - -bool EditorNode3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { - if (get_script_instance() && get_script_instance()->has_method("_has_gizmo")) { - return get_script_instance()->call("_has_gizmo", p_spatial); - } - return false; -} - -Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::create_gizmo(Node3D *p_spatial) { - if (get_script_instance() && get_script_instance()->has_method("_create_gizmo")) { - return get_script_instance()->call("_create_gizmo", p_spatial); - } - - Ref<EditorNode3DGizmo> ref; - if (has_gizmo(p_spatial)) { - ref.instantiate(); - } - return ref; -} - -bool EditorNode3DGizmoPlugin::can_be_hidden() const { - if (get_script_instance() && get_script_instance()->has_method("_can_be_hidden")) { - return get_script_instance()->call("_can_be_hidden"); - } - return true; -} - -bool EditorNode3DGizmoPlugin::is_selectable_when_hidden() const { - if (get_script_instance() && get_script_instance()->has_method("_is_selectable_when_hidden")) { - return get_script_instance()->call("_is_selectable_when_hidden"); - } - return false; -} - -void EditorNode3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - if (get_script_instance() && get_script_instance()->has_method("_redraw")) { - Ref<EditorNode3DGizmo> ref(p_gizmo); - get_script_instance()->call("_redraw", ref); - } -} - -String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - if (get_script_instance() && get_script_instance()->has_method("_get_handle_name")) { - return get_script_instance()->call("_get_handle_name", p_gizmo, p_idx); - } - return ""; -} - -Variant EditorNode3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { - if (get_script_instance() && get_script_instance()->has_method("_get_handle_value")) { - return get_script_instance()->call("_get_handle_value", p_gizmo, p_idx); - } - return Variant(); -} - -void EditorNode3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { - if (get_script_instance() && get_script_instance()->has_method("_set_handle")) { - get_script_instance()->call("_set_handle", p_gizmo, p_idx, p_camera, p_point); - } -} - -void EditorNode3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { - if (get_script_instance() && get_script_instance()->has_method("_commit_handle")) { - get_script_instance()->call("_commit_handle", p_gizmo, p_idx, p_restore, p_cancel); - } -} - -bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_idx) const { - if (get_script_instance() && get_script_instance()->has_method("_is_handle_highlighted")) { - return get_script_instance()->call("_is_handle_highlighted", p_gizmo, p_idx); - } - return false; -} - -void EditorNode3DGizmoPlugin::set_state(int p_state) { - current_state = p_state; - for (int i = 0; i < current_gizmos.size(); ++i) { - current_gizmos[i]->set_hidden(current_state == HIDDEN); - } -} - -int EditorNode3DGizmoPlugin::get_state() const { - return current_state; -} - -void EditorNode3DGizmoPlugin::unregister_gizmo(EditorNode3DGizmo *p_gizmo) { - current_gizmos.erase(p_gizmo); -} - -EditorNode3DGizmoPlugin::EditorNode3DGizmoPlugin() { - current_state = VISIBLE; -} - -EditorNode3DGizmoPlugin::~EditorNode3DGizmoPlugin() { - for (int i = 0; i < current_gizmos.size(); ++i) { - current_gizmos[i]->set_plugin(nullptr); - current_gizmos[i]->get_spatial_node()->set_gizmo(nullptr); - } - if (Node3DEditor::get_singleton()) { - Node3DEditor::get_singleton()->update_all_gizmos(); - } -} diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index cc65cb53ca..576e4c93d3 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -34,6 +34,7 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "editor/editor_scale.h" +#include "editor/plugins/node_3d_editor_gizmos.h" #include "scene/3d/light_3d.h" #include "scene/3d/visual_instance_3d.h" #include "scene/3d/world_environment.h" @@ -43,96 +44,10 @@ class Camera3D; class Node3DEditor; -class EditorNode3DGizmoPlugin; class Node3DEditorViewport; class SubViewportContainer; - -class EditorNode3DGizmo : public Node3DGizmo { - GDCLASS(EditorNode3DGizmo, Node3DGizmo); - - bool selected; - bool instantiated; - -public: - void set_selected(bool p_selected) { selected = p_selected; } - bool is_selected() const { return selected; } - - struct Instance { - RID instance; - Ref<ArrayMesh> mesh; - Ref<Material> material; - Ref<SkinReference> skin_reference; - RID skeleton; - bool billboard = false; - bool unscaled = false; - bool can_intersect = false; - bool extra_margin = false; - - void create_instance(Node3D *p_base, bool p_hidden = false); - }; - - Vector<Vector3> collision_segments; - Ref<TriangleMesh> collision_mesh; - - struct Handle { - Vector3 pos; - bool billboard = false; - }; - - Vector<Vector3> handles; - Vector<Vector3> secondary_handles; - float selectable_icon_size; - bool billboard_handle; - - bool valid; - bool hidden; - Node3D *base; - Vector<Instance> instances; - Node3D *spatial_node; - EditorNode3DGizmoPlugin *gizmo_plugin; - - void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Node3D>(p_node)); } - -protected: - static void _bind_methods(); - -public: - void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); - void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); - void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>(), const Ref<Material> &p_material = Ref<Material>()); - void add_collision_segments(const Vector<Vector3> &p_lines); - void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); - void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1, const Color &p_modulate = Color(1, 1, 1)); - void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard = false, bool p_secondary = false); - void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3()); - - virtual bool is_handle_highlighted(int p_idx) const; - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx); - virtual void set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); - - void set_spatial_node(Node3D *p_node); - Node3D *get_spatial_node() const { return spatial_node; } - Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; } - Vector3 get_handle_pos(int p_idx) const; - bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum); - bool intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = nullptr, bool p_sec_first = false); - - virtual void clear() override; - virtual void create() override; - virtual void transform() override; - virtual void redraw() override; - virtual void free() override; - - virtual bool is_editable() const; - - void set_hidden(bool p_hidden); - void set_plugin(EditorNode3DGizmoPlugin *p_plugin); - - EditorNode3DGizmo(); - ~EditorNode3DGizmo(); -}; +class DirectionalLight3D; +class WorldEnvironment; class ViewportRotationControl : public Control { GDCLASS(ViewportRotationControl, Control); @@ -307,17 +222,15 @@ private: struct _RayResult { Node3D *item = nullptr; float depth = 0; - int handle = 0; _FORCE_INLINE_ bool operator<(const _RayResult &p_rr) const { return depth < p_rr.depth; } }; void _update_name(); void _compute_edit(const Point2 &p_point); void _clear_selected(); - void _select_clicked(bool p_append, bool p_single, bool p_allow_locked = false); - void _select(Node *p_node, bool p_append, bool p_single); - ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = nullptr, bool p_alt_select = false); - void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false, bool p_include_locked_nodes = false); + void _select_clicked(bool p_allow_locked); + ObjectID _select_ray(const Point2 &p_pos); + void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked); Vector3 _get_ray_pos(const Vector2 &p_pos) const; Vector3 _get_ray(const Vector2 &p_pos) const; Point2 _point_to_screen(const Vector3 &p_point); @@ -329,7 +242,8 @@ private: Vector3 _get_screen_to_space(const Vector3 &p_vector3); void _select_region(); - bool _gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false); + bool _transform_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false); + void _transform_gizmo_apply(Node3D *p_node, const Transform3D &p_transform, bool p_local); void _nav_pan(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative); void _nav_zoom(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative); @@ -342,7 +256,6 @@ private: ObjectID clicked; Vector<_RayResult> selection_results; - bool clicked_includes_current; bool clicked_wants_append; PopupMenu *selection_menu; @@ -383,15 +296,12 @@ private: Vector3 click_ray; Vector3 click_ray_pos; Vector3 center; - Vector3 orig_gizmo_pos; - int edited_gizmo = 0; Point2 mouse_pos; Point2 original_mouse_pos; bool snap = false; Ref<EditorNode3DGizmo> gizmo; int gizmo_handle = 0; Variant gizmo_initial_value; - Vector3 gizmo_initial_pos; } _edit; struct Cursor { @@ -472,6 +382,8 @@ private: void _project_settings_changed(); + Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local); + protected: void _notification(int p_what); static void _bind_methods(); @@ -512,6 +424,8 @@ public: Node3D *sp; RID sbox_instance; RID sbox_instance_xray; + Ref<EditorNode3DGizmo> gizmo; + Map<int, Transform3D> subgizmos; // map ID -> initial transform Node3DEditorSelectedItem() { sp = nullptr; @@ -617,7 +531,9 @@ private: Ref<StandardMaterial3D> plane_gizmo_color_hl[3]; Ref<ShaderMaterial> rotate_gizmo_color_hl[3]; - int over_gizmo_handle; + Ref<Node3DGizmo> current_hover_gizmo; + int current_hover_gizmo_handle; + float snap_translate_value; float snap_rotate_value; float snap_scale_value; @@ -688,7 +604,6 @@ private: LineEdit *snap_translate; LineEdit *snap_rotate; LineEdit *snap_scale; - PanelContainer *menu_panel; LineEdit *xform_translate[3]; LineEdit *xform_rotate[3]; @@ -734,6 +649,7 @@ private: Node3D *selected; void _request_gizmo(Object *p_obj); + void _clear_subgizmo_selection(Object *p_obj = nullptr); static Node3DEditor *singleton; @@ -746,8 +662,7 @@ private: Node3DEditor(); - bool is_any_freelook_active() const; - + void _selection_changed(); void _refresh_menu_icons(); // Preview Sun and Environment @@ -861,10 +776,16 @@ public: VSplitContainer *get_shader_split(); HSplitContainer *get_palette_split(); - Node3D *get_selected() { return selected; } + Node3D *get_single_selected_node() { return selected; } + bool is_current_selected_gizmo(const EditorNode3DGizmo *p_gizmo); + bool is_subgizmo_selected(int p_id); + Vector<int> get_subgizmo_selection(); + + Ref<EditorNode3DGizmo> get_current_hover_gizmo() const { return current_hover_gizmo; } + void set_current_hover_gizmo(Ref<EditorNode3DGizmo> p_gizmo) { current_hover_gizmo = p_gizmo; } - int get_over_gizmo_handle() const { return over_gizmo_handle; } - void set_over_gizmo_handle(int idx) { over_gizmo_handle = idx; } + void set_current_hover_gizmo_handle(int p_id) { current_hover_gizmo_handle = p_id; } + int get_current_hover_gizmo_handle() const { return current_hover_gizmo_handle; } void set_can_preview(Camera3D *p_preview); @@ -907,50 +828,4 @@ public: ~Node3DEditorPlugin(); }; -class EditorNode3DGizmoPlugin : public Resource { - GDCLASS(EditorNode3DGizmoPlugin, Resource); - -public: - static const int VISIBLE = 0; - static const int HIDDEN = 1; - static const int ON_TOP = 2; - -protected: - int current_state; - List<EditorNode3DGizmo *> current_gizmos; - HashMap<String, Vector<Ref<StandardMaterial3D>>> materials; - - static void _bind_methods(); - virtual bool has_gizmo(Node3D *p_spatial); - virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial); - -public: - void create_material(const String &p_name, const Color &p_color, bool p_billboard = false, bool p_on_top = false, bool p_use_vertex_color = false); - void create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1)); - void create_handle_material(const String &p_name, bool p_billboard = false, const Ref<Texture2D> &p_texture = nullptr); - void add_material(const String &p_name, Ref<StandardMaterial3D> p_material); - - Ref<StandardMaterial3D> get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo = Ref<EditorNode3DGizmo>()); - - virtual String get_gizmo_name() const; - virtual int get_priority() const; - virtual bool can_be_hidden() const; - virtual bool is_selectable_when_hidden() const; - - virtual void redraw(EditorNode3DGizmo *p_gizmo); - virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const; - virtual Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const; - virtual void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point); - virtual void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); - virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_idx) const; - - Ref<EditorNode3DGizmo> get_gizmo(Node3D *p_spatial); - void set_state(int p_state); - int get_state() const; - void unregister_gizmo(EditorNode3DGizmo *p_gizmo); - - EditorNode3DGizmoPlugin(); - virtual ~EditorNode3DGizmoPlugin(); -}; - #endif // NODE_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 0a95986fe2..63b89aea35 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -36,20 +36,20 @@ #include "node_3d_editor_plugin.h" #include "scene/resources/curve.h" -String Path3DGizmo::get_handle_name(int p_idx) const { +String Path3DGizmo::get_handle_name(int p_id) const { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return ""; } - if (p_idx < c->get_point_count()) { - return TTR("Curve Point #") + itos(p_idx); + if (p_id < c->get_point_count()) { + return TTR("Curve Point #") + itos(p_id); } - p_idx = p_idx - c->get_point_count() + 1; + p_id = p_id - c->get_point_count() + 1; - int idx = p_idx / 2; - int t = p_idx % 2; + int idx = p_id / 2; + int t = p_id % 2; String n = TTR("Curve Point #") + itos(idx); if (t == 0) { n += " In"; @@ -60,21 +60,21 @@ String Path3DGizmo::get_handle_name(int p_idx) const { return n; } -Variant Path3DGizmo::get_handle_value(int p_idx) { +Variant Path3DGizmo::get_handle_value(int p_id) const { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return Variant(); } - if (p_idx < c->get_point_count()) { - original = c->get_point_position(p_idx); + if (p_id < c->get_point_count()) { + original = c->get_point_position(p_id); return original; } - p_idx = p_idx - c->get_point_count() + 1; + p_id = p_id - c->get_point_count() + 1; - int idx = p_idx / 2; - int t = p_idx % 2; + int idx = p_id / 2; + int t = p_id % 2; Vector3 ofs; if (t == 0) { @@ -88,7 +88,7 @@ Variant Path3DGizmo::get_handle_value(int p_idx) { return ofs; } -void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return; @@ -100,7 +100,7 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin Vector3 ray_dir = p_camera->project_ray_normal(p_point); // Setting curve point positions - if (p_idx < c->get_point_count()) { + if (p_id < c->get_point_count()) { Plane p(gt.xform(original), p_camera->get_transform().basis.get_axis(2)); Vector3 inters; @@ -112,16 +112,16 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin } Vector3 local = gi.xform(inters); - c->set_point_position(p_idx, local); + c->set_point_position(p_id, local); } return; } - p_idx = p_idx - c->get_point_count() + 1; + p_id = p_id - c->get_point_count() + 1; - int idx = p_idx / 2; - int t = p_idx % 2; + int idx = p_id / 2; + int t = p_id % 2; Vector3 base = c->get_point_position(idx); @@ -157,7 +157,7 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin } } -void Path3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { +void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) const { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return; @@ -165,27 +165,27 @@ void Path3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_canc UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); - if (p_idx < c->get_point_count()) { + if (p_id < c->get_point_count()) { if (p_cancel) { - c->set_point_position(p_idx, p_restore); + c->set_point_position(p_id, p_restore); return; } ur->create_action(TTR("Set Curve Point Position")); - ur->add_do_method(c.ptr(), "set_point_position", p_idx, c->get_point_position(p_idx)); - ur->add_undo_method(c.ptr(), "set_point_position", p_idx, p_restore); + ur->add_do_method(c.ptr(), "set_point_position", p_id, c->get_point_position(p_id)); + ur->add_undo_method(c.ptr(), "set_point_position", p_id, p_restore); ur->commit_action(); return; } - p_idx = p_idx - c->get_point_count() + 1; + p_id = p_id - c->get_point_count() + 1; - int idx = p_idx / 2; - int t = p_idx % 2; + int idx = p_id / 2; + int t = p_id % 2; if (t == 0) { if (p_cancel) { - c->set_point_in(p_idx, p_restore); + c->set_point_in(p_id, p_restore); return; } @@ -282,7 +282,7 @@ void Path3DGizmo::redraw() { add_handles(handles, handles_material); } if (sec_handles.size()) { - add_handles(sec_handles, sec_handles_material, false, true); + add_handles(sec_handles, sec_handles_material, Vector<int>(), false, true); } } } diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index 13870d7591..5902500526 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -31,7 +31,9 @@ #ifndef PATH_EDITOR_PLUGIN_H #define PATH_EDITOR_PLUGIN_H -#include "editor/node_3d_editor_gizmos.h" +#include "editor/editor_plugin.h" +#include "editor/plugins/node_3d_editor_gizmos.h" +#include "scene/3d/camera_3d.h" #include "scene/3d/path_3d.h" class Path3DGizmo : public EditorNode3DGizmo { @@ -44,9 +46,9 @@ class Path3DGizmo : public EditorNode3DGizmo { public: virtual String get_handle_name(int p_idx) const override; - virtual Variant get_handle_value(int p_idx) override; - virtual void set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false) override; + virtual Variant get_handle_value(int p_id) const override; + virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) const override; virtual void redraw() override; Path3DGizmo(Path3D *p_path = nullptr); diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index e099c8b5fd..cbea2405b8 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -181,21 +181,21 @@ void ResourcePreloaderEditor::_update_library() { preloader->get_resource_list(&rnames); List<String> names; - for (List<StringName>::Element *E = rnames.front(); E; E = E->next()) { - names.push_back(E->get()); + for (const StringName &E : rnames) { + names.push_back(E); } names.sort(); - for (List<String>::Element *E = names.front(); E; E = E->next()) { + for (const String &E : names) { TreeItem *ti = tree->create_item(root); ti->set_cell_mode(0, TreeItem::CELL_MODE_STRING); ti->set_editable(0, true); ti->set_selectable(0, true); - ti->set_text(0, E->get()); - ti->set_metadata(0, E->get()); + ti->set_text(0, E); + ti->set_metadata(0, E); - RES r = preloader->get_resource(E->get()); + RES r = preloader->get_resource(E); ERR_CONTINUE(r.is_null()); diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index cea76f5233..ed91f174d1 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -70,8 +70,8 @@ void EditorPropertyRootMotion::_node_assign() { List<StringName> animations; player->get_animation_list(&animations); - for (List<StringName>::Element *E = animations.front(); E; E = E->next()) { - Ref<Animation> anim = player->get_animation(E->get()); + for (const StringName &E : animations) { + Ref<Animation> anim = player->get_animation(E); for (int i = 0; i < anim->get_track_count(); i++) { paths.insert(anim->track_get_path(i)); } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 1851ffdc34..668a15da37 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -103,8 +103,8 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color type_color = EDITOR_GET("text_editor/highlighting/engine_type_color"); List<StringName> types; ClassDB::get_class_list(&types); - for (List<StringName>::Element *E = types.front(); E; E = E->next()) { - String n = E->get(); + for (const StringName &E : types) { + String n = E; if (n.begins_with("_")) { n = n.substr(1, n.length()); } @@ -115,8 +115,8 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color usertype_color = EDITOR_GET("text_editor/highlighting/user_type_color"); List<StringName> global_classes; ScriptServer::get_global_class_list(&global_classes); - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - highlighter->add_keyword_color(E->get(), usertype_color); + for (const StringName &E : global_classes) { + highlighter->add_keyword_color(E, usertype_color); } /* Autoloads. */ @@ -134,8 +134,8 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color"); List<String> core_types; script->get_language()->get_core_type_words(&core_types); - for (List<String>::Element *E = core_types.front(); E; E = E->next()) { - highlighter->add_keyword_color(E->get(), basetype_color); + for (const String &E : core_types) { + highlighter->add_keyword_color(E, basetype_color); } /* Reserved words. */ @@ -143,11 +143,11 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color control_flow_keyword_color = EDITOR_GET("text_editor/highlighting/control_flow_keyword_color"); List<String> keywords; script->get_language()->get_reserved_words(&keywords); - for (List<String>::Element *E = keywords.front(); E; E = E->next()) { - if (script->get_language()->is_control_flow_keyword(E->get())) { - highlighter->add_keyword_color(E->get(), control_flow_keyword_color); + for (const String &E : keywords) { + if (script->get_language()->is_control_flow_keyword(E)) { + highlighter->add_keyword_color(E, control_flow_keyword_color); } else { - highlighter->add_keyword_color(E->get(), keyword_color); + highlighter->add_keyword_color(E, keyword_color); } } @@ -157,9 +157,9 @@ void EditorStandardSyntaxHighlighter::_update_cache() { if (instance_base != StringName()) { List<PropertyInfo> plist; ClassDB::get_property_list(instance_base, &plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - String name = E->get().name; - if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP) { + for (const PropertyInfo &E : plist) { + String name = E.name; + if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) { continue; } if (name.find("/") != -1) { @@ -170,8 +170,8 @@ void EditorStandardSyntaxHighlighter::_update_cache() { List<String> clist; ClassDB::get_integer_constant_list(instance_base, &clist); - for (List<String>::Element *E = clist.front(); E; E = E->next()) { - highlighter->add_member_keyword_color(E->get(), member_variable_color); + for (const String &E : clist) { + highlighter->add_member_keyword_color(E, member_variable_color); } } @@ -179,8 +179,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color"); List<String> comments; script->get_language()->get_comment_delimiters(&comments); - for (List<String>::Element *E = comments.front(); E; E = E->next()) { - String comment = E->get(); + for (const String &comment : comments) { String beg = comment.get_slice(" ", 0); String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String(); highlighter->add_color_region(beg, end, comment_color, end == ""); @@ -190,8 +189,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color string_color = EDITOR_GET("text_editor/highlighting/string_color"); List<String> strings; script->get_language()->get_string_delimiters(&strings); - for (List<String>::Element *E = strings.front(); E; E = E->next()) { - String string = E->get(); + for (const String &string : strings) { String beg = string.get_slice(" ", 0); String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String(); highlighter->add_color_region(beg, end, string_color, end == ""); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 1a6dfa273e..65459d159d 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -50,9 +50,7 @@ void ConnectionInfoDialog::popup_connections(String p_method, Vector<Node *> p_n List<Connection> all_connections; p_nodes[i]->get_signals_connected_to_this(&all_connections); - for (List<Connection>::Element *E = all_connections.front(); E; E = E->next()) { - Connection connection = E->get(); - + for (const Connection &connection : all_connections) { if (connection.callable.get_method() != p_method) { continue; } @@ -116,8 +114,8 @@ Vector<String> ScriptTextEditor::get_functions() { if (script->get_language()->validate(text, script->get_path(), &fnc)) { //if valid rewrite functions to latest functions.clear(); - for (List<String>::Element *E = fnc.front(); E; E = E->next()) { - functions.push_back(E->get()); + for (const String &E : fnc) { + functions.push_back(E); } } @@ -203,8 +201,7 @@ void ScriptTextEditor::_set_theme_for_script() { List<String> strings; script->get_language()->get_string_delimiters(&strings); text_edit->clear_string_delimiters(); - for (List<String>::Element *E = strings.front(); E; E = E->next()) { - String string = E->get(); + for (const String &string : strings) { String beg = string.get_slice(" ", 0); String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String(); text_edit->add_string_delimiter(beg, end, end == ""); @@ -213,8 +210,7 @@ void ScriptTextEditor::_set_theme_for_script() { List<String> comments; script->get_language()->get_comment_delimiters(&comments); text_edit->clear_comment_delimiters(); - for (List<String>::Element *E = comments.front(); E; E = E->next()) { - String comment = E->get(); + for (const String &comment : comments) { String beg = comment.get_slice(" ", 0); String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String(); text_edit->add_comment_delimiter(beg, end, end == ""); @@ -417,8 +413,8 @@ void ScriptTextEditor::_validate_script() { } functions.clear(); - for (List<String>::Element *E = fnc.front(); E; E = E->next()) { - functions.push_back(E->get()); + for (const String &E : fnc) { + functions.push_back(E); } script_is_valid = true; } @@ -432,9 +428,7 @@ void ScriptTextEditor::_validate_script() { Node *base = get_tree()->get_edited_scene_root(); if (base && missing_connections.size() > 0) { warnings_panel->push_table(1); - for (List<Connection>::Element *E = missing_connections.front(); E; E = E->next()) { - Connection connection = E->get(); - + for (const Connection &connection : missing_connections) { String base_path = base->get_name(); String source_path = base == connection.signal.get_object() ? base_path : base_path + "/" + base->get_path_to(Object::cast_to<Node>(connection.signal.get_object())); String target_path = base == connection.callable.get_object() ? base_path : base_path + "/" + base->get_path_to(Object::cast_to<Node>(connection.callable.get_object())); @@ -456,9 +450,7 @@ void ScriptTextEditor::_validate_script() { // Add script warnings. warnings_panel->push_table(3); - for (List<ScriptLanguage::Warning>::Element *E = warnings.front(); E; E = E->next()) { - ScriptLanguage::Warning w = E->get(); - + for (const ScriptLanguage::Warning &w : warnings) { Dictionary ignore_meta; ignore_meta["line"] = w.start_line; ignore_meta["code"] = w.string_code.to_lower(); @@ -488,9 +480,7 @@ void ScriptTextEditor::_validate_script() { errors_panel->clear(); errors_panel->push_table(2); - for (List<ScriptLanguage::ScriptError>::Element *E = errors.front(); E; E = E->next()) { - ScriptLanguage::ScriptError err = E->get(); - + for (const ScriptLanguage::ScriptError &err : errors) { errors_panel->push_cell(); errors_panel->push_meta(err.line - 1); errors_panel->push_color(warnings_panel->get_theme_color(SNAME("error_color"), SNAME("Editor"))); @@ -511,8 +501,8 @@ void ScriptTextEditor::_validate_script() { if (errors.is_empty()) { te->set_line_background_color(i, Color(0, 0, 0, 0)); } else { - for (List<ScriptLanguage::ScriptError>::Element *E = errors.front(); E; E = E->next()) { - bool error_line = i == E->get().line - 1; + for (const ScriptLanguage::ScriptError &E : errors) { + bool error_line = i == E.line - 1; te->set_line_background_color(i, error_line ? marked_line_color : Color(0, 0, 0, 0)); if (error_line) { break; @@ -910,8 +900,7 @@ void ScriptTextEditor::_update_connected_methods() { List<Connection> connections; nodes[i]->get_signals_connected_to_this(&connections); - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - Connection connection = E->get(); + for (const Connection &connection : connections) { if (!(connection.flags & CONNECT_PERSIST)) { continue; } @@ -1286,8 +1275,7 @@ void ScriptTextEditor::_edit_option_toggle_inline_comment() { List<String> comment_delimiters; script->get_language()->get_comment_delimiters(&comment_delimiters); - for (List<String>::Element *E = comment_delimiters.front(); E; E = E->next()) { - String script_delimiter = E->get(); + for (const String &script_delimiter : comment_delimiters) { if (script_delimiter.find(" ") == -1) { delimiter = script_delimiter; break; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 0d65dec87b..2c45b96106 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -118,11 +118,11 @@ void ShaderTextEditor::_load_theme_settings() { const Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color"); const Color control_flow_keyword_color = EDITOR_GET("text_editor/highlighting/control_flow_keyword_color"); - for (List<String>::Element *E = keywords.front(); E; E = E->next()) { - if (ShaderLanguage::is_control_flow_keyword(E->get())) { - syntax_highlighter->add_keyword_color(E->get(), control_flow_keyword_color); + for (const String &E : keywords) { + if (ShaderLanguage::is_control_flow_keyword(E)) { + syntax_highlighter->add_keyword_color(E, control_flow_keyword_color); } else { - syntax_highlighter->add_keyword_color(E->get(), keyword_color); + syntax_highlighter->add_keyword_color(E, keyword_color); } } @@ -144,8 +144,8 @@ void ShaderTextEditor::_load_theme_settings() { const Color member_variable_color = EDITOR_GET("text_editor/highlighting/member_variable_color"); - for (List<String>::Element *E = built_ins.front(); E; E = E->next()) { - syntax_highlighter->add_keyword_color(E->get(), member_variable_color); + for (const String &E : built_ins) { + syntax_highlighter->add_keyword_color(E, member_variable_color); } // Colorize comments. @@ -770,7 +770,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { disk_changed->add_child(vbc); Label *dl = memnew(Label); - dl->set_text(TTR("This shader has been modified on on disk.\nWhat action should be taken?")); + dl->set_text(TTR("This shader has been modified on disk.\nWhat action should be taken?")); vbc->add_child(dl); disk_changed->connect("confirmed", callable_mp(this, &ShaderEditor::_reload_shader_from_disk)); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 9bb8fbacbb..a5d0ebbc12 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -365,8 +365,8 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_ int count = 0; - for (List<Ref<Texture2D>>::Element *E = resources.front(); E; E = E->next()) { - undo_redo->add_do_method(frames, "add_frame", edited_anim, E->get(), p_at_pos == -1 ? -1 : p_at_pos + count); + for (Ref<Texture2D> &E : resources) { + undo_redo->add_do_method(frames, "add_frame", edited_anim, E, p_at_pos == -1 ? -1 : p_at_pos + count); undo_redo->add_undo_method(frames, "remove_frame", edited_anim, p_at_pos == -1 ? fc : p_at_pos); count++; } @@ -624,10 +624,10 @@ void SpriteFramesEditor::_animation_name_edited() { undo_redo->add_do_method(frames, "rename_animation", edited_anim, name); undo_redo->add_undo_method(frames, "rename_animation", name, edited_anim); - for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) { - String current = E->get()->call("get_animation"); - undo_redo->add_do_method(E->get(), "set_animation", name); - undo_redo->add_undo_method(E->get(), "set_animation", edited_anim); + for (Node *E : nodes) { + String current = E->call("get_animation"); + undo_redo->add_do_method(E, "set_animation", name); + undo_redo->add_undo_method(E, "set_animation", edited_anim); } undo_redo->add_do_method(this, "_update_library"); @@ -655,10 +655,10 @@ void SpriteFramesEditor::_animation_add() { undo_redo->add_do_method(this, "_update_library"); undo_redo->add_undo_method(this, "_update_library"); - for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) { - String current = E->get()->call("get_animation"); - undo_redo->add_do_method(E->get(), "set_animation", name); - undo_redo->add_undo_method(E->get(), "set_animation", current); + for (Node *E : nodes) { + String current = E->call("get_animation"); + undo_redo->add_do_method(E, "set_animation", name); + undo_redo->add_undo_method(E, "set_animation", current); } edited_anim = name; @@ -788,8 +788,8 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) { anim_names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) { - String name = E->get(); + for (const StringName &E : anim_names) { + String name = E; TreeItem *it = animations->create_item(anim_root); @@ -798,7 +798,7 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) { it->set_text(0, name); it->set_editable(0, true); - if (E->get() == edited_anim) { + if (E == edited_anim) { it->select(0); } } diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 4029d6785c..44db06bcfd 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -36,9 +36,30 @@ TextureRect *TexturePreview::get_texture_display() { return texture_display; } +void TexturePreview::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + if (!is_inside_tree()) { + // TODO: This is a workaround because `NOTIFICATION_THEME_CHANGED` + // is getting called for some reason when the `TexturePreview` is + // getting destroyed, which causes `get_theme_font()` to return `nullptr`. + // See https://github.com/godotengine/godot/issues/50743. + break; + } + + if (metadata_label) { + Ref<Font> metadata_label_font = get_theme_font(SNAME("expression"), SNAME("EditorFonts")); + metadata_label->add_theme_font_override("font", metadata_label_font); + } + + checkerboard->set_texture(get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"))); + } break; + } +} + TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) { - TextureRect *checkerboard = memnew(TextureRect); - checkerboard->set_texture(get_theme_icon("Checkerboard", "EditorIcons")); + checkerboard = memnew(TextureRect); checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE); checkerboard->set_texture_repeat(CanvasItem::TEXTURE_REPEAT_ENABLED); checkerboard->set_custom_minimum_size(Size2(0.0, 256.0) * EDSCALE); @@ -52,7 +73,7 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) { add_child(texture_display); if (p_show_metadata) { - Label *metadata_label = memnew(Label); + metadata_label = memnew(Label); String format; if (Object::cast_to<ImageTexture>(*p_texture)) { @@ -65,16 +86,14 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) { metadata_label->set_text(itos(p_texture->get_width()) + "x" + itos(p_texture->get_height()) + " " + format); - metadata_label->add_theme_font_size_override("font_size", 16 * EDSCALE); - metadata_label->add_theme_color_override("font_outline_color", Color::named("black")); - metadata_label->add_theme_constant_override("outline_size", 2 * EDSCALE); - Ref<Font> metadata_label_font = get_theme_font("expression", "EditorFonts"); - metadata_label->add_theme_font_override("font", metadata_label_font); - // It's okay that these colors are static since the grid color is static too. metadata_label->add_theme_color_override("font_color", Color::named("white")); metadata_label->add_theme_color_override("font_color_shadow", Color::named("black")); + metadata_label->add_theme_font_size_override("font_size", 16 * EDSCALE); + metadata_label->add_theme_color_override("font_outline_color", Color::named("black")); + metadata_label->add_theme_constant_override("outline_size", 2 * EDSCALE); + metadata_label->add_theme_constant_override("shadow_as_outline", 1); metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END); metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END); diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index 165090be93..36a5513ea6 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -39,7 +39,13 @@ class TexturePreview : public MarginContainer { GDCLASS(TexturePreview, MarginContainer); private: - TextureRect *texture_display; + TextureRect *texture_display = nullptr; + + TextureRect *checkerboard = nullptr; + Label *metadata_label = nullptr; + +protected: + void _notification(int p_what); public: TextureRect *get_texture_display(); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index e323f1571d..b277f2ab42 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -144,8 +144,7 @@ void TextureRegionEditor::_region_draw() { } } } else if (snap_mode == SNAP_AUTOSLICE) { - for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) { - Rect2 r = E->get(); + for (const Rect2 &r : autoslice_cache) { Vector2 endpoints[4] = { mtx.basis_xform(r.position), mtx.basis_xform(r.position + Vector2(r.size.x, 0)), @@ -328,9 +327,9 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } if (edited_margin < 0 && snap_mode == SNAP_AUTOSLICE) { Vector2 point = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y)); - for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) { - if (E->get().has_point(point)) { - rect = E->get(); + for (const Rect2 &E : autoslice_cache) { + if (E.has_point(point)) { + rect = E; if (Input::get_singleton()->is_key_pressed(KEY_CTRL) && !(Input::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) { Rect2 r; if (node_sprite) { @@ -749,12 +748,12 @@ void TextureRegionEditor::_update_autoslice() { for (int x = 0; x < texture->get_width(); x++) { if (texture->is_pixel_opaque(x, y)) { bool found = false; - for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) { - Rect2 grown = E->get().grow(1.5); + for (Rect2 &E : autoslice_cache) { + Rect2 grown = E.grow(1.5); if (grown.has_point(Point2(x, y))) { - E->get().expand_to(Point2(x, y)); - E->get().expand_to(Point2(x + 1, y + 1)); - x = E->get().position.x + E->get().size.x - 1; + E.expand_to(Point2(x, y)); + E.expand_to(Point2(x + 1, y + 1)); + x = E.position.x + E.size.x - 1; bool merged = true; while (merged) { merged = false; @@ -764,12 +763,12 @@ void TextureRegionEditor::_update_autoslice() { autoslice_cache.erase(F->prev()); queue_erase = false; } - if (F == E) { + if (F->get() == E) { continue; } - if (E->get().grow(1).intersects(F->get())) { - E->get().expand_to(F->get().position); - E->get().expand_to(F->get().position + F->get().size); + if (E.grow(1).intersects(F->get())) { + E.expand_to(F->get().position); + E.expand_to(F->get().position + F->get().size); if (F->prev()) { F = F->prev(); autoslice_cache.erase(F->next()); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 9338ea6ddd..6bd901cead 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -65,8 +65,8 @@ void ThemeItemImportTree::_update_items_tree() { tree_icon_items.clear(); tree_stylebox_items.clear(); - for (List<StringName>::Element *E = types.front(); E; E = E->next()) { - String type_name = (String)E->get(); + for (const StringName &E : types) { + String type_name = (String)E; TreeItem *type_node = import_items_tree->create_item(root); type_node->set_meta("_can_be_imported", false); @@ -89,12 +89,12 @@ void ThemeItemImportTree::_update_items_tree() { names.clear(); filtered_names.clear(); - base_theme->get_theme_item_list(dt, E->get(), &names); + base_theme->get_theme_item_list(dt, E, &names); bool data_type_has_filtered_items = false; - for (List<StringName>::Element *F = names.front(); F; F = F->next()) { - String item_name = (String)F->get(); + for (const StringName &F : names) { + String item_name = (String)F; bool is_item_matching_filter = (item_name.findn(filter_text) > -1); if (!filter_text.is_empty() && !is_matching_filter && !is_item_matching_filter) { continue; @@ -105,7 +105,7 @@ void ThemeItemImportTree::_update_items_tree() { has_filtered_items = true; data_type_has_filtered_items = true; } - filtered_names.push_back(F->get()); + filtered_names.push_back(F); } if (filtered_names.size() == 0) { @@ -182,10 +182,10 @@ void ThemeItemImportTree::_update_items_tree() { bool data_type_any_checked_with_data = false; filtered_names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = filtered_names.front(); F; F = F->next()) { + for (const StringName &F : filtered_names) { TreeItem *item_node = import_items_tree->create_item(data_type_node); item_node->set_meta("_can_be_imported", true); - item_node->set_text(0, F->get()); + item_node->set_text(0, F); item_node->set_cell_mode(IMPORT_ITEM, TreeItem::CELL_MODE_CHECK); item_node->set_checked(IMPORT_ITEM, false); item_node->set_editable(IMPORT_ITEM, true); @@ -754,7 +754,7 @@ void ThemeItemImportTree::_import_selected() { return; } - // Prevent changes from immediatelly being reported while the operation is still ongoing. + // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); ProgressDialog::get_singleton()->add_task("import_theme_items", TTR("Importing Theme Items"), selected_items.size() + 2); @@ -1236,16 +1236,16 @@ void ThemeItemEditorDialog::_update_edit_types() { bool item_reselected = false; edit_type_list->clear(); int e_idx = 0; - for (List<StringName>::Element *E = theme_types.front(); E; E = E->next()) { + for (const StringName &E : theme_types) { Ref<Texture2D> item_icon; - if (E->get() == "") { + if (E == "") { item_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons")); } else { - item_icon = EditorNode::get_singleton()->get_class_icon(E->get(), "NodeDisabled"); + item_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled"); } - edit_type_list->add_item(E->get(), item_icon); + edit_type_list->add_item(E, item_icon); - if (E->get() == edited_item_type) { + if (E == edited_item_type) { edit_type_list->select(e_idx); item_reselected = true; } @@ -1318,9 +1318,9 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) { color_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Color Items")); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { TreeItem *item = edit_items_tree->create_item(color_root); - item->set_text(0, E->get()); + item->set_text(0, E); item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item")); item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item")); } @@ -1339,9 +1339,9 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) { constant_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Constant Items")); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { TreeItem *item = edit_items_tree->create_item(constant_root); - item->set_text(0, E->get()); + item->set_text(0, E); item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item")); item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item")); } @@ -1360,9 +1360,9 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) { font_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Font Items")); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { TreeItem *item = edit_items_tree->create_item(font_root); - item->set_text(0, E->get()); + item->set_text(0, E); item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item")); item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item")); } @@ -1381,9 +1381,9 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) { font_size_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Font Size Items")); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { TreeItem *item = edit_items_tree->create_item(font_size_root); - item->set_text(0, E->get()); + item->set_text(0, E); item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item")); item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item")); } @@ -1402,9 +1402,9 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) { icon_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Icon Items")); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { TreeItem *item = edit_items_tree->create_item(icon_root); - item->set_text(0, E->get()); + item->set_text(0, E); item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item")); item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item")); } @@ -1423,9 +1423,9 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) { stylebox_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All StyleBox Items")); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { TreeItem *item = edit_items_tree->create_item(stylebox_root); - item->set_text(0, E->get()); + item->set_text(0, E); item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item")); item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item")); } @@ -1503,12 +1503,12 @@ void ThemeItemEditorDialog::_add_theme_item(Theme::DataType p_data_type, String void ThemeItemEditorDialog::_remove_data_type_items(Theme::DataType p_data_type, String p_item_type) { List<StringName> names; - // Prevent changes from immediatelly being reported while the operation is still ongoing. + // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); edited_theme->get_theme_item_list(p_data_type, p_item_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - edited_theme->clear_theme_item(p_data_type, E->get(), p_item_type); + for (const StringName &E : names) { + edited_theme->clear_theme_item(p_data_type, E, p_item_type); } // Allow changes to be reported now that the operation is finished. @@ -1518,7 +1518,7 @@ void ThemeItemEditorDialog::_remove_data_type_items(Theme::DataType p_data_type, void ThemeItemEditorDialog::_remove_class_items() { List<StringName> names; - // Prevent changes from immediatelly being reported while the operation is still ongoing. + // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); for (int dt = 0; dt < Theme::DATA_TYPE_MAX; dt++) { @@ -1526,9 +1526,9 @@ void ThemeItemEditorDialog::_remove_class_items() { names.clear(); Theme::get_default()->get_theme_item_list(data_type, edited_item_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (edited_theme->has_theme_item_nocheck(data_type, E->get(), edited_item_type)) { - edited_theme->clear_theme_item(data_type, E->get(), edited_item_type); + for (const StringName &E : names) { + if (edited_theme->has_theme_item_nocheck(data_type, E, edited_item_type)) { + edited_theme->clear_theme_item(data_type, E, edited_item_type); } } } @@ -1542,7 +1542,7 @@ void ThemeItemEditorDialog::_remove_class_items() { void ThemeItemEditorDialog::_remove_custom_items() { List<StringName> names; - // Prevent changes from immediatelly being reported while the operation is still ongoing. + // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); for (int dt = 0; dt < Theme::DATA_TYPE_MAX; dt++) { @@ -1550,9 +1550,9 @@ void ThemeItemEditorDialog::_remove_custom_items() { names.clear(); edited_theme->get_theme_item_list(data_type, edited_item_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (!Theme::get_default()->has_theme_item_nocheck(data_type, E->get(), edited_item_type)) { - edited_theme->clear_theme_item(data_type, E->get(), edited_item_type); + for (const StringName &E : names) { + if (!Theme::get_default()->has_theme_item_nocheck(data_type, E, edited_item_type)) { + edited_theme->clear_theme_item(data_type, E, edited_item_type); } } } @@ -1566,7 +1566,7 @@ void ThemeItemEditorDialog::_remove_custom_items() { void ThemeItemEditorDialog::_remove_all_items() { List<StringName> names; - // Prevent changes from immediatelly being reported while the operation is still ongoing. + // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); for (int dt = 0; dt < Theme::DATA_TYPE_MAX; dt++) { @@ -1574,8 +1574,8 @@ void ThemeItemEditorDialog::_remove_all_items() { names.clear(); edited_theme->get_theme_item_list(data_type, edited_item_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - edited_theme->clear_theme_item(data_type, E->get(), edited_item_type); + for (const StringName &E : names) { + edited_theme->clear_theme_item(data_type, E, edited_item_type); } } @@ -1927,8 +1927,8 @@ ThemeItemEditorDialog::ThemeItemEditorDialog() { import_another_theme_dialog->set_title(TTR("Select Another Theme Resource:")); List<String> ext; ResourceLoader::get_recognized_extensions_for_type("Theme", &ext); - for (List<String>::Element *E = ext.front(); E; E = E->next()) { - import_another_theme_dialog->add_filter("*." + E->get() + "; Theme Resource"); + for (const String &E : ext) { + import_another_theme_dialog->add_filter("*." + E + "; Theme Resource"); } import_another_file_hb->add_child(import_another_theme_dialog); import_another_theme_dialog->connect("file_selected", callable_mp(this, &ThemeItemEditorDialog::_select_another_theme_cbk)); @@ -1969,26 +1969,26 @@ void ThemeTypeDialog::_update_add_type_options(const String &p_filter) { names.sort_custom<StringName::AlphCompare>(); Vector<StringName> unique_names; - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { // Filter out undesired values. - if (!p_filter.is_subsequence_ofi(String(E->get()))) { + if (!p_filter.is_subsequence_ofi(String(E))) { continue; } // Skip duplicate values. - if (unique_names.has(E->get())) { + if (unique_names.has(E)) { continue; } - unique_names.append(E->get()); + unique_names.append(E); Ref<Texture2D> item_icon; - if (E->get() == "") { + if (E == "") { item_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons")); } else { - item_icon = EditorNode::get_singleton()->get_class_icon(E->get(), "NodeDisabled"); + item_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled"); } - add_type_options->add_item(E->get(), item_icon); + add_type_options->add_item(E, item_icon); } } @@ -2132,16 +2132,16 @@ void ThemeTypeEditor::_update_type_list() { bool item_reselected = false; int e_idx = 0; - for (List<StringName>::Element *E = theme_types.front(); E; E = E->next()) { + for (const StringName &E : theme_types) { Ref<Texture2D> item_icon; - if (E->get() == "") { + if (E == "") { item_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons")); } else { - item_icon = EditorNode::get_singleton()->get_class_icon(E->get(), "NodeDisabled"); + item_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled"); } - theme_type_list->add_icon_item(item_icon, E->get()); + theme_type_list->add_icon_item(item_icon, E); - if (E->get() == edited_type) { + if (E == edited_type) { theme_type_list->select(e_idx); item_reselected = true; } @@ -2182,8 +2182,8 @@ OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_ (Theme::get_default().operator->()->*get_list_func)(default_type, &names); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - items[E->get()] = false; + for (const StringName &E : names) { + items[E] = false; } } @@ -2191,8 +2191,8 @@ OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_ names.clear(); (edited_theme.operator->()->*get_list_func)(p_type_name, &names); names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - items[E->get()] = true; + for (const StringName &E : names) { + items[E] = true; } } @@ -2203,8 +2203,8 @@ OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_ keys.sort_custom<StringName::AlphCompare>(); OrderedHashMap<StringName, bool> ordered_items; - for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { - ordered_items[E->get()] = items[E->get()]; + for (const StringName &E : keys) { + ordered_items[E] = items[E]; } return ordered_items; @@ -2574,60 +2574,60 @@ void ThemeTypeEditor::_add_default_type_items() { } updating = true; - // Prevent changes from immediatelly being reported while the operation is still ongoing. + // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); { names.clear(); Theme::get_default()->get_icon_list(default_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (!edited_theme->has_icon(E->get(), edited_type)) { - edited_theme->set_icon(E->get(), edited_type, Ref<Texture2D>()); + for (const StringName &E : names) { + if (!edited_theme->has_icon(E, edited_type)) { + edited_theme->set_icon(E, edited_type, Ref<Texture2D>()); } } } { names.clear(); Theme::get_default()->get_stylebox_list(default_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (!edited_theme->has_stylebox(E->get(), edited_type)) { - edited_theme->set_stylebox(E->get(), edited_type, Ref<StyleBox>()); + for (const StringName &E : names) { + if (!edited_theme->has_stylebox(E, edited_type)) { + edited_theme->set_stylebox(E, edited_type, Ref<StyleBox>()); } } } { names.clear(); Theme::get_default()->get_font_list(default_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (!edited_theme->has_font(E->get(), edited_type)) { - edited_theme->set_font(E->get(), edited_type, Ref<Font>()); + for (const StringName &E : names) { + if (!edited_theme->has_font(E, edited_type)) { + edited_theme->set_font(E, edited_type, Ref<Font>()); } } } { names.clear(); Theme::get_default()->get_font_size_list(default_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (!edited_theme->has_font_size(E->get(), edited_type)) { - edited_theme->set_font_size(E->get(), edited_type, Theme::get_default()->get_font_size(E->get(), default_type)); + for (const StringName &E : names) { + if (!edited_theme->has_font_size(E, edited_type)) { + edited_theme->set_font_size(E, edited_type, Theme::get_default()->get_font_size(E, default_type)); } } } { names.clear(); Theme::get_default()->get_color_list(default_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (!edited_theme->has_color(E->get(), edited_type)) { - edited_theme->set_color(E->get(), edited_type, Theme::get_default()->get_color(E->get(), default_type)); + for (const StringName &E : names) { + if (!edited_theme->has_color(E, edited_type)) { + edited_theme->set_color(E, edited_type, Theme::get_default()->get_color(E, default_type)); } } } { names.clear(); Theme::get_default()->get_constant_list(default_type, &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (!edited_theme->has_constant(E->get(), edited_type)) { - edited_theme->set_constant(E->get(), edited_type, Theme::get_default()->get_constant(E->get(), default_type)); + for (const StringName &E : names) { + if (!edited_theme->has_constant(E, edited_type)) { + edited_theme->set_constant(E, edited_type, Theme::get_default()->get_constant(E, default_type)); } } } @@ -2876,18 +2876,18 @@ void ThemeTypeEditor::_update_stylebox_from_leading() { return; } - // Prevent changes from immediatelly being reported while the operation is still ongoing. + // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); List<StringName> names; edited_theme->get_stylebox_list(edited_type, &names); List<Ref<StyleBox>> styleboxes; - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (E->get() == leading_stylebox.item_name) { + for (const StringName &E : names) { + if (E == leading_stylebox.item_name) { continue; } - Ref<StyleBox> sb = edited_theme->get_stylebox(E->get(), edited_type); + Ref<StyleBox> sb = edited_theme->get_stylebox(E, edited_type); if (sb->get_class() == leading_stylebox.stylebox->get_class()) { styleboxes.push_back(sb); } @@ -2895,20 +2895,20 @@ void ThemeTypeEditor::_update_stylebox_from_leading() { List<PropertyInfo> props; leading_stylebox.stylebox->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant value = leading_stylebox.stylebox->get(E->get().name); - Variant ref_value = leading_stylebox.ref_stylebox->get(E->get().name); + Variant value = leading_stylebox.stylebox->get(E.name); + Variant ref_value = leading_stylebox.ref_stylebox->get(E.name); if (value == ref_value) { continue; } - for (List<Ref<StyleBox>>::Element *F = styleboxes.front(); F; F = F->next()) { - Ref<StyleBox> sb = F->get(); - sb->set(E->get().name, value); + for (Ref<StyleBox> F : styleboxes) { + Ref<StyleBox> sb = F; + sb->set(E.name, value); } } @@ -3301,8 +3301,8 @@ ThemeEditor::ThemeEditor() { preview_scene_dialog->set_title(TTR("Select UI Scene:")); List<String> ext; ResourceLoader::get_recognized_extensions_for_type("PackedScene", &ext); - for (List<String>::Element *E = ext.front(); E; E = E->next()) { - preview_scene_dialog->add_filter("*." + E->get() + "; Scene"); + for (const String &E : ext) { + preview_scene_dialog->add_filter("*." + E + "; Scene"); } main_hs->add_child(preview_scene_dialog); preview_scene_dialog->connect("file_selected", callable_mp(this, &ThemeEditor::_preview_scene_dialog_cbk)); @@ -3343,12 +3343,12 @@ bool ThemeEditorPlugin::handles(Object *p_node) const { List<StringName> names; edited_theme->get_font_type_list(&types); - for (List<StringName>::Element *E = types.front(); E; E = E->next()) { + for (const StringName &E : types) { names.clear(); - edited_theme->get_font_list(E->get(), &names); + edited_theme->get_font_list(E, &names); - for (List<StringName>::Element *F = names.front(); F; F = F->next()) { - if (font_item == edited_theme->get_font(F->get(), E->get())) { + for (const StringName &F : names) { + if (font_item == edited_theme->get_font(F, E)) { belongs_to_theme = true; break; } @@ -3360,12 +3360,12 @@ bool ThemeEditorPlugin::handles(Object *p_node) const { List<StringName> names; edited_theme->get_stylebox_type_list(&types); - for (List<StringName>::Element *E = types.front(); E; E = E->next()) { + for (const StringName &E : types) { names.clear(); - edited_theme->get_stylebox_list(E->get(), &names); + edited_theme->get_stylebox_list(E, &names); - for (List<StringName>::Element *F = names.front(); F; F = F->next()) { - if (stylebox_item == edited_theme->get_stylebox(F->get(), E->get())) { + for (const StringName &F : names) { + if (stylebox_item == edited_theme->get_stylebox(F, E)) { belongs_to_theme = true; break; } @@ -3377,12 +3377,12 @@ bool ThemeEditorPlugin::handles(Object *p_node) const { List<StringName> names; edited_theme->get_icon_type_list(&types); - for (List<StringName>::Element *E = types.front(); E; E = E->next()) { + for (const StringName &E : types) { names.clear(); - edited_theme->get_icon_list(E->get(), &names); + edited_theme->get_icon_list(E, &names); - for (List<StringName>::Element *F = names.front(); F; F = F->next()) { - if (icon_item == edited_theme->get_icon(F->get(), E->get())) { + for (const StringName &F : names) { + if (icon_item == edited_theme->get_icon(F, E)) { belongs_to_theme = true; break; } diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index dd2922286f..bab55df65a 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -1244,7 +1244,7 @@ void TileDataCollisionEditor::_polygons_changed() { } } - // Remove uneeded properties and their editors. + // Remove unneeded properties and their editors. for (int i = polygon_editor->get_polygon_count(); dummy_object->has_dummy_property(vformat("polygon_%d_one_way", i)); i++) { dummy_object->remove_dummy_property(vformat("polygon_%d_one_way", i)); } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 44822bec3a..4a4e81dae3 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -1210,9 +1210,6 @@ void TileMapEditorTilesPlugin::_stop_dragging() { case DRAG_TYPE_BUCKET: { undo_redo->create_action(TTR("Paint tiles")); for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) { - if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) { - continue; - } undo_redo->add_do_method(tile_map, "set_cell", E->key(), tile_map->get_cell_source_id(E->key()), tile_map->get_cell_atlas_coords(E->key()), tile_map->get_cell_alternative_tile(E->key())); undo_redo->add_undo_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); } diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index de910dfd32..432f48fa85 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -303,9 +303,9 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro } // Add only properties that are common to all tiles. - for (List<PLData *>::Element *E = data_list.front(); E; E = E->next()) { - if (E->get()->uses == tiles.size()) { - p_list->push_back(E->get()->property_info); + for (const PLData *E : data_list) { + if (E->uses == tiles.size()) { + p_list->push_back(E->property_info); } } } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index f49279aa33..46818afe45 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -666,8 +666,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (valid_left) { name_left = vsnode->get_input_port_name(i); port_left = vsnode->get_input_port_type(i); - for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { - if (E->get().to_node == p_id && E->get().to_port == j) { + for (const VisualShader::Connection &E : connections) { + if (E.to_node == p_id && E.to_port == j) { port_left_used = true; } } @@ -899,11 +899,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { expression_box->set_syntax_highlighter(expression_syntax_highlighter); expression_box->add_theme_color_override("background_color", background_color); - for (List<String>::Element *E = VisualShaderEditor::get_singleton()->keyword_list.front(); E; E = E->next()) { - if (ShaderLanguage::is_control_flow_keyword(E->get())) { - expression_syntax_highlighter->add_keyword_color(E->get(), control_flow_keyword_color); + for (const String &E : VisualShaderEditor::get_singleton()->keyword_list) { + if (ShaderLanguage::is_control_flow_keyword(E)) { + expression_syntax_highlighter->add_keyword_color(E, control_flow_keyword_color); } else { - expression_syntax_highlighter->add_keyword_color(E->get(), keyword_color); + expression_syntax_highlighter->add_keyword_color(E, keyword_color); } } @@ -961,7 +961,7 @@ void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_fro void VisualShaderGraphPlugin::disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { if (visual_shader->get_shader_type() == p_type) { VisualShaderEditor::get_singleton()->graph->disconnect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port); - for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { + for (const List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { connections.erase(E); break; @@ -1470,11 +1470,11 @@ void VisualShaderEditor::_update_graph() { graph_plugin->make_dirty(false); - for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { - int from = E->get().from_node; - int from_idx = E->get().from_port; - int to = E->get().to_node; - int to_idx = E->get().to_port; + for (const VisualShader::Connection &E : connections) { + int from = E.from_node; + int from_idx = E.from_port; + int to = E.to_node; + int to_idx = E.to_port; graph->connect_node(itos(from), from_idx, itos(to), to_idx); } @@ -1634,11 +1634,11 @@ void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expa List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - int from_node = E->get().from_node; - int from_port = E->get().from_port; - int to_node = E->get().to_node; - int to_port = E->get().to_port; + for (const VisualShader::Connection &E : conns) { + int from_node = E.from_node; + int from_port = E.from_port; + int to_node = E.to_node; + int to_port = E.to_port; if (from_node == p_node) { if (p_expand) { @@ -1708,11 +1708,11 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) { List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - int from_node = E->get().from_node; - int from_port = E->get().from_port; - int to_node = E->get().to_node; - int to_port = E->get().to_port; + for (const VisualShader::Connection &E : conns) { + int from_node = E.from_node; + int from_port = E.from_port; + int to_node = E.to_node; + int to_port = E.to_port; if (to_node == p_node) { if (to_port == p_port) { @@ -1757,11 +1757,11 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) { List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - int from_node = E->get().from_node; - int from_port = E->get().from_port; - int to_node = E->get().to_node; - int to_port = E->get().to_port; + for (const VisualShader::Connection &E : conns) { + int from_node = E.from_node; + int from_port = E.from_port; + int to_node = E.to_node; + int to_port = E.to_port; if (from_node == p_node) { if (from_port == p_port) { @@ -2518,11 +2518,11 @@ void VisualShaderEditor::_nodes_dragged() { undo_redo->create_action(TTR("Node(s) Moved")); - for (List<DragOp>::Element *E = drag_buffer.front(); E; E = E->next()) { - undo_redo->add_do_method(visual_shader.ptr(), "set_node_position", E->get().type, E->get().node, E->get().to); - undo_redo->add_undo_method(visual_shader.ptr(), "set_node_position", E->get().type, E->get().node, E->get().from); - undo_redo->add_do_method(graph_plugin.ptr(), "set_node_position", E->get().type, E->get().node, E->get().to); - undo_redo->add_undo_method(graph_plugin.ptr(), "set_node_position", E->get().type, E->get().node, E->get().from); + for (const DragOp &E : drag_buffer) { + undo_redo->add_do_method(visual_shader.ptr(), "set_node_position", E.type, E.node, E.to); + undo_redo->add_undo_method(visual_shader.ptr(), "set_node_position", E.type, E.node, E.from); + undo_redo->add_do_method(graph_plugin.ptr(), "set_node_position", E.type, E.node, E.to); + undo_redo->add_undo_method(graph_plugin.ptr(), "set_node_position", E.type, E.node, E.from); } drag_buffer.clear(); @@ -2544,12 +2544,12 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().to_node == to && E->get().to_port == p_to_index) { - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + for (const VisualShader::Connection &E : conns) { + if (E.to_node == to && E.to_port == p_to_index) { + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } @@ -2597,22 +2597,22 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == F->get() || E->get().to_node == F->get()) { - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + for (const int &F : p_nodes) { + for (const VisualShader::Connection &E : conns) { + if (E.from_node == F || E.to_node == F) { + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } } Set<String> uniform_names; - for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { - Ref<VisualShaderNode> node = visual_shader->get_node(type, F->get()); + for (const int &F : p_nodes) { + Ref<VisualShaderNode> node = visual_shader->get_node(type, F); - undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, F->get()); - undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, F->get()), F->get()); - undo_redo->add_undo_method(graph_plugin.ptr(), "add_node", type, F->get()); + undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, F); + undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, F), F); + undo_redo->add_undo_method(graph_plugin.ptr(), "add_node", type, F); undo_redo->add_do_method(this, "_clear_buffer"); undo_redo->add_undo_method(this, "_clear_buffer"); @@ -2638,28 +2638,28 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { } List<VisualShader::Connection> used_conns; - for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == F->get() || E->get().to_node == F->get()) { + for (const int &F : p_nodes) { + for (const VisualShader::Connection &E : conns) { + if (E.from_node == F || E.to_node == F) { bool cancel = false; for (List<VisualShader::Connection>::Element *R = used_conns.front(); R; R = R->next()) { - if (R->get().from_node == E->get().from_node && R->get().from_port == E->get().from_port && R->get().to_node == E->get().to_node && R->get().to_port == E->get().to_port) { + if (R->get().from_node == E.from_node && R->get().from_port == E.from_port && R->get().to_node == E.to_node && R->get().to_port == E.to_port) { cancel = true; // to avoid ERR_ALREADY_EXISTS warning break; } } if (!cancel) { - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - used_conns.push_back(E->get()); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + used_conns.push_back(E); } } } } // delete nodes from the graph - for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { - undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F->get()); + for (const int &F : p_nodes) { + undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F); } // update uniform refs if any uniform has been deleted @@ -3094,11 +3094,11 @@ void VisualShaderEditor::_notification(int p_what) { preview_text->add_theme_color_override("background_color", background_color); - for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) { - if (ShaderLanguage::is_control_flow_keyword(E->get())) { - syntax_highlighter->add_keyword_color(E->get(), control_flow_keyword_color); + for (const String &E : keyword_list) { + if (ShaderLanguage::is_control_flow_keyword(E)) { + syntax_highlighter->add_keyword_color(E, control_flow_keyword_color); } else { - syntax_highlighter->add_keyword_color(E->get(), keyword_color); + syntax_highlighter->add_keyword_color(E, keyword_color); } } @@ -3206,9 +3206,9 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in Map<int, int> connection_remap; Set<int> unsupported_set; - for (List<int>::Element *E = r_nodes.front(); E; E = E->next()) { - connection_remap[E->get()] = id_from; - Ref<VisualShaderNode> node = visual_shader->get_node(pasted_type, E->get()); + for (int &E : r_nodes) { + connection_remap[E] = id_from; + Ref<VisualShaderNode> node = visual_shader->get_node(pasted_type, E); bool unsupported = false; for (int i = 0; i < add_options.size(); i++) { @@ -3220,13 +3220,13 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in } } if (unsupported) { - unsupported_set.insert(E->get()); + unsupported_set.insert(E); continue; } Ref<VisualShaderNode> dupli = node->duplicate(); - undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(pasted_type, E->get()) + p_offset, id_from); + undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(pasted_type, E) + p_offset, id_from); undo_redo->add_do_method(graph_plugin.ptr(), "add_node", type, id_from); // duplicate size, inputs and outputs if node is group @@ -3249,19 +3249,19 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in List<VisualShader::Connection> conns; visual_shader->get_node_connections(pasted_type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (unsupported_set.has(E->get().from_node) || unsupported_set.has(E->get().to_node)) { + for (const VisualShader::Connection &E : conns) { + if (unsupported_set.has(E.from_node) || unsupported_set.has(E.to_node)) { continue; } - if (connection_remap.has(E->get().from_node) && connection_remap.has(E->get().to_node)) { - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port); + if (connection_remap.has(E.from_node) && connection_remap.has(E.to_node)) { + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, connection_remap[E.from_node], E.from_port, connection_remap[E.to_node], E.to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, connection_remap[E.from_node], E.from_port, connection_remap[E.to_node], E.to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, connection_remap[E.from_node], E.from_port, connection_remap[E.to_node], E.to_port); } } id_from = base_id; - for (List<int>::Element *E = r_nodes.front(); E; E = E->next()) { + for (int i = 0; i < r_nodes.size(); i++) { undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from); undo_redo->add_undo_method(graph_plugin.ptr(), "remove_node", type, id_from); id_from++; @@ -3399,17 +3399,17 @@ void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, if (type_changed) { List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == id) { - if (visual_shader->is_port_types_compatible(p_input->get_input_type_by_name(p_name), visual_shader->get_node(type, E->get().to_node)->get_input_port_type(E->get().to_port))) { - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + for (const VisualShader::Connection &E : conns) { + if (E.from_node == id) { + if (visual_shader->is_port_types_compatible(p_input->get_input_type_by_name(p_name), visual_shader->get_node(type, E.to_node)->get_input_port_type(E.to_port))) { + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); continue; } - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } } @@ -3445,15 +3445,15 @@ void VisualShaderEditor::_uniform_select_item(Ref<VisualShaderNodeUniformRef> p_ if (type_changed) { List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == id) { - if (visual_shader->is_port_types_compatible(p_uniform_ref->get_uniform_type_by_name(p_name), visual_shader->get_node(type, E->get().to_node)->get_input_port_type(E->get().to_port))) { + for (const VisualShader::Connection &E : conns) { + if (E.from_node == id) { + if (visual_shader->is_port_types_compatible(p_uniform_ref->get_uniform_type_by_name(p_name), visual_shader->get_node(type, E.to_node)->get_input_port_type(E.to_port))) { continue; } - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } } @@ -4825,10 +4825,10 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par Vector<PropertyInfo> pinfo; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + for (const PropertyInfo &E : props) { for (int i = 0; i < properties.size(); i++) { - if (E->get().name == String(properties[i])) { - pinfo.push_back(E->get()); + if (E.name == String(properties[i])) { + pinfo.push_back(E); } } } @@ -4894,9 +4894,9 @@ void EditorPropertyShaderMode::_option_selected(int p_which) { VisualShader::Type type = VisualShader::Type(i); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().to_node == VisualShader::NODE_ID_OUTPUT) { - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + for (const VisualShader::Connection &E : conns) { + if (E.to_node == VisualShader::NODE_ID_OUTPUT) { + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } } @@ -4918,9 +4918,9 @@ void EditorPropertyShaderMode::_option_selected(int p_which) { List<PropertyInfo> props; visual_shader->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().name.begins_with("flags/") || E->get().name.begins_with("modes/")) { - undo_redo->add_undo_property(visual_shader.ptr(), E->get().name, visual_shader->get(E->get().name)); + for (const PropertyInfo &E : props) { + if (E.name.begins_with("flags/") || E.name.begins_with("modes/")) { + undo_redo->add_undo_property(visual_shader.ptr(), E.name, visual_shader->get(E.name)); } } @@ -5024,8 +5024,8 @@ void VisualShaderNodePortPreview::_shader_changed() { if (src_mat && src_mat->get_shader().is_valid()) { List<PropertyInfo> params; src_mat->get_shader()->get_param_list(¶ms); - for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) { - material->set(E->get().name, src_mat->get(E->get().name)); + for (const PropertyInfo &E : params) { + material->set(E.name, src_mat->get(E.name)); } } } diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 1e818b9d43..fcb714bdf7 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -340,8 +340,8 @@ void ProjectExportDialog::_update_feature_list() { } } - for (List<String>::Element *E = features.front(); E; E = E->next()) { - fset.insert(E->get()); + for (const String &E : features) { + fset.insert(E); } custom_feature_display->clear(); @@ -567,8 +567,8 @@ void ProjectExportDialog::_duplicate_preset() { preset->set_exclude_filter(current->get_exclude_filter()); preset->set_custom_features(current->get_custom_features()); - for (const List<PropertyInfo>::Element *E = current->get_properties().front(); E; E = E->next()) { - preset->set(E->get().name, current->get(E->get().name)); + for (const PropertyInfo &E : current->get_properties()) { + preset->set(E.name, current->get(E.name)); } EditorExport::get_singleton()->add_export_preset(preset); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 46a1253ca0..fd4f22425f 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -494,13 +494,13 @@ private: if (!f) { set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR); } else { - f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]"); + f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=3]"); f->store_line(""); - f->store_line("[sub_resource type=\"Sky\" id=1]"); + f->store_line("[sub_resource type=\"Sky\" id=\"1\"]"); f->store_line(""); f->store_line("[resource]"); f->store_line("background_mode = 2"); - f->store_line("sky = SubResource( 1 )"); + f->store_line("sky = SubResource( \"1\" )"); memdelete(f); } } @@ -1238,16 +1238,16 @@ void ProjectList::load_projects() { Set<String> favorites; // Find favourites... - for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - String property_key = E->get().name; + for (const PropertyInfo &E : properties) { + String property_key = E.name; if (property_key.begins_with("favorite_projects/")) { favorites.insert(property_key); } } - for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { + for (const PropertyInfo &E : properties) { // This is actually something like "projects/C:::Documents::Godot::Projects::MyGame" - String property_key = E->get().name; + String property_key = E.name; if (!property_key.begins_with("projects/")) { continue; } @@ -1582,8 +1582,8 @@ int ProjectList::refresh_project(const String &dir_path) { String favorite_property_key = "favorite_projects/" + project_key; bool found = false; - for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - String prop = E->get().name; + for (const PropertyInfo &E : properties) { + String prop = E.name; if (!found && prop == property_key) { found = true; } else if (!is_favourite && prop == favorite_property_key) { @@ -2188,9 +2188,9 @@ void ProjectManager::_scan_begin(const String &p_base) { _scan_dir(p_base, &projects); print_line("Found " + itos(projects.size()) + " projects."); - for (List<String>::Element *E = projects.front(); E; E = E->next()) { - String proj = get_project_key_from_path(E->get()); - EditorSettings::get_singleton()->set("projects/" + proj, E->get()); + for (const String &E : projects) { + String proj = get_project_key_from_path(E); + EditorSettings::get_singleton()->set("projects/" + proj, E); } EditorSettings::get_singleton()->save(); _load_recent_projects(); @@ -2625,8 +2625,7 @@ ProjectManager::ProjectManager() { Vector<String> editor_languages; List<PropertyInfo> editor_settings_properties; EditorSettings::get_singleton()->get_property_list(&editor_settings_properties); - for (List<PropertyInfo>::Element *E = editor_settings_properties.front(); E; E = E->next()) { - PropertyInfo &pi = E->get(); + for (const PropertyInfo &pi : editor_settings_properties) { if (pi.name == "interface/editor/editor_language") { editor_languages = pi.hint_string.split(","); break; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 2c4b28e13d..b8ccab78dd 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -229,16 +229,16 @@ void ProjectSettingsEditor::_add_feature_overrides() { for (int i = 0; i < ee->get_export_platform_count(); i++) { List<String> p; ee->get_export_platform(i)->get_platform_features(&p); - for (List<String>::Element *E = p.front(); E; E = E->next()) { - presets.insert(E->get()); + for (const String &E : p) { + presets.insert(E); } } for (int i = 0; i < ee->get_export_preset_count(); i++) { List<String> p; ee->get_export_preset(i)->get_platform()->get_preset_features(ee->get_export_preset(i), &p); - for (List<String>::Element *E = p.front(); E; E = E->next()) { - presets.insert(E->get()); + for (const String &E : p) { + presets.insert(E); } String custom = ee->get_export_preset(i)->get_custom_features(); @@ -391,8 +391,7 @@ void ProjectSettingsEditor::_action_reordered(const String &p_action_name, const undo_redo->create_action(TTR("Update Input Action Order")); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - PropertyInfo prop = E->get(); + for (const PropertyInfo &prop : props) { // Skip builtins and non-inputs if (ProjectSettings::get_singleton()->is_builtin_setting(prop.name) || !prop.name.begins_with("input/")) { continue; @@ -445,8 +444,8 @@ void ProjectSettingsEditor::_update_action_map_editor() { ProjectSettings::get_singleton()->get_property_list(&props); const Ref<Texture2D> builtin_icon = get_theme_icon(SNAME("PinPressed"), SNAME("EditorIcons")); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - const String property_name = E->get().name; + for (const PropertyInfo &E : props) { + const String property_name = E.name; if (!property_name.begins_with("input/")) { continue; diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index db8334b485..7338588d56 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -143,8 +143,8 @@ void CustomPropertyEditor::_menu_option(int p_which) { } Set<String> valid_extensions; - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - valid_extensions.insert(E->get()); + for (const String &E : extensions) { + valid_extensions.insert(E); } file->clear_filters(); @@ -179,9 +179,8 @@ void CustomPropertyEditor::_menu_option(int p_which) { res_orig->get_property_list(&property_list); List<Pair<String, Variant>> propvalues; - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { + for (const PropertyInfo &pi : property_list) { Pair<String, Variant> p; - PropertyInfo &pi = E->get(); if (pi.usage & PROPERTY_USAGE_STORAGE) { p.first = pi.name; p.second = res_orig->get(pi.name); @@ -198,8 +197,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { ERR_FAIL_COND(res.is_null()); - for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { - Pair<String, Variant> &p = E->get(); + for (const Pair<String, Variant> &p : propvalues) { res->set(p.first, p.second); } @@ -1293,8 +1291,8 @@ void CustomPropertyEditor::_action_pressed(int p_which) { ResourceLoader::get_recognized_extensions_for_type(type, &extensions); file->clear_filters(); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - file->add_filter("*." + E->get() + " ; " + E->get().to_upper()); + for (const String &E : extensions) { + file->add_filter("*." + E + " ; " + E.to_upper()); } file->popup_file_dialog(); @@ -1321,9 +1319,8 @@ void CustomPropertyEditor::_action_pressed(int p_which) { res_orig->get_property_list(&property_list); List<Pair<String, Variant>> propvalues; - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { + for (const PropertyInfo &pi : property_list) { Pair<String, Variant> p; - PropertyInfo &pi = E->get(); if (pi.usage & PROPERTY_USAGE_STORAGE) { p.first = pi.name; p.second = res_orig->get(pi.name); @@ -1336,8 +1333,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { ERR_FAIL_COND(res.is_null()); - for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { - Pair<String, Variant> &p = E->get(); + for (const Pair<String, Variant> &p : propvalues) { res->set(p.first, p.second); } diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index d26fc6ad9d..a1deae92a4 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -156,43 +156,43 @@ void PropertySelector::_update_search() { search_options->get_theme_icon(SNAME("PackedColorArray"), SNAME("EditorIcons")) }; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().usage == PROPERTY_USAGE_CATEGORY) { + for (const PropertyInfo &E : props) { + if (E.usage == PROPERTY_USAGE_CATEGORY) { if (category && category->get_first_child() == nullptr) { memdelete(category); //old category was unused } category = search_options->create_item(root); - category->set_text(0, E->get().name); + category->set_text(0, E.name); category->set_selectable(0, false); Ref<Texture2D> icon; - if (E->get().name == "Script Variables") { + if (E.name == "Script Variables") { icon = search_options->get_theme_icon(SNAME("Script"), SNAME("EditorIcons")); } else { - icon = EditorNode::get_singleton()->get_class_icon(E->get().name); + icon = EditorNode::get_singleton()->get_class_icon(E.name); } category->set_icon(0, icon); continue; } - if (!(E->get().usage & PROPERTY_USAGE_EDITOR) && !(E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE)) { + if (!(E.usage & PROPERTY_USAGE_EDITOR) && !(E.usage & PROPERTY_USAGE_SCRIPT_VARIABLE)) { continue; } - if (search_box->get_text() != String() && E->get().name.findn(search_text) == -1) { + if (search_box->get_text() != String() && E.name.findn(search_text) == -1) { continue; } - if (type_filter.size() && type_filter.find(E->get().type) == -1) { + if (type_filter.size() && type_filter.find(E.type) == -1) { continue; } TreeItem *item = search_options->create_item(category ? category : root); - item->set_text(0, E->get().name); - item->set_metadata(0, E->get().name); - item->set_icon(0, type_icons[E->get().type]); + item->set_text(0, E.name); + item->set_metadata(0, E.name); + item->set_icon(0, type_icons[E.type]); - if (!found && search_box->get_text() != String() && E->get().name.findn(search_text) != -1) { + if (!found && search_box->get_text() != String() && E.name.findn(search_text) != -1) { item->select(0); found = true; } @@ -231,19 +231,19 @@ void PropertySelector::_update_search() { bool found = false; bool script_methods = false; - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().name.begins_with("*")) { + for (MethodInfo &mi : methods) { + if (mi.name.begins_with("*")) { if (category && category->get_first_child() == nullptr) { memdelete(category); //old category was unused } category = search_options->create_item(root); - category->set_text(0, E->get().name.replace_first("*", "")); + category->set_text(0, mi.name.replace_first("*", "")); category->set_selectable(0, false); Ref<Texture2D> icon; script_methods = false; - String rep = E->get().name.replace("*", ""); - if (E->get().name == "*Script Methods") { + String rep = mi.name.replace("*", ""); + if (mi.name == "*Script Methods") { icon = search_options->get_theme_icon(SNAME("Script"), SNAME("EditorIcons")); script_methods = true; } else { @@ -254,16 +254,16 @@ void PropertySelector::_update_search() { continue; } - String name = E->get().name.get_slice(":", 0); - if (!script_methods && name.begins_with("_") && !(E->get().flags & METHOD_FLAG_VIRTUAL)) { + String name = mi.name.get_slice(":", 0); + if (!script_methods && name.begins_with("_") && !(mi.flags & METHOD_FLAG_VIRTUAL)) { continue; } - if (virtuals_only && !(E->get().flags & METHOD_FLAG_VIRTUAL)) { + if (virtuals_only && !(mi.flags & METHOD_FLAG_VIRTUAL)) { continue; } - if (!virtuals_only && (E->get().flags & METHOD_FLAG_VIRTUAL)) { + if (!virtuals_only && (mi.flags & METHOD_FLAG_VIRTUAL)) { continue; } @@ -273,8 +273,6 @@ void PropertySelector::_update_search() { TreeItem *item = search_options->create_item(category ? category : root); - MethodInfo mi = E->get(); - String desc; if (mi.name.find(":") != -1) { desc = mi.name.get_slice(":", 1) + " "; @@ -306,11 +304,11 @@ void PropertySelector::_update_search() { desc += ")"; - if (E->get().flags & METHOD_FLAG_CONST) { + if (mi.flags & METHOD_FLAG_CONST) { desc += " const"; } - if (E->get().flags & METHOD_FLAG_VIRTUAL) { + if (mi.flags & METHOD_FLAG_VIRTUAL) { desc += " virtual"; } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 6d1deb86c6..c4d47c7594 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -263,8 +263,8 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) List<Node *> owned; base->get_owned_by(base->get_owner(), &owned); Array owners; - for (List<Node *>::Element *F = owned.front(); F; F = F->next()) { - owners.push_back(F->get()); + for (Node *F : owned) { + owners.push_back(F); } undo_redo->add_do_method(instantiated_scene, "set_owner", edited_scene); undo_redo->add_undo_method(this, "_set_owners", edited_scene, owners); @@ -441,8 +441,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { selection.sort_custom<Node::Comparator>(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node *node = E->get(); + for (Node *node : selection) { Map<const Node *, Node *> duplimap; Node *dup = node->duplicate_from_editor(duplimap); @@ -462,8 +461,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { bool has_cycle = false; if (edited_scene->get_filename() != String()) { - for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { - if (edited_scene->get_filename() == E->get()->get_filename()) { + for (Node *E : node_clipboard) { + if (edited_scene->get_filename() == E->get_filename()) { has_cycle = true; break; } @@ -496,16 +495,15 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (target_scene != clipboard_source_scene) { if (!clipboard_resource_remap.has(target_scene)) { Map<RES, RES> remap; - for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { - _create_remap_for_node(E->get(), remap); + for (Node *E : node_clipboard) { + _create_remap_for_node(E, remap); } clipboard_resource_remap[target_scene] = remap; } resource_remap = clipboard_resource_remap[target_scene]; } - for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { - Node *node = E->get(); + for (Node *node : node_clipboard) { Map<const Node *, Node *> duplimap; Node *dup = node->duplicate_from_editor(duplimap, resource_remap); @@ -627,8 +625,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { int lowest_id = common_parent->get_child_count() - 1; int highest_id = 0; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - int index = E->get()->get_index(); + for (Node *E : selection) { + int index = E->get_index(); if (index > highest_id) { highest_id = index; @@ -637,7 +635,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { lowest_id = index; } - if (E->get()->get_parent() != common_parent) { + if (E->get_parent() != common_parent) { common_parent = nullptr; } } @@ -704,8 +702,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *add_below_node = selection.back()->get(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node *node = E->get(); + for (Node *node : selection) { Node *parent = node->get_parent(); List<Node *> owned; @@ -724,11 +721,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { editor_data->get_undo_redo().add_do_method(add_below_node, "add_sibling", dup); - for (List<Node *>::Element *F = owned.front(); F; F = F->next()) { - if (!duplimap.has(F->get())) { + for (Node *F : owned) { + if (!duplimap.has(F)) { continue; } - Node *d = duplimap[F->get()]; + Node *d = duplimap[F]; editor_data->get_undo_redo().add_do_method(d, "set_owner", node->get_owner()); } editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", dup); @@ -771,8 +768,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { List<Node *> nodes = editor_selection->get_selected_node_list(); Set<Node *> nodeset; - for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) { - nodeset.insert(E->get()); + for (Node *E : nodes) { + nodeset.insert(E); } reparent_dialog->set_current(nodeset); reparent_dialog->popup_centered_clamped(Size2(350, 700) * EDSCALE); @@ -1384,30 +1381,25 @@ void SceneTreeDock::_set_owners(Node *p_owner, const Array &p_nodes) { } } -void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath>> *p_renames) { +void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, Map<Node *, NodePath> *p_renames) { base_path.push_back(p_node->get_name()); if (new_base_path.size()) { new_base_path.push_back(p_node->get_name()); } - NodePath from(base_path, true); - NodePath to; + NodePath new_path; if (new_base_path.size()) { - to = NodePath(new_base_path, true); + new_path = NodePath(new_base_path, true); } - Pair<NodePath, NodePath> npp; - npp.first = from; - npp.second = to; - - p_renames->push_back(npp); + p_renames->insert(p_node, new_path); for (int i = 0; i < p_node->get_child_count(); i++) { _fill_path_renames(base_path, new_base_path, p_node->get_child(i), p_renames); } } -void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath>> *p_renames) { +void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, Map<Node *, NodePath> *p_renames) { Vector<StringName> base_path; Node *n = p_node->get_parent(); while (n) { @@ -1430,50 +1422,41 @@ void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pai _fill_path_renames(base_path, new_base_path, p_node, p_renames); } -bool SceneTreeDock::_update_node_path(const NodePath &p_root_path, NodePath &r_node_path, List<Pair<NodePath, NodePath>> *p_renames) { - NodePath root_path_new = p_root_path; - for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) { - if (p_root_path == F->get().first) { - root_path_new = F->get().second; - break; - } - } - - // Goes through all paths to check if it's matching. - for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) { - NodePath rel_path_old = p_root_path.rel_path_to(F->get().first); +bool SceneTreeDock::_update_node_path(Node *p_root_node, NodePath &r_node_path, Map<Node *, NodePath> *p_renames) const { + Node *target_node = p_root_node->get_node_or_null(r_node_path); + ERR_FAIL_NULL_V_MSG(target_node, false, "Found invalid node path '" + String(r_node_path) + "' on node '" + String(scene_root->get_path_to(p_root_node)) + "'"); - // If old path detected, then it needs to be replaced with the new one. - if (r_node_path == rel_path_old) { - NodePath rel_path_new = F->get().second; + // Try to find the target node in modified node paths. + Map<Node *, NodePath>::Element *found_node_path = p_renames->find(target_node); + if (found_node_path) { + Map<Node *, NodePath>::Element *found_root_path = p_renames->find(p_root_node); + NodePath root_path_new = found_root_path ? found_root_path->get() : p_root_node->get_path(); + r_node_path = root_path_new.rel_path_to(found_node_path->get()); - // If not empty, get new relative path. - if (!rel_path_new.is_empty()) { - rel_path_new = root_path_new.rel_path_to(rel_path_new); - } + return true; + } - r_node_path = rel_path_new; - return true; + // Update the path if the base node has changed and has not been deleted. + Map<Node *, NodePath>::Element *found_root_path = p_renames->find(p_root_node); + if (found_root_path) { + NodePath root_path_new = found_root_path->get(); + if (!root_path_new.is_empty()) { + NodePath old_abs_path = NodePath(String(p_root_node->get_path()).plus_file(r_node_path)); + old_abs_path.simplify(); + r_node_path = root_path_new.rel_path_to(old_abs_path); } - // Update the node itself if it has a valid node path and has not been deleted. - if (p_root_path == F->get().first && r_node_path != NodePath() && F->get().second != NodePath()) { - NodePath abs_path = NodePath(String(root_path_new).plus_file(r_node_path)).simplified(); - NodePath rel_path_new = F->get().second.rel_path_to(abs_path); - - r_node_path = rel_path_new; - return true; - } + return true; } return false; } -bool SceneTreeDock::_check_node_path_recursive(const NodePath &p_root_path, Variant &r_variant, List<Pair<NodePath, NodePath>> *p_renames) { +bool SceneTreeDock::_check_node_path_recursive(Node *p_root_node, Variant &r_variant, Map<Node *, NodePath> *p_renames) const { switch (r_variant.get_type()) { case Variant::NODE_PATH: { NodePath node_path = r_variant; - if (_update_node_path(p_root_path, node_path, p_renames)) { + if (!node_path.is_empty() && _update_node_path(p_root_node, node_path, p_renames)) { r_variant = node_path; return true; } @@ -1484,7 +1467,7 @@ bool SceneTreeDock::_check_node_path_recursive(const NodePath &p_root_path, Vari bool updated = false; for (int i = 0; i < a.size(); i++) { Variant value = a[i]; - if (_check_node_path_recursive(p_root_path, value, p_renames)) { + if (_check_node_path_recursive(p_root_node, value, p_renames)) { if (!updated) { a = a.duplicate(); // Need to duplicate for undo-redo to work. updated = true; @@ -1503,7 +1486,7 @@ bool SceneTreeDock::_check_node_path_recursive(const NodePath &p_root_path, Vari bool updated = false; for (int i = 0; i < d.size(); i++) { Variant value = d.get_value_at_index(i); - if (_check_node_path_recursive(p_root_path, value, p_renames)) { + if (_check_node_path_recursive(p_root_node, value, p_renames)) { if (!updated) { d = d.duplicate(); // Need to duplicate for undo-redo to work. updated = true; @@ -1524,7 +1507,7 @@ bool SceneTreeDock::_check_node_path_recursive(const NodePath &p_root_path, Vari return false; } -void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath>> *p_renames, Map<Ref<Animation>, Set<int>> *r_rem_anims) { +void SceneTreeDock::perform_node_renames(Node *p_base, Map<Node *, NodePath> *p_renames, Map<Ref<Animation>, Set<int>> *r_rem_anims) { Map<Ref<Animation>, Set<int>> rem_anims; if (!r_rem_anims) { r_rem_anims = &rem_anims; @@ -1538,19 +1521,24 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP return; } + // No renaming if base node is deleted. + Map<Node *, NodePath>::Element *found_base_path = p_renames->find(p_base); + if (found_base_path && found_base_path->get().is_empty()) { + return; + } + // Renaming node paths used in node properties. List<PropertyInfo> properties; p_base->get_property_list(&properties); - NodePath base_root_path = p_base->get_path(); - for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (!(E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR))) { + for (const PropertyInfo &E : properties) { + if (!(E.usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR))) { continue; } - String propertyname = E->get().name; + String propertyname = E.name; Variant old_variant = p_base->get(propertyname); Variant updated_variant = old_variant; - if (_check_node_path_recursive(base_root_path, updated_variant, p_renames)) { + if (_check_node_path_recursive(p_base, updated_variant, p_renames)) { editor_data->get_undo_redo().add_do_property(p_base, propertyname, updated_variant); editor_data->get_undo_redo().add_undo_property(p_base, propertyname, old_variant); p_base->set(propertyname, updated_variant); @@ -1566,21 +1554,11 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP Node *root = ap->get_node(ap->get_root()); if (root) { - NodePath root_path = root->get_path(); - NodePath new_root_path = root_path; - - for (List<Pair<NodePath, NodePath>>::Element *E = p_renames->front(); E; E = E->next()) { - if (E->get().first == root_path) { - new_root_path = E->get().second; - break; - } - } - - if (new_root_path != NodePath()) { - //will not be erased - - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { - Ref<Animation> anim = ap->get_animation(E->get()); + Map<Node *, NodePath>::Element *found_root_path = p_renames->find(root); + NodePath new_root_path = found_root_path ? found_root_path->get() : root->get_path(); + if (!new_root_path.is_empty()) { // No renaming if root node is deleted. + for (const StringName &E : anims) { + Ref<Animation> anim = ap->get_animation(E); if (!r_rem_anims->has(anim)) { r_rem_anims->insert(anim, Set<int>()); Set<int> &ran = r_rem_anims->find(anim)->get(); @@ -1602,47 +1580,44 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP continue; } - NodePath old_np = n->get_path(); - if (!ran.has(i)) { continue; //channel was removed } - for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) { - if (F->get().first == old_np) { - if (F->get().second == NodePath()) { - //will be erased - - int idx = 0; - Set<int>::Element *EI = ran.front(); - ERR_FAIL_COND(!EI); //bug - while (EI->get() != i) { - idx++; - EI = EI->next(); - ERR_FAIL_COND(!EI); //another bug - } - - editor_data->get_undo_redo().add_do_method(anim.ptr(), "remove_track", idx); - editor_data->get_undo_redo().add_undo_method(anim.ptr(), "add_track", anim->track_get_type(i), idx); - editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", idx, track_np); - editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i)); - for (int j = 0; j < anim->track_get_key_count(i); j++) { - editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j)); - } - - ran.erase(i); //byebye channel - - } else { - //will be renamed - NodePath rel_path = new_root_path.rel_path_to(F->get().second); - - NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false); - if (new_path == track_np) { - continue; //bleh - } - editor_data->get_undo_redo().add_do_method(anim.ptr(), "track_set_path", i, new_path); - editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", i, track_np); + Map<Node *, NodePath>::Element *found_path = p_renames->find(n); + if (found_path) { + if (found_path->get() == NodePath()) { + //will be erased + + int idx = 0; + Set<int>::Element *EI = ran.front(); + ERR_FAIL_COND(!EI); //bug + while (EI->get() != i) { + idx++; + EI = EI->next(); + ERR_FAIL_COND(!EI); //another bug + } + + editor_data->get_undo_redo().add_do_method(anim.ptr(), "remove_track", idx); + editor_data->get_undo_redo().add_undo_method(anim.ptr(), "add_track", anim->track_get_type(i), idx); + editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", idx, track_np); + editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i)); + for (int j = 0; j < anim->track_get_key_count(i); j++) { + editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j)); + } + + ran.erase(i); //byebye channel + + } else { + //will be renamed + NodePath rel_path = new_root_path.rel_path_to(found_path->get()); + + NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false); + if (new_path == track_np) { + continue; //bleh } + editor_data->get_undo_redo().add_do_method(anim.ptr(), "track_set_path", i, new_path); + editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", i, track_np); } } } @@ -1657,7 +1632,7 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP } void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) { - List<Pair<NodePath, NodePath>> path_renames; + Map<Node *, NodePath> path_renames; Vector<StringName> base_path; Node *n = p_node->get_parent(); @@ -1672,10 +1647,8 @@ void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) { new_base_path.push_back(p_new_name); - Pair<NodePath, NodePath> npp; - npp.first = NodePath(base_path, true); - npp.second = NodePath(new_base_path, true); - path_renames.push_back(npp); + NodePath new_path(new_base_path, true); + path_renames[p_node] = new_path; for (int i = 0; i < p_node->get_child_count(); i++) { _fill_path_renames(base_path, new_base_path, p_node->get_child(i), &path_renames); @@ -1687,8 +1660,8 @@ void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) { bool SceneTreeDock::_validate_no_foreign() { List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - if (E->get() != edited_scene && E->get()->get_owner() != edited_scene) { + for (Node *E : selection) { + if (E != edited_scene && E->get_owner() != edited_scene) { accept->set_text(TTR("Can't operate on nodes from a foreign scene!")); accept->popup_centered(); return false; @@ -1697,11 +1670,11 @@ bool SceneTreeDock::_validate_no_foreign() { // When edited_scene inherits from another one the root Node will be the parent Scene, // we don't want to consider that Node a foreign one otherwise we would not be able to // delete it. - if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) { + if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E) { continue; } - if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) { + if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E)) >= 0) { accept->set_text(TTR("Can't operate on nodes the current scene inherits from!")); accept->popup_centered(); return false; @@ -1714,8 +1687,8 @@ bool SceneTreeDock::_validate_no_foreign() { bool SceneTreeDock::_validate_no_instance() { List<Node *> selection = editor_selection->get_selected_node_list(); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - if (E->get() != edited_scene && E->get()->get_filename() != "") { + for (Node *E : selection) { + if (E != edited_scene && E->get_filename() != "") { accept->set_text(TTR("This operation can't be done on instantiated scenes.")); accept->popup_centered(); return false; @@ -1737,8 +1710,8 @@ void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) { Vector<Node *> nodes; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - nodes.push_back(E->get()); + for (Node *E : selection) { + nodes.push_back(E); } _do_reparent(new_parent, -1, nodes, p_keep_global_xform); @@ -1780,7 +1753,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V editor_data->get_undo_redo().create_action(TTR("Reparent Node")); - List<Pair<NodePath, NodePath>> path_renames; + Map<Node *, NodePath> path_renames; Vector<StringName> former_names; int inc = 0; @@ -1795,8 +1768,8 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V List<Node *> owned; node->get_owned_by(node->get_owner(), &owned); Array owners; - for (List<Node *>::Element *E = owned.front(); E; E = E->next()) { - owners.push_back(E->get()); + for (Node *E : owned) { + owners.push_back(E); } if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni) { @@ -1817,21 +1790,24 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V // Name was modified, fix the path renames. if (old_name.casecmp_to(new_name) != 0) { // Fix the to name to have the new name. - NodePath old_new_name = path_renames[ni].second; - NodePath new_path; - - Vector<StringName> unfixed_new_names = old_new_name.get_names(); - Vector<StringName> fixed_new_names; + Map<Node *, NodePath>::Element *found_path = path_renames.find(node); + if (found_path) { + NodePath old_new_name = found_path->get(); - // Get last name and replace with fixed new name. - for (int a = 0; a < (unfixed_new_names.size() - 1); a++) { - fixed_new_names.push_back(unfixed_new_names[a]); - } - fixed_new_names.push_back(new_name); + Vector<StringName> unfixed_new_names = old_new_name.get_names(); + Vector<StringName> fixed_new_names; - NodePath fixed_node_path = NodePath(fixed_new_names, true); + // Get last name and replace with fixed new name. + for (int a = 0; a < (unfixed_new_names.size() - 1); a++) { + fixed_new_names.push_back(unfixed_new_names[a]); + } + fixed_new_names.push_back(new_name); - path_renames[ni].second = fixed_node_path; + NodePath fixed_node_path = NodePath(fixed_new_names, true); + path_renames[node] = fixed_node_path; + } else { + ERR_PRINT("Internal error. Can't find renamed path for node '" + node->get_path() + "'"); + } } editor_data->get_undo_redo().add_do_method(ed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, p_position_in_parent + inc); @@ -1868,8 +1844,8 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V List<Node *> owned; node->get_owned_by(node->get_owner(), &owned); Array owners; - for (List<Node *>::Element *E = owned.front(); E; E = E->next()) { - owners.push_back(E->get()); + for (Node *E : owned) { + owners.push_back(E); } int child_pos = node->get_index(); @@ -1949,10 +1925,10 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { } editor_data->get_undo_redo().create_action(TTR("Attach Script")); - for (List<Node *>::Element *E = selected.front(); E; E = E->next()) { - Ref<Script> existing = E->get()->get_script(); - editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script); - editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); + for (Node *E : selected) { + Ref<Script> existing = E->get_script(); + editor_data->get_undo_redo().add_do_method(E, "set_script", p_script); + editor_data->get_undo_redo().add_undo_method(E, "set_script", existing); editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); } @@ -2027,8 +2003,8 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { bool entire_scene = false; - for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) { - if (E->get() == edited_scene) { + for (Node *E : remove_list) { + if (E == edited_scene) { entire_scene = true; } } @@ -2042,11 +2018,10 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { } else { remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions - List<Pair<NodePath, NodePath>> path_renames; + Map<Node *, NodePath> path_renames; //delete from animation - for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) { - Node *n = E->get(); + for (Node *n : remove_list) { if (!n->is_inside_tree() || !n->get_parent()) { continue; } @@ -2056,8 +2031,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { perform_node_renames(nullptr, &path_renames); //delete for read - for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) { - Node *n = E->get(); + for (Node *n : remove_list) { if (!n->is_inside_tree() || !n->get_parent()) { continue; } @@ -2065,8 +2039,8 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { List<Node *> owned; n->get_owned_by(n->get_owner(), &owned); Array owners; - for (List<Node *>::Element *F = owned.front(); F; F = F->next()) { - owners.push_back(F->get()); + for (Node *F : owned) { + owners.push_back(F); } editor_data->get_undo_redo().add_do_method(n->get_parent(), "remove_child", n); @@ -2219,8 +2193,7 @@ void SceneTreeDock::_create() { UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Change type of node(s)")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node *n = E->get(); + for (Node *n : selection) { ERR_FAIL_COND(!n); Variant c = create_dialog->instance_selected(); @@ -2277,8 +2250,8 @@ void SceneTreeDock::_create() { _do_create(parent); Vector<Node *> nodes; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - nodes.push_back(E->get()); + for (Node *E : selection) { + nodes.push_back(E); } // This works because editor_selection was cleared and populated with last created node in _do_create() @@ -2298,13 +2271,13 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop List<PropertyInfo> pinfo; n->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : pinfo) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - if (E->get().name == "__meta__") { - Dictionary metadata = n->get(E->get().name); + if (E.name == "__meta__") { + Dictionary metadata = n->get(E.name); if (metadata.has("_editor_description_")) { newnode->set_meta("_editor_description_", metadata["_editor_description_"]); } @@ -2321,8 +2294,8 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop continue; } - if (default_oldnode->get(E->get().name) != n->get(E->get().name)) { - newnode->set(E->get().name, n->get(E->get().name)); + if (default_oldnode->get(E.name) != n->get(E.name)) { + newnode->set(E.name, n->get(E.name)); } } @@ -2335,12 +2308,11 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop List<MethodInfo> sl; n->get_signal_list(&sl); - for (List<MethodInfo>::Element *E = sl.front(); E; E = E->next()) { + for (const MethodInfo &E : sl) { List<Object::Connection> cl; - n->get_signal_connection_list(E->get().name, &cl); + n->get_signal_connection_list(E.name, &cl); - for (List<Object::Connection>::Element *F = cl.front(); F; F = F->next()) { - Object::Connection &c = F->get(); + for (const Object::Connection &c : cl) { if (!(c.flags & Object::CONNECT_PERSIST)) { continue; } @@ -2546,13 +2518,13 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_ List<PropertyInfo> pinfo; node->get_property_list(&pinfo); - for (PropertyInfo &p : pinfo) { + for (const PropertyInfo &p : pinfo) { if (!(p.usage & PROPERTY_USAGE_EDITOR) || !(p.usage & PROPERTY_USAGE_STORAGE) || p.hint != PROPERTY_HINT_RESOURCE_TYPE) { continue; } Vector<String> valid_types = p.hint_string.split(","); - for (String &prop_type : valid_types) { + for (const String &prop_type : valid_types) { if (res_type == prop_type || ClassDB::is_parent_class(res_type, prop_type) || EditorNode::get_editor_data().script_class_is_parent(res_type, prop_type)) { valid_properties.push_back(p.name); break; @@ -2566,7 +2538,7 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_ bool capitalize = bool(EDITOR_GET("interface/inspector/capitalize_properties")); menu_properties->clear(); - for (String &p : valid_properties) { + for (const String &p : valid_properties) { menu_properties->add_item(capitalize ? p.capitalize() : p); menu_properties->set_item_metadata(menu_properties->get_item_count() - 1, p); } @@ -2607,8 +2579,8 @@ void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) { } Vector<Node *> nodes; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - nodes.push_back(E->get()); + for (Node *E : selection) { + nodes.push_back(E); } int to_pos = -1; @@ -2624,15 +2596,15 @@ void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) { List<PropertyInfo> pinfo; p_obj->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) { + for (const PropertyInfo &E : pinfo) { + if (!(E.usage & PROPERTY_USAGE_EDITOR)) { continue; } - if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE) { + if (E.hint != PROPERTY_HINT_RESOURCE_TYPE) { continue; } - Variant value = p_obj->get(E->get().name); + Variant value = p_obj->get(E.name); if (value.get_type() != Variant::OBJECT) { continue; } @@ -2647,7 +2619,7 @@ void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) { menu->add_submenu_item(TTR("Sub-Resources"), "Sub-Resources"); } int index = menu_subresources->get_item_count(); - menu_subresources->add_icon_item(icon, E->get().name.capitalize(), EDIT_SUBRESOURCE_BASE + subresources.size()); + menu_subresources->add_icon_item(icon, E.name.capitalize(), EDIT_SUBRESOURCE_BASE + subresources.size()); menu_subresources->set_item_h_offset(index, p_depth * 10 * EDSCALE); subresources.push_back(obj->get_instance_id()); @@ -2729,8 +2701,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_theme_icon(SNAME("ScriptRemove"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT); } else if (full_selection.size() > 1) { bool script_exists = false; - for (List<Node *>::Element *E = full_selection.front(); E; E = E->next()) { - if (!E->get()->get_script().is_null()) { + for (Node *E : full_selection) { + if (!E->get_script().is_null()) { script_exists = true; break; } @@ -2753,8 +2725,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { } bool can_replace = true; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - if (E->get() != edited_scene && (E->get()->get_owner() != edited_scene || E->get()->get_filename() != "")) { + for (Node *E : selection) { + if (E != edited_scene && (E->get_owner() != edited_scene || E->get_filename() != "")) { can_replace = false; break; } @@ -3067,8 +3039,8 @@ void SceneTreeDock::_feature_profile_changed() { } void SceneTreeDock::_clear_clipboard() { - for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { - memdelete(E->get()); + for (Node *E : node_clipboard) { + memdelete(E); } node_clipboard.clear(); clipboard_resource_remap.clear(); @@ -3079,18 +3051,18 @@ void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) p_node->get_property_list(&props); bool is_instantiated = EditorPropertyRevert::may_node_be_in_instance(p_node); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant v = p_node->get(E->get().name); + Variant v = p_node->get(E.name); if (v.is_ref()) { RES res = v; if (res.is_valid()) { if (is_instantiated) { Variant orig; - if (EditorPropertyRevert::get_instantiated_node_original_property(p_node, E->get().name, orig)) { + if (EditorPropertyRevert::get_instantiated_node_original_property(p_node, E.name, orig)) { if (!EditorPropertyRevert::is_node_property_different(p_node, v, orig)) { continue; } @@ -3115,12 +3087,12 @@ void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_ List<PropertyInfo> props; p_resource->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant v = p_resource->get(E->get().name); + Variant v = p_resource->get(E.name); if (v.is_ref()) { RES res = v; if (res.is_valid()) { diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index fd9299fb2b..4952122cb7 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -217,7 +217,7 @@ class SceneTreeDock : public VBoxContainer { void _selection_changed(); void _update_script_button(); - void _fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath>> *p_renames); + void _fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, Map<Node *, NodePath> *p_renames); void _normalize_drop(Node *&to_node, int &to_pos, int p_type); @@ -253,8 +253,8 @@ class SceneTreeDock : public VBoxContainer { static SceneTreeDock *singleton; static void _update_configuration_warning(); - static bool _update_node_path(const NodePath &p_root_path, NodePath &r_node_path, List<Pair<NodePath, NodePath>> *p_renames); - static bool _check_node_path_recursive(const NodePath &p_root_path, Variant &r_variant, List<Pair<NodePath, NodePath>> *p_renames); + bool _update_node_path(Node *p_root_node, NodePath &r_node_path, Map<Node *, NodePath> *p_renames) const; + bool _check_node_path_recursive(Node *p_root_node, Variant &r_variant, Map<Node *, NodePath> *p_renames) const; protected: void _notification(int p_what); @@ -272,8 +272,8 @@ public: void instantiate(const String &p_file); void instantiate_scenes(const Vector<String> &p_files, Node *p_parent = nullptr); void set_selected(Node *p_node, bool p_emit_selected = false); - void fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath>> *p_renames); - void perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath>> *p_renames, Map<Ref<Animation>, Set<int>> *r_rem_anims = nullptr); + void fill_path_renames(Node *p_node, Node *p_new_parent, Map<Node *, NodePath> *p_renames); + void perform_node_renames(Node *p_base, Map<Node *, NodePath> *p_renames, Map<Ref<Animation>, Set<int>> *r_rem_anims = nullptr); SceneTreeEditor *get_tree_editor() { return scene_tree; } EditorData *get_editor_data() { return editor_data; } diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index c6f2c9253e..83b0203f32 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -79,8 +79,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i _toggle_visible(n); List<Node *> selection = editor_selection->get_selected_node_list(); if (selection.size() > 1 && selection.find(n) != nullptr) { - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node *nv = E->get(); + for (Node *nv : selection) { ERR_FAIL_COND(!nv); if (nv == n) { continue; @@ -521,7 +520,7 @@ void SceneTreeEditor::_node_removed(Node *p_node) { if (p_node == selected) { selected = nullptr; - _emit_node_selected(); + emit_signal("node_selected"); } } @@ -615,6 +614,24 @@ void SceneTreeEditor::_tree_changed() { pending_test_update = true; } +void SceneTreeEditor::_selected_changed() { + TreeItem *s = tree->get_selected(); + ERR_FAIL_COND(!s); + NodePath np = s->get_metadata(0); + + Node *n = get_node(np); + + if (n == selected) { + return; + } + + selected = get_node(np); + + blocked++; + emit_signal("node_selected"); + blocked--; +} + void SceneTreeEditor::_deselect_items() { // Clear currently selected items in scene tree dock. if (editor_selection) { @@ -623,12 +640,6 @@ void SceneTreeEditor::_deselect_items() { } } -void SceneTreeEditor::_emit_node_selected() { - blocked++; - emit_signal(SNAME("node_selected")); - blocked--; -} - void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_selected) { TreeItem *item = Object::cast_to<TreeItem>(p_object); ERR_FAIL_COND(!item); @@ -652,11 +663,8 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_ editor_selection->remove_node(n); } - // Selection changed to be single node, so emit "selected" (for single node) rather than "changed" (for multiple nodes) - if (editor_selection->get_selected_nodes().size() == 1) { - selected = editor_selection->get_selected_node_list()[0]; - _emit_node_selected(); - } else { + // Emitted "selected" in _selected_changed() when select single node, so select multiple node emit "changed" + if (editor_selection->get_selected_nodes().size() > 1) { emit_signal(SNAME("node_changed")); } } @@ -747,7 +755,7 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) { } if (p_emit_selected) { - _emit_node_selected(); + emit_signal("node_selected"); } } @@ -1197,6 +1205,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope tree->connect("empty_tree_rmb_selected", callable_mp(this, &SceneTreeEditor::_rmb_select)); } + tree->connect("cell_selected", callable_mp(this, &SceneTreeEditor::_selected_changed)); tree->connect("item_edited", callable_mp(this, &SceneTreeEditor::_renamed), varray(), CONNECT_DEFERRED); tree->connect("multi_selected", callable_mp(this, &SceneTreeEditor::_cell_multi_selected)); tree->connect("button_pressed", callable_mp(this, &SceneTreeEditor::_cell_button_pressed)); diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index e833bf93e0..acd49e8d92 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -81,6 +81,7 @@ class SceneTreeEditor : public Control { TreeItem *_find(TreeItem *p_node, const NodePath &p_path); void _notification(int p_what); + void _selected_changed(); void _deselect_items(); void _rename_node(ObjectID p_node, const String &p_name); @@ -132,8 +133,6 @@ class SceneTreeEditor : public Control { Vector<StringName> valid_types; - void _emit_node_selected(); - public: void set_filter(const String &p_filter); String get_filter() const; diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 2601382009..9a4b38db74 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -205,12 +205,12 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must bool found = false; bool match = false; int index = 0; - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(extension) == 0) { + for (const String &E : extensions) { + if (E.nocasecmp_to(extension) == 0) { //FIXME (?) - changing language this way doesn't update controls, needs rework //language_menu->select(index); // change Language option by extension found = true; - if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) { + if (E == ScriptServer::get_language(language_menu->get_selected())->get_extension()) { match = true; } break; @@ -373,8 +373,8 @@ void ScriptCreateDialog::_lang_changed(int l) { ScriptServer::get_language(m)->get_recognized_extensions(&extensions); } - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(extension) == 0) { + for (const String &E : extensions) { + if (E.nocasecmp_to(extension) == 0) { path = path.get_basename() + selected_ext; _path_changed(path); break; @@ -534,8 +534,8 @@ void ScriptCreateDialog::_browse_path(bool browse_parent, bool p_save) { int lang = language_menu->get_selected(); ScriptServer::get_language(lang)->get_recognized_extensions(&extensions); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - file_browse->add_filter("*." + E->get()); + for (const String &E : extensions) { + file_browse->add_filter("*." + E); } file_browse->set_current_path(file_path->get_text()); diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 0524b91634..aefa8e434e 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -324,15 +324,15 @@ void EditorSettingsDialog::_update_shortcuts() { List<String> slist; EditorSettings::get_singleton()->get_shortcut_list(&slist); - for (List<String>::Element *E = slist.front(); E; E = E->next()) { - Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E->get()); + for (const String &E : slist) { + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E); if (!sc->has_meta("original")) { continue; } Ref<InputEvent> original = sc->get_meta("original"); - String section_name = E->get().get_slice("/", 0); + String section_name = E.get_slice("/", 0); TreeItem *section; @@ -372,8 +372,8 @@ void EditorSettingsDialog::_update_shortcuts() { item->add_button(1, shortcuts->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), 0); item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), 1); - item->set_tooltip(0, E->get()); - item->set_metadata(0, E->get()); + item->set_tooltip(0, E); + item->set_metadata(0, E); } } @@ -403,10 +403,9 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins()[current_action]; // Convert the list to an array, and only keep key events as this is for the editor. - for (List<Ref<InputEvent>>::Element *E = defaults.front(); E; E = E->next()) { - Ref<InputEventKey> k = E->get(); + for (Ref<InputEvent> k : defaults) { if (k.is_valid()) { - events.append(E->get()); + events.append(k); } } diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index a0f4654639..99579c7b34 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -6979,7 +6979,7 @@ msgstr "" #: editor/plugins/shader_editor_plugin.cpp msgid "" -"This shader has been modified on on disk.\n" +"This shader has been modified on disk.\n" "What action should be taken?" msgstr "" diff --git a/main/main.cpp b/main/main.cpp index 1e5445fd93..02c3dffd11 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1080,7 +1080,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #else const String error_msg = "Error: Couldn't load project data at path \"" + project_path + "\". Is the .pck file missing?\nIf you've renamed the executable, the associated .pck file should also be renamed to match the executable's name (without the extension).\n"; OS::get_singleton()->print("%s", error_msg.ascii().get_data()); - DisplayServer::get_singleton()->alert(error_msg); + OS::get_singleton()->alert(error_msg); goto error; #endif @@ -1089,6 +1089,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // Initialize user data dir. OS::get_singleton()->ensure_user_data_dir(); + ResourceUID::get_singleton()->load_from_cache(); // load UUIDs from cache. + GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60); ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/multithreaded_server/rid_pool_prealloc", PropertyInfo(Variant::INT, @@ -2015,6 +2017,7 @@ bool Main::start() { // Let's throw an error gently. The code leading to this is pretty brittle so // this might end up triggered by valid usage, in which case we'll have to // fine-tune further. + OS::get_singleton()->alert("Couldn't detect whether to run the editor, the project manager or a specific project. Aborting."); ERR_FAIL_V_MSG(false, "Couldn't detect whether to run the editor, the project manager or a specific project. Aborting."); } #endif @@ -2044,9 +2047,8 @@ bool Main::start() { if (obj) { memdelete(obj); } - ERR_FAIL_V_MSG(false, - vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", - script)); + OS::get_singleton()->alert(vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script)); + ERR_FAIL_V_MSG(false, vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script)); } script_loop->set_initialize_script(script_res); @@ -2065,7 +2067,7 @@ bool Main::start() { if (obj) { memdelete(obj); } - DisplayServer::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base); + OS::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base); ERR_FAIL_V_MSG(false, vformat("The global class %s does not inherit from SceneTree or MainLoop.", main_loop_type)); } script_loop->set_initialize_script(script_res); @@ -2079,7 +2081,7 @@ bool Main::start() { if (!main_loop) { if (!ClassDB::class_exists(main_loop_type)) { - DisplayServer::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type); + OS::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type); return false; } else { Object *ml = ClassDB::instantiate(main_loop_type); @@ -2169,8 +2171,8 @@ bool Main::start() { } } - for (List<Node *>::Element *E = to_add.front(); E; E = E->next()) { - sml->get_root()->add_child(E->get()); + for (Node *E : to_add) { + sml->get_root()->add_child(E); } } } diff --git a/misc/dist/windows/modpath.pas b/misc/dist/windows/modpath.pas index c55ec60163..ab09f18254 100644 --- a/misc/dist/windows/modpath.pas +++ b/misc/dist/windows/modpath.pas @@ -144,7 +144,7 @@ begin end; end; -// Split a string into an array using passed delimeter +// Split a string into an array using passed delimiter. procedure MPExplode(var Dest: TArrayOfString; Text: String; Separator: String); var i: Integer; diff --git a/modules/camera/camera_osx.h b/modules/camera/camera_osx.h index 964b7c1edc..84274f0bf6 100644 --- a/modules/camera/camera_osx.h +++ b/modules/camera/camera_osx.h @@ -32,7 +32,7 @@ #define CAMERAOSX_H ///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimize code duplication!!!! -// If you fix something here, make sure you fix it there as wel! +// If you fix something here, make sure you fix it there as well! #include "servers/camera_server.h" diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm index 6bc56add20..4875eb578a 100644 --- a/modules/camera/camera_osx.mm +++ b/modules/camera/camera_osx.mm @@ -29,7 +29,7 @@ /*************************************************************************/ ///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimize code duplication!!!! -// If you fix something here, make sure you fix it there as wel! +// If you fix something here, make sure you fix it there as well! #include "camera_osx.h" #include "servers/camera/camera_feed.h" diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 57206ae18b..cb82b65307 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -530,8 +530,8 @@ void CSGBrushOperation::MeshMerge::_add_distance(List<real_t> &r_intersectionsA, List<real_t> &intersections = p_from_B ? r_intersectionsB : r_intersectionsA; // Check if distance exists. - for (const List<real_t>::Element *E = intersections.front(); E; E = E->next()) { - if (Math::is_equal_approx(**E, p_distance)) { + for (const real_t E : intersections) { + if (Math::is_equal_approx(E, p_distance)) { return; } } diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index 37a7d96de5..fc84c029ec 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "csg_gizmos.h" +#include "editor/plugins/node_3d_editor_plugin.h" +#include "scene/3d/camera_3d.h" /////////// @@ -48,7 +50,7 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() { create_handle_material("handles"); } -String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); if (Object::cast_to<CSGSphere3D>(cs)) { @@ -60,17 +62,17 @@ String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, } if (Object::cast_to<CSGCylinder3D>(cs)) { - return p_idx == 0 ? "Radius" : "Height"; + return p_id == 0 ? "Radius" : "Height"; } if (Object::cast_to<CSGTorus3D>(cs)) { - return p_idx == 0 ? "InnerRadius" : "OuterRadius"; + return p_id == 0 ? "InnerRadius" : "OuterRadius"; } return ""; } -Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); if (Object::cast_to<CSGSphere3D>(cs)) { @@ -85,18 +87,18 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int if (Object::cast_to<CSGCylinder3D>(cs)) { CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs); - return p_idx == 0 ? s->get_radius() : s->get_height(); + return p_id == 0 ? s->get_radius() : s->get_height(); } if (Object::cast_to<CSGTorus3D>(cs)) { CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs); - return p_idx == 0 ? s->get_inner_radius() : s->get_outer_radius(); + return p_id == 0 ? s->get_inner_radius() : s->get_outer_radius(); } return Variant(); } -void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); Transform3D gt = cs->get_global_transform(); @@ -129,10 +131,10 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca CSGBox3D *s = Object::cast_to<CSGBox3D>(cs); Vector3 axis; - axis[p_idx] = 1.0; + axis[p_id] = 1.0; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; + float d = ra[p_id]; if (Node3DEditor::get_singleton()->is_snap_enabled()) { d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); } @@ -142,7 +144,7 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca } Vector3 h = s->get_size(); - h[p_idx] = d * 2; + h[p_id] = d * 2; s->set_size(h); } @@ -150,7 +152,7 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs); Vector3 axis; - axis[p_idx == 0 ? 0 : 1] = 1.0; + axis[p_id == 0 ? 0 : 1] = 1.0; Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = axis.dot(ra); @@ -162,9 +164,9 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca d = 0.001; } - if (p_idx == 0) { + if (p_id == 0) { s->set_radius(d); - } else if (p_idx == 1) { + } else if (p_id == 1) { s->set_height(d * 2.0); } } @@ -185,15 +187,15 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca d = 0.001; } - if (p_idx == 0) { + if (p_id == 0) { s->set_inner_radius(d); - } else if (p_idx == 1) { + } else if (p_id == 1) { s->set_outer_radius(d); } } } -void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); if (Object::cast_to<CSGSphere3D>(cs)) { @@ -227,7 +229,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, if (Object::cast_to<CSGCylinder3D>(cs)) { CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs); if (p_cancel) { - if (p_idx == 0) { + if (p_id == 0) { s->set_radius(p_restore); } else { s->set_height(p_restore); @@ -236,7 +238,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, } UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); - if (p_idx == 0) { + if (p_id == 0) { ur->create_action(TTR("Change Cylinder Radius")); ur->add_do_method(s, "set_radius", s->get_radius()); ur->add_undo_method(s, "set_radius", p_restore); @@ -252,7 +254,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, if (Object::cast_to<CSGTorus3D>(cs)) { CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs); if (p_cancel) { - if (p_idx == 0) { + if (p_id == 0) { s->set_inner_radius(p_restore); } else { s->set_outer_radius(p_restore); @@ -261,7 +263,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, } UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); - if (p_idx == 0) { + if (p_id == 0) { ur->create_action(TTR("Change Torus Inner Radius")); ur->add_do_method(s, "set_inner_radius", s->get_inner_radius()); ur->add_undo_method(s, "set_inner_radius", p_restore); @@ -356,7 +358,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { break; } - p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), solid_material); + p_gizmo->add_mesh(mesh, solid_material); } if (Object::cast_to<CSGSphere3D>(cs)) { diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h index 8f7da35de3..847313c0b4 100644 --- a/modules/csg/csg_gizmos.h +++ b/modules/csg/csg_gizmos.h @@ -33,22 +33,22 @@ #include "csg_shape.h" #include "editor/editor_plugin.h" -#include "editor/node_3d_editor_gizmos.h" +#include "editor/plugins/node_3d_editor_gizmos.h" class CSGShape3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(CSGShape3DGizmoPlugin, EditorNode3DGizmoPlugin); public: - bool has_gizmo(Node3D *p_spatial) override; - String get_gizmo_name() const override; - int get_priority() const override; - bool is_selectable_when_hidden() const override; - void redraw(EditorNode3DGizmo *p_gizmo) override; - - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override; - Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) override; + virtual bool has_gizmo(Node3D *p_spatial) override; + virtual String get_gizmo_name() const override; + virtual int get_priority() const override; + virtual bool is_selectable_when_hidden() const override; + virtual void redraw(EditorNode3DGizmo *p_gizmo) override; + + virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override; + virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const override; CSGShape3DGizmoPlugin(); }; diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 729dc2f8fc..73c1ba554c 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -548,7 +548,7 @@ void CSGShape3D::_notification(int p_what) { void CSGShape3D::set_operation(Operation p_operation) { operation = p_operation; _make_dirty(); - update_gizmo(); + update_gizmos(); } CSGShape3D::Operation CSGShape3D::get_operation() const { @@ -845,7 +845,7 @@ CSGBrush *CSGMesh3D::_build_brush() { void CSGMesh3D::_mesh_changed() { _make_dirty(); - update_gizmo(); + update_gizmos(); } void CSGMesh3D::set_material(const Ref<Material> &p_material) { @@ -1034,7 +1034,7 @@ void CSGSphere3D::set_radius(const float p_radius) { ERR_FAIL_COND(p_radius <= 0); radius = p_radius; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGSphere3D::get_radius() const { @@ -1044,7 +1044,7 @@ float CSGSphere3D::get_radius() const { void CSGSphere3D::set_radial_segments(const int p_radial_segments) { radial_segments = p_radial_segments > 4 ? p_radial_segments : 4; _make_dirty(); - update_gizmo(); + update_gizmos(); } int CSGSphere3D::get_radial_segments() const { @@ -1054,7 +1054,7 @@ int CSGSphere3D::get_radial_segments() const { void CSGSphere3D::set_rings(const int p_rings) { rings = p_rings > 1 ? p_rings : 1; _make_dirty(); - update_gizmo(); + update_gizmos(); } int CSGSphere3D::get_rings() const { @@ -1203,7 +1203,7 @@ void CSGBox3D::_bind_methods() { void CSGBox3D::set_size(const Vector3 &p_size) { size = p_size; _make_dirty(); - update_gizmo(); + update_gizmos(); } Vector3 CSGBox3D::get_size() const { @@ -1213,7 +1213,7 @@ Vector3 CSGBox3D::get_size() const { void CSGBox3D::set_material(const Ref<Material> &p_material) { material = p_material; _make_dirty(); - update_gizmo(); + update_gizmos(); } Ref<Material> CSGBox3D::get_material() const { @@ -1384,7 +1384,7 @@ void CSGCylinder3D::_bind_methods() { void CSGCylinder3D::set_radius(const float p_radius) { radius = p_radius; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGCylinder3D::get_radius() const { @@ -1394,7 +1394,7 @@ float CSGCylinder3D::get_radius() const { void CSGCylinder3D::set_height(const float p_height) { height = p_height; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGCylinder3D::get_height() const { @@ -1405,7 +1405,7 @@ void CSGCylinder3D::set_sides(const int p_sides) { ERR_FAIL_COND(p_sides < 3); sides = p_sides; _make_dirty(); - update_gizmo(); + update_gizmos(); } int CSGCylinder3D::get_sides() const { @@ -1415,7 +1415,7 @@ int CSGCylinder3D::get_sides() const { void CSGCylinder3D::set_cone(const bool p_cone) { cone = p_cone; _make_dirty(); - update_gizmo(); + update_gizmos(); } bool CSGCylinder3D::is_cone() const { @@ -1603,7 +1603,7 @@ void CSGTorus3D::_bind_methods() { void CSGTorus3D::set_inner_radius(const float p_inner_radius) { inner_radius = p_inner_radius; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGTorus3D::get_inner_radius() const { @@ -1613,7 +1613,7 @@ float CSGTorus3D::get_inner_radius() const { void CSGTorus3D::set_outer_radius(const float p_outer_radius) { outer_radius = p_outer_radius; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGTorus3D::get_outer_radius() const { @@ -1624,7 +1624,7 @@ void CSGTorus3D::set_sides(const int p_sides) { ERR_FAIL_COND(p_sides < 3); sides = p_sides; _make_dirty(); - update_gizmo(); + update_gizmos(); } int CSGTorus3D::get_sides() const { @@ -1635,7 +1635,7 @@ void CSGTorus3D::set_ring_sides(const int p_ring_sides) { ERR_FAIL_COND(p_ring_sides < 3); ring_sides = p_ring_sides; _make_dirty(); - update_gizmo(); + update_gizmos(); } int CSGTorus3D::get_ring_sides() const { @@ -2172,7 +2172,7 @@ void CSGPolygon3D::_validate_property(PropertyInfo &property) const { void CSGPolygon3D::_path_changed() { _make_dirty(); - update_gizmo(); + update_gizmos(); } void CSGPolygon3D::_path_exited() { @@ -2248,7 +2248,7 @@ void CSGPolygon3D::_bind_methods() { void CSGPolygon3D::set_polygon(const Vector<Vector2> &p_polygon) { polygon = p_polygon; _make_dirty(); - update_gizmo(); + update_gizmos(); } Vector<Vector2> CSGPolygon3D::get_polygon() const { @@ -2258,7 +2258,7 @@ Vector<Vector2> CSGPolygon3D::get_polygon() const { void CSGPolygon3D::set_mode(Mode p_mode) { mode = p_mode; _make_dirty(); - update_gizmo(); + update_gizmos(); notify_property_list_changed(); } @@ -2270,7 +2270,7 @@ void CSGPolygon3D::set_depth(const float p_depth) { ERR_FAIL_COND(p_depth < 0.001); depth = p_depth; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGPolygon3D::get_depth() const { @@ -2290,7 +2290,7 @@ void CSGPolygon3D::set_spin_degrees(const float p_spin_degrees) { ERR_FAIL_COND(p_spin_degrees < 0.01 || p_spin_degrees > 360); spin_degrees = p_spin_degrees; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGPolygon3D::get_spin_degrees() const { @@ -2301,7 +2301,7 @@ void CSGPolygon3D::set_spin_sides(const int p_spin_sides) { ERR_FAIL_COND(p_spin_sides < 3); spin_sides = p_spin_sides; _make_dirty(); - update_gizmo(); + update_gizmos(); } int CSGPolygon3D::get_spin_sides() const { @@ -2311,7 +2311,7 @@ int CSGPolygon3D::get_spin_sides() const { void CSGPolygon3D::set_path_node(const NodePath &p_path) { path_node = p_path; _make_dirty(); - update_gizmo(); + update_gizmos(); } NodePath CSGPolygon3D::get_path_node() const { @@ -2322,7 +2322,7 @@ void CSGPolygon3D::set_path_interval(float p_interval) { ERR_FAIL_COND_MSG(p_interval < 0.001, "Path interval cannot be smaller than 0.001."); path_interval = p_interval; _make_dirty(); - update_gizmo(); + update_gizmos(); } float CSGPolygon3D::get_path_interval() const { @@ -2332,7 +2332,7 @@ float CSGPolygon3D::get_path_interval() const { void CSGPolygon3D::set_path_rotation(PathRotation p_rotation) { path_rotation = p_rotation; _make_dirty(); - update_gizmo(); + update_gizmos(); } CSGPolygon3D::PathRotation CSGPolygon3D::get_path_rotation() const { @@ -2342,7 +2342,7 @@ CSGPolygon3D::PathRotation CSGPolygon3D::get_path_rotation() const { void CSGPolygon3D::set_path_local(bool p_enable) { path_local = p_enable; _make_dirty(); - update_gizmo(); + update_gizmos(); } bool CSGPolygon3D::is_path_local() const { @@ -2352,7 +2352,7 @@ bool CSGPolygon3D::is_path_local() const { void CSGPolygon3D::set_path_joined(bool p_enable) { path_joined = p_enable; _make_dirty(); - update_gizmo(); + update_gizmos(); } bool CSGPolygon3D::is_path_joined() const { diff --git a/modules/fbx/fbx_parser/ByteSwapper.h b/modules/fbx/fbx_parser/ByteSwapper.h index 5c16383974..08d38147d5 100644 --- a/modules/fbx/fbx_parser/ByteSwapper.h +++ b/modules/fbx/fbx_parser/ByteSwapper.h @@ -70,7 +70,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -/** @file Helper class tp perform various byte oder swappings +/** @file Helper class tp perform various byte order swappings (e.g. little to big endian) */ #ifndef BYTE_SWAPPER_H #define BYTE_SWAPPER_H diff --git a/modules/fbx/fbx_parser/FBXDocument.cpp b/modules/fbx/fbx_parser/FBXDocument.cpp index 89c69d2ee8..92c62e68b5 100644 --- a/modules/fbx/fbx_parser/FBXDocument.cpp +++ b/modules/fbx/fbx_parser/FBXDocument.cpp @@ -198,7 +198,7 @@ ObjectPtr LazyObject::LoadObject() { object.reset(new ModelLimbNode(id, element, doc, name)); } else if (strcmp(classtag.c_str(), "IKEffector") && strcmp(classtag.c_str(), "FKEffector")) { - // FK and IK effectors are not supporte + // FK and IK effectors are not supported. object.reset(new Model(id, element, doc, name)); } } else if (!strncmp(obtype, "Material", length)) { diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 1ff591a87f..9445fac1c6 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -129,9 +129,7 @@ void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { config_file->get_section_keys("entry", &entry_key_list); } - for (List<String>::Element *E = entry_key_list.front(); E; E = E->next()) { - String key = E->get(); - + for (const String &key : entry_key_list) { PropertyInfo prop; prop.type = Variant::STRING; @@ -147,9 +145,7 @@ void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { config_file->get_section_keys("dependencies", &dependency_key_list); } - for (List<String>::Element *E = dependency_key_list.front(); E; E = E->next()) { - String key = E->get(); - + for (const String &key : dependency_key_list) { PropertyInfo prop; prop.type = Variant::STRING; @@ -175,9 +171,7 @@ void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) { p_config_file->get_section_keys("entry", &entry_keys); } - for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { - String key = E->get(); - + for (const String &key : entry_keys) { Vector<String> tags = key.split("."); bool skip = false; @@ -207,9 +201,7 @@ void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) { p_config_file->get_section_keys("dependencies", &dependency_keys); } - for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { - String key = E->get(); - + for (const String &key : dependency_keys) { Vector<String> tags = key.split("."); bool skip = false; diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index cfb57137bb..1d75ea206c 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -915,8 +915,8 @@ void GDAPI godot_variant_get_builtin_method_list(godot_variant_type p_type, godo List<StringName> list; Variant::get_builtin_method_list((Variant::Type)p_type, &list); int i = 0; - for (const List<StringName>::Element *E = list.front(); E; E = E->next()) { - memnew_placement_custom(&r_list[i], StringName, StringName(E->get())); + for (const StringName &E : list) { + memnew_placement_custom(&r_list[i], StringName, StringName(E)); } } @@ -970,8 +970,8 @@ void GDAPI godot_variant_get_member_list(godot_variant_type p_type, godot_string List<StringName> members; Variant::get_member_list((Variant::Type)p_type, &members); int i = 0; - for (const List<StringName>::Element *E = members.front(); E; E = E->next()) { - memnew_placement_custom(&r_list[i++], StringName, StringName(E->get())); + for (const StringName &E : members) { + memnew_placement_custom(&r_list[i++], StringName, StringName(E)); } } @@ -1075,8 +1075,8 @@ void GDAPI godot_variant_get_constants_list(godot_variant_type p_type, godot_str List<StringName> constants; int i = 0; Variant::get_constants_for_type((Variant::Type)p_type, &constants); - for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) { - memnew_placement_custom(&r_list[i++], StringName, StringName(E->get())); + for (const StringName &E : constants) { + memnew_placement_custom(&r_list[i++], StringName, StringName(E)); } } @@ -1227,8 +1227,8 @@ void GDAPI godot_variant_get_utility_function_list(godot_string_name *r_function godot_string_name *func = r_functions; Variant::get_utility_function_list(&functions); - for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) { - memnew_placement_custom(func++, StringName, StringName(E->get())); + for (const StringName &E : functions) { + memnew_placement_custom(func++, StringName, StringName(E)); } } diff --git a/modules/gdnative/include/net/godot_webrtc.h b/modules/gdnative/include/net/godot_webrtc.h index 62b7e3c2c5..52006e56ec 100644 --- a/modules/gdnative/include/net/godot_webrtc.h +++ b/modules/gdnative/include/net/godot_webrtc.h @@ -37,8 +37,8 @@ extern "C" { #endif -#define GODOT_NET_WEBRTC_API_MAJOR 3 -#define GODOT_NET_WEBRTC_API_MINOR 2 +#define GODOT_NET_WEBRTC_API_MAJOR 4 +#define GODOT_NET_WEBRTC_API_MINOR 0 /* Library Interface (used to set default GDNative WebRTC implementation */ typedef struct { diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 477bc9f74d..df0f29277e 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -425,11 +425,11 @@ List<ClassAPI> generate_c_api_classes() { List<EnumAPI> enums; List<StringName> enum_names; ClassDB::get_enum_list(class_name, &enum_names, true); - for (List<StringName>::Element *E = enum_names.front(); E; E = E->next()) { + for (const StringName &E : enum_names) { List<StringName> value_names; EnumAPI enum_api; - enum_api.name = E->get(); - ClassDB::get_enum_constants(class_name, E->get(), &value_names, true); + enum_api.name = E; + ClassDB::get_enum_constants(class_name, E, &value_names, true); for (List<StringName>::Element *val_e = value_names.front(); val_e; val_e = val_e->next()) { int int_val = ClassDB::get_integer_constant(class_name, val_e->get(), nullptr); enum_api.values.push_back(Pair<int, String>(int_val, val_e->get())); @@ -459,8 +459,8 @@ List<ClassAPI> generate_c_builtin_api_types() { List<StringName> utility_functions; Variant::get_utility_function_list(&utility_functions); - for (const List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { - const StringName &function_name = E->get(); + for (const StringName &E : utility_functions) { + const StringName &function_name = E; MethodAPI function_api; function_api.method_name = function_name; @@ -521,8 +521,8 @@ List<ClassAPI> generate_c_builtin_api_types() { List<StringName> methods; Variant::get_builtin_method_list(type, &methods); - for (const List<StringName>::Element *E = methods.front(); E; E = E->next()) { - const StringName &method_name = E->get(); + for (const StringName &E : methods) { + const StringName &method_name = E; MethodAPI method_api; @@ -578,8 +578,8 @@ List<ClassAPI> generate_c_builtin_api_types() { List<StringName> constants; Variant::get_constants_for_type(type, &constants); - for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) { - const StringName &constant_name = E->get(); + for (const StringName &E : constants) { + const StringName &constant_name = E; ConstantAPI constant_api; constant_api.constant_name = constant_name; @@ -593,8 +593,8 @@ List<ClassAPI> generate_c_builtin_api_types() { List<StringName> members; Variant::get_member_list(type, &members); - for (const List<StringName>::Element *E = members.front(); E; E = E->next()) { - const StringName &member_name = E->get(); + for (const StringName &E : members) { + const StringName &member_name = E; PropertyAPI member_api; member_api.name = member_name; diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index d7943827c2..f3a0e9603f 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -98,10 +98,10 @@ void NativeScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) List<PropertyInfo> info; get_script_property_list(&info); Map<StringName, Variant> values; - for (List<PropertyInfo>::Element *E = info.front(); E; E = E->next()) { + for (const PropertyInfo &E : info) { Variant value; - get_property_default_value(E->get().name, value); - values[E->get().name] = value; + get_property_default_value(E.name, value); + values[E.name] = value; } p_placeholder->update(info, values); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 8e5ae29ed9..a41c4f7b19 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -79,9 +79,7 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty List<String> entry_keys; config->get_section_keys("entry", &entry_keys); - for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { - String key = E->get(); - + for (const String &key : entry_keys) { Vector<String> tags = key.split("."); bool skip = false; @@ -112,9 +110,7 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty List<String> dependency_keys; config->get_section_keys("dependencies", &dependency_keys); - for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { - String key = E->get(); - + for (const String &key : dependency_keys) { Vector<String> tags = key.split("."); bool skip = false; @@ -149,9 +145,7 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty List<String> entry_keys; config->get_section_keys("entry", &entry_keys); - for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { - String key = E->get(); - + for (const String &key : entry_keys) { Vector<String> tags = key.split("."); bool skip = false; diff --git a/modules/gdnative/tests/test_variant.h b/modules/gdnative/tests/test_variant.h index 2850036604..c506882283 100644 --- a/modules/gdnative/tests/test_variant.h +++ b/modules/gdnative/tests/test_variant.h @@ -191,8 +191,8 @@ TEST_CASE("[GDNative Variant] Get utility function list") { godot_string_name *cur = c_list; - for (const List<StringName>::Element *E = cpp_list.front(); E; E = E->next()) { - const StringName &cpp_name = E->get(); + for (const StringName &E : cpp_list) { + const StringName &cpp_name = E; StringName *c_name = (StringName *)cur++; CHECK(*c_name == cpp_name); diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 839aa6b3c6..e68deb070d 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -241,16 +241,18 @@ </methods> <constants> <constant name="PI" value="3.14159265358979"> - Constant that represents how many times the diameter of a circle fits around its perimeter. This is equivalent to [code]TAU / 2[/code]. + Constant that represents how many times the diameter of a circle fits around its perimeter. This is equivalent to [code]TAU / 2[/code], or 180 degrees in rotations. </constant> <constant name="TAU" value="6.28318530717959"> - The circle constant, the circumference of the unit circle in radians. + The circle constant, the circumference of the unit circle in radians. This is equivalent to [code]PI * 2[/code], or 360 degrees in rotations. </constant> <constant name="INF" value="inf"> - Positive infinity. For negative infinity, use -INF. + Positive floating-point infinity. This is the result of floating-point division when the divisor is [code]0.0[/code]. For negative infinity, use [code]-INF[/code]. Dividing by [code]-0.0[/code] will result in negative infinity if the numerator is positive, so dividing by [code]0.0[/code] is not the same as dividing by [code]-0.0[/code] (despite [code]0.0 == -0.0[/code] returning [code]true[/code]). + [b]Note:[/b] Numeric infinity is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer number by [code]0[/code] will not result in [constant INF] and will result in a run-time error instead. </constant> <constant name="NAN" value="nan"> - "Not a Number", an invalid value. [code]NaN[/code] has special properties, including that it is not equal to itself. It is output by some invalid operations, such as dividing zero by zero. + "Not a Number", an invalid floating-point value. [constant NAN] has special properties, including that it is not equal to itself ([code]NAN == NAN[/code] returns [code]false[/code]). It is output by some invalid operations, such as dividing floating-point [code]0.0[/code] by [code]0.0[/code]. + [b]Note:[/b] "Not a Number" is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer [code]0[/code] by [code]0[/code] will not result in [constant NAN] and will result in a run-time error instead. </constant> </constants> </class> diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 9a4c22f49f..ed8b0a4690 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -458,8 +458,8 @@ void GDScriptSyntaxHighlighter::_update_cache() { const Color types_color = EDITOR_GET("text_editor/highlighting/engine_type_color"); List<StringName> types; ClassDB::get_class_list(&types); - for (List<StringName>::Element *E = types.front(); E; E = E->next()) { - String n = E->get(); + for (const StringName &E : types) { + String n = E; if (n.begins_with("_")) { n = n.substr(1, n.length()); } @@ -470,8 +470,8 @@ void GDScriptSyntaxHighlighter::_update_cache() { const Color usertype_color = EDITOR_GET("text_editor/highlighting/user_type_color"); List<StringName> global_classes; ScriptServer::get_global_class_list(&global_classes); - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - keywords[String(E->get())] = usertype_color; + for (const StringName &E : global_classes) { + keywords[String(E)] = usertype_color; } /* Autoloads. */ @@ -489,8 +489,8 @@ void GDScriptSyntaxHighlighter::_update_cache() { const Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color"); List<String> core_types; gdscript->get_core_type_words(&core_types); - for (List<String>::Element *E = core_types.front(); E; E = E->next()) { - keywords[E->get()] = basetype_color; + for (const String &E : core_types) { + keywords[E] = basetype_color; } /* Reserved words. */ @@ -498,11 +498,11 @@ void GDScriptSyntaxHighlighter::_update_cache() { const Color control_flow_keyword_color = EDITOR_GET("text_editor/highlighting/control_flow_keyword_color"); List<String> keyword_list; gdscript->get_reserved_words(&keyword_list); - for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) { - if (gdscript->is_control_flow_keyword(E->get())) { - keywords[E->get()] = control_flow_keyword_color; + for (const String &E : keyword_list) { + if (gdscript->is_control_flow_keyword(E)) { + keywords[E] = control_flow_keyword_color; } else { - keywords[E->get()] = keyword_color; + keywords[E] = keyword_color; } } @@ -510,8 +510,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { const Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color"); List<String> comments; gdscript->get_comment_delimiters(&comments); - for (List<String>::Element *E = comments.front(); E; E = E->next()) { - String comment = E->get(); + for (const String &comment : comments) { String beg = comment.get_slice(" ", 0); String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String(); add_color_region(beg, end, comment_color, end == ""); @@ -521,8 +520,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { const Color string_color = EDITOR_GET("text_editor/highlighting/string_color"); List<String> strings; gdscript->get_string_delimiters(&strings); - for (List<String>::Element *E = strings.front(); E; E = E->next()) { - String string = E->get(); + for (const String &string : strings) { String beg = string.get_slice(" ", 0); String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String(); add_color_region(beg, end, string_color, end == ""); @@ -536,9 +534,9 @@ void GDScriptSyntaxHighlighter::_update_cache() { if (instance_base != StringName()) { List<PropertyInfo> plist; ClassDB::get_property_list(instance_base, &plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - String name = E->get().name; - if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP) { + for (const PropertyInfo &E : plist) { + String name = E.name; + if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) { continue; } if (name.find("/") != -1) { @@ -549,8 +547,8 @@ void GDScriptSyntaxHighlighter::_update_cache() { List<String> clist; ClassDB::get_integer_constant_list(instance_base, &clist); - for (List<String>::Element *E = clist.front(); E; E = E->next()) { - member_keywords[E->get()] = member_variable_color; + for (const String &E : clist) { + member_keywords[E] = member_variable_color; } } } diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index f7113674ec..bcb53508ea 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -291,8 +291,8 @@ void GDScript::_get_script_property_list(List<PropertyInfo> *r_list, bool p_incl sptr = sptr->_base; } - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - r_list->push_back(E->get()); + for (const PropertyInfo &E : props) { + r_list->push_back(E); } } @@ -401,8 +401,8 @@ void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<Pro values[E->key()] = E->get(); } - for (List<PropertyInfo>::Element *E = members_cache.front(); E; E = E->next()) { - propnames.push_back(E->get()); + for (const PropertyInfo &E : members_cache) { + propnames.push_back(E); } } @@ -861,8 +861,7 @@ Error GDScript::reload(bool p_keep_state) { } } #ifdef DEBUG_ENABLED - for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E; E = E->next()) { - const GDScriptWarning &warning = E->get(); + for (const GDScriptWarning &warning : parser.get_warnings()) { if (EngineDebugger::is_active()) { Vector<ScriptLanguage::StackInfo> si; EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.start_line, warning.get_name(), warning.get_message(), ERR_HANDLER_WARNING, si); @@ -1445,8 +1444,8 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const sptr = sptr->_base; } - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - p_properties->push_back(E->get()); + for (const PropertyInfo &E : props) { + p_properties->push_back(E); } } @@ -1644,26 +1643,25 @@ void GDScriptLanguage::init() { List<StringName> class_list; ClassDB::get_class_list(&class_list); - for (List<StringName>::Element *E = class_list.front(); E; E = E->next()) { - StringName n = E->get(); + for (const StringName &n : class_list) { String s = String(n); if (s.begins_with("_")) { - n = s.substr(1, s.length()); + s = s.substr(1, s.length()); } - if (globals.has(n)) { + if (globals.has(s)) { continue; } - Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(E->get())); - _add_global(n, nc); + Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(n)); + _add_global(s, nc); } //populate singletons List<Engine::Singleton> singletons; Engine::get_singleton()->get_singletons(&singletons); - for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { - _add_global(E->get().name, E->get().ptr); + for (const Engine::Singleton &E : singletons) { + _add_global(E.name, E.ptr); } #ifdef TESTS_ENABLED @@ -1806,10 +1804,10 @@ void GDScriptLanguage::reload_all_scripts() { scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order - for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) { - print_verbose("GDScript: Reloading: " + E->get()->get_path()); - E->get()->load_source_code(E->get()->get_path()); - E->get()->reload(true); + for (Ref<GDScript> E : scripts) { + print_verbose("GDScript: Reloading: " + E->get_path()); + E->load_source_code(E->get_path()); + E->reload(true); } #endif } @@ -1838,21 +1836,21 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order - for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) { - bool reload = E->get() == p_script || to_reload.has(E->get()->get_base()); + for (Ref<GDScript> E : scripts) { + bool reload = E == p_script || to_reload.has(E->get_base()); if (!reload) { continue; } - to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant>>>()); + to_reload.insert(E, Map<ObjectID, List<Pair<StringName, Variant>>>()); if (!p_soft_reload) { //save state and remove script from instances - Map<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[E->get()]; + Map<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[E]; - while (E->get()->instances.front()) { - Object *obj = E->get()->instances.front()->get(); + while (E->instances.front()) { + Object *obj = E->instances.front()->get(); //save instance info List<Pair<StringName, Variant>> state; if (obj->get_script_instance()) { @@ -1865,8 +1863,8 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so //same thing for placeholders #ifdef TOOLS_ENABLED - while (E->get()->placeholders.size()) { - Object *obj = E->get()->placeholders.front()->get()->get_owner(); + while (E->placeholders.size()) { + Object *obj = E->placeholders.front()->get()->get_owner(); //save instance info if (obj->get_script_instance()) { @@ -1876,13 +1874,13 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so obj->set_script(Variant()); } else { // no instance found. Let's remove it so we don't loop forever - E->get()->placeholders.erase(E->get()->placeholders.front()->get()); + E->placeholders.erase(E->placeholders.front()->get()); } } #endif - for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) { + for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->pending_reload_state.front(); F; F = F->next()) { map[F->key()] = F->get(); //pending to reload, use this one instead } } @@ -2025,8 +2023,8 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { List<StringName> functions; GDScriptUtilityFunctions::get_function_list(&functions); - for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) { - p_words->push_back(String(E->get())); + for (const StringName &E : functions) { + p_words->push_back(String(E)); } } @@ -2296,8 +2294,8 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S return; } - for (const List<String>::Element *E = parser.get_dependencies().front(); E; E = E->next()) { - p_dependencies->push_back(E->get()); + for (const String &E : parser.get_dependencies()) { + p_dependencies->push_back(E); } } diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index e7fb33a6a7..ab37e54cf1 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -115,8 +115,8 @@ static GDScriptParser::DataType make_native_enum_type(const StringName &p_native StringName real_native_name = GDScriptParser::get_real_class_name(p_native_class); ClassDB::get_enum_constants(real_native_name, p_enum_name, &enum_values); - for (const List<StringName>::Element *E = enum_values.front(); E != nullptr; E = E->next()) { - type.enum_values[E->get()] = ClassDB::get_integer_constant(real_native_name, E->get()); + for (const StringName &E : enum_values) { + type.enum_values[E] = ClassDB::get_integer_constant(real_native_name, E); } return type; @@ -573,8 +573,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas member.variable->set_datatype(datatype); // Apply annotations. - for (List<GDScriptParser::AnnotationNode *>::Element *E = member.variable->annotations.front(); E; E = E->next()) { - E->get()->apply(parser, member.variable); + for (GDScriptParser::AnnotationNode *&E : member.variable->annotations) { + E->apply(parser, member.variable); } } break; case GDScriptParser::ClassNode::Member::CONSTANT: { @@ -622,8 +622,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas member.constant->set_datatype(datatype); // Apply annotations. - for (List<GDScriptParser::AnnotationNode *>::Element *E = member.constant->annotations.front(); E; E = E->next()) { - E->get()->apply(parser, member.constant); + for (GDScriptParser::AnnotationNode *&E : member.constant->annotations) { + E->apply(parser, member.constant); } } break; case GDScriptParser::ClassNode::Member::SIGNAL: { @@ -641,8 +641,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas member.signal->set_datatype(signal_type); // Apply annotations. - for (List<GDScriptParser::AnnotationNode *>::Element *E = member.signal->annotations.front(); E; E = E->next()) { - E->get()->apply(parser, member.signal); + for (GDScriptParser::AnnotationNode *&E : member.signal->annotations) { + E->apply(parser, member.signal); } } break; case GDScriptParser::ClassNode::Member::ENUM: { @@ -688,8 +688,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas member.m_enum->set_datatype(enum_type); // Apply annotations. - for (List<GDScriptParser::AnnotationNode *>::Element *E = member.m_enum->annotations.front(); E; E = E->next()) { - E->get()->apply(parser, member.m_enum); + for (GDScriptParser::AnnotationNode *&E : member.m_enum->annotations) { + E->apply(parser, member.m_enum); } } break; case GDScriptParser::ClassNode::Member::FUNCTION: @@ -761,8 +761,8 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class) { resolve_function_body(member.function); // Apply annotations. - for (List<GDScriptParser::AnnotationNode *>::Element *E = member.function->annotations.front(); E; E = E->next()) { - E->get()->apply(parser, member.function); + for (GDScriptParser::AnnotationNode *&E : member.function->annotations) { + E->apply(parser, member.function); } } @@ -1927,9 +1927,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa Variant::get_constructor_list(builtin_type, &constructors); bool match = false; - for (const List<MethodInfo>::Element *E = constructors.front(); E != nullptr; E = E->next()) { - const MethodInfo &info = E->get(); - + for (const MethodInfo &info : constructors) { if (p_call->arguments.size() < info.arguments.size() - info.default_arguments.size()) { continue; } @@ -2326,8 +2324,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod Variant::construct(base.builtin_type, dummy, nullptr, 0, temp); List<PropertyInfo> properties; dummy.get_property_list(&properties); - for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) { - const PropertyInfo &prop = E->get(); + for (const PropertyInfo &prop : properties) { if (prop.name == name) { p_identifier->set_datatype(type_from_property(prop)); return; @@ -3125,8 +3122,8 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_va GDScriptParser::ClassNode *found = ref->get_parser()->head; // It should be okay to assume this exists, since we have a complete script already. - for (const List<StringName>::Element *E = class_chain.front(); E; E = E->next()) { - found = found->get_member(E->get()).m_class; + for (const StringName &E : class_chain) { + found = found->get_member(E).m_class; } result.class_type = found; @@ -3222,9 +3219,9 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, GD List<MethodInfo> methods; dummy.get_method_list(&methods); - for (const List<MethodInfo>::Element *E = methods.front(); E != nullptr; E = E->next()) { - if (E->get().name == p_function) { - return function_signature_from_info(E->get(), r_return_type, r_par_types, r_default_arg_count, r_static, r_vararg); + for (const MethodInfo &E : methods) { + if (E.name == p_function) { + return function_signature_from_info(E, r_return_type, r_par_types, r_default_arg_count, r_static, r_vararg); } } @@ -3321,8 +3318,8 @@ bool GDScriptAnalyzer::function_signature_from_info(const MethodInfo &p_info, GD r_default_arg_count = p_info.default_arguments.size(); r_vararg = (p_info.flags & METHOD_FLAG_VARARG) != 0; - for (const List<PropertyInfo>::Element *E = p_info.arguments.front(); E != nullptr; E = E->next()) { - r_par_types.push_back(type_from_property(E->get())); + for (const PropertyInfo &E : p_info.arguments) { + r_par_types.push_back(type_from_property(E)); } return true; } @@ -3330,8 +3327,8 @@ bool GDScriptAnalyzer::function_signature_from_info(const MethodInfo &p_info, GD bool GDScriptAnalyzer::validate_call_arg(const MethodInfo &p_method, const GDScriptParser::CallNode *p_call) { List<GDScriptParser::DataType> arg_types; - for (const List<PropertyInfo>::Element *E = p_method.arguments.front(); E != nullptr; E = E->next()) { - arg_types.push_back(type_from_property(E->get())); + for (const PropertyInfo &E : p_method.arguments) { + arg_types.push_back(type_from_property(E)); } return validate_call_arg(arg_types, p_method.default_arguments.size(), (p_method.flags & METHOD_FLAG_VARARG) != 0, p_call); @@ -3658,11 +3655,11 @@ Error GDScriptAnalyzer::resolve_program() { List<String> parser_keys; depended_parsers.get_key_list(&parser_keys); - for (const List<String>::Element *E = parser_keys.front(); E != nullptr; E = E->next()) { - if (depended_parsers[E->get()].is_null()) { + for (const String &E : parser_keys) { + if (depended_parsers[E].is_null()) { return ERR_PARSE_ERROR; } - depended_parsers[E->get()]->raise_status(GDScriptParserRef::FULLY_SOLVED); + depended_parsers[E]->raise_status(GDScriptParserRef::FULLY_SOLVED); } return parser->errors.is_empty() ? OK : ERR_PARSE_ERROR; } diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 9ff5a342ec..5958326315 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -1459,8 +1459,8 @@ void GDScriptByteCodeGenerator::write_endfor() { } // Patch break statements. - for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) { - patch_jump(E->get()); + for (const int &E : current_breaks_to_patch.back()->get()) { + patch_jump(E); } current_breaks_to_patch.pop_back(); @@ -1494,8 +1494,8 @@ void GDScriptByteCodeGenerator::write_endwhile() { while_jmp_addrs.pop_back(); // Patch break statements. - for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) { - patch_jump(E->get()); + for (const int &E : current_breaks_to_patch.back()->get()) { + patch_jump(E); } current_breaks_to_patch.pop_back(); } @@ -1506,8 +1506,8 @@ void GDScriptByteCodeGenerator::start_match() { void GDScriptByteCodeGenerator::start_match_branch() { // Patch continue statements. - for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) { - patch_jump(E->get()); + for (const int &E : match_continues_to_patch.back()->get()) { + patch_jump(E); } match_continues_to_patch.pop_back(); // Start a new list for next branch. @@ -1516,8 +1516,8 @@ void GDScriptByteCodeGenerator::start_match_branch() { void GDScriptByteCodeGenerator::end_match() { // Patch continue statements. - for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) { - patch_jump(E->get()); + for (const int &E : match_continues_to_patch.back()->get()) { + patch_jump(E); } match_continues_to_patch.pop_back(); } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index fbe791a109..7c9d08b782 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -981,8 +981,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code assigned = prev_base; // Set back the values into their bases. - for (List<ChainInfo>::Element *E = set_chain.front(); E; E = E->next()) { - const ChainInfo &info = E->get(); + for (const ChainInfo &info : set_chain) { if (!info.is_named) { gen->write_set(info.base, info.key, assigned); if (info.key.mode == GDScriptCodeGenerator::Address::TEMPORARY) { diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 79023df284..2a93bb620b 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -141,8 +141,8 @@ bool GDScriptLanguage::validate(const String &p_script, const String &p_path, Li } #ifdef DEBUG_ENABLED if (r_warnings) { - for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E; E = E->next()) { - const GDScriptWarning &warn = E->get(); + for (const GDScriptWarning &E : parser.get_warnings()) { + const GDScriptWarning &warn = E; ScriptLanguage::Warning w; w.start_line = warn.start_line; w.end_line = warn.end_line; @@ -157,8 +157,8 @@ bool GDScriptLanguage::validate(const String &p_script, const String &p_path, Li #endif if (err) { if (r_errors) { - for (const List<GDScriptParser::ParserError>::Element *E = parser.get_errors().front(); E; E = E->next()) { - const GDScriptParser::ParserError &pe = E->get(); + for (const GDScriptParser::ParserError &E : parser.get_errors()) { + const GDScriptParser::ParserError &pe = E; ScriptLanguage::ScriptError e; e.line = pe.line; e.column = pe.column; @@ -319,9 +319,9 @@ void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p List<Pair<StringName, int>> locals; f->debug_get_stack_member_state(*_call_stack[l].line, &locals); - for (List<Pair<StringName, int>>::Element *E = locals.front(); E; E = E->next()) { - p_locals->push_back(E->get().first); - p_values->push_back(_call_stack[l].stack[E->get().second]); + for (const Pair<StringName, int> &E : locals) { + p_locals->push_back(E.first); + p_values->push_back(_call_stack[l].stack[E.second]); } } @@ -421,8 +421,8 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const List<StringName> functions; GDScriptUtilityFunctions::get_function_list(&functions); - for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) { - p_functions->push_back(GDScriptUtilityFunctions::get_function_info(E->get())); + for (const StringName &E : functions) { + p_functions->push_back(GDScriptUtilityFunctions::get_function_info(E)); } // Not really "functions", but show in documentation. @@ -548,7 +548,7 @@ static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx, bool int def_args = p_info.arguments.size() - p_info.default_arguments.size(); int i = 0; - for (const List<PropertyInfo>::Element *E = p_info.arguments.front(); E; E = E->next()) { + for (const PropertyInfo &E : p_info.arguments) { if (i > 0) { arghint += ", "; } @@ -556,7 +556,7 @@ static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx, bool if (i == p_arg_idx) { arghint += String::chr(0xFFFF); } - arghint += E->get().name + ": " + _get_visual_datatype(E->get(), true); + arghint += E.name + ": " + _get_visual_datatype(E, true); if (i - def_args >= 0) { arghint += String(" = ") + p_info.default_arguments[i - def_args].get_construct_string(); @@ -662,11 +662,11 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a r_result.insert(node.display, node); List<StringName> node_types; ClassDB::get_inheriters_from_class("Node", &node_types); - for (const List<StringName>::Element *E = node_types.front(); E != nullptr; E = E->next()) { - if (!ClassDB::is_class_exposed(E->get())) { + for (const StringName &E : node_types) { + if (!ClassDB::is_class_exposed(E)) { continue; } - ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CLASS); + ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS); r_result.insert(option.display, option); } } @@ -675,9 +675,9 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a static void _list_available_types(bool p_inherit_only, GDScriptParser::CompletionContext &p_context, Map<String, ScriptCodeCompletionOption> &r_result) { List<StringName> native_types; ClassDB::get_class_list(&native_types); - for (const List<StringName>::Element *E = native_types.front(); E != nullptr; E = E->next()) { - if (ClassDB::is_class_exposed(E->get()) && !Engine::get_singleton()->has_singleton(E->get())) { - ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CLASS); + for (const StringName &E : native_types) { + if (ClassDB::is_class_exposed(E) && !Engine::get_singleton()->has_singleton(E)) { + ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS); r_result.insert(option.display, option); } } @@ -687,8 +687,8 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio // Native enums from base class List<StringName> enums; ClassDB::get_enum_list(p_context.current_class->base_type.native_type, &enums); - for (const List<StringName>::Element *E = enums.front(); E != nullptr; E = E->next()) { - ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_ENUM); + for (const StringName &E : enums) { + ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_ENUM); r_result.insert(option.display, option); } } @@ -725,8 +725,8 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio // Global scripts List<StringName> global_classes; ScriptServer::get_global_class_list(&global_classes); - for (const List<StringName>::Element *E = global_classes.front(); E != nullptr; E = E->next()) { - ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CLASS); + for (const StringName &E : global_classes) { + ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS); r_result.insert(option.display, option); } @@ -865,8 +865,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base if (!_static) { List<PropertyInfo> members; scr->get_script_property_list(&members); - for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { - ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + for (const PropertyInfo &E : members) { + ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_MEMBER); r_result.insert(option.display, option); } } @@ -879,20 +879,20 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base List<MethodInfo> signals; scr->get_script_signal_list(&signals); - for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL); + for (const MethodInfo &E : signals) { + ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_SIGNAL); r_result.insert(option.display, option); } } List<MethodInfo> methods; scr->get_script_method_list(&methods); - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().name.begins_with("@")) { + for (const MethodInfo &E : methods) { + if (E.name.begins_with("@")) { continue; } - ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); - if (E->get().arguments.size()) { + ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_FUNCTION); + if (E.arguments.size()) { option.insert_text += "("; } else { option.insert_text += "()"; @@ -920,22 +920,22 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base if (!p_only_functions) { List<String> constants; ClassDB::get_integer_constant_list(type, &constants); - for (List<String>::Element *E = constants.front(); E; E = E->next()) { - ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT); + for (const String &E : constants) { + ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CONSTANT); r_result.insert(option.display, option); } if (!_static || Engine::get_singleton()->has_singleton(type)) { List<PropertyInfo> pinfo; ClassDB::get_property_list(type, &pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) { + for (const PropertyInfo &E : pinfo) { + if (E.usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) { continue; } - if (E->get().name.find("/") != -1) { + if (E.name.find("/") != -1) { continue; } - ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_MEMBER); r_result.insert(option.display, option); } } @@ -945,12 +945,12 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base List<MethodInfo> methods; bool is_autocompleting_getters = GLOBAL_GET("debug/gdscript/completion/autocomplete_setters_and_getters").booleanize(); ClassDB::get_method_list(type, &methods, false, !is_autocompleting_getters); - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().name.begins_with("_")) { + for (const MethodInfo &E : methods) { + if (E.name.begins_with("_")) { continue; } - ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); - if (E->get().arguments.size()) { + ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_FUNCTION); + if (E.arguments.size()) { option.insert_text += "("; } else { option.insert_text += "()"; @@ -977,9 +977,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base tmp.get_property_list(&members); } - for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { - if (String(E->get().name).find("/") == -1) { - ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + for (const PropertyInfo &E : members) { + if (String(E.name).find("/") == -1) { + ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_MEMBER); r_result.insert(option.display, option); } } @@ -987,9 +987,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base List<MethodInfo> methods; tmp.get_method_list(&methods); - for (const List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); - if (E->get().arguments.size()) { + for (const MethodInfo &E : methods) { + ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_FUNCTION); + if (E.arguments.size()) { option.insert_text += "("; } else { option.insert_text += "()"; @@ -1019,9 +1019,9 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool List<StringName> functions; GDScriptUtilityFunctions::get_function_list(&functions); - for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) { - MethodInfo function = GDScriptUtilityFunctions::get_function_info(E->get()); - ScriptCodeCompletionOption option(String(E->get()), ScriptCodeCompletionOption::KIND_FUNCTION); + for (const StringName &E : functions) { + MethodInfo function = GDScriptUtilityFunctions::get_function_info(E); + ScriptCodeCompletionOption option(String(E), ScriptCodeCompletionOption::KIND_FUNCTION); if (function.arguments.size() || (function.flags & METHOD_FLAG_VARARG)) { option.insert_text += "("; } else { @@ -1768,9 +1768,9 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context, StringName real_native = GDScriptParser::get_real_class_name(base_type.native_type); MethodInfo info; if (ClassDB::get_method_info(real_native, p_context.current_function->identifier->name, &info)) { - for (const List<PropertyInfo>::Element *E = info.arguments.front(); E; E = E->next()) { - if (E->get().name == p_identifier) { - r_type = _type_from_property(E->get()); + for (const PropertyInfo &E : info.arguments) { + if (E.name == p_identifier) { + r_type = _type_from_property(E); return true; } } @@ -1932,8 +1932,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext & if (!is_static) { List<PropertyInfo> members; scr->get_script_property_list(&members); - for (const List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { - const PropertyInfo &prop = E->get(); + for (const PropertyInfo &prop : members) { if (prop.name == p_identifier) { r_type = _type_from_property(prop); return true; @@ -2096,8 +2095,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex if (scr.is_valid()) { List<MethodInfo> methods; scr->get_script_method_list(&methods); - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - MethodInfo &mi = E->get(); + for (const MethodInfo &mi : methods) { if (mi.name == p_method) { r_type = _type_from_property(mi.return_val); return true; @@ -2137,8 +2135,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex List<MethodInfo> methods; tmp.get_method_list(&methods); - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - MethodInfo &mi = E->get(); + for (const MethodInfo &mi : methods) { if (mi.name == p_method) { r_type = _type_from_property(mi.return_val); return true; @@ -2183,8 +2180,8 @@ static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_co List<StringName> enum_constants; ClassDB::get_enum_constants(class_name, enum_name, &enum_constants); - for (List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) { - String candidate = class_name + "." + E->get(); + for (const StringName &E : enum_constants) { + String candidate = class_name + "." + E; ScriptCodeCompletionOption option(candidate, ScriptCodeCompletionOption::KIND_ENUM); r_result.insert(option.display, option); } @@ -2228,8 +2225,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c if (obj) { List<String> options; obj->get_argument_options(p_method, p_argidx, &options); - for (List<String>::Element *F = options.front(); F; F = F->next()) { - ScriptCodeCompletionOption option(F->get(), ScriptCodeCompletionOption::KIND_FUNCTION); + for (const String &F : options) { + ScriptCodeCompletionOption option(F, ScriptCodeCompletionOption::KIND_FUNCTION); r_result.insert(option.display, option); } } @@ -2250,8 +2247,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; + for (const PropertyInfo &E : props) { + String s = E.name; if (!s.begins_with("autoload/")) { continue; } @@ -2266,8 +2263,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c // Get input actions List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; + for (const PropertyInfo &E : props) { + String s = E.name; if (!s.begins_with("input/")) { continue; } @@ -2291,9 +2288,9 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c List<MethodInfo> methods; base.get_method_list(&methods); - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().name == p_method) { - r_arghint = _make_arguments_hint(E->get(), p_argidx); + for (const MethodInfo &E : methods) { + if (E.name == p_method) { + r_arghint = _make_arguments_hint(E, p_argidx); return; } } @@ -2340,14 +2337,14 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c Variant::get_constructor_list(GDScriptParser::get_builtin_type(call->function_name), &constructors); int i = 0; - for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) { - if (p_argidx >= E->get().arguments.size()) { + for (const MethodInfo &E : constructors) { + if (p_argidx >= E.arguments.size()) { continue; } if (i > 0) { r_arghint += "\n"; } - r_arghint += _make_arguments_hint(E->get(), p_argidx); + r_arghint += _make_arguments_hint(E, p_argidx); i++; } return; @@ -2406,9 +2403,9 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c case GDScriptParser::COMPLETION_ANNOTATION: { List<MethodInfo> annotations; parser.get_annotation_list(&annotations); - for (const List<MethodInfo>::Element *E = annotations.front(); E != nullptr; E = E->next()) { - ScriptCodeCompletionOption option(E->get().name.substr(1), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); - if (E->get().arguments.size() > 0) { + for (const MethodInfo &E : annotations) { + ScriptCodeCompletionOption option(E.name.substr(1), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + if (E.arguments.size() > 0) { option.insert_text += "("; } options.insert(option.display, option); @@ -2426,10 +2423,10 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c case GDScriptParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: { List<StringName> constants; Variant::get_constants_for_type(completion_context.builtin_type, &constants); - for (const List<StringName>::Element *E = constants.front(); E != nullptr; E = E->next()) { - ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT); + for (const StringName &E : constants) { + ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CONSTANT); bool valid = false; - Variant default_value = Variant::get_constant_value(completion_context.builtin_type, E->get(), &valid); + Variant default_value = Variant::get_constant_value(completion_context.builtin_type, E, &valid); if (valid) { option.default_value = default_value; } @@ -2606,8 +2603,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c List<MethodInfo> virtual_methods; ClassDB::get_virtual_methods(class_name, &virtual_methods); - for (List<MethodInfo>::Element *E = virtual_methods.front(); E; E = E->next()) { - MethodInfo &mi = E->get(); + for (const MethodInfo &mi : virtual_methods) { String method_hint = mi.name; if (method_hint.find(":") != -1) { method_hint = method_hint.get_slice(":", 0); @@ -2656,8 +2652,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c List<String> opts; p_owner->get_argument_options("get_node", 0, &opts); - for (List<String>::Element *E = opts.front(); E; E = E->next()) { - String opt = E->get().strip_edges(); + for (const String &E : opts) { + String opt = E.strip_edges(); if (opt.is_quoted()) { r_forced = true; String idopt = opt.unquote(); @@ -2841,8 +2837,8 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co List<MethodInfo> virtual_methods; ClassDB::get_virtual_methods(class_name, &virtual_methods, true); - for (List<MethodInfo>::Element *E = virtual_methods.front(); E; E = E->next()) { - if (E->get().name == p_symbol) { + for (const MethodInfo &E : virtual_methods) { + if (E.name == p_symbol) { r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_METHOD; r_result.class_name = base_type.native_type; r_result.class_member = p_symbol; @@ -2860,8 +2856,8 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co List<String> constants; ClassDB::get_integer_constant_list(class_name, &constants, true); - for (List<String>::Element *E = constants.front(); E; E = E->next()) { - if (E->get() == p_symbol) { + for (const String &E : constants) { + if (E == p_symbol) { r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT; r_result.class_name = base_type.native_type; r_result.class_member = p_symbol; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index f300d5a2c9..876c508689 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -94,8 +94,7 @@ struct _GDFKCS { void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const { int oc = 0; Map<StringName, _GDFKC> sdmap; - for (const List<StackDebug>::Element *E = stack_debug.front(); E; E = E->next()) { - const StackDebug &sd = E->get(); + for (const StackDebug &sd : stack_debug) { if (sd.line > p_line) { break; } @@ -131,10 +130,10 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String stackpositions.sort(); - for (List<_GDFKCS>::Element *E = stackpositions.front(); E; E = E->next()) { + for (_GDFKCS &E : stackpositions) { Pair<StringName, int> p; - p.first = E->get().id; - p.second = E->get().pos; + p.first = E.id; + p.second = E.pos; r_stackvars->push_back(p); } } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e103d86b15..466ddb4b10 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -136,8 +136,8 @@ void GDScriptParser::cleanup() { void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const { List<StringName> keys; valid_annotations.get_key_list(&keys); - for (const List<StringName>::Element *E = keys.front(); E != nullptr; E = E->next()) { - r_annotations->push_back(valid_annotations[E->get()].info); + for (const StringName &E : keys) { + r_annotations->push_back(valid_annotations[E].info); } } @@ -248,7 +248,7 @@ void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_ warning.rightmost_column = p_source->rightmost_column; List<GDScriptWarning>::Element *before = nullptr; - for (List<GDScriptWarning>::Element *E = warnings.front(); E != nullptr; E = E->next()) { + for (List<GDScriptWarning>::Element *E = warnings.front(); E; E = E->next()) { if (E->get().start_line > warning.start_line) { break; } @@ -1332,8 +1332,7 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali } void GDScriptParser::clear_unused_annotations() { - for (const List<AnnotationNode *>::Element *E = annotation_stack.front(); E != nullptr; E = E->next()) { - AnnotationNode *annotation = E->get(); + for (const AnnotationNode *annotation : annotation_stack) { push_error(vformat(R"(Annotation "%s" does not precedes a valid target, so it will have no effect.)", annotation->name), annotation); } @@ -1796,8 +1795,8 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() { List<StringName> binds; branch->patterns[0]->binds.get_key_list(&binds); - for (List<StringName>::Element *E = binds.front(); E != nullptr; E = E->next()) { - SuiteNode::Local local(branch->patterns[0]->binds[E->get()], current_function); + for (const StringName &E : binds) { + SuiteNode::Local local(branch->patterns[0]->binds[E], current_function); suite->add_local(local); } } @@ -3618,7 +3617,7 @@ void GDScriptParser::TreePrinter::push_text(const String &p_text) { printed += p_text; } -void GDScriptParser::TreePrinter::print_annotation(AnnotationNode *p_annotation) { +void GDScriptParser::TreePrinter::print_annotation(const AnnotationNode *p_annotation) { push_text(p_annotation->name); push_text(" ("); for (int i = 0; i < p_annotation->arguments.size(); i++) { @@ -3993,8 +3992,8 @@ void GDScriptParser::TreePrinter::print_for(ForNode *p_for) { } void GDScriptParser::TreePrinter::print_function(FunctionNode *p_function, const String &p_context) { - for (const List<AnnotationNode *>::Element *E = p_function->annotations.front(); E != nullptr; E = E->next()) { - print_annotation(E->get()); + for (const AnnotationNode *E : p_function->annotations) { + print_annotation(E); } push_text(p_context); push_text(" "); @@ -4333,8 +4332,8 @@ void GDScriptParser::TreePrinter::print_unary_op(UnaryOpNode *p_unary_op) { } void GDScriptParser::TreePrinter::print_variable(VariableNode *p_variable) { - for (const List<AnnotationNode *>::Element *E = p_variable->annotations.front(); E != nullptr; E = E->next()) { - print_annotation(E->get()); + for (const AnnotationNode *E : p_variable->annotations) { + print_annotation(E); } push_text("Variable "); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 043d87c705..6a227a55e5 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1431,7 +1431,7 @@ public: void push_line(const String &p_line = String()); void push_text(const String &p_text); - void print_annotation(AnnotationNode *p_annotation); + void print_annotation(const AnnotationNode *p_annotation); void print_array(ArrayNode *p_array); void print_assert(AssertNode *p_assert); void print_assignment(AssignmentNode *p_assignment); diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index 64c629662c..62531473c3 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -706,8 +706,8 @@ bool GDScriptUtilityFunctions::function_exists(const StringName &p_function) { } void GDScriptUtilityFunctions::get_function_list(List<StringName> *r_functions) { - for (const List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) { - r_functions->push_back(E->get()); + for (const StringName &E : utility_function_name_table) { + r_functions->push_back(E); } } diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index e9a7bf3830..b3469ec47c 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -39,8 +39,7 @@ void ExtendGDScriptParser::update_diagnostics() { diagnostics.clear(); const List<ParserError> &errors = get_errors(); - for (const List<ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) { - const ParserError &error = E->get(); + for (const ParserError &error : errors) { lsp::Diagnostic diagnostic; diagnostic.severity = lsp::DiagnosticSeverity::Error; diagnostic.message = error.message; @@ -61,8 +60,7 @@ void ExtendGDScriptParser::update_diagnostics() { } const List<GDScriptWarning> &warnings = get_warnings(); - for (const List<GDScriptWarning>::Element *E = warnings.front(); E; E = E->next()) { - const GDScriptWarning &warning = E->get(); + for (const GDScriptWarning &warning : warnings) { lsp::Diagnostic diagnostic; diagnostic.severity = lsp::DiagnosticSeverity::Warning; diagnostic.message = "(" + warning.get_name() + "): " + warning.get_message(); @@ -467,8 +465,8 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) { } String doc; - for (List<String>::Element *E = doc_lines.front(); E; E = E->next()) { - doc += E->get() + "\n"; + for (const String &E : doc_lines) { + doc += E + "\n"; } return doc; } diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 55aff618aa..69ddbe5d1e 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -157,8 +157,7 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) { int i = 0; arr.resize(options.size()); - for (const List<ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) { - const ScriptCodeCompletionOption &option = E->get(); + for (const ScriptCodeCompletionOption &option : options) { lsp::CompletionItem item; item.label = option.display; item.data = request_data; @@ -294,8 +293,8 @@ Array GDScriptTextDocument::documentLink(const Dictionary &p_params) { List<lsp::DocumentLink> links; GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_document_links(params.textDocument.uri, links); - for (const List<lsp::DocumentLink>::Element *E = links.front(); E; E = E->next()) { - ret.push_back(E->get().to_json()); + for (const lsp::DocumentLink &E : links) { + ret.push_back(E.to_json()); } return ret; } @@ -322,8 +321,8 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) { Array contents; List<const lsp::DocumentSymbol *> list; GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(params, list); - for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) { - if (const lsp::DocumentSymbol *s = E->get()) { + for (const lsp::DocumentSymbol *&E : list) { + if (const lsp::DocumentSymbol *s = E) { contents.push_back(s->render().value); } } @@ -430,8 +429,8 @@ Array GDScriptTextDocument::find_symbols(const lsp::TextDocumentPositionParams & } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { List<const lsp::DocumentSymbol *> list; GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(p_location, list); - for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) { - if (const lsp::DocumentSymbol *s = E->get()) { + for (const lsp::DocumentSymbol *&E : list) { + if (const lsp::DocumentSymbol *s = E) { if (!s->uri.is_empty()) { lsp::Location location; location.uri = s->uri; diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 1915c92cbf..e6c819b22f 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -119,8 +119,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_ void GDScriptWorkspace::reload_all_workspace_scripts() { List<String> paths; list_script_files("res://", paths); - for (List<String>::Element *E = paths.front(); E; E = E->next()) { - const String &path = E->get(); + for (const String &path : paths) { Error err; String content = FileAccess::get_file_as_string(path, &err); ERR_CONTINUE(err != OK); @@ -559,8 +558,8 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::N void GDScriptWorkspace::resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list) { if (const ExtendGDScriptParser *parser = get_parse_successed_script(get_file_path(p_uri))) { const List<lsp::DocumentLink> &links = parser->get_document_links(); - for (const List<lsp::DocumentLink>::Element *E = links.front(); E; E = E->next()) { - r_list.push_back(E->get()); + for (const lsp::DocumentLink &E : links) { + r_list.push_back(E); } } } @@ -587,8 +586,7 @@ Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(text_pos, symbols); } - for (List<const lsp::DocumentSymbol *>::Element *E = symbols.front(); E; E = E->next()) { - const lsp::DocumentSymbol *symbol = E->get(); + for (const lsp::DocumentSymbol *const &symbol : symbols) { if (symbol->kind == lsp::SymbolKind::Method || symbol->kind == lsp::SymbolKind::Function) { lsp::SignatureInformation signature_info; signature_info.label = symbol->detail; diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index b7faebb4ef..03a48bf071 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -295,7 +295,7 @@ void GDScriptTestRunner::handle_cmdline() { String test_cmd = "--gdscript-test"; String gen_cmd = "--gdscript-generate-tests"; - for (List<String>::Element *E = cmdline_args.front(); E != nullptr; E = E->next()) { + for (List<String>::Element *E = cmdline_args.front(); E; E = E->next()) { String &cmd = E->get(); if (cmd == test_cmd || cmd == gen_cmd) { if (E->next() == nullptr) { @@ -440,8 +440,8 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) { result.output = get_text_for_status(result.status) + "\n"; const List<GDScriptParser::ParserError> &errors = parser.get_errors(); - for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E; E = E->next()) { - result.output += E->get().message + "\n"; // TODO: line, column? + for (const GDScriptParser::ParserError &E : errors) { + result.output += E.message + "\n"; // TODO: line, column? break; // Only the first error since the following might be cascading. } if (!p_is_generating) { @@ -459,8 +459,8 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) { result.output = get_text_for_status(result.status) + "\n"; const List<GDScriptParser::ParserError> &errors = parser.get_errors(); - for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E; E = E->next()) { - result.output += E->get().message + "\n"; // TODO: line, column? + for (const GDScriptParser::ParserError &E : errors) { + result.output += E.message + "\n"; // TODO: line, column? break; // Only the first error since the following might be cascading. } if (!p_is_generating) { @@ -470,8 +470,8 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) { } StringBuilder warning_string; - for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E != nullptr; E = E->next()) { - const GDScriptWarning warning = E->get(); + for (const GDScriptWarning &E : parser.get_warnings()) { + const GDScriptWarning warning = E; warning_string.append(">> WARNING"); warning_string.append("\n>> Line: "); warning_string.append(itos(warning.start_line)); diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index 7aa5895981..52e9d92223 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -113,8 +113,7 @@ static void test_parser(const String &p_code, const String &p_script_path, const if (err != OK) { const List<GDScriptParser::ParserError> &errors = parser.get_errors(); - for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) { - const GDScriptParser::ParserError &error = E->get(); + for (const GDScriptParser::ParserError &error : errors) { print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message)); } } @@ -124,8 +123,7 @@ static void test_parser(const String &p_code, const String &p_script_path, const if (err != OK) { const List<GDScriptParser::ParserError> &errors = parser.get_errors(); - for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) { - const GDScriptParser::ParserError &error = E->get(); + for (const GDScriptParser::ParserError &error : errors) { print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message)); } } @@ -143,8 +141,7 @@ static void test_compiler(const String &p_code, const String &p_script_path, con if (err != OK) { print_line("Error in parser:"); const List<GDScriptParser::ParserError> &errors = parser.get_errors(); - for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) { - const GDScriptParser::ParserError &error = E->get(); + for (const GDScriptParser::ParserError &error : errors) { print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message)); } return; @@ -156,8 +153,7 @@ static void test_compiler(const String &p_code, const String &p_script_path, con if (err != OK) { print_line("Error in analyzer:"); const List<GDScriptParser::ParserError> &errors = parser.get_errors(); - for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) { - const GDScriptParser::ParserError &error = E->get(); + for (const GDScriptParser::ParserError &error : errors) { print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message)); } return; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 09bae884b9..30d023606f 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -2796,7 +2796,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) { mat = mat3d; } - import_mesh->add_surface(primitive, array, morphs, Dictionary(), mat, mat->get_name()); + import_mesh->add_surface(primitive, array, morphs, Dictionary(), mat, mat.is_valid() ? mat->get_name() : String()); } Vector<float> blend_weights; diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 0cd41133f1..fea513c820 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -519,14 +519,14 @@ bool GridMap::_octant_update(const OctantKey &p_key) { RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); int idx = 0; - for (List<Pair<Transform3D, IndexKey>>::Element *F = E->get().front(); F; F = F->next()) { - RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F->get().first); + for (const Pair<Transform3D, IndexKey> &F : E->get()) { + RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F.first); #ifdef TOOLS_ENABLED Octant::MultimeshInstance::Item it; it.index = idx; - it.transform = F->get().first; - it.key = F->get().second; + it.transform = F.first; + it.key = F.second; mmi.items.push_back(it); #endif diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 046f8c0adb..989c2d295c 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -497,8 +497,8 @@ void GridMapEditor::_fill_selection() { } void GridMapEditor::_clear_clipboard_data() { - for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - RenderingServer::get_singleton()->free(E->get().instance); + for (const ClipboardItem &E : clipboard_items) { + RenderingServer::get_singleton()->free(E.instance); } clipboard_items.clear(); @@ -552,9 +552,7 @@ void GridMapEditor::_update_paste_indicator() { RenderingServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf); - for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - ClipboardItem &item = E->get(); - + for (const ClipboardItem &item : clipboard_items) { xf = Transform3D(); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); xf.basis = rot * xf.basis; @@ -578,9 +576,7 @@ void GridMapEditor::_do_paste() { Vector3 ofs = paste_indicator.current - paste_indicator.click; undo_redo->create_action(TTR("GridMap Paste Selection")); - for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - ClipboardItem &item = E->get(); - + for (const ClipboardItem &item : clipboard_items) { Vector3 position = rot.xform(item.grid_offset) + paste_indicator.begin + ofs; Basis orm; @@ -663,8 +659,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In if ((mb->get_button_index() == MOUSE_BUTTON_RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action == INPUT_PAINT)) { if (set_items.size()) { undo_redo->create_action(TTR("GridMap Paint")); - for (List<SetItem>::Element *E = set_items.front(); E; E = E->next()) { - const SetItem &si = E->get(); + for (const SetItem &si : set_items) { undo_redo->add_do_method(node, "set_cell_item", si.position, si.new_value, si.new_orientation); } for (List<SetItem>::Element *E = set_items.back(); E; E = E->prev()) { @@ -869,8 +864,8 @@ void GridMapEditor::update_palette() { int item = 0; - for (List<_CGMEItemSort>::Element *E = il.front(); E; E = E->next()) { - int id = E->get().id; + for (_CGMEItemSort &E : il) { + int id = E.id; String name = mesh_library->get_item_name(id); Ref<Texture2D> preview = mesh_library->get_item_preview(id); diff --git a/modules/mono/.editorconfig b/modules/mono/.editorconfig new file mode 100644 index 0000000000..c9dcd7724e --- /dev/null +++ b/modules/mono/.editorconfig @@ -0,0 +1,14 @@ +[*.sln] +indent_style = tab + +[*.{csproj,props,targets,nuspec,resx}] +indent_style = space +indent_size = 2 + +[*.cs] +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 120 +csharp_indent_case_contents_when_block = false diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp index 25193a1352..0da06131af 100644 --- a/modules/mono/class_db_api_json.cpp +++ b/modules/mono/class_db_api_json.cpp @@ -50,8 +50,8 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { //must be alphabetically sorted for hash to compute names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - ClassDB::ClassInfo *t = ClassDB::classes.getptr(E->get()); + for (const StringName &E : names) { + ClassDB::ClassInfo *t = ClassDB::classes.getptr(E); ERR_FAIL_COND(!t); if (t->api != p_api || !t->exposed) { continue; @@ -84,11 +84,11 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { Array methods; - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + for (const StringName &F : snames) { Dictionary method_dict; methods.push_back(method_dict); - MethodBind *mb = t->method_map[F->get()]; + MethodBind *mb = t->method_map[F]; method_dict["name"] = mb->get_name(); method_dict["argument_count"] = mb->get_argument_count(); method_dict["return_type"] = mb->get_argument_type(-1); @@ -141,12 +141,12 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { Array constants; - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + for (const StringName &F : snames) { Dictionary constant_dict; constants.push_back(constant_dict); - constant_dict["name"] = F->get(); - constant_dict["value"] = t->constant_map[F->get()]; + constant_dict["name"] = F; + constant_dict["value"] = t->constant_map[F]; } if (!constants.is_empty()) { @@ -168,12 +168,12 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { Array signals; - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + for (const StringName &F : snames) { Dictionary signal_dict; signals.push_back(signal_dict); - MethodInfo &mi = t->signal_map[F->get()]; - signal_dict["name"] = F->get(); + MethodInfo &mi = t->signal_map[F]; + signal_dict["name"] = F; Array arguments; signal_dict["arguments"] = arguments; @@ -203,13 +203,13 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { Array properties; - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + for (const StringName &F : snames) { Dictionary property_dict; properties.push_back(property_dict); - ClassDB::PropertySetGet *psg = t->property_setget.getptr(F->get()); + ClassDB::PropertySetGet *psg = t->property_setget.getptr(F); - property_dict["name"] = F->get(); + property_dict["name"] = F; property_dict["setter"] = psg->setter; property_dict["getter"] = psg->getter; } @@ -222,15 +222,15 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { Array property_list; //property list - for (List<PropertyInfo>::Element *F = t->property_list.front(); F; F = F->next()) { + for (const PropertyInfo &F : t->property_list) { Dictionary property_dict; property_list.push_back(property_dict); - property_dict["name"] = F->get().name; - property_dict["type"] = F->get().type; - property_dict["hint"] = F->get().hint; - property_dict["hint_string"] = F->get().hint_string; - property_dict["usage"] = F->get().usage; + property_dict["name"] = F.name; + property_dict["type"] = F.type; + property_dict["hint"] = F.hint; + property_dict["hint_string"] = F.hint_string; + property_dict["usage"] = F.usage; } if (!property_list.is_empty()) { diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 80675feb3b..b52277974f 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -874,9 +874,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { // As scripts are going to be reloaded, must proceed without locking here - for (List<Ref<CSharpScript>>::Element *E = scripts.front(); E; E = E->next()) { - Ref<CSharpScript> &script = E->get(); - + for (Ref<CSharpScript> script : scripts) { to_reload.push_back(script); if (script->get_path().is_empty()) { @@ -936,9 +934,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { } // After the state of all instances is saved, clear scripts and script instances - for (List<Ref<CSharpScript>>::Element *E = scripts.front(); E; E = E->next()) { - Ref<CSharpScript> &script = E->get(); - + for (Ref<CSharpScript> script : scripts) { while (script->instances.front()) { Object *obj = script->instances.front()->get(); obj->set_script(REF()); // Remove script and existing script instances (placeholder are not removed before domain reload) @@ -951,9 +947,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { if (gdmono->reload_scripts_domain() != OK) { // Failed to reload the scripts domain // Make sure to add the scripts back to their owners before returning - for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) { - Ref<CSharpScript> scr = E->get(); - + for (Ref<CSharpScript> scr : to_reload) { for (const Map<ObjectID, CSharpScript::StateBackup>::Element *F = scr->pending_reload_state.front(); F; F = F->next()) { Object *obj = ObjectDB::get_instance(F->key()); @@ -988,9 +982,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { List<Ref<CSharpScript>> to_reload_state; - for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) { - Ref<CSharpScript> script = E->get(); - + for (Ref<CSharpScript> script : to_reload) { #ifdef TOOLS_ENABLED script->exports_invalidated = true; #endif @@ -1095,9 +1087,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { to_reload_state.push_back(script); } - for (List<Ref<CSharpScript>>::Element *E = to_reload_state.front(); E; E = E->next()) { - Ref<CSharpScript> script = E->get(); - + for (Ref<CSharpScript> script : to_reload_state) { for (Set<ObjectID>::Element *F = script->pending_reload_instances.front(); F; F = F->next()) { ObjectID obj_id = F->get(); Object *obj = ObjectDB::get_instance(obj_id); @@ -1741,9 +1731,9 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va List<PropertyInfo> pinfo; get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + for (const PropertyInfo &E : pinfo) { Pair<StringName, Variant> state_pair; - state_pair.first = E->get().name; + state_pair.first = E.name; ManagedType managedType; @@ -2049,8 +2039,7 @@ void CSharpInstance::connect_event_signals() { } void CSharpInstance::disconnect_event_signals() { - for (const List<Callable>::Element *E = connected_event_signals.front(); E; E = E->next()) { - const Callable &callable = E->get(); + for (const Callable &callable : connected_event_signals) { const EventSignalCallable *event_signal_callable = static_cast<const EventSignalCallable *>(callable.get_custom()); owner->disconnect(event_signal_callable->get_signal(), callable); } @@ -2324,8 +2313,8 @@ void CSharpScript::_update_exports_values(Map<StringName, Variant> &values, List values[E->key()] = E->get(); } - for (List<PropertyInfo>::Element *E = exported_members_cache.front(); E; E = E->next()) { - propnames.push_back(E->get()); + for (const PropertyInfo &E : exported_members_cache) { + propnames.push_back(E); } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj index 224d7e5b5a..11d8e0f72b 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj @@ -15,8 +15,9 @@ <PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl> <PackageLicenseExpression>MIT</PackageLicenseExpression> - <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!-- Generates a package at build --> - <IncludeBuildOutput>false</IncludeBuildOutput> <!-- Do not include the generator as a lib dependency --> + <GeneratePackageOnBuild>true</GeneratePackageOnBuild> + <!-- Do not include the generator as a lib dependency --> + <IncludeBuildOutput>false</IncludeBuildOutput> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" PrivateAssets="all" /> diff --git a/modules/mono/editor/GodotTools/.gitignore b/modules/mono/editor/GodotTools/.gitignore index 48e2f914d8..a41d1c89b5 100644 --- a/modules/mono/editor/GodotTools/.gitignore +++ b/modules/mono/editor/GodotTools/.gitignore @@ -353,4 +353,3 @@ healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ - diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs index 4db71500da..450c4bf0cb 100644 --- a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs +++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs @@ -113,8 +113,7 @@ namespace GodotTools.IdeMessaging.CLI } } - ExitMainLoop: - + ExitMainLoop: await forwarder.WriteLineToOutput("Event=Quit"); } diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs index cc0da44a13..284e94810a 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -150,8 +150,8 @@ EndProject"; {"Tools|Any CPU", "ExportRelease|Any CPU"} }; - var regex = new Regex(string.Join("|",dict.Keys.Select(Regex.Escape))); - var result = regex.Replace(input,m => dict[m.Value]); + var regex = new Regex(string.Join("|", dict.Keys.Select(Regex.Escape))); + var result = regex.Replace(input, m => dict[m.Value]); if (result != input) { diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index 5bb8d444c2..f69307104f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs @@ -577,27 +577,27 @@ MONO_AOT_MODE_LAST = 1000, { case OS.Platforms.Windows: case OS.Platforms.UWP: - { - string arch = bits == "64" ? "x86_64" : "i686"; - return $"windows-{arch}"; - } + { + string arch = bits == "64" ? "x86_64" : "i686"; + return $"windows-{arch}"; + } case OS.Platforms.MacOS: - { - Debug.Assert(bits == null || bits == "64"); - string arch = "x86_64"; - return $"{platform}-{arch}"; - } + { + Debug.Assert(bits == null || bits == "64"); + string arch = "x86_64"; + return $"{platform}-{arch}"; + } case OS.Platforms.LinuxBSD: case OS.Platforms.Server: - { - string arch = bits == "64" ? "x86_64" : "i686"; - return $"linux-{arch}"; - } + { + string arch = bits == "64" ? "x86_64" : "i686"; + return $"linux-{arch}"; + } case OS.Platforms.Haiku: - { - string arch = bits == "64" ? "x86_64" : "i686"; - return $"{platform}-{arch}"; - } + { + string arch = bits == "64" ? "x86_64" : "i686"; + return $"{platform}-{arch}"; + } default: throw new NotSupportedException($"Platform not supported: {platform}"); } diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 270be8b6bf..0b5aa72a81 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -76,9 +76,9 @@ namespace GodotTools.Export GlobalDef("mono/export/aot/use_interpreter", true); // --aot or --aot=opt1,opt2 (use 'mono --aot=help AuxAssembly.dll' to list AOT options) - GlobalDef("mono/export/aot/extra_aot_options", new string[] { }); + GlobalDef("mono/export/aot/extra_aot_options", Array.Empty<string>()); // --optimize/-O=opt1,opt2 (use 'mono --list-opt'' to list optimize options) - GlobalDef("mono/export/aot/extra_optimizer_options", new string[] { }); + GlobalDef("mono/export/aot/extra_optimizer_options", Array.Empty<string>()); GlobalDef("mono/export/aot/android_toolchain_path", ""); } @@ -188,7 +188,7 @@ namespace GodotTools.Export // However, at least in the case of 'WebAssembly.Net.Http' for some reason the BCL assemblies // reference a different version even though the assembly is the same, for some weird reason. - var wasmFrameworkAssemblies = new[] {"WebAssembly.Bindings", "WebAssembly.Net.WebSockets"}; + var wasmFrameworkAssemblies = new[] { "WebAssembly.Bindings", "WebAssembly.Net.WebSockets" }; foreach (string thisWasmFrameworkAssemblyName in wasmFrameworkAssemblies) { @@ -298,8 +298,8 @@ namespace GodotTools.Export LLVMOutputPath = "", FullAot = platform == OS.Platforms.iOS || (bool)(ProjectSettings.GetSetting("mono/export/aot/full_aot") ?? false), UseInterpreter = (bool)ProjectSettings.GetSetting("mono/export/aot/use_interpreter"), - ExtraAotOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_aot_options") ?? new string[] { }, - ExtraOptimizerOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_optimizer_options") ?? new string[] { }, + ExtraAotOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_aot_options") ?? Array.Empty<string>(), + ExtraOptimizerOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_optimizer_options") ?? Array.Empty<string>(), ToolchainPath = aotToolchainPath }; @@ -381,7 +381,7 @@ namespace GodotTools.Export private static bool PlatformHasTemplateDir(string platform) { // OSX export templates are contained in a zip, so we place our custom template inside it and let Godot do the rest. - return !new[] {OS.Platforms.MacOS, OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5}.Contains(platform); + return !new[] { OS.Platforms.MacOS, OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5 }.Contains(platform); } private static bool DeterminePlatformFromFeatures(IEnumerable<string> features, out string platform) @@ -430,7 +430,7 @@ namespace GodotTools.Export /// </summary> private static bool PlatformRequiresCustomBcl(string platform) { - if (new[] {OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5}.Contains(platform)) + if (new[] { OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5 }.Contains(platform)) return true; // The 'net_4_x' BCL is not compatible between Windows and the other platforms. diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj index 3f14629b11..b9aa760f4d 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj +++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj @@ -3,7 +3,8 @@ <ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid> <TargetFramework>net472</TargetFramework> <LangVersion>7.2</LangVersion> - <GodotApiConfiguration>Debug</GodotApiConfiguration> <!-- The Godot editor uses the Debug Godot API assemblies --> + <!-- The Godot editor uses the Debug Godot API assemblies --> + <GodotApiConfiguration>Debug</GodotApiConfiguration> <GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath> <GodotOutputDataDir>$(GodotSourceRootPath)/bin/GodotSharp</GodotOutputDataDir> <GodotApiAssembliesDir>$(GodotOutputDataDir)/Api/$(GodotApiConfiguration)</GodotApiAssembliesDir> diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs index 94fc5da425..821532f759 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs @@ -47,7 +47,7 @@ namespace GodotTools.Ides.Rider GD.PushWarning(e.Message); } - return new RiderInfo[0]; + return Array.Empty<RiderInfo>(); } private static RiderInfo[] CollectAllRiderPathsLinux() @@ -249,7 +249,7 @@ namespace GodotTools.Ides.Rider bool isMac) { if (!Directory.Exists(toolboxRiderRootPath)) - return new string[0]; + return Array.Empty<string>(); var channelDirs = Directory.GetDirectories(toolboxRiderRootPath); var paths = channelDirs.SelectMany(channelDir => @@ -295,7 +295,7 @@ namespace GodotTools.Ides.Rider Logger.Warn($"Failed to get RiderPath from {channelDir}", e); } - return new string[0]; + return Array.Empty<string>(); }) .Where(c => !string.IsNullOrEmpty(c)) .ToArray(); @@ -306,7 +306,7 @@ namespace GodotTools.Ides.Rider { var folder = new DirectoryInfo(Path.Combine(buildDir, dirName)); if (!folder.Exists) - return new string[0]; + return Array.Empty<string>(); if (!isMac) return new[] { Path.Combine(folder.FullName, searchPattern) }.Where(File.Exists).ToArray(); diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs index ed25cdaa63..60dd565ef2 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs @@ -57,7 +57,7 @@ namespace GodotTools.Ides.Rider public static bool IsExternalEditorSetToRider(EditorSettings editorSettings) { - return editorSettings.HasSetting(EditorPathSettingName) && IsRider((string) editorSettings.GetSetting(EditorPathSettingName)); + return editorSettings.HasSetting(EditorPathSettingName) && IsRider((string)editorSettings.GetSetting(EditorPathSettingName)); } public static bool IsRider(string path) diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index e745966435..ee4e7ba9d4 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -74,10 +74,10 @@ namespace GodotTools.Utils } private static readonly IEnumerable<string> LinuxBSDPlatforms = - new[] {Names.Linux, Names.FreeBSD, Names.NetBSD, Names.BSD}; + new[] { Names.Linux, Names.FreeBSD, Names.NetBSD, Names.BSD }; private static readonly IEnumerable<string> UnixLikePlatforms = - new[] {Names.MacOS, Names.Server, Names.Haiku, Names.Android, Names.iOS} + new[] { Names.MacOS, Names.Server, Names.Haiku, Names.Android, Names.iOS } .Concat(LinuxBSDPlatforms).ToArray(); private static readonly Lazy<bool> _isWindows = new Lazy<bool>(() => IsOS(Names.Windows)); @@ -111,7 +111,7 @@ namespace GodotTools.Utils private static string PathWhichWindows([NotNull] string name) { - string[] windowsExts = Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) ?? new string[] { }; + string[] windowsExts = Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) ?? Array.Empty<string>(); string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep); var searchDirs = new List<string>(); @@ -128,10 +128,10 @@ namespace GodotTools.Utils return searchDirs.Select(dir => Path.Combine(dir, name)).FirstOrDefault(File.Exists); return (from dir in searchDirs - select Path.Combine(dir, name) + select Path.Combine(dir, name) into path - from ext in windowsExts - select path + ext).FirstOrDefault(File.Exists); + from ext in windowsExts + select path + ext).FirstOrDefault(File.Exists); } private static string PathWhichUnix([NotNull] string name) @@ -196,7 +196,7 @@ namespace GodotTools.Utils startInfo.UseShellExecute = false; - using (var process = new Process {StartInfo = startInfo}) + using (var process = new Process { StartInfo = startInfo }) { process.Start(); process.WaitForExit(); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 620b031ddb..c134136e1c 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -416,8 +416,8 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf // Try to find as global enum constant const EnumInterface *target_ienum = nullptr; - for (const List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) { - target_ienum = &E->get(); + for (const EnumInterface &ienum : global_enums) { + target_ienum = &ienum; target_iconst = find_constant_by_name(target_name, target_ienum->constants); if (target_iconst) { break; @@ -455,8 +455,8 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf // Try to find as enum constant in the current class const EnumInterface *target_ienum = nullptr; - for (const List<EnumInterface>::Element *E = target_itype->enums.front(); E; E = E->next()) { - target_ienum = &E->get(); + for (const EnumInterface &ienum : target_itype->enums) { + target_ienum = &ienum; target_iconst = find_constant_by_name(target_name, target_ienum->constants); if (target_iconst) { break; @@ -682,12 +682,10 @@ int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) { void BindingsGenerator::_apply_prefix_to_enum_constants(BindingsGenerator::EnumInterface &p_ienum, int p_prefix_length) { if (p_prefix_length > 0) { - for (List<ConstantInterface>::Element *E = p_ienum.constants.front(); E; E = E->next()) { + for (ConstantInterface &iconstant : p_ienum.constants) { int curr_prefix_length = p_prefix_length; - ConstantInterface &curr_const = E->get(); - - String constant_name = curr_const.name; + String constant_name = iconstant.name; Vector<String> parts = constant_name.split("_", /* p_allow_empty: */ true); @@ -713,15 +711,13 @@ void BindingsGenerator::_apply_prefix_to_enum_constants(BindingsGenerator::EnumI constant_name += parts[i]; } - curr_const.proxy_name = snake_to_pascal_case(constant_name, true); + iconstant.proxy_name = snake_to_pascal_case(constant_name, true); } } } void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { - for (const List<MethodInterface>::Element *E = p_itype.methods.front(); E; E = E->next()) { - const MethodInterface &imethod = E->get(); - + for (const MethodInterface &imethod : p_itype.methods) { if (imethod.is_virtual) { continue; } @@ -735,8 +731,8 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { // Get arguments information int i = 0; - for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) { - const TypeInterface *arg_type = _get_type_or_placeholder(F->get().type); + for (const ArgumentInterface &iarg : imethod.arguments) { + const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); im_sig += ", "; im_sig += arg_type->im_type_in; @@ -776,10 +772,10 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { if (p_itype.api_type != ClassDB::API_EDITOR) { match->get().editor_only = false; } - method_icalls_map.insert(&E->get(), &match->get()); + method_icalls_map.insert(&imethod, &match->get()); } else { List<InternalCall>::Element *added = method_icalls.push_back(im_icall); - method_icalls_map.insert(&E->get(), &added->get()); + method_icalls_map.insert(&imethod, &added->get()); } } } @@ -859,9 +855,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { p_output.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); p_output.append(INDENT1 "public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n" INDENT1 "{"); - for (const List<ConstantInterface>::Element *E = global_constants.front(); E; E = E->next()) { - const ConstantInterface &iconstant = E->get(); - + for (const ConstantInterface &iconstant : global_constants) { if (iconstant.const_doc && iconstant.const_doc->description.size()) { String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), nullptr); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); @@ -894,9 +888,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { // Enums - for (List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) { - const EnumInterface &ienum = E->get(); - + for (const EnumInterface &ienum : global_enums) { CRASH_COND(ienum.constants.is_empty()); String enum_proxy_name = ienum.cname.operator String(); @@ -921,9 +913,8 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { p_output.append(enum_proxy_name); p_output.append("\n" INDENT1 OPEN_BLOCK); - for (const List<ConstantInterface>::Element *F = ienum.constants.front(); F; F = F->next()) { - const ConstantInterface &iconstant = F->get(); - + const ConstantInterface &last = ienum.constants.back()->get(); + for (const ConstantInterface &iconstant : ienum.constants) { if (iconstant.const_doc && iconstant.const_doc->description.size()) { String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), nullptr); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); @@ -945,7 +936,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { p_output.append(iconstant.proxy_name); p_output.append(" = "); p_output.append(itos(iconstant.value)); - p_output.append(F != ienum.constants.back() ? ",\n" : "\n"); + p_output.append(&iconstant != &last ? ",\n" : "\n"); } p_output.append(INDENT1 CLOSE_BLOCK); @@ -1053,11 +1044,11 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) { cs_icalls_content.append(m_icall.im_sig + ");\n"); \ } - for (const List<InternalCall>::Element *E = core_custom_icalls.front(); E; E = E->next()) { - ADD_INTERNAL_CALL(E->get()); + for (const InternalCall &internal_call : core_custom_icalls) { + ADD_INTERNAL_CALL(internal_call); } - for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next()) { - ADD_INTERNAL_CALL(E->get()); + for (const InternalCall &internal_call : method_icalls) { + ADD_INTERNAL_CALL(internal_call); } #undef ADD_INTERNAL_CALL @@ -1161,11 +1152,11 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) { cs_icalls_content.append(m_icall.im_sig + ");\n"); \ } - for (const List<InternalCall>::Element *E = editor_custom_icalls.front(); E; E = E->next()) { - ADD_INTERNAL_CALL(E->get()); + for (const InternalCall &internal_call : editor_custom_icalls) { + ADD_INTERNAL_CALL(internal_call); } - for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next()) { - ADD_INTERNAL_CALL(E->get()); + for (const InternalCall &internal_call : method_icalls) { + ADD_INTERNAL_CALL(internal_call); } #undef ADD_INTERNAL_CALL @@ -1327,9 +1318,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str // Add constants - for (const List<ConstantInterface>::Element *E = itype.constants.front(); E; E = E->next()) { - const ConstantInterface &iconstant = E->get(); - + for (const ConstantInterface &iconstant : itype.constants) { if (iconstant.const_doc && iconstant.const_doc->description.size()) { String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), &itype); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); @@ -1360,18 +1349,15 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str // Add enums - for (const List<EnumInterface>::Element *E = itype.enums.front(); E; E = E->next()) { - const EnumInterface &ienum = E->get(); - + for (const EnumInterface &ienum : itype.enums) { ERR_FAIL_COND_V(ienum.constants.is_empty(), ERR_BUG); output.append(MEMBER_BEGIN "public enum "); output.append(ienum.cname.operator String()); output.append(MEMBER_BEGIN OPEN_BLOCK); - for (const List<ConstantInterface>::Element *F = ienum.constants.front(); F; F = F->next()) { - const ConstantInterface &iconstant = F->get(); - + const ConstantInterface &last = ienum.constants.back()->get(); + for (const ConstantInterface &iconstant : ienum.constants) { if (iconstant.const_doc && iconstant.const_doc->description.size()) { String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), &itype); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); @@ -1393,7 +1379,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(iconstant.proxy_name); output.append(" = "); output.append(itos(iconstant.value)); - output.append(F != ienum.constants.back() ? ",\n" : "\n"); + output.append(&iconstant != &last ? ",\n" : "\n"); } output.append(INDENT2 CLOSE_BLOCK); @@ -1401,8 +1387,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str // Add properties - for (const List<PropertyInterface>::Element *E = itype.properties.front(); E; E = E->next()) { - const PropertyInterface &iprop = E->get(); + for (const PropertyInterface &iprop : itype.properties) { Error prop_err = _generate_cs_property(itype, iprop, output); ERR_FAIL_COND_V_MSG(prop_err != OK, prop_err, "Failed to generate property '" + iprop.cname.operator String() + @@ -1463,15 +1448,13 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } int method_bind_count = 0; - for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) { - const MethodInterface &imethod = E->get(); + for (const MethodInterface &imethod : itype.methods) { Error method_err = _generate_cs_method(itype, imethod, method_bind_count, output); ERR_FAIL_COND_V_MSG(method_err != OK, method_err, "Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'."); } - for (const List<SignalInterface>::Element *E = itype.signals_.front(); E; E = E->next()) { - const SignalInterface &isignal = E->get(); + for (const SignalInterface &isignal : itype.signals_) { Error method_err = _generate_cs_signal(itype, isignal, output); ERR_FAIL_COND_V_MSG(method_err != OK, method_err, "Failed to generate signal '" + isignal.name + "' for class '" + itype.name + "'."); @@ -1678,8 +1661,8 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf StringBuilder default_args_doc; // Retrieve information from the arguments - for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) { - const ArgumentInterface &iarg = F->get(); + const ArgumentInterface &first = p_imethod.arguments.front()->get(); + for (const ArgumentInterface &iarg : p_imethod.arguments) { const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG, @@ -1699,7 +1682,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf // Add the current arguments to the signature // If the argument has a default value which is not a constant, we will make it Nullable { - if (F != p_imethod.arguments.front()) { + if (&iarg != &first) { arguments_sig += ", "; } @@ -1754,7 +1737,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf cs_in_statements += " : "; } - String def_arg = sformat(iarg.default_argument, arg_type->cs_type); + String cs_type = arg_type->cs_type; + if (cs_type.ends_with("[]")) { + cs_type = cs_type.substr(0, cs_type.length() - 2); + } + + String def_arg = sformat(iarg.default_argument, cs_type); cs_in_statements += def_arg; cs_in_statements += ";\n" INDENT3; @@ -1763,8 +1751,10 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf // Apparently the name attribute must not include the @ String param_tag_name = iarg.name.begins_with("@") ? iarg.name.substr(1, iarg.name.length()) : iarg.name; + // Escape < and > in the attribute default value + String param_def_arg = def_arg.replacen("<", "<").replacen(">", ">"); - default_args_doc.append(MEMBER_BEGIN "/// <param name=\"" + param_tag_name + "\">If the parameter is null, then the default value is " + def_arg + "</param>"); + default_args_doc.append(MEMBER_BEGIN "/// <param name=\"" + param_tag_name + "\">If the parameter is null, then the default value is " + param_def_arg + "</param>"); } else { icall_params += arg_type->cs_in.is_empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name); } @@ -1855,9 +1845,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf p_output.append(p_imethod.name); p_output.append("\""); - for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) { + for (const ArgumentInterface &iarg : p_imethod.arguments) { p_output.append(", "); - p_output.append(F->get().name); + p_output.append(iarg.name); } p_output.append(");\n" CLOSE_BLOCK_L2); @@ -1899,8 +1889,8 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf String arguments_sig; // Retrieve information from the arguments - for (const List<ArgumentInterface>::Element *F = p_isignal.arguments.front(); F; F = F->next()) { - const ArgumentInterface &iarg = F->get(); + const ArgumentInterface &first = p_isignal.arguments.front()->get(); + for (const ArgumentInterface &iarg : p_isignal.arguments) { const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG, @@ -1914,7 +1904,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf // Add the current arguments to the signature - if (F != p_isignal.arguments.front()) { + if (&iarg != &first) { arguments_sig += ", "; } @@ -2042,8 +2032,7 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor"); // Used only for derived types - for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) { - const MethodInterface &imethod = E->get(); + for (const MethodInterface &imethod : itype.methods) { Error method_err = _generate_glue_method(itype, imethod, output); ERR_FAIL_COND_V_MSG(method_err != OK, method_err, "Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'."); @@ -2114,20 +2103,20 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { } bool tools_sequence = false; - for (const List<InternalCall>::Element *E = core_custom_icalls.front(); E; E = E->next()) { + for (const InternalCall &internal_call : core_custom_icalls) { if (tools_sequence) { - if (!E->get().editor_only) { + if (!internal_call.editor_only) { tools_sequence = false; output.append("#endif\n"); } } else { - if (E->get().editor_only) { + if (internal_call.editor_only) { output.append("#ifdef TOOLS_ENABLED\n"); tools_sequence = true; } } - ADD_INTERNAL_CALL_REGISTRATION(E->get()); + ADD_INTERNAL_CALL_REGISTRATION(internal_call); } if (tools_sequence) { @@ -2136,24 +2125,24 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { } output.append("#ifdef TOOLS_ENABLED\n"); - for (const List<InternalCall>::Element *E = editor_custom_icalls.front(); E; E = E->next()) - ADD_INTERNAL_CALL_REGISTRATION(E->get()); + for (const InternalCall &internal_call : editor_custom_icalls) + ADD_INTERNAL_CALL_REGISTRATION(internal_call); output.append("#endif // TOOLS_ENABLED\n"); - for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next()) { + for (const InternalCall &internal_call : method_icalls) { if (tools_sequence) { - if (!E->get().editor_only) { + if (!internal_call.editor_only) { tools_sequence = false; output.append("#endif\n"); } } else { - if (E->get().editor_only) { + if (internal_call.editor_only) { output.append("#ifdef TOOLS_ENABLED\n"); tools_sequence = true; } } - ADD_INTERNAL_CALL_REGISTRATION(E->get()); + ADD_INTERNAL_CALL_REGISTRATION(internal_call); } if (tools_sequence) { @@ -2209,8 +2198,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte // Get arguments information int i = 0; - for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) { - const ArgumentInterface &iarg = F->get(); + for (const ArgumentInterface &iarg : p_imethod.arguments) { const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); String c_param_name = "arg" + itos(i + 1); @@ -2623,9 +2611,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { Map<StringName, StringName> accessor_methods; - for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { - const PropertyInfo &property = E->get(); - + for (const PropertyInfo &property : property_list) { if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY) { continue; } @@ -2684,9 +2670,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { ClassDB::get_method_list(type_cname, &method_list, true); method_list.sort(); - for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { - const MethodInfo &method_info = E->get(); - + for (const MethodInfo &method_info : method_list) { int argc = method_info.arguments.size(); if (method_info.name.is_empty()) { @@ -2840,9 +2824,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { // Classes starting with an underscore are ignored unless they're used as a property setter or getter if (!imethod.is_virtual && imethod.name[0] == '_') { - for (const List<PropertyInterface>::Element *F = itype.properties.front(); F; F = F->next()) { - const PropertyInterface &iprop = F->get(); - + for (const PropertyInterface &iprop : itype.properties) { if (iprop.setter == imethod.name || iprop.getter == imethod.name) { imethod.is_internal = true; itype.methods.push_back(imethod); @@ -2952,8 +2934,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } EnumInterface ienum(enum_proxy_cname); const List<StringName> &enum_constants = enum_map.get(*k); - for (const List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) { - const StringName &constant_cname = E->get(); + for (const StringName &constant_cname : enum_constants) { String constant_name = constant_cname.operator String(); int *value = class_info->constant_map.getptr(constant_cname); ERR_FAIL_NULL_V(value, false); @@ -2989,9 +2970,8 @@ bool BindingsGenerator::_populate_object_type_interfaces() { enum_types.insert(enum_itype.cname, enum_itype); } - for (const List<String>::Element *E = constants.front(); E; E = E->next()) { - const String &constant_name = E->get(); - int *value = class_info->constant_map.getptr(StringName(E->get())); + for (const String &constant_name : constants) { + int *value = class_info->constant_map.getptr(StringName(constant_name)); ERR_FAIL_NULL_V(value, false); ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value); @@ -3099,6 +3079,9 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = "null"; break; case Variant::ARRAY: + r_iarg.default_argument = "new %s { }"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF; + break; case Variant::PACKED_BYTE_ARRAY: case Variant::PACKED_INT32_ARRAY: case Variant::PACKED_INT64_ARRAY: @@ -3108,7 +3091,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar case Variant::PACKED_VECTOR2_ARRAY: case Variant::PACKED_VECTOR3_ARRAY: case Variant::PACKED_COLOR_ARRAY: - r_iarg.default_argument = "new %s {}"; + r_iarg.default_argument = "Array.Empty<%s>()"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF; break; case Variant::TRANSFORM2D: { @@ -3539,9 +3522,7 @@ void BindingsGenerator::_populate_global_constants() { } } - for (List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) { - EnumInterface &ienum = E->get(); - + for (EnumInterface &ienum : global_enums) { TypeInterface enum_itype; enum_itype.is_enum = true; enum_itype.name = ienum.cname.operator String(); @@ -3571,13 +3552,13 @@ void BindingsGenerator::_populate_global_constants() { hardcoded_enums.push_back("Vector2i.Axis"); hardcoded_enums.push_back("Vector3.Axis"); hardcoded_enums.push_back("Vector3i.Axis"); - for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) { + for (const StringName &enum_cname : hardcoded_enums) { // These enums are not generated and must be written manually (e.g.: Vector3.Axis) // Here, we assume core types do not begin with underscore TypeInterface enum_itype; enum_itype.is_enum = true; - enum_itype.name = E->get().operator String(); - enum_itype.cname = E->get(); + enum_itype.name = enum_cname.operator String(); + enum_itype.cname = enum_cname; enum_itype.proxy_name = enum_itype.name; TypeInterface::postsetup_enum_type(enum_itype); enum_types.insert(enum_itype.cname, enum_itype); diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 48c0e02723..a649181b20 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -357,9 +357,9 @@ class BindingsGenerator { List<SignalInterface> signals_; const MethodInterface *find_method_by_name(const StringName &p_cname) const { - for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().cname == p_cname) { - return &E->get(); + for (const MethodInterface &E : methods) { + if (E.cname == p_cname) { + return &E; } } @@ -367,9 +367,9 @@ class BindingsGenerator { } const PropertyInterface *find_property_by_name(const StringName &p_cname) const { - for (const List<PropertyInterface>::Element *E = properties.front(); E; E = E->next()) { - if (E->get().cname == p_cname) { - return &E->get(); + for (const PropertyInterface &E : properties) { + if (E.cname == p_cname) { + return &E; } } @@ -377,9 +377,9 @@ class BindingsGenerator { } const PropertyInterface *find_property_by_proxy_name(const String &p_proxy_name) const { - for (const List<PropertyInterface>::Element *E = properties.front(); E; E = E->next()) { - if (E->get().proxy_name == p_proxy_name) { - return &E->get(); + for (const PropertyInterface &E : properties) { + if (E.proxy_name == p_proxy_name) { + return &E; } } @@ -387,9 +387,9 @@ class BindingsGenerator { } const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const { - for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().proxy_name == p_proxy_name) { - return &E->get(); + for (const MethodInterface &E : methods) { + if (E.proxy_name == p_proxy_name) { + return &E; } } @@ -613,9 +613,9 @@ class BindingsGenerator { } const ConstantInterface *find_constant_by_name(const String &p_name, const List<ConstantInterface> &p_constants) const { - for (const List<ConstantInterface>::Element *E = p_constants.front(); E; E = E->next()) { - if (E->get().name == p_name) { - return &E->get(); + for (const ConstantInterface &E : p_constants) { + if (E.name == p_name) { + return &E; } } diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index bbfba83e6f..fa7d418844 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -109,9 +109,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr List<PropertyInfo> project_props; ProjectSettings::get_singleton()->get_property_list(&project_props); - for (List<PropertyInfo>::Element *E = project_props.front(); E; E = E->next()) { - const PropertyInfo &prop = E->get(); - + for (const PropertyInfo &prop : project_props) { if (!prop.name.begins_with("input/")) { continue; } @@ -187,8 +185,8 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr ClassDB::get_signal_list(native, &signals, /* p_no_inheritance: */ false); } - for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - const String &signal = E->get().name; + for (const MethodInfo &E : signals) { + const String &signal = E.name; suggestions.push_back(quoted(signal)); } } break; @@ -199,8 +197,8 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr List<StringName> sn; Theme::get_default()->get_color_list(base->get_class(), &sn); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - suggestions.push_back(quoted(E->get())); + for (const StringName &E : sn) { + suggestions.push_back(quoted(E)); } } } break; @@ -211,8 +209,8 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr List<StringName> sn; Theme::get_default()->get_constant_list(base->get_class(), &sn); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - suggestions.push_back(quoted(E->get())); + for (const StringName &E : sn) { + suggestions.push_back(quoted(E)); } } } break; @@ -223,8 +221,8 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr List<StringName> sn; Theme::get_default()->get_font_list(base->get_class(), &sn); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - suggestions.push_back(quoted(E->get())); + for (const StringName &E : sn) { + suggestions.push_back(quoted(E)); } } } break; @@ -235,8 +233,8 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr List<StringName> sn; Theme::get_default()->get_font_size_list(base->get_class(), &sn); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - suggestions.push_back(quoted(E->get())); + for (const StringName &E : sn) { + suggestions.push_back(quoted(E)); } } } break; @@ -247,8 +245,8 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr List<StringName> sn; Theme::get_default()->get_stylebox_list(base->get_class(), &sn); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - suggestions.push_back(quoted(E->get())); + for (const StringName &E : sn) { + suggestions.push_back(quoted(E)); } } } break; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs index 2b641a8937..061c572c32 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs @@ -1,16 +1,10 @@ -// file: core/math/aabb.h -// commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451 -// file: core/math/aabb.cpp -// commit: bd282ff43f23fe845f29a3e25c8efc01bd65ffb0 -// file: core/variant_call.cpp -// commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685 -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs index ce613f7ef9..f52a767018 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs @@ -25,16 +25,30 @@ namespace Godot.Collections } } + /// <summary> + /// Wrapper around Godot's Array class, an array of Variant + /// typed elements allocated in the engine in C++. Useful when + /// interfacing with the engine. Otherwise prefer .NET collections + /// such as <see cref="System.Array"/> or <see cref="List{T}"/>. + /// </summary> public class Array : IList, IDisposable { ArraySafeHandle safeHandle; bool disposed = false; + /// <summary> + /// Constructs a new empty <see cref="Array"/>. + /// </summary> public Array() { safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor()); } + /// <summary> + /// Constructs a new <see cref="Array"/> from the given collection's elements. + /// </summary> + /// <param name="collection">The collection of elements to construct from.</param> + /// <returns>A new Godot Array.</returns> public Array(IEnumerable collection) : this() { if (collection == null) @@ -44,6 +58,11 @@ namespace Godot.Collections Add(element); } + /// <summary> + /// Constructs a new <see cref="Array"/> from the given objects. + /// </summary> + /// <param name="array">The objects to put in the new array.</param> + /// <returns>A new Godot Array.</returns> public Array(params object[] array) : this() { if (array == null) @@ -71,21 +90,40 @@ namespace Godot.Collections return safeHandle.DangerousGetHandle(); } + /// <summary> + /// Duplicates this <see cref="Array"/>. + /// </summary> + /// <param name="deep">If true, performs a deep copy.</param> + /// <returns>A new Godot Array.</returns> public Array Duplicate(bool deep = false) { return new Array(godot_icall_Array_Duplicate(GetPtr(), deep)); } + /// <summary> + /// Resizes this <see cref="Array"/> to the given size. + /// </summary> + /// <param name="newSize">The new size of the array.</param> + /// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns> public Error Resize(int newSize) { return godot_icall_Array_Resize(GetPtr(), newSize); } + /// <summary> + /// Shuffles the contents of this <see cref="Array"/> into a random order. + /// </summary> public void Shuffle() { godot_icall_Array_Shuffle(GetPtr()); } + /// <summary> + /// Concatenates these two <see cref="Array"/>s. + /// </summary> + /// <param name="left">The first array.</param> + /// <param name="right">The second array.</param> + /// <returns>A new Godot Array with the contents of both arrays.</returns> public static Array operator +(Array left, Array right) { return new Array(godot_icall_Array_Concatenate(left.GetPtr(), right.GetPtr())); @@ -93,6 +131,9 @@ namespace Godot.Collections // IDisposable + /// <summary> + /// Disposes of this <see cref="Array"/>. + /// </summary> public void Dispose() { if (disposed) @@ -109,38 +150,90 @@ namespace Godot.Collections // IList - public bool IsReadOnly => false; + bool IList.IsReadOnly => false; - public bool IsFixedSize => false; + bool IList.IsFixedSize => false; + /// <summary> + /// Returns the object at the given index. + /// </summary> + /// <value>The object at the given index.</value> public object this[int index] { get => godot_icall_Array_At(GetPtr(), index); set => godot_icall_Array_SetAt(GetPtr(), index, value); } + /// <summary> + /// Adds an object to the end of this <see cref="Array"/>. + /// This is the same as `append` or `push_back` in GDScript. + /// </summary> + /// <param name="value">The object to add.</param> + /// <returns>The new size after adding the object.</returns> public int Add(object value) => godot_icall_Array_Add(GetPtr(), value); + /// <summary> + /// Checks if this <see cref="Array"/> contains the given object. + /// </summary> + /// <param name="value">The item to look for.</param> + /// <returns>Whether or not this array contains the given object.</returns> public bool Contains(object value) => godot_icall_Array_Contains(GetPtr(), value); + /// <summary> + /// Erases all items from this <see cref="Array"/>. + /// </summary> public void Clear() => godot_icall_Array_Clear(GetPtr()); + /// <summary> + /// Searches this <see cref="Array"/> for an object + /// and returns its index or -1 if not found. + /// </summary> + /// <param name="value">The object to search for.</param> + /// <returns>The index of the object, or -1 if not found.</returns> public int IndexOf(object value) => godot_icall_Array_IndexOf(GetPtr(), value); + /// <summary> + /// Inserts a new object at a given position in the array. + /// The position must be a valid position of an existing item, + /// or the position at the end of the array. + /// Existing items will be moved to the right. + /// </summary> + /// <param name="index">The index to insert at.</param> + /// <param name="value">The object to insert.</param> public void Insert(int index, object value) => godot_icall_Array_Insert(GetPtr(), index, value); + /// <summary> + /// Removes the first occurrence of the specified value + /// from this <see cref="Array"/>. + /// </summary> + /// <param name="value">The value to remove.</param> public void Remove(object value) => godot_icall_Array_Remove(GetPtr(), value); + /// <summary> + /// Removes an element from this <see cref="Array"/> by index. + /// </summary> + /// <param name="index">The index of the element to remove.</param> public void RemoveAt(int index) => godot_icall_Array_RemoveAt(GetPtr(), index); // ICollection + /// <summary> + /// Returns the number of elements in this <see cref="Array"/>. + /// This is also known as the size or length of the array. + /// </summary> + /// <returns>The number of elements.</returns> public int Count => godot_icall_Array_Count(GetPtr()); - public object SyncRoot => this; + object ICollection.SyncRoot => this; - public bool IsSynchronized => false; + bool ICollection.IsSynchronized => false; + /// <summary> + /// Copies the elements of this <see cref="Array"/> to the given + /// untyped C# array, starting at the given index. + /// </summary> + /// <param name="array">The array to copy to.</param> + /// <param name="index">The index to start at.</param> public void CopyTo(System.Array array, int index) { if (array == null) @@ -155,6 +248,10 @@ namespace Godot.Collections // IEnumerable + /// <summary> + /// Gets an enumerator for this <see cref="Array"/>. + /// </summary> + /// <returns>An enumerator.</returns> public IEnumerator GetEnumerator() { int count = Count; @@ -165,6 +262,10 @@ namespace Godot.Collections } } + /// <summary> + /// Converts this <see cref="Array"/> to a string. + /// </summary> + /// <returns>A string representation of this array.</returns> public override string ToString() { return godot_icall_Array_ToString(GetPtr()); @@ -234,6 +335,13 @@ namespace Godot.Collections internal extern static string godot_icall_Array_ToString(IntPtr ptr); } + /// <summary> + /// Typed wrapper around Godot's Array class, an array of Variant + /// typed elements allocated in the engine in C++. Useful when + /// interfacing with the engine. Otherwise prefer .NET collections + /// such as arrays or <see cref="List{T}"/>. + /// </summary> + /// <typeparam name="T">The type of the array.</typeparam> public class Array<T> : IList<T>, ICollection<T>, IEnumerable<T> { Array objectArray; @@ -246,11 +354,19 @@ namespace Godot.Collections Array.godot_icall_Array_Generic_GetElementTypeInfo(typeof(T), out elemTypeEncoding, out elemTypeClass); } + /// <summary> + /// Constructs a new empty <see cref="Array{T}"/>. + /// </summary> public Array() { objectArray = new Array(); } + /// <summary> + /// Constructs a new <see cref="Array{T}"/> from the given collection's elements. + /// </summary> + /// <param name="collection">The collection of elements to construct from.</param> + /// <returns>A new Godot Array.</returns> public Array(IEnumerable<T> collection) { if (collection == null) @@ -259,6 +375,11 @@ namespace Godot.Collections objectArray = new Array(collection); } + /// <summary> + /// Constructs a new <see cref="Array{T}"/> from the given items. + /// </summary> + /// <param name="array">The items to put in the new array.</param> + /// <returns>A new Godot Array.</returns> public Array(params T[] array) : this() { if (array == null) @@ -268,6 +389,10 @@ namespace Godot.Collections objectArray = new Array(array); } + /// <summary> + /// Constructs a typed <see cref="Array{T}"/> from an untyped <see cref="Array"/>. + /// </summary> + /// <param name="array">The untyped array to construct from.</param> public Array(Array array) { objectArray = array; @@ -288,26 +413,49 @@ namespace Godot.Collections return objectArray.GetPtr(); } + /// <summary> + /// Converts this typed <see cref="Array{T}"/> to an untyped <see cref="Array"/>. + /// </summary> + /// <param name="from">The typed array to convert.</param> public static explicit operator Array(Array<T> from) { return from.objectArray; } + /// <summary> + /// Duplicates this <see cref="Array{T}"/>. + /// </summary> + /// <param name="deep">If true, performs a deep copy.</param> + /// <returns>A new Godot Array.</returns> public Array<T> Duplicate(bool deep = false) { return new Array<T>(objectArray.Duplicate(deep)); } + /// <summary> + /// Resizes this <see cref="Array{T}"/> to the given size. + /// </summary> + /// <param name="newSize">The new size of the array.</param> + /// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns> public Error Resize(int newSize) { return objectArray.Resize(newSize); } + /// <summary> + /// Shuffles the contents of this <see cref="Array{T}"/> into a random order. + /// </summary> public void Shuffle() { objectArray.Shuffle(); } + /// <summary> + /// Concatenates these two <see cref="Array{T}"/>s. + /// </summary> + /// <param name="left">The first array.</param> + /// <param name="right">The second array.</param> + /// <returns>A new Godot Array with the contents of both arrays.</returns> public static Array<T> operator +(Array<T> left, Array<T> right) { return new Array<T>(left.objectArray + right.objectArray); @@ -315,22 +463,44 @@ namespace Godot.Collections // IList<T> + /// <summary> + /// Returns the value at the given index. + /// </summary> + /// <value>The value at the given index.</value> public T this[int index] { get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); } set { objectArray[index] = value; } } + /// <summary> + /// Searches this <see cref="Array{T}"/> for an item + /// and returns its index or -1 if not found. + /// </summary> + /// <param name="item">The item to search for.</param> + /// <returns>The index of the item, or -1 if not found.</returns> public int IndexOf(T item) { return objectArray.IndexOf(item); } + /// <summary> + /// Inserts a new item at a given position in the <see cref="Array{T}"/>. + /// The position must be a valid position of an existing item, + /// or the position at the end of the array. + /// Existing items will be moved to the right. + /// </summary> + /// <param name="index">The index to insert at.</param> + /// <param name="item">The item to insert.</param> public void Insert(int index, T item) { objectArray.Insert(index, item); } + /// <summary> + /// Removes an element from this <see cref="Array{T}"/> by index. + /// </summary> + /// <param name="index">The index of the element to remove.</param> public void RemoveAt(int index) { objectArray.RemoveAt(index); @@ -338,31 +508,53 @@ namespace Godot.Collections // ICollection<T> + /// <summary> + /// Returns the number of elements in this <see cref="Array{T}"/>. + /// This is also known as the size or length of the array. + /// </summary> + /// <returns>The number of elements.</returns> public int Count { get { return objectArray.Count; } } - public bool IsReadOnly - { - get { return objectArray.IsReadOnly; } - } + bool ICollection<T>.IsReadOnly => false; + /// <summary> + /// Adds an item to the end of this <see cref="Array{T}"/>. + /// This is the same as `append` or `push_back` in GDScript. + /// </summary> + /// <param name="item">The item to add.</param> + /// <returns>The new size after adding the item.</returns> public void Add(T item) { objectArray.Add(item); } + /// <summary> + /// Erases all items from this <see cref="Array{T}"/>. + /// </summary> public void Clear() { objectArray.Clear(); } + /// <summary> + /// Checks if this <see cref="Array{T}"/> contains the given item. + /// </summary> + /// <param name="item">The item to look for.</param> + /// <returns>Whether or not this array contains the given item.</returns> public bool Contains(T item) { return objectArray.Contains(item); } + /// <summary> + /// Copies the elements of this <see cref="Array{T}"/> to the given + /// C# array, starting at the given index. + /// </summary> + /// <param name="array">The C# array to copy to.</param> + /// <param name="arrayIndex">The index to start at.</param> public void CopyTo(T[] array, int arrayIndex) { if (array == null) @@ -386,6 +578,12 @@ namespace Godot.Collections } } + /// <summary> + /// Removes the first occurrence of the specified value + /// from this <see cref="Array{T}"/>. + /// </summary> + /// <param name="item">The value to remove.</param> + /// <returns>A bool indicating success or failure.</returns> public bool Remove(T item) { return Array.godot_icall_Array_Remove(GetPtr(), item); @@ -393,6 +591,10 @@ namespace Godot.Collections // IEnumerable<T> + /// <summary> + /// Gets an enumerator for this <see cref="Array{T}"/>. + /// </summary> + /// <returns>An enumerator.</returns> public IEnumerator<T> GetEnumerator() { int count = objectArray.Count; @@ -408,6 +610,10 @@ namespace Godot.Collections return GetEnumerator(); } + /// <summary> + /// Converts this <see cref="Array{T}"/> to a string. + /// </summary> + /// <returns>A string representation of this array.</returns> public override string ToString() => objectArray.ToString(); } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index 5dbf5d5657..cef343e152 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -1,10 +1,10 @@ -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs index 4bb727bd35..d64c8b563e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace Godot diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index 785e87a043..1dca9e6ea7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -61,7 +61,7 @@ namespace Godot using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { - writer.Write((ulong) TargetKind.Static); + writer.Write((ulong)TargetKind.Static); SerializeType(writer, @delegate.GetType()); @@ -77,8 +77,8 @@ namespace Godot using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { - writer.Write((ulong) TargetKind.GodotObject); - writer.Write((ulong) godotObject.GetInstanceId()); + writer.Write((ulong)TargetKind.GodotObject); + writer.Write((ulong)godotObject.GetInstanceId()); SerializeType(writer, @delegate.GetType()); @@ -100,7 +100,7 @@ namespace Godot using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { - writer.Write((ulong) TargetKind.CompilerGenerated); + writer.Write((ulong)TargetKind.CompilerGenerated); SerializeType(writer, targetType); SerializeType(writer, @delegate.GetType()); @@ -149,14 +149,14 @@ namespace Godot int flags = 0; if (methodInfo.IsPublic) - flags |= (int) BindingFlags.Public; + flags |= (int)BindingFlags.Public; else - flags |= (int) BindingFlags.NonPublic; + flags |= (int)BindingFlags.NonPublic; if (methodInfo.IsStatic) - flags |= (int) BindingFlags.Static; + flags |= (int)BindingFlags.Static; else - flags |= (int) BindingFlags.Instance; + flags |= (int)BindingFlags.Instance; writer.Write(flags); @@ -238,7 +238,7 @@ namespace Godot } else { - if (TryDeserializeSingleDelegate((byte[]) elem, out Delegate oneDelegate)) + if (TryDeserializeSingleDelegate((byte[])elem, out Delegate oneDelegate)) delegates.Add(oneDelegate); } } @@ -257,7 +257,7 @@ namespace Godot using (var stream = new MemoryStream(buffer, writable: false)) using (var reader = new BinaryReader(stream)) { - var targetKind = (TargetKind) reader.ReadUInt64(); + var targetKind = (TargetKind)reader.ReadUInt64(); switch (targetKind) { @@ -353,11 +353,11 @@ namespace Godot parameterTypes[i] = parameterType; } - methodInfo = declaringType.GetMethod(methodName, (BindingFlags) flags, null, parameterTypes, null); + methodInfo = declaringType.GetMethod(methodName, (BindingFlags)flags, null, parameterTypes, null); return methodInfo != null && methodInfo.ReturnType == returnType; } - methodInfo = declaringType.GetMethod(methodName, (BindingFlags) flags); + methodInfo = declaringType.GetMethod(methodName, (BindingFlags)flags); return methodInfo != null && methodInfo.ReturnType == returnType; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs index c4c911b863..0c21bcaa3f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs @@ -1,4 +1,3 @@ - using System; using System.Collections.Generic; using System.Dynamic; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index 6699c5992c..e7d4c40034 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -1,12 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; - #endif +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; // TODO: Add comments describing what this class does. It is not obvious. @@ -26,7 +25,7 @@ namespace Godot public static real_t Db2Linear(real_t db) { - return (real_t) Math.Exp(db * 0.11512925464970228420089957273422); + return (real_t)Math.Exp(db * 0.11512925464970228420089957273422); } public static real_t DecTime(real_t value, real_t amount, real_t step) @@ -51,7 +50,7 @@ namespace Godot public static real_t Linear2Db(real_t linear) { - return (real_t) (Math.Log(linear) * 8.6858896380650365530225783783321); + return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321); } public static Resource Load(string path) @@ -76,7 +75,7 @@ namespace Godot public static void Print(params object[] what) { - godot_icall_GD_print(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null")); + godot_icall_GD_print(Array.ConvertAll(what ?? new object[] { "null" }, x => x != null ? x.ToString() : "null")); } public static void PrintStack() @@ -86,22 +85,22 @@ namespace Godot public static void PrintErr(params object[] what) { - godot_icall_GD_printerr(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null")); + godot_icall_GD_printerr(Array.ConvertAll(what ?? new object[] { "null" }, x => x != null ? x.ToString() : "null")); } public static void PrintRaw(params object[] what) { - godot_icall_GD_printraw(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null")); + godot_icall_GD_printraw(Array.ConvertAll(what ?? new object[] { "null" }, x => x != null ? x.ToString() : "null")); } public static void PrintS(params object[] what) { - godot_icall_GD_prints(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null")); + godot_icall_GD_prints(Array.ConvertAll(what ?? new object[] { "null" }, x => x != null ? x.ToString() : "null")); } public static void PrintT(params object[] what) { - godot_icall_GD_printt(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null")); + godot_icall_GD_printt(Array.ConvertAll(what ?? new object[] { "null" }, x => x != null ? x.ToString() : "null")); } public static float Randf() diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs index f1a00ae0fa..a566b53659 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTraceListener.cs @@ -1,4 +1,3 @@ -using System; using System.Diagnostics; namespace Godot diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs index 702a6c76ba..729529d093 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs index c59d083080..f508211f68 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs @@ -1,12 +1,8 @@ using System; -using System.Collections; using System.Collections.Generic; namespace Godot { - using Array = Godot.Collections.Array; - using Dictionary = Godot.Collections.Dictionary; - static class MarshalUtils { /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index c3f372d415..213f84ad73 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -1,9 +1,9 @@ -using System; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; namespace Godot { @@ -14,13 +14,15 @@ namespace Godot /// <summary> /// The circle constant, the circumference of the unit circle in radians. /// </summary> - public const real_t Tau = (real_t) 6.2831853071795864769252867666M; // 6.2831855f and 6.28318530717959 + // 6.2831855f and 6.28318530717959 + public const real_t Tau = (real_t)6.2831853071795864769252867666M; /// <summary> /// Constant that represents how many times the diameter of a circle /// fits around its perimeter. This is equivalent to `Mathf.Tau / 2`. /// </summary> - public const real_t Pi = (real_t) 3.1415926535897932384626433833M; // 3.1415927f and 3.14159265358979 + // 3.1415927f and 3.14159265358979 + public const real_t Pi = (real_t)3.1415926535897932384626433833M; /// <summary> /// Positive infinity. For negative infinity, use `-Mathf.Inf`. @@ -34,8 +36,10 @@ namespace Godot /// </summary> public const real_t NaN = real_t.NaN; - private const real_t Deg2RadConst = (real_t) 0.0174532925199432957692369077M; // 0.0174532924f and 0.0174532925199433 - private const real_t Rad2DegConst = (real_t) 57.295779513082320876798154814M; // 57.29578f and 57.2957795130823 + // 0.0174532924f and 0.0174532925199433 + private const real_t Deg2RadConst = (real_t)0.0174532925199432957692369077M; + // 57.29578f and 57.2957795130823 + private const real_t Rad2DegConst = (real_t)57.295779513082320876798154814M; /// <summary> /// Returns the absolute value of `s` (i.e. positive value). @@ -515,7 +519,8 @@ namespace Godot /// <returns>One of three possible values: `1`, `-1`, or `0`.</returns> public static int Sign(int s) { - if (s == 0) return 0; + if (s == 0) + return 0; return s < 0 ? -1 : 1; } @@ -526,7 +531,8 @@ namespace Godot /// <returns>One of three possible values: `1`, `-1`, or `0`.</returns> public static int Sign(real_t s) { - if (s == 0) return 0; + if (s == 0) + return 0; return s < 0 ? -1 : 1; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs index c2f4701b5f..0888e33090 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs @@ -1,10 +1,9 @@ -using System; - #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; namespace Godot { @@ -15,12 +14,12 @@ namespace Godot /// <summary> /// The natural number `e`. /// </summary> - public const real_t E = (real_t) 2.7182818284590452353602874714M; // 2.7182817f and 2.718281828459045 + public const real_t E = (real_t)2.7182818284590452353602874714M; // 2.7182817f and 2.718281828459045 /// <summary> /// The square root of 2. /// </summary> - public const real_t Sqrt2 = (real_t) 1.4142135623730950488016887242M; // 1.4142136f and 1.414213562373095 + public const real_t Sqrt2 = (real_t)1.4142135623730950488016887242M; // 1.4142136f and 1.414213562373095 /// <summary> /// A very small number used for float comparison with error tolerance. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs index ad6ca51e8b..1278fb53c2 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs @@ -1,10 +1,10 @@ -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { @@ -177,7 +177,7 @@ namespace Godot return null; } - return from + dir * -dist; + return from - (dir * dist); } /// <summary> @@ -206,7 +206,7 @@ namespace Godot return null; } - return begin + segment * -dist; + return begin - (segment * dist); } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index 817103994a..35f8217432 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -1,10 +1,10 @@ -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs index 612fb64a3d..1053baaa26 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs @@ -1,10 +1,10 @@ -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index 98efa89ef0..b182f1f15e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -61,9 +61,9 @@ namespace Godot return string.Empty; } - // <summary> - // If the string is a path to a file, return the path to the file without the extension. - // </summary> + /// <summary> + /// If the string is a path to a file, return the path to the file without the extension. + /// </summary> public static string BaseName(this string instance) { int index = instance.LastIndexOf('.'); @@ -74,17 +74,17 @@ namespace Godot return instance; } - // <summary> - // Return true if the strings begins with the given string. - // </summary> + /// <summary> + /// Return <see langword="true"/> if the strings begins with the given string. + /// </summary> public static bool BeginsWith(this string instance, string text) { return instance.StartsWith(text); } - // <summary> - // Return the bigrams (pairs of consecutive letters) of this string. - // </summary> + /// <summary> + /// Return the bigrams (pairs of consecutive letters) of this string. + /// </summary> public static string[] Bigrams(this string instance) { var b = new string[instance.Length - 1]; @@ -124,12 +124,12 @@ namespace Godot instance = instance.Substring(2); } - return sign * Convert.ToInt32(instance, 2);; + return sign * Convert.ToInt32(instance, 2); } - // <summary> - // Return the amount of substrings in string. - // </summary> + /// <summary> + /// Return the amount of substrings in string. + /// </summary> public static int Count(this string instance, string what, bool caseSensitive = true, int from = 0, int to = 0) { if (what.Length == 0) @@ -187,9 +187,9 @@ namespace Godot return c; } - // <summary> - // Return a copy of the string with special characters escaped using the C language standard. - // </summary> + /// <summary> + /// Return a copy of the string with special characters escaped using the C language standard. + /// </summary> public static string CEscape(this string instance) { var sb = new StringBuilder(string.Copy(instance)); @@ -209,9 +209,10 @@ namespace Godot return sb.ToString(); } - // <summary> - // Return a copy of the string with escaped characters replaced by their meanings according to the C language standard. - // </summary> + /// <summary> + /// Return a copy of the string with escaped characters replaced by their meanings + /// according to the C language standard. + /// </summary> public static string CUnescape(this string instance) { var sb = new StringBuilder(string.Copy(instance)); @@ -231,9 +232,12 @@ namespace Godot return sb.ToString(); } - // <summary> - // Change the case of some letters. Replace underscores with spaces, convert all letters to lowercase then capitalize first and every letter following the space character. For [code]capitalize camelCase mixed_with_underscores[/code] it will return [code]Capitalize Camelcase Mixed With Underscores[/code]. - // </summary> + /// <summary> + /// Change the case of some letters. Replace underscores with spaces, convert all letters + /// to lowercase then capitalize first and every letter following the space character. + /// For <c>capitalize camelCase mixed_with_underscores</c> it will return + /// <c>Capitalize Camelcase Mixed With Underscores</c>. + /// </summary> public static string Capitalize(this string instance) { string aux = instance.Replace("_", " ").ToLower(); @@ -254,17 +258,17 @@ namespace Godot return cap; } - // <summary> - // Perform a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater. - // </summary> + /// <summary> + /// Perform a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater. + /// </summary> public static int CasecmpTo(this string instance, string to) { return instance.CompareTo(to, caseSensitive: true); } - // <summary> - // Perform a comparison to another string, return -1 if less, 0 if equal and +1 if greater. - // </summary> + /// <summary> + /// Perform a comparison to another string, return -1 if less, 0 if equal and +1 if greater. + /// </summary> public static int CompareTo(this string instance, string to, bool caseSensitive = true) { if (string.IsNullOrEmpty(instance)) @@ -316,25 +320,25 @@ namespace Godot } } - // <summary> - // Return true if the strings ends with the given string. - // </summary> + /// <summary> + /// Return <see langword="true"/> if the strings ends with the given string. + /// </summary> public static bool EndsWith(this string instance, string text) { return instance.EndsWith(text); } - // <summary> - // Erase [code]chars[/code] characters from the string starting from [code]pos[/code]. - // </summary> + /// <summary> + /// Erase <paramref name="chars"/> characters from the string starting from <paramref name="pos"/>. + /// </summary> public static void Erase(this StringBuilder instance, int pos, int chars) { instance.Remove(pos, chars); } - // <summary> - // If the string is a path to a file, return the extension. - // </summary> + /// <summary> + /// If the string is a path to a file, return the extension. + /// </summary> public static string Extension(this string instance) { int pos = instance.FindLast("."); @@ -345,14 +349,18 @@ namespace Godot return instance.Substring(pos + 1); } - /// <summary>Find the first occurrence of a substring. Optionally, the search starting position can be passed.</summary> + /// <summary> + /// Find the first occurrence of a substring. Optionally, the search starting position can be passed. + /// </summary> /// <returns>The starting position of the substring, or -1 if not found.</returns> public static int Find(this string instance, string what, int from = 0, bool caseSensitive = true) { return instance.IndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); } - /// <summary>Find the first occurrence of a char. Optionally, the search starting position can be passed.</summary> + /// <summary> + /// Find the first occurrence of a char. Optionally, the search starting position can be passed. + /// </summary> /// <returns>The first instance of the char, or -1 if not found.</returns> public static int Find(this string instance, char what, int from = 0, bool caseSensitive = true) { @@ -375,16 +383,19 @@ namespace Godot return instance.LastIndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); } - /// <summary>Find the first occurrence of a substring but search as case-insensitive. Optionally, the search starting position can be passed.</summary> + /// <summary> + /// Find the first occurrence of a substring but search as case-insensitive. + /// Optionally, the search starting position can be passed. + /// </summary> /// <returns>The starting position of the substring, or -1 if not found.</returns> public static int FindN(this string instance, string what, int from = 0) { return instance.IndexOf(what, from, StringComparison.OrdinalIgnoreCase); } - // <summary> - // If the string is a path to a file, return the base directory. - // </summary> + /// <summary> + /// If the string is a path to a file, return the base directory. + /// </summary> public static string GetBaseDir(this string instance) { int basepos = instance.Find("://"); @@ -419,9 +430,9 @@ namespace Godot return @base + rs.Substr(0, sep); } - // <summary> - // If the string is a path to a file, return the file and ignore the base directory. - // </summary> + /// <summary> + /// If the string is a path to a file, return the file and ignore the base directory. + /// </summary> public static string GetFile(this string instance) { int sep = Mathf.Max(instance.FindLast("/"), instance.FindLast("\\")); @@ -461,14 +472,14 @@ namespace Godot return Encoding.UTF8.GetString(bytes); } - // <summary> - // Hash the string and return a 32 bits unsigned integer. - // </summary> + /// <summary> + /// Hash the string and return a 32 bits unsigned integer. + /// </summary> public static uint Hash(this string instance) { uint hash = 5381; - foreach(uint c in instance) + foreach (uint c in instance) { hash = (hash << 5) + hash + c; // hash * 33 + c } @@ -553,17 +564,17 @@ namespace Godot return sign * int.Parse(instance, NumberStyles.HexNumber); } - // <summary> - // Insert a substring at a given position. - // </summary> + /// <summary> + /// Insert a substring at a given position. + /// </summary> public static string Insert(this string instance, int pos, string what) { return instance.Insert(pos, what); } - // <summary> - // If the string is a path to a file or directory, return true if the path is absolute. - // </summary> + /// <summary> + /// If the string is a path to a file or directory, return <see langword="true"/> if the path is absolute. + /// </summary> public static bool IsAbsPath(this string instance) { if (string.IsNullOrEmpty(instance)) @@ -574,17 +585,17 @@ namespace Godot return instance[0] == '/' || instance[0] == '\\'; } - // <summary> - // If the string is a path to a file or directory, return true if the path is relative. - // </summary> + /// <summary> + /// If the string is a path to a file or directory, return <see langword="true"/> if the path is relative. + /// </summary> public static bool IsRelPath(this string instance) { return !IsAbsPath(instance); } - // <summary> - // Check whether this string is a subsequence of the given string. - // </summary> + /// <summary> + /// Check whether this string is a subsequence of the given string. + /// </summary> public static bool IsSubsequenceOf(this string instance, string text, bool caseSensitive = true) { int len = instance.Length; @@ -625,34 +636,36 @@ namespace Godot return false; } - // <summary> - // Check whether this string is a subsequence of the given string, ignoring case differences. - // </summary> + /// <summary> + /// Check whether this string is a subsequence of the given string, ignoring case differences. + /// </summary> public static bool IsSubsequenceOfI(this string instance, string text) { return instance.IsSubsequenceOf(text, caseSensitive: false); } - // <summary> - // Check whether the string contains a valid float. - // </summary> + /// <summary> + /// Check whether the string contains a valid <see langword="float"/>. + /// </summary> public static bool IsValidFloat(this string instance) { float f; return float.TryParse(instance, out f); } - // <summary> - // Check whether the string contains a valid color in HTML notation. - // </summary> + /// <summary> + /// Check whether the string contains a valid color in HTML notation. + /// </summary> public static bool IsValidHtmlColor(this string instance) { return Color.HtmlIsValid(instance); } - // <summary> - // Check whether the string is a valid identifier. As is common in programming languages, a valid identifier may contain only letters, digits and underscores (_) and the first character may not be a digit. - // </summary> + /// <summary> + /// Check whether the string is a valid identifier. As is common in + /// programming languages, a valid identifier may contain only letters, + /// digits and underscores (_) and the first character may not be a digit. + /// </summary> public static bool IsValidIdentifier(this string instance) { int len = instance.Length; @@ -680,18 +693,18 @@ namespace Godot return true; } - // <summary> - // Check whether the string contains a valid integer. - // </summary> + /// <summary> + /// Check whether the string contains a valid integer. + /// </summary> public static bool IsValidInteger(this string instance) { int f; return int.TryParse(instance, out f); } - // <summary> - // Check whether the string contains a valid IP address. - // </summary> + /// <summary> + /// Check whether the string contains a valid IP address. + /// </summary> public static bool IsValidIPAddress(this string instance) { // TODO: Support IPv6 addresses @@ -714,9 +727,9 @@ namespace Godot return true; } - // <summary> - // Return a copy of the string with special characters escaped using the JSON standard. - // </summary> + /// <summary> + /// Return a copy of the string with special characters escaped using the JSON standard. + /// </summary> public static string JSONEscape(this string instance) { var sb = new StringBuilder(string.Copy(instance)); @@ -733,9 +746,9 @@ namespace Godot return sb.ToString(); } - // <summary> - // Return an amount of characters from the left of the string. - // </summary> + /// <summary> + /// Return an amount of characters from the left of the string. + /// </summary> public static string Left(this string instance, int pos) { if (pos <= 0) @@ -783,7 +796,8 @@ namespace Godot } /// <summary> - /// Do a simple expression match, where '*' matches zero or more arbitrary characters and '?' matches any single character except '.'. + /// Do a simple expression match, where '*' matches zero or more + /// arbitrary characters and '?' matches any single character except '.'. /// </summary> private static bool ExprMatch(this string instance, string expr, bool caseSensitive) { @@ -798,13 +812,17 @@ namespace Godot case '?': return instance.Length > 0 && instance[0] != '.' && ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive); default: - if (instance.Length == 0) return false; - return (caseSensitive ? instance[0] == expr[0] : char.ToUpper(instance[0]) == char.ToUpper(expr[0])) && ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive); + if (instance.Length == 0) + return false; + if (caseSensitive) + return instance[0] == expr[0]; + return (char.ToUpper(instance[0]) == char.ToUpper(expr[0])) && ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive); } } /// <summary> - /// Do a simple case sensitive expression match, using ? and * wildcards (see [method expr_match]). + /// Do a simple case sensitive expression match, using ? and * wildcards + /// (see <see cref="ExprMatch(string, string, bool)"/>). /// </summary> public static bool Match(this string instance, string expr, bool caseSensitive = true) { @@ -815,7 +833,8 @@ namespace Godot } /// <summary> - /// Do a simple case insensitive expression match, using ? and * wildcards (see [method expr_match]). + /// Do a simple case insensitive expression match, using ? and * wildcards + /// (see <see cref="ExprMatch(string, string, bool)"/>). /// </summary> public static bool MatchN(this string instance, string expr) { @@ -825,9 +844,9 @@ namespace Godot return instance.ExprMatch(expr, caseSensitive: false); } - // <summary> - // Return the MD5 hash of the string as an array of bytes. - // </summary> + /// <summary> + /// Return the MD5 hash of the string as an array of bytes. + /// </summary> public static byte[] MD5Buffer(this string instance) { return godot_icall_String_md5_buffer(instance); @@ -836,9 +855,9 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static byte[] godot_icall_String_md5_buffer(string str); - // <summary> - // Return the MD5 hash of the string as a string. - // </summary> + /// <summary> + /// Return the MD5 hash of the string as a string. + /// </summary> public static string MD5Text(this string instance) { return godot_icall_String_md5_text(instance); @@ -847,25 +866,25 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static string godot_icall_String_md5_text(string str); - // <summary> - // Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater. - // </summary> + /// <summary> + /// Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater. + /// </summary> public static int NocasecmpTo(this string instance, string to) { return instance.CompareTo(to, caseSensitive: false); } - // <summary> - // Return the character code at position [code]at[/code]. - // </summary> + /// <summary> + /// Return the character code at position <paramref name="at"/>. + /// </summary> public static int OrdAt(this string instance, int at) { return instance[at]; } - // <summary> - // Format a number to have an exact number of [code]digits[/code] after the decimal point. - // </summary> + /// <summary> + /// Format a number to have an exact number of <paramref name="digits"/> after the decimal point. + /// </summary> public static string PadDecimals(this string instance, int digits) { int c = instance.Find("."); @@ -899,9 +918,9 @@ namespace Godot return instance; } - // <summary> - // Format a number to have an exact number of [code]digits[/code] before the decimal point. - // </summary> + /// <summary> + /// Format a number to have an exact number of <paramref name="digits"/> before the decimal point. + /// </summary> public static string PadZeros(this string instance, int digits) { string s = instance; @@ -932,9 +951,10 @@ namespace Godot return s; } - // <summary> - // If the string is a path, this concatenates [code]file[/code] at the end of the string as a subpath. E.g. [code]"this/is".plus_file("path") == "this/is/path"[/code]. - // </summary> + /// <summary> + /// If the string is a path, this concatenates <paramref name="file"/> at the end of the string as a subpath. + /// E.g. <c>"this/is".PlusFile("path") == "this/is/path"</c>. + /// </summary> public static string PlusFile(this string instance, string file) { if (instance.Length > 0 && instance[instance.Length - 1] == '/') @@ -942,25 +962,25 @@ namespace Godot return instance + "/" + file; } - // <summary> - // Replace occurrences of a substring for different ones inside the string. - // </summary> + /// <summary> + /// Replace occurrences of a substring for different ones inside the string. + /// </summary> public static string Replace(this string instance, string what, string forwhat) { return instance.Replace(what, forwhat); } - // <summary> - // Replace occurrences of a substring for different ones inside the string, but search case-insensitive. - // </summary> + /// <summary> + /// Replace occurrences of a substring for different ones inside the string, but search case-insensitive. + /// </summary> public static string ReplaceN(this string instance, string what, string forwhat) { return Regex.Replace(instance, what, forwhat, RegexOptions.IgnoreCase); } - // <summary> - // Perform a search for a substring, but start from the end of the string instead of the beginning. - // </summary> + /// <summary> + /// Perform a search for a substring, but start from the end of the string instead of the beginning. + /// </summary> public static int RFind(this string instance, string what, int from = -1) { return godot_icall_String_rfind(instance, what, from); @@ -969,9 +989,10 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static int godot_icall_String_rfind(string str, string what, int from); - // <summary> - // Perform a search for a substring, but start from the end of the string instead of the beginning. Also search case-insensitive. - // </summary> + /// <summary> + /// Perform a search for a substring, but start from the end of the string instead of the beginning. + /// Also search case-insensitive. + /// </summary> public static int RFindN(this string instance, string what, int from = -1) { return godot_icall_String_rfindn(instance, what, from); @@ -980,9 +1001,9 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static int godot_icall_String_rfindn(string str, string what, int from); - // <summary> - // Return the right side of the string from a given position. - // </summary> + /// <summary> + /// Return the right side of the string from a given position. + /// </summary> public static string Right(this string instance, int pos) { if (pos >= instance.Length) @@ -1029,9 +1050,9 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static byte[] godot_icall_String_sha256_buffer(string str); - // <summary> - // Return the SHA-256 hash of the string as a string. - // </summary> + /// <summary> + /// Return the SHA-256 hash of the string as a string. + /// </summary> public static string SHA256Text(this string instance) { return godot_icall_String_sha256_text(instance); @@ -1040,9 +1061,10 @@ namespace Godot [MethodImpl(MethodImplOptions.InternalCall)] internal extern static string godot_icall_String_sha256_text(string str); - // <summary> - // Return the similarity index of the text compared to this string. 1 means totally similar and 0 means totally dissimilar. - // </summary> + /// <summary> + /// Return the similarity index of the text compared to this string. + /// 1 means totally similar and 0 means totally dissimilar. + /// </summary> public static float Similarity(this string instance, string text) { if (instance == text) @@ -1080,17 +1102,19 @@ namespace Godot return 2.0f * inter / sum; } - // <summary> - // Split the string by a divisor string, return an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". - // </summary> + /// <summary> + /// Split the string by a divisor string, return an array of the substrings. + /// Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". + /// </summary> public static string[] Split(this string instance, string divisor, bool allowEmpty = true) { return instance.Split(new[] { divisor }, StringSplitOptions.RemoveEmptyEntries); } - // <summary> - // Split the string in floats by using a divisor string, return an array of the substrings. Example "1,2.5,3" will return [1,2.5,3] if split by ",". - // </summary> + /// <summary> + /// Split the string in floats by using a divisor string, return an array of the substrings. + /// Example "1,2.5,3" will return [1,2.5,3] if split by ",". + /// </summary> public static float[] SplitFloats(this string instance, string divisor, bool allowEmpty = true) { var ret = new List<float>(); @@ -1122,9 +1146,10 @@ namespace Godot (char)30, (char)31, (char)32 }; - // <summary> - // Return a copy of the string stripped of any non-printable character at the beginning and the end. The optional arguments are used to toggle stripping on the left and right edges respectively. - // </summary> + /// <summary> + /// Return a copy of the string stripped of any non-printable character at the beginning and the end. + /// The optional arguments are used to toggle stripping on the left and right edges respectively. + /// </summary> public static string StripEdges(this string instance, bool left = true, bool right = true) { if (left) @@ -1137,58 +1162,62 @@ namespace Godot return instance.TrimEnd(_nonPrintable); } - // <summary> - // Return part of the string from the position [code]from[/code], with length [code]len[/code]. - // </summary> + /// <summary> + /// Return part of the string from the position <paramref name="from"/>, with length <paramref name="len"/>. + /// </summary> public static string Substr(this string instance, int from, int len) { int max = instance.Length - from; return instance.Substring(from, len > max ? max : len); } - // <summary> - // Convert the String (which is a character array) to PackedByteArray (which is an array of bytes). The conversion is speeded up in comparison to to_utf8() with the assumption that all the characters the String contains are only ASCII characters. - // </summary> + /// <summary> + /// Convert the String (which is a character array) to PackedByteArray (which is an array of bytes). + /// The conversion is speeded up in comparison to <see cref="ToUTF8(string)"/> with the assumption + /// that all the characters the String contains are only ASCII characters. + /// </summary> public static byte[] ToAscii(this string instance) { return Encoding.ASCII.GetBytes(instance); } - // <summary> - // Convert a string, containing a decimal number, into a [code]float[/code]. - // </summary> + /// <summary> + /// Convert a string, containing a decimal number, into a <see langword="float" />. + /// </summary> public static float ToFloat(this string instance) { return float.Parse(instance); } - // <summary> - // Convert a string, containing an integer number, into an [code]int[/code]. - // </summary> + /// <summary> + /// Convert a string, containing an integer number, into an <see langword="int" />. + /// </summary> public static int ToInt(this string instance) { return int.Parse(instance); } - // <summary> - // Return the string converted to lowercase. - // </summary> + /// <summary> + /// Return the string converted to lowercase. + /// </summary> public static string ToLower(this string instance) { return instance.ToLower(); } - // <summary> - // Return the string converted to uppercase. - // </summary> + /// <summary> + /// Return the string converted to uppercase. + /// </summary> public static string ToUpper(this string instance) { return instance.ToUpper(); } - // <summary> - // Convert the String (which is an array of characters) to PackedByteArray (which is an array of bytes). The conversion is a bit slower than to_ascii(), but supports all UTF-8 characters. Therefore, you should prefer this function over to_ascii(). - // </summary> + /// <summary> + /// Convert the String (which is an array of characters) to PackedByteArray (which is an array of bytes). + /// The conversion is a bit slower than <see cref="ToAscii(string)"/>, but supports all UTF-8 characters. + /// Therefore, you should prefer this function over <see cref="ToAscii(string)"/>. + /// </summary> public static byte[] ToUTF8(this string instance) { return Encoding.UTF8.GetBytes(instance); @@ -1221,17 +1250,18 @@ namespace Godot return Uri.EscapeDataString(instance); } - // <summary> - // Return a copy of the string with special characters escaped using the XML standard. - // </summary> + /// <summary> + /// Return a copy of the string with special characters escaped using the XML standard. + /// </summary> public static string XMLEscape(this string instance) { return SecurityElement.Escape(instance); } - // <summary> - // Return a copy of the string with escaped characters replaced by their meanings according to the XML standard. - // </summary> + /// <summary> + /// Return a copy of the string with escaped characters replaced by their meanings + /// according to the XML standard. + /// </summary> public static string XMLUnescape(this string instance) { return SecurityElement.FromString(instance).Text; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index fe93592667..c135eb137f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -1,10 +1,10 @@ -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 26b1a9e8b2..5c57203ca7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -1,10 +1,10 @@ -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index af053bd263..a0948d8b10 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -1,16 +1,10 @@ -// file: core/math/math_2d.h -// commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451 -// file: core/math/math_2d.cpp -// commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451 -// file: core/variant_call.cpp -// commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685 -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs index 9068593fd8..b4c631608e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -1,11 +1,10 @@ -using System; -using System.Runtime.InteropServices; - #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 31a9af2d9e..a02a0d2dd9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -1,16 +1,10 @@ -// file: core/math/vector3.h -// commit: bd282ff43f23fe845f29a3e25c8efc01bd65ffb0 -// file: core/math/vector3.cpp -// commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451 -// file: core/variant_call.cpp -// commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685 -using System; -using System.Runtime.InteropServices; #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs index e727afa3ff..80bad061b2 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs @@ -1,11 +1,10 @@ -using System; -using System.Runtime.InteropServices; - #if REAL_T_IS_DOUBLE using real_t = System.Double; #else using real_t = System.Single; #endif +using System; +using System.Runtime.InteropServices; namespace Godot { diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 2d04cedb9b..a99dff8432 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -177,8 +177,8 @@ MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) { MonoArray *result = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), property_list.size()); int i = 0; - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { - MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get().name); + for (const PropertyInfo &E : property_list) { + MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E.name); mono_array_setref(result, i, boxed); i++; } diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 02d875f669..299344bb93 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -100,8 +100,8 @@ void gd_mono_setup_runtime_main_args() { main_args.write[0] = execpath.ptrw(); int i = 1; - for (List<String>::Element *E = cmdline_args.front(); E; E = E->next()) { - CharString &stored = cmdline_args_utf8.push_back(E->get().utf8())->get(); + for (const String &E : cmdline_args) { + CharString &stored = cmdline_args_utf8.push_back(E.utf8())->get(); main_args.write[i] = stored.ptrw(); i++; } diff --git a/modules/navigation/navigation_mesh_editor_plugin.cpp b/modules/navigation/navigation_mesh_editor_plugin.cpp index 8f4203e260..587e56f593 100644 --- a/modules/navigation/navigation_mesh_editor_plugin.cpp +++ b/modules/navigation/navigation_mesh_editor_plugin.cpp @@ -65,7 +65,7 @@ void NavigationMeshEditor::_bake_pressed() { NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh()); NavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node); - node->update_gizmo(); + node->update_gizmos(); } void NavigationMeshEditor::_clear_pressed() { @@ -77,7 +77,7 @@ void NavigationMeshEditor::_clear_pressed() { bake_info->set_text(""); if (node) { - node->update_gizmo(); + node->update_gizmos(); } } diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 7aeb9e1858..41cd75fd22 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -514,11 +514,11 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) } Transform3D navmesh_xform = Object::cast_to<Node3D>(p_node)->get_transform().affine_inverse(); - for (const List<Node *>::Element *E = parse_nodes.front(); E; E = E->next()) { + for (Node *E : parse_nodes) { int geometry_type = p_nav_mesh->get_parsed_geometry_type(); uint32_t collision_mask = p_nav_mesh->get_collision_mask(); bool recurse_children = p_nav_mesh->get_source_geometry_mode() != NavigationMesh::SOURCE_GEOMETRY_GROUPS_EXPLICIT; - _parse_geometry(navmesh_xform, E->get(), vertices, indices, geometry_type, collision_mask, recurse_children); + _parse_geometry(navmesh_xform, E, vertices, indices, geometry_type, collision_mask, recurse_children); } if (vertices.size() > 0 && indices.size() > 0) { diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 2513039e8e..fa4888f843 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -927,14 +927,14 @@ void TextServerAdvanced::font_set_oversampling(float p_oversampling) { oversampling = p_oversampling; List<RID> fonts; font_owner.get_owned_list(&fonts); - for (List<RID>::Element *E = fonts.front(); E; E = E->next()) { - font_owner.getornull(E->get())->clear_cache(); + for (const RID &E : fonts) { + font_owner.getornull(E)->clear_cache(); } List<RID> text_bufs; shaped_owner.get_owned_list(&text_bufs); - for (List<RID>::Element *E = text_bufs.front(); E; E = E->next()) { - invalidate(shaped_owner.getornull(E->get())); + for (const RID &E : text_bufs) { + invalidate(shaped_owner.getornull(E)); } } } diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 9ad7dabbcc..004cbc2bb3 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -473,8 +473,8 @@ void TextServerFallback::font_set_oversampling(float p_oversampling) { oversampling = p_oversampling; List<RID> fonts; font_owner.get_owned_list(&fonts); - for (List<RID>::Element *E = fonts.front(); E; E = E->next()) { - font_owner.getornull(E->get())->clear_cache(); + for (const RID &E : fonts) { + font_owner.getornull(E)->clear_cache(); } } } diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 0de39512ae..7a2404fd80 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -588,14 +588,14 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p variables.erase(p_name); List<int> ids; get_node_list(&ids); - for (List<int>::Element *E = ids.front(); E; E = E->next()) { - Ref<VisualScriptVariableGet> nodeget = get_node(E->get()); + for (int &E : ids) { + Ref<VisualScriptVariableGet> nodeget = get_node(E); if (nodeget.is_valid()) { if (nodeget->get_variable() == p_name) { nodeget->set_variable(p_new_name); } } else { - Ref<VisualScriptVariableSet> nodeset = get_node(E->get()); + Ref<VisualScriptVariableSet> nodeset = get_node(E); if (nodeset.is_valid()) { if (nodeset->get_variable() == p_name) { nodeset->set_variable(p_new_name); @@ -715,9 +715,9 @@ int VisualScript::get_available_id() const { List<int> nds; nodes.get_key_list(&nds); int max = -1; - for (const List<int>::Element *E = nds.front(); E; E = E->next()) { - if (E->get() > max) { - max = E->get(); + for (const int &E : nds) { + if (E > max) { + max = E; } } return (max + 1); @@ -752,15 +752,15 @@ void VisualScript::_update_placeholders() { List<StringName> keys; variables.get_key_list(&keys); - for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { - if (!variables[E->get()]._export) { + for (const StringName &E : keys) { + if (!variables[E]._export) { continue; } - PropertyInfo p = variables[E->get()].info; - p.name = String(E->get()); + PropertyInfo p = variables[E].info; + p.name = String(E); pinfo.push_back(p); - values[p.name] = variables[E->get()].default_value; + values[p.name] = variables[E].default_value; } for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) { @@ -783,15 +783,15 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) { List<StringName> keys; variables.get_key_list(&keys); - for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { - if (!variables[E->get()]._export) { + for (const StringName &E : keys) { + if (!variables[E]._export) { continue; } - PropertyInfo p = variables[E->get()].info; - p.name = String(E->get()); + PropertyInfo p = variables[E].info; + p.name = String(E); pinfo.push_back(p); - values[p.name] = variables[E->get()].default_value; + values[p.name] = variables[E].default_value; } sins->update(pinfo, values); @@ -874,11 +874,11 @@ void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const { List<StringName> funcs; functions.get_key_list(&funcs); - for (List<StringName>::Element *E = funcs.front(); E; E = E->next()) { + for (const StringName &E : funcs) { MethodInfo mi; - mi.name = E->get(); - if (functions[E->get()].func_id >= 0) { - Ref<VisualScriptFunction> func = nodes[functions[E->get()].func_id].node; + mi.name = E; + if (functions[E].func_id >= 0) { + Ref<VisualScriptFunction> func = nodes[functions[E].func_id].node; if (func.is_valid()) { for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arg; @@ -928,10 +928,10 @@ void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const { List<StringName> vars; get_variable_list(&vars); - for (List<StringName>::Element *E = vars.front(); E; E = E->next()) { - //if (!variables[E->get()]._export) + for (const StringName &E : vars) { + //if (!variables[E]._export) // continue; - PropertyInfo pi = variables[E->get()].info; + PropertyInfo pi = variables[E].info; pi.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; p_list->push_back(pi); } @@ -945,8 +945,8 @@ int VisualScript::get_member_line(const StringName &p_member) const { bool VisualScript::are_subnodes_edited() const { List<int> keys; nodes.get_key_list(&keys); - for (const List<int>::Element *F = keys.front(); F; F = F->next()) { - if (nodes[F->get()].node->is_edited()) { + for (const int &F : keys) { + if (nodes[F].node->is_edited()) { return true; } } @@ -1017,13 +1017,13 @@ void VisualScript::_set_data(const Dictionary &p_data) { rpc_functions.clear(); List<StringName> fns; functions.get_key_list(&fns); - for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) { - if (functions[E->get()].func_id >= 0 && nodes.has(functions[E->get()].func_id)) { - Ref<VisualScriptFunction> vsf = nodes[functions[E->get()].func_id].node; + for (const StringName &E : fns) { + if (functions[E].func_id >= 0 && nodes.has(functions[E].func_id)) { + Ref<VisualScriptFunction> vsf = nodes[functions[E].func_id].node; if (vsf.is_valid()) { if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { MultiplayerAPI::RPCConfig nd; - nd.name = E->get(); + nd.name = E; nd.rpc_mode = vsf->get_rpc_mode(); nd.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE; // TODO if (rpc_functions.find(nd) == -1) { @@ -1045,11 +1045,11 @@ Dictionary VisualScript::_get_data() const { Array vars; List<StringName> var_names; variables.get_key_list(&var_names); - for (const List<StringName>::Element *E = var_names.front(); E; E = E->next()) { - Dictionary var = _get_variable_info(E->get()); - var["name"] = E->get(); // Make sure it's the right one. - var["default_value"] = variables[E->get()].default_value; - var["export"] = variables[E->get()]._export; + for (const StringName &E : var_names) { + Dictionary var = _get_variable_info(E); + var["name"] = E; // Make sure it's the right one. + var["default_value"] = variables[E].default_value; + var["export"] = variables[E]._export; vars.push_back(var); } d["variables"] = vars; @@ -1073,10 +1073,10 @@ Dictionary VisualScript::_get_data() const { Array funcs; List<StringName> func_names; functions.get_key_list(&func_names); - for (const List<StringName>::Element *E = func_names.front(); E; E = E->next()) { + for (const StringName &E : func_names) { Dictionary func; - func["name"] = E->get(); - func["function_id"] = functions[E->get()].func_id; + func["name"] = E; + func["function_id"] = functions[E].func_id; funcs.push_back(func); } d["functions"] = funcs; @@ -1084,10 +1084,10 @@ Dictionary VisualScript::_get_data() const { Array nds; List<int> node_ids; nodes.get_key_list(&node_ids); - for (const List<int>::Element *F = node_ids.front(); F; F = F->next()) { - nds.push_back(F->get()); - nds.push_back(nodes[F->get()].pos); - nds.push_back(nodes[F->get()].node); + for (const int &F : node_ids) { + nds.push_back(F); + nds.push_back(nodes[F].pos); + nds.push_back(nodes[F].node); } d["nodes"] = nds; @@ -1202,8 +1202,8 @@ VisualScript::~VisualScript() { // Remove all nodes and stuff that hold data refs. List<int> nds; nodes.get_key_list(&nds); - for (const List<int>::Element *E = nds.front(); E; E = E->next()) { - remove_node(E->get()); + for (const int &E : nds) { + remove_node(E); } } @@ -1233,12 +1233,12 @@ bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const { void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { List<StringName> vars; script->variables.get_key_list(&vars); - for (const List<StringName>::Element *E = vars.front(); E; E = E->next()) { - if (!script->variables[E->get()]._export) { + for (const StringName &E : vars) { + if (!script->variables[E]._export) { continue; } - PropertyInfo p = script->variables[E->get()].info; - p.name = String(E->get()); + PropertyInfo p = script->variables[E].info; + p.name = String(E); p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; p_properties->push_back(p); } @@ -1262,11 +1262,11 @@ Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { List<StringName> fns; script->functions.get_key_list(&fns); - for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) { + for (const StringName &E : fns) { MethodInfo mi; - mi.name = E->get(); - if (script->functions[E->get()].func_id >= 0 && script->nodes.has(script->functions[E->get()].func_id)) { - Ref<VisualScriptFunction> vsf = script->nodes[script->functions[E->get()].func_id].node; + mi.name = E; + if (script->functions[E].func_id >= 0 && script->nodes.has(script->functions[E].func_id)) { + Ref<VisualScriptFunction> vsf = script->nodes[script->functions[E].func_id].node; if (vsf.is_valid()) { for (int i = 0; i < vsf->get_argument_count(); i++) { PropertyInfo arg; @@ -1868,8 +1868,8 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o { List<StringName> keys; script->variables.get_key_list(&keys); - for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { - variables[E->get()] = script->variables[E->get()].default_value; + for (const StringName &E : keys) { + variables[E] = script->variables[E].default_value; } } @@ -1877,8 +1877,8 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o { List<StringName> keys; script->functions.get_key_list(&keys); - for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { - const VisualScript::Function vsfn = p_script->functions[E->get()]; + for (const StringName &E : keys) { + const VisualScript::Function vsfn = p_script->functions[E]; Function function; function.node = vsfn.func_id; function.max_stack = 0; @@ -1889,7 +1889,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o Map<StringName, int> local_var_indices; if (function.node < 0) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E->get())); + VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E)); ERR_CONTINUE(function.node < 0); } @@ -1897,7 +1897,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o Ref<VisualScriptFunction> func_node = script->get_node(vsfn.func_id); if (func_node.is_null()) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E->get())); + VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E)); } ERR_CONTINUE(!func_node.is_valid()); @@ -1938,12 +1938,12 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o while (!nd_queue.is_empty()) { int ky = nd_queue.front()->get(); dc_lut[ky].get_key_list(&dc_keys); - for (const List<int>::Element *F = dc_keys.front(); F; F = F->next()) { + for (const int &F : dc_keys) { VisualScript::DataConnection dc; - dc.from_node = dc_lut[ky][F->get()].first; - dc.from_port = dc_lut[ky][F->get()].second; + dc.from_node = dc_lut[ky][F].first; + dc.from_port = dc_lut[ky][F].second; dc.to_node = ky; - dc.to_port = F->get(); + dc.to_port = F; dataconns.insert(dc); nd_queue.push_back(dc.from_node); node_ids.insert(dc.from_node); @@ -2093,7 +2093,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o } } - functions[E->get()] = function; + functions[E] = function; } } } @@ -2467,10 +2467,10 @@ void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<Strin List<StringName> vars; vs->get_variable_list(&vars); - for (List<StringName>::Element *E = vars.front(); E; E = E->next()) { + for (const StringName &E : vars) { Variant v; - if (_call_stack[l].instance->get_variable(E->get(), &v)) { - p_members->push_back("variables/" + E->get()); + if (_call_stack[l].instance->get_variable(E, &v)) { + p_members->push_back("variables/" + E); p_values->push_back(v); } } diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index ed0583a133..fca7985b74 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -561,18 +561,16 @@ void VisualScriptEditor::_update_graph_connections() { List<VisualScript::SequenceConnection> sequence_conns; script->get_sequence_connection_list(&sequence_conns); - for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { - graph->connect_node(itos(E->get().from_node), E->get().from_output, itos(E->get().to_node), 0); + for (const VisualScript::SequenceConnection &E : sequence_conns) { + graph->connect_node(itos(E.from_node), E.from_output, itos(E.to_node), 0); } List<VisualScript::DataConnection> data_conns; script->get_data_connection_list(&data_conns); - for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) { - VisualScript::DataConnection dc = E->get(); - - Ref<VisualScriptNode> from_node = script->get_node(E->get().from_node); - Ref<VisualScriptNode> to_node = script->get_node(E->get().to_node); + for (VisualScript::DataConnection &dc : data_conns) { + Ref<VisualScriptNode> from_node = script->get_node(dc.from_node); + Ref<VisualScriptNode> to_node = script->get_node(dc.to_node); if (to_node->has_input_sequence_port()) { dc.to_port++; @@ -580,7 +578,7 @@ void VisualScriptEditor::_update_graph_connections() { dc.from_port += from_node->get_output_sequence_port_count(); - graph->connect_node(itos(E->get().from_node), dc.from_port, itos(E->get().to_node), dc.to_port); + graph->connect_node(itos(dc.from_node), dc.from_port, itos(dc.to_node), dc.to_port); } } @@ -656,27 +654,27 @@ void VisualScriptEditor::_update_graph(int p_only_id) { script->get_node_list(&ids); StringName editor_icons = "EditorIcons"; - for (List<int>::Element *E = ids.front(); E; E = E->next()) { - if (p_only_id >= 0 && p_only_id != E->get()) { + for (int &E : ids) { + if (p_only_id >= 0 && p_only_id != E) { continue; } - Ref<VisualScriptNode> node = script->get_node(E->get()); - Vector2 pos = script->get_node_position(E->get()); + Ref<VisualScriptNode> node = script->get_node(E); + Vector2 pos = script->get_node_position(E); GraphNode *gnode = memnew(GraphNode); gnode->set_title(node->get_caption()); gnode->set_position_offset(pos * EDSCALE); - if (error_line == E->get()) { + if (error_line == E) { gnode->set_overlay(GraphNode::OVERLAY_POSITION); } else if (node->is_breakpoint()) { gnode->set_overlay(GraphNode::OVERLAY_BREAKPOINT); } gnode->set_meta("__vnode", node); - gnode->set_name(itos(E->get())); - gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E->get())); - gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E->get()), CONNECT_DEFERRED); + gnode->set_name(itos(E)); + gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E)); + gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E), CONNECT_DEFERRED); { Ref<VisualScriptFunction> v = node; @@ -696,7 +694,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Button *btn = memnew(Button); btn->set_text(TTR("Add Input Port")); hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E->get()), CONNECT_DEFERRED); + btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E), CONNECT_DEFERRED); } if (nd_list->is_output_port_editable()) { if (nd_list->is_input_port_editable()) { @@ -706,7 +704,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Button *btn = memnew(Button); btn->set_text(TTR("Add Output Port")); hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E->get()), CONNECT_DEFERRED); + btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E), CONNECT_DEFERRED); } gnode->add_child(hbnc); } else if (Object::cast_to<VisualScriptExpression>(node.ptr())) { @@ -716,7 +714,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { line_edit->set_expand_to_text_length_enabled(true); line_edit->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts"))); gnode->add_child(line_edit); - line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E->get())); + line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E)); } else { String text = node->get_text(); if (!text.is_empty()) { @@ -732,7 +730,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { gnode->set_comment(true); gnode->set_resizable(true); gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE); - gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E->get())); + gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E)); } if (node_styles.has(node->get_category())) { @@ -835,8 +833,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) { name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); name_box->set_text(left_name); name_box->set_expand_to_text_length_enabled(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get())); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, true)); + name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E)); + name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E, i, true)); } else { hbc->add_child(memnew(Label(left_name))); } @@ -849,18 +847,18 @@ void VisualScriptEditor::_update_graph(int p_only_id) { opbtn->select(left_type); opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, true), CONNECT_DEFERRED); + opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E, i, true), CONNECT_DEFERRED); } Button *rmbtn = memnew(Button); rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E->get(), i), CONNECT_DEFERRED); + rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E, i), CONNECT_DEFERRED); } else { hbc->add_child(memnew(Label(left_name))); } - if (left_type != Variant::NIL && !script->is_input_value_port_connected(E->get(), i)) { + if (left_type != Variant::NIL && !script->is_input_value_port_connected(E, i)) { PropertyInfo pi = node->get_input_value_port_info(i); Button *button = memnew(Button); Variant value = node->get_default_input_value(i); @@ -887,7 +885,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { } else { button->set_text(value); } - button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E->get(), i)); + button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E, i)); hbc2->add_child(button); } } else { @@ -911,7 +909,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Button *rmbtn = memnew(Button); rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E->get(), i), CONNECT_DEFERRED); + rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E, i), CONNECT_DEFERRED); if (nd_list->is_output_port_type_editable()) { OptionButton *opbtn = memnew(OptionButton); @@ -921,7 +919,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { opbtn->select(right_type); opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, false), CONNECT_DEFERRED); + opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E, i, false), CONNECT_DEFERRED); } if (nd_list->is_output_port_name_editable()) { @@ -930,8 +928,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) { name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); name_box->set_text(right_name); name_box->set_expand_to_text_length_enabled(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get())); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, false)); + name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E)); + name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E, i, false)); } else { hbc->add_child(memnew(Label(right_name))); } @@ -1047,13 +1045,13 @@ void VisualScriptEditor::_update_members() { List<StringName> func_names; script->get_function_list(&func_names); func_names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = func_names.front(); E; E = E->next()) { + for (const StringName &E : func_names) { TreeItem *ti = members->create_item(functions); - ti->set_text(0, E->get()); + ti->set_text(0, E); ti->set_selectable(0, true); - ti->set_metadata(0, E->get()); + ti->set_metadata(0, E); ti->add_button(0, Control::get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), 0); - if (selected == E->get()) { + if (selected == E) { ti->select(0); } } @@ -1101,18 +1099,18 @@ void VisualScriptEditor::_update_members() { List<StringName> var_names; script->get_variable_list(&var_names); - for (List<StringName>::Element *E = var_names.front(); E; E = E->next()) { + for (const StringName &E : var_names) { TreeItem *ti = members->create_item(variables); - ti->set_text(0, E->get()); + ti->set_text(0, E); - ti->set_suffix(0, "= " + _sanitized_variant_text(E->get())); - ti->set_icon(0, type_icons[script->get_variable_info(E->get()).type]); + ti->set_suffix(0, "= " + _sanitized_variant_text(E)); + ti->set_icon(0, type_icons[script->get_variable_info(E).type]); ti->set_selectable(0, true); ti->set_editable(0, true); - ti->set_metadata(0, E->get()); - if (selected == E->get()) { + ti->set_metadata(0, E); + if (selected == E) { ti->select(0); } } @@ -1125,13 +1123,13 @@ void VisualScriptEditor::_update_members() { List<StringName> signal_names; script->get_custom_signal_list(&signal_names); - for (List<StringName>::Element *E = signal_names.front(); E; E = E->next()) { + for (const StringName &E : signal_names) { TreeItem *ti = members->create_item(_signals); - ti->set_text(0, E->get()); + ti->set_text(0, E); ti->set_selectable(0, true); ti->set_editable(0, true); - ti->set_metadata(0, E->get()); - if (selected == E->get()) { + ti->set_metadata(0, E); + if (selected == E) { ti->select(0); } } @@ -1237,8 +1235,8 @@ void VisualScriptEditor::_member_edited() { // Also fix all function calls. List<int> lst; script->get_node_list(&lst); - for (List<int>::Element *F = lst.front(); F; F = F->next()) { - Ref<VisualScriptFunctionCall> fncall = script->get_node(F->get()); + for (int &F : lst) { + Ref<VisualScriptFunctionCall> fncall = script->get_node(F); if (!fncall.is_valid()) { continue; } @@ -1572,13 +1570,13 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { script->get_data_connection_list(&data_connections); HashMap<int, Set<int>> conn_map; - for (const List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { - if (E->get().from_node == p_id && E->get().from_port == p_port) { + for (const VisualScript::DataConnection &E : data_connections) { + if (E.from_node == p_id && E.from_port == p_port) { // Push into the connections map. - if (!conn_map.has(E->get().to_node)) { - conn_map.set(E->get().to_node, Set<int>()); + if (!conn_map.has(E.to_node)) { + conn_map.set(E.to_node, Set<int>()); } - conn_map[E->get().to_node].insert(E->get().to_port); + conn_map[E.to_node].insert(E.to_port); } } @@ -1587,9 +1585,9 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { List<int> keys; conn_map.get_key_list(&keys); - for (const List<int>::Element *E = keys.front(); E; E = E->next()) { - for (const Set<int>::Element *F = conn_map[E->get()].front(); F; F = F->next()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E->get(), F->get()); + for (const int &E : keys) { + for (const Set<int>::Element *F = conn_map[E].front(); F; F = F->next()) { + undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E, F); } } @@ -1642,8 +1640,8 @@ Vector2 VisualScriptEditor::_get_available_pos(bool p_centered, Vector2 p_pos) c bool exists = false; List<int> existing; script->get_node_list(&existing); - for (List<int>::Element *E = existing.front(); E; E = E->next()) { - Point2 pos = script->get_node_position(E->get()); + for (int &E : existing) { + Point2 pos = script->get_node_position(E); if (pos.distance_to(p_pos) < 50) { p_pos += Vector2(graph->get_snap(), graph->get_snap()); exists = true; @@ -1698,8 +1696,8 @@ void VisualScriptEditor::_on_nodes_delete() { undo_redo->create_action(TTR("Remove VisualScript Nodes")); - for (List<int>::Element *F = to_erase.front(); F; F = F->next()) { - int cr_node = F->get(); + for (int &F : to_erase) { + int cr_node = F; undo_redo->add_do_method(script.ptr(), "remove_node", cr_node); undo_redo->add_undo_method(script.ptr(), "add_node", cr_node, script->get_node(cr_node), script->get_node_position(cr_node)); @@ -1707,18 +1705,18 @@ void VisualScriptEditor::_on_nodes_delete() { List<VisualScript::SequenceConnection> sequence_conns; script->get_sequence_connection_list(&sequence_conns); - for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { - if (E->get().from_node == cr_node || E->get().to_node == cr_node) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node); + for (const VisualScript::SequenceConnection &E : sequence_conns) { + if (E.from_node == cr_node || E.to_node == cr_node) { + undo_redo->add_undo_method(script.ptr(), "sequence_connect", E.from_node, E.from_output, E.to_node); } } List<VisualScript::DataConnection> data_conns; script->get_data_connection_list(&data_conns); - for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) { - if (E->get().from_node == F->get() || E->get().to_node == F->get()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + for (const VisualScript::DataConnection &E : data_conns) { + if (E.from_node == F || E.to_node == F) { + undo_redo->add_undo_method(script.ptr(), "data_connect", E.from_node, E.from_port, E.to_node, E.to_port); } } } @@ -1767,17 +1765,17 @@ void VisualScriptEditor::_on_nodes_duplicate() { List<VisualScript::SequenceConnection> seqs; script->get_sequence_connection_list(&seqs); - for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) { - if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); + for (const VisualScript::SequenceConnection &E : seqs) { + if (to_duplicate.has(E.from_node) && to_duplicate.has(E.to_node)) { + undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E.from_node], E.from_output, remap[E.to_node]); } } List<VisualScript::DataConnection> data; script->get_data_connection_list(&data); - for (List<VisualScript::DataConnection>::Element *E = data.front(); E; E = E->next()) { - if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) { - undo_redo->add_do_method(script.ptr(), "data_connect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); + for (const VisualScript::DataConnection &E : data) { + if (to_duplicate.has(E.from_node) && to_duplicate.has(E.to_node)) { + undo_redo->add_do_method(script.ptr(), "data_connect", remap[E.from_node], E.from_port, remap[E.to_node], E.to_port); } } @@ -1903,8 +1901,8 @@ void VisualScriptEditor::_rename_function(const String &name, const String &new_ // Also fix all function calls. List<int> lst; script->get_node_list(&lst); - for (List<int>::Element *F = lst.front(); F; F = F->next()) { - Ref<VisualScriptFunctionCall> fncall = script->get_node(F->get()); + for (int &F : lst) { + Ref<VisualScriptFunctionCall> fncall = script->get_node(F); if (!fncall.is_valid()) { continue; } @@ -2188,7 +2186,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da int new_id = script->get_available_id(); if (files.size()) { - undo_redo->create_action(TTR("Add Preload Node")); + undo_redo->create_action(TTR("Add Node(s)")); for (int i = 0; i < files.size(); i++) { Ref<Resource> res = ResourceLoader::load(files[i]); @@ -2221,8 +2219,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da undo_redo->commit_action(); } - for (List<int>::Element *E = new_ids.front(); E; E = E->next()) { - Node *node = graph->get_node(itos(E->get())); + for (int &E : new_ids) { + Node *node = graph->get_node(itos(E)); if (node) { graph->set_selected(node); _node_selected(node); @@ -2554,12 +2552,12 @@ void VisualScriptEditor::goto_line(int p_line, bool p_with_error) { List<StringName> functions; script->get_function_list(&functions); - for (List<StringName>::Element *E = functions.front(); E; E = E->next()) { + for (const StringName &E : functions) { if (script->has_node(p_line)) { _update_graph(); _update_members(); - call_deferred(SNAME("call_deferred"), "_center_on_node", E->get(), p_line); //editor might be just created and size might not exist yet + call_deferred(SNAME("call_deferred"), "_center_on_node", E, p_line); //editor might be just created and size might not exist yet return; } } @@ -2600,13 +2598,13 @@ Array VisualScriptEditor::get_breakpoints() { Array breakpoints; List<StringName> functions; script->get_function_list(&functions); - for (List<StringName>::Element *E = functions.front(); E; E = E->next()) { + for (int i = 0; i < functions.size(); i++) { List<int> nodes; script->get_node_list(&nodes); - for (List<int>::Element *F = nodes.front(); F; F = F->next()) { - Ref<VisualScriptNode> vsn = script->get_node(F->get()); + for (int &F : nodes) { + Ref<VisualScriptNode> vsn = script->get_node(F); if (vsn->is_breakpoint()) { - breakpoints.push_back(F->get() - 1); // Subtract 1 because breakpoints in text start from zero. + breakpoints.push_back(F - 1); // Subtract 1 because breakpoints in text start from zero. } } } @@ -2775,18 +2773,18 @@ void VisualScriptEditor::_remove_node(int p_id) { List<VisualScript::SequenceConnection> sequence_conns; script->get_sequence_connection_list(&sequence_conns); - for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { - if (E->get().from_node == p_id || E->get().to_node == p_id) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node); + for (const VisualScript::SequenceConnection &E : sequence_conns) { + if (E.from_node == p_id || E.to_node == p_id) { + undo_redo->add_undo_method(script.ptr(), "sequence_connect", E.from_node, E.from_output, E.to_node); } } List<VisualScript::DataConnection> data_conns; script->get_data_connection_list(&data_conns); - for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) { - if (E->get().from_node == p_id || E->get().to_node == p_id) { - undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + for (const VisualScript::DataConnection &E : data_conns) { + if (E.from_node == p_id || E.to_node == p_id) { + undo_redo->add_undo_method(script.ptr(), "data_connect", E.from_node, E.from_port, E.to_node, E.to_port); } } @@ -2804,9 +2802,9 @@ bool VisualScriptEditor::node_has_sequence_connections(int p_id) { List<VisualScript::SequenceConnection> sequence_conns; script->get_sequence_connection_list(&sequence_conns); - for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) { - int from = E->get().from_node; - int to = E->get().to_node; + for (const VisualScript::SequenceConnection &E : sequence_conns) { + int from = E.from_node; + int to = E.to_node; if (to == p_id || from == p_id) { return true; @@ -3462,9 +3460,9 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons List<MethodInfo> methods; bool found = false; ClassDB::get_virtual_methods(script->get_instance_base_type(), &methods); - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().name == name) { - minfo = E->get(); + for (const MethodInfo &E : methods) { + if (E.name == name) { + minfo = E; found = true; } } @@ -3734,8 +3732,8 @@ void VisualScriptEditor::_menu_option(int p_what) { _update_graph(); - for (List<String>::Element *E = reselect.front(); E; E = E->next()) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(E->get())); + for (const String &E : reselect) { + GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(E)); gn->set_selected(true); } @@ -3774,18 +3772,18 @@ void VisualScriptEditor::_menu_option(int p_what) { List<VisualScript::SequenceConnection> sequence_connections; script->get_sequence_connection_list(&sequence_connections); - for (List<VisualScript::SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { - if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) { - clipboard->sequence_connections.insert(E->get()); + for (const VisualScript::SequenceConnection &E : sequence_connections) { + if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { + clipboard->sequence_connections.insert(E); } } List<VisualScript::DataConnection> data_connections; script->get_data_connection_list(&data_connections); - for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { - if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) { - clipboard->data_connections.insert(E->get()); + for (const VisualScript::DataConnection &E : data_connections) { + if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { + clipboard->data_connections.insert(E); } } if (p_what == EDIT_CUT_NODES) { @@ -3811,8 +3809,8 @@ void VisualScriptEditor::_menu_option(int p_what) { { List<int> nodes; script->get_node_list(&nodes); - for (List<int>::Element *E = nodes.front(); E; E = E->next()) { - Vector2 pos = script->get_node_position(E->get()).snapped(Vector2(2, 2)); + for (int &E : nodes) { + Vector2 pos = script->get_node_position(E).snapped(Vector2(2, 2)); existing_positions.insert(pos); } } @@ -3935,22 +3933,22 @@ void VisualScriptEditor::_menu_option(int p_what) { // Pick the node with input sequence. Set<int> nodes_from; Set<int> nodes_to; - for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) { - if (nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) { - seqmove.insert(E->get()); - nodes_from.insert(E->get().from_node); - } else if (nodes.has(E->get().from_node) && !nodes.has(E->get().to_node)) { - seqext.insert(E->get()); - } else if (!nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) { + for (const VisualScript::SequenceConnection &E : seqs) { + if (nodes.has(E.from_node) && nodes.has(E.to_node)) { + seqmove.insert(E); + nodes_from.insert(E.from_node); + } else if (nodes.has(E.from_node) && !nodes.has(E.to_node)) { + seqext.insert(E); + } else if (!nodes.has(E.from_node) && nodes.has(E.to_node)) { if (start_node == -1) { - seqext.insert(E->get()); - start_node = E->get().to_node; + seqext.insert(E); + start_node = E.to_node; } else { EditorNode::get_singleton()->show_warning(TTR("Try to only have one sequence input in selection.")); return; } } - nodes_to.insert(E->get().to_node); + nodes_to.insert(E.to_node); } // To use to add return nodes. @@ -3978,20 +3976,20 @@ void VisualScriptEditor::_menu_option(int p_what) { { List<VisualScript::DataConnection> dats; script->get_data_connection_list(&dats); - for (List<VisualScript::DataConnection>::Element *E = dats.front(); E; E = E->next()) { - if (nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) { - datamove.insert(E->get()); - } else if (!nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) { + for (const VisualScript::DataConnection &E : dats) { + if (nodes.has(E.from_node) && nodes.has(E.to_node)) { + datamove.insert(E); + } else if (!nodes.has(E.from_node) && nodes.has(E.to_node)) { // Add all these as inputs for the Function. - Ref<VisualScriptNode> node = script->get_node(E->get().to_node); + Ref<VisualScriptNode> node = script->get_node(E.to_node); if (node.is_valid()) { - dataext.insert(E->get()); - PropertyInfo pi = node->get_input_value_port_info(E->get().to_port); + dataext.insert(E); + PropertyInfo pi = node->get_input_value_port_info(E.to_port); inputs.push_back(pi.type); - input_connections.push_back(Pair<int, int>(E->get().to_node, E->get().to_port)); + input_connections.push_back(Pair<int, int>(E.to_node, E.to_port)); } - } else if (nodes.has(E->get().from_node) && !nodes.has(E->get().to_node)) { - dataext.insert(E->get()); + } else if (nodes.has(E.from_node) && !nodes.has(E.to_node)) { + dataext.insert(E); } } } @@ -4092,9 +4090,9 @@ void VisualScriptEditor::_menu_option(int p_what) { // but I hope that it will not be a problem considering that we won't be creating functions so frequently, // and cyclic connections would be a problem but hopefully we won't let them get to this point. void VisualScriptEditor::_get_ends(int p_node, const List<VisualScript::SequenceConnection> &p_seqs, const Set<int> &p_selected, Set<int> &r_end_nodes) { - for (const List<VisualScript::SequenceConnection>::Element *E = p_seqs.front(); E; E = E->next()) { - int from = E->get().from_node; - int to = E->get().to_node; + for (const VisualScript::SequenceConnection &E : p_seqs) { + int from = E.from_node; + int to = E.to_node; if (from == p_node && p_selected.has(to)) { // This is an interior connection move forward to the to node. @@ -4168,16 +4166,16 @@ void VisualScriptEditor::_member_option(int p_option) { undo_redo->add_undo_method(script.ptr(), "add_node", fn_node, script->get_node(fn_node), script->get_node_position(fn_node)); List<VisualScript::SequenceConnection> seqcons; script->get_sequence_connection_list(&seqcons); - for (const List<VisualScript::SequenceConnection>::Element *E = seqcons.front(); E; E = E->next()) { - if (E->get().from_node == fn_node) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", fn_node, E->get().from_output, E->get().to_node); + for (const VisualScript::SequenceConnection &E : seqcons) { + if (E.from_node == fn_node) { + undo_redo->add_undo_method(script.ptr(), "sequence_connect", fn_node, E.from_output, E.to_node); } } List<VisualScript::DataConnection> datcons; script->get_data_connection_list(&datcons); - for (const List<VisualScript::DataConnection>::Element *E = datcons.front(); E; E = E->next()) { - if (E->get().from_node == fn_node) { - undo_redo->add_undo_method(script.ptr(), "data_connect", fn_node, E->get().from_port, E->get().to_node, E->get().to_port); + for (const VisualScript::DataConnection &E : datcons) { + if (E.from_node == fn_node) { + undo_redo->add_undo_method(script.ptr(), "data_connect", fn_node, E.from_port, E.to_node, E.to_port); } } undo_redo->add_do_method(this, "_update_members"); diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index af86f90b25..62a4f465cb 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -852,11 +852,11 @@ void VisualScriptTypeCast::_bind_methods() { } String script_ext_hint; - for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) { + for (const String &E : script_extensions) { if (script_ext_hint != String()) { script_ext_hint += ","; } - script_ext_hint += "*." + E->get(); + script_ext_hint += "*." + E; } ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 7b5ca56dcc..6ba5ad4fd6 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -538,11 +538,11 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const Engine::get_singleton()->get_singletons(&names); property.hint = PROPERTY_HINT_ENUM; String sl; - for (List<Engine::Singleton>::Element *E = names.front(); E; E = E->next()) { + for (const Engine::Singleton &E : names) { if (sl != String()) { sl += ","; } - sl += E->get().name; + sl += E.name; } property.hint_string = sl; } @@ -683,11 +683,11 @@ void VisualScriptFunctionCall::_bind_methods() { } String script_ext_hint; - for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) { + for (const String &E : script_extensions) { if (script_ext_hint != String()) { script_ext_hint += ","; } - script_ext_hint += "*." + E->get(); + script_ext_hint += "*." + E; } ADD_PROPERTY(PropertyInfo(Variant::INT, "call_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type,Singleton"), "set_call_mode", "get_call_mode"); @@ -1004,13 +1004,13 @@ PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const List<PropertyInfo> props; ClassDB::get_property_list(_get_base_type(), &props, false); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().name == property) { + for (const PropertyInfo &E : props) { + if (E.name == property) { String detail_prop_name = property; if (index != StringName()) { detail_prop_name += "." + String(index); } - PropertyInfo pinfo = PropertyInfo(E->get().type, detail_prop_name, PROPERTY_HINT_TYPE_STRING, E->get().hint_string); + PropertyInfo pinfo = PropertyInfo(E.type, detail_prop_name, PROPERTY_HINT_TYPE_STRING, E.hint_string); _adjust_input_index(pinfo); return pinfo; } @@ -1135,9 +1135,9 @@ void VisualScriptPropertySet::_update_cache() { List<PropertyInfo> pinfo; v.get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().name == property) { - type_cache = E->get(); + for (const PropertyInfo &E : pinfo) { + if (E.name == property) { + type_cache = E; } } @@ -1186,9 +1186,9 @@ void VisualScriptPropertySet::_update_cache() { script->get_script_property_list(&pinfo); } - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().name == property) { - type_cache = E->get(); + for (const PropertyInfo &E : pinfo) { + if (E.name == property) { + type_cache = E; return; } } @@ -1354,8 +1354,8 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { List<PropertyInfo> plist; v.get_property_list(&plist); String options = ""; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - options += "," + E->get().name; + for (const PropertyInfo &E : plist) { + options += "," + E.name; } property.hint = PROPERTY_HINT_ENUM; @@ -1410,11 +1410,11 @@ void VisualScriptPropertySet::_bind_methods() { } String script_ext_hint; - for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) { + for (const String &E : script_extensions) { if (script_ext_hint != String()) { script_ext_hint += ","; } - script_ext_hint += "*." + E->get(); + script_ext_hint += "*." + E; } ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); @@ -1820,9 +1820,9 @@ void VisualScriptPropertyGet::_update_cache() { List<PropertyInfo> pinfo; v.get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().name == property) { - type_cache = E->get().type; + for (const PropertyInfo &E : pinfo) { + if (E.name == property) { + type_cache = E.type; return; } } @@ -2059,8 +2059,8 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { List<PropertyInfo> plist; v.get_property_list(&plist); String options = ""; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - options += "," + E->get().name; + for (const PropertyInfo &E : plist) { + options += "," + E.name; } property.hint = PROPERTY_HINT_ENUM; @@ -2112,11 +2112,11 @@ void VisualScriptPropertyGet::_bind_methods() { } String script_ext_hint; - for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) { + for (const String &E : script_extensions) { if (script_ext_hint != String()) { script_ext_hint += ","; } - script_ext_hint += "." + E->get(); + script_ext_hint += "." + E; } ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); @@ -2268,7 +2268,7 @@ int VisualScriptEmitSignal::get_input_value_port_count() const { } int VisualScriptEmitSignal::get_output_value_port_count() const { - return 1; + return 0; } String VisualScriptEmitSignal::get_output_sequence_port_text(int p_port) const { @@ -2311,16 +2311,6 @@ StringName VisualScriptEmitSignal::get_signal() const { return name; } -void VisualScriptEmitSignal::_adjust_input_index(PropertyInfo &pinfo) const { - if (index != StringName()) { - Variant v; - Callable::CallError ce; - Variant::construct(pinfo.type, v, nullptr, 0, ce); - Variant i = v.get(index); - pinfo.type = i.get_type(); - } -} - void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const { if (property.name == "signal") { property.hint = PROPERTY_HINT_ENUM; @@ -2333,11 +2323,11 @@ void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const { } String ml; - for (List<StringName>::Element *E = sigs.front(); E; E = E->next()) { + for (const StringName &E : sigs) { if (ml != String()) { ml += ","; } - ml += E->get(); + ml += E; } property.hint_string = ml; @@ -2428,8 +2418,8 @@ void register_visual_script_func_nodes() { List<MethodInfo> ml; vt.get_method_list(&ml); - for (List<MethodInfo>::Element *E = ml.front(); E; E = E->next()) { - VisualScriptLanguage::singleton->add_register_func("functions/by_type/" + type_name + "/" + E->get().name, create_basic_type_call_node); + for (const MethodInfo &E : ml) { + VisualScriptLanguage::singleton->add_register_func("functions/by_type/" + type_name + "/" + E.name, create_basic_type_call_node); } } } diff --git a/modules/visual_script/visual_script_func_nodes.h b/modules/visual_script/visual_script_func_nodes.h index 37a707d108..cca08455f9 100644 --- a/modules/visual_script/visual_script_func_nodes.h +++ b/modules/visual_script/visual_script_func_nodes.h @@ -328,9 +328,6 @@ class VisualScriptEmitSignal : public VisualScriptNode { private: StringName name; - StringName index; - - void _adjust_input_index(PropertyInfo &pinfo) const; protected: virtual void _validate_property(PropertyInfo &property) const override; diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 86d8050acb..c517d89aa5 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -1306,12 +1306,12 @@ void VisualScriptVariableGet::_validate_property(PropertyInfo &property) const { vs->get_variable_list(&vars); String vhint; - for (List<StringName>::Element *E = vars.front(); E; E = E->next()) { + for (const StringName &E : vars) { if (vhint != String()) { vhint += ","; } - vhint += E->get().operator String(); + vhint += E.operator String(); } property.hint = PROPERTY_HINT_ENUM; @@ -1416,12 +1416,12 @@ void VisualScriptVariableSet::_validate_property(PropertyInfo &property) const { vs->get_variable_list(&vars); String vhint; - for (List<StringName>::Element *E = vars.front(); E; E = E->next()) { + for (const StringName &E : vars) { if (vhint != String()) { vhint += ","; } - vhint += E->get().operator String(); + vhint += E.operator String(); } property.hint = PROPERTY_HINT_ENUM; @@ -1944,8 +1944,8 @@ void VisualScriptClassConstant::set_base_type(const StringName &p_which) { ClassDB::get_integer_constant_list(base_type, &constants, true); if (constants.size() > 0) { bool found_name = false; - for (List<String>::Element *E = constants.front(); E; E = E->next()) { - if (E->get() == name) { + for (const String &E : constants) { + if (E == name) { found_name = true; break; } @@ -1993,11 +1993,11 @@ void VisualScriptClassConstant::_validate_property(PropertyInfo &property) const ClassDB::get_integer_constant_list(base_type, &constants, true); property.hint_string = ""; - for (List<String>::Element *E = constants.front(); E; E = E->next()) { + for (const String &E : constants) { if (property.hint_string != String()) { property.hint_string += ","; } - property.hint_string += E->get(); + property.hint_string += E; } } } @@ -2078,8 +2078,8 @@ void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) { Variant::get_constants_for_type(type, &constants); if (constants.size() > 0) { bool found_name = false; - for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { - if (E->get() == name) { + for (const StringName &E : constants) { + if (E == name) { found_name = true; break; } @@ -2131,11 +2131,11 @@ void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) c return; } property.hint_string = ""; - for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { + for (const StringName &E : constants) { if (property.hint_string != String()) { property.hint_string += ","; } - property.hint_string += String(E->get()); + property.hint_string += String(E); } } } @@ -2358,15 +2358,15 @@ void VisualScriptEngineSingleton::_validate_property(PropertyInfo &property) con Engine::get_singleton()->get_singletons(&singletons); - for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { - if (E->get().name == "VS" || E->get().name == "PS" || E->get().name == "PS2D" || E->get().name == "AS" || E->get().name == "TS" || E->get().name == "SS" || E->get().name == "SS2D") { + for (const Engine::Singleton &E : singletons) { + if (E.name == "VS" || E.name == "PS" || E.name == "PS2D" || E.name == "AS" || E.name == "TS" || E.name == "SS" || E.name == "SS2D") { continue; //skip these, too simple named } if (cc != String()) { cc += ","; } - cc += E->get().name; + cc += E.name; } property.hint = PROPERTY_HINT_ENUM; @@ -3749,9 +3749,7 @@ void VisualScriptInputAction::_validate_property(PropertyInfo &property) const { ProjectSettings::get_singleton()->get_property_list(&pinfo); Vector<String> al; - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (const PropertyInfo &pi : pinfo) { if (!pi.name.begins_with("input/")) { continue; } @@ -3844,10 +3842,10 @@ void VisualScriptDeconstruct::_update_elements() { List<PropertyInfo> pinfo; v.get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + for (const PropertyInfo &E : pinfo) { Element e; - e.name = E->get().name; - e.type = E->get().type; + e.name = E.name; + e.type = E.type; elements.push_back(e); } } @@ -4025,24 +4023,24 @@ void register_visual_script_nodes() { List<MethodInfo> constructors; Variant::get_constructor_list(Variant::Type(i), &constructors); - for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) { - if (E->get().arguments.size() > 0) { + for (const MethodInfo &E : constructors) { + if (E.arguments.size() > 0) { String name = "functions/constructors/" + Variant::get_type_name(Variant::Type(i)) + "("; - for (int j = 0; j < E->get().arguments.size(); j++) { + for (int j = 0; j < E.arguments.size(); j++) { if (j > 0) { name += ", "; } - if (E->get().arguments.size() == 1) { - name += Variant::get_type_name(E->get().arguments[j].type); + if (E.arguments.size() == 1) { + name += Variant::get_type_name(E.arguments[j].type); } else { - name += E->get().arguments[j].name; + name += E.arguments[j].name; } } name += ")"; VisualScriptLanguage::singleton->add_register_func(name, create_constructor_node); Pair<Variant::Type, MethodInfo> pair; pair.first = Variant::Type(i); - pair.second = E->get(); + pair.second = E; constructor_map[name] = pair; } } diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index ccb2e2df75..8bf1c6cbfa 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -93,7 +93,7 @@ void VisualScriptPropertySelector::_update_search() { base = ClassDB::get_parent_class_nocheck(base); } - for (List<StringName>::Element *E = base_list.front(); E; E = E->next()) { + for (const StringName &E : base_list) { List<MethodInfo> methods; List<PropertyInfo> props; TreeItem *category = nullptr; @@ -135,7 +135,7 @@ void VisualScriptPropertySelector::_update_search() { vbc->get_theme_icon(SNAME("PackedColorArray"), SNAME("EditorIcons")) }; { - String b = String(E->get()); + String b = String(E); category = search_options->create_item(root); if (category) { category->set_text(0, b.replace_first("*", "")); @@ -154,30 +154,30 @@ void VisualScriptPropertySelector::_update_search() { if (Object::cast_to<Script>(obj)) { Object::cast_to<Script>(obj)->get_script_property_list(&props); } else { - ClassDB::get_property_list(E->get(), &props, true); + ClassDB::get_property_list(E, &props, true); } } - for (List<PropertyInfo>::Element *F = props.front(); F; F = F->next()) { - if (!(F->get().usage & PROPERTY_USAGE_EDITOR) && !(F->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE)) { + for (const PropertyInfo &F : props) { + if (!(F.usage & PROPERTY_USAGE_EDITOR) && !(F.usage & PROPERTY_USAGE_SCRIPT_VARIABLE)) { continue; } - if (type_filter.size() && type_filter.find(F->get().type) == -1) { + if (type_filter.size() && type_filter.find(F.type) == -1) { continue; } // capitalize() also converts underscore to space, we'll match again both possible styles - String get_text_raw = String(vformat(TTR("Get %s"), F->get().name)); + String get_text_raw = String(vformat(TTR("Get %s"), F.name)); String get_text = get_text_raw.capitalize(); - String set_text_raw = String(vformat(TTR("Set %s"), F->get().name)); + String set_text_raw = String(vformat(TTR("Set %s"), F.name)); String set_text = set_text_raw.capitalize(); String input = search_box->get_text().capitalize(); if (input == String() || get_text_raw.findn(input) != -1 || get_text.findn(input) != -1) { TreeItem *item = search_options->create_item(category ? category : root); item->set_text(0, get_text); - item->set_metadata(0, F->get().name); - item->set_icon(0, type_icons[F->get().type]); + item->set_metadata(0, F.name); + item->set_icon(0, type_icons[F.type]); item->set_metadata(1, "get"); item->set_collapsed(true); item->set_selectable(0, true); @@ -189,8 +189,8 @@ void VisualScriptPropertySelector::_update_search() { if (input == String() || set_text_raw.findn(input) != -1 || set_text.findn(input) != -1) { TreeItem *item = search_options->create_item(category ? category : root); item->set_text(0, set_text); - item->set_metadata(0, F->get().name); - item->set_icon(0, type_icons[F->get().type]); + item->set_metadata(0, F.name); + item->set_icon(0, type_icons[F.type]); item->set_metadata(1, "set"); item->set_selectable(0, true); item->set_selectable(1, false); @@ -211,7 +211,7 @@ void VisualScriptPropertySelector::_update_search() { Object::cast_to<Script>(obj)->get_script_method_list(&methods); } - ClassDB::get_method_list(E->get(), &methods, true, true); + ClassDB::get_method_list(E, &methods, true, true); } } for (List<MethodInfo>::Element *M = methods.front(); M; M = M->next()) { @@ -340,11 +340,11 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt List<String> fnodes; VisualScriptLanguage::singleton->get_registered_node_names(&fnodes); - for (List<String>::Element *E = fnodes.front(); E; E = E->next()) { - if (!E->get().begins_with(root_filter)) { + for (const String &E : fnodes) { + if (!E.begins_with(root_filter)) { continue; } - Vector<String> path = E->get().split("/"); + Vector<String> path = E.split("/"); // check if the name has the filter bool in_filter = false; @@ -355,7 +355,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt } else { in_filter = false; } - if (E->get().findn(tx_filters[i]) != -1) { + if (E.findn(tx_filters[i]) != -1) { in_filter = true; break; } @@ -366,7 +366,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt bool in_modifier = p_modifiers.is_empty(); for (Set<String>::Element *F = p_modifiers.front(); F && in_modifier; F = F->next()) { - if (E->get().findn(F->get()) != -1) { + if (E.findn(F->get()) != -1) { in_modifier = true; } } @@ -375,7 +375,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt } TreeItem *item = search_options->create_item(root); - Ref<VisualScriptNode> vnode = VisualScriptLanguage::singleton->create_node_from_name(E->get()); + Ref<VisualScriptNode> vnode = VisualScriptLanguage::singleton->create_node_from_name(E); Ref<VisualScriptOperator> vnode_operator = vnode; String type_name; if (vnode_operator.is_valid()) { @@ -409,7 +409,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt item->set_text(0, type_name + String("").join(desc)); item->set_icon(0, vbc->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons"))); item->set_selectable(0, true); - item->set_metadata(0, E->get()); + item->set_metadata(0, E); item->set_selectable(0, true); item->set_metadata(1, "visualscript"); item->set_selectable(1, false); diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index d8bc926a1d..9fa49b8a1d 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -438,21 +438,21 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const { ClassDB::get_signal_list(_get_base_type(), &methods); List<String> mstring; - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().name.begins_with("_")) { + for (const MethodInfo &E : methods) { + if (E.name.begins_with("_")) { continue; } - mstring.push_back(E->get().name.get_slice(":", 0)); + mstring.push_back(E.name.get_slice(":", 0)); } mstring.sort(); String ml; - for (List<String>::Element *E = mstring.front(); E; E = E->next()) { + for (const String &E : mstring) { if (ml != String()) { ml += ","; } - ml += E->get(); + ml += E; } property.hint_string = ml; diff --git a/modules/webrtc/webrtc_multiplayer_peer.cpp b/modules/webrtc/webrtc_multiplayer_peer.cpp index 51101e3124..77857255c1 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.cpp +++ b/modules/webrtc/webrtc_multiplayer_peer.cpp @@ -112,22 +112,22 @@ void WebRTCMultiplayerPeer::poll() { } } // Remove disconnected peers - for (List<int>::Element *E = remove.front(); E; E = E->next()) { - remove_peer(E->get()); - if (next_packet_peer == E->get()) { + for (int &E : remove) { + remove_peer(E); + if (next_packet_peer == E) { next_packet_peer = 0; } } // Signal newly connected peers - for (List<int>::Element *E = add.front(); E; E = E->next()) { + for (int &E : add) { // Already connected to server: simply notify new peer. // NOTE: Mesh is always connected. if (connection_status == CONNECTION_CONNECTED) { - emit_signal(SNAME("peer_connected"), E->get()); + emit_signal(SNAME("peer_connected"), E); } // Server emulation mode suppresses peer_conencted until server connects. - if (server_compat && E->get() == TARGET_PEER_SERVER) { + if (server_compat && E == TARGET_PEER_SERVER) { // Server connected. connection_status = CONNECTION_CONNECTED; emit_signal(SNAME("peer_connected"), TARGET_PEER_SERVER); @@ -154,8 +154,8 @@ void WebRTCMultiplayerPeer::_find_next_peer() { } // After last. while (E) { - for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) { - if (F->get()->get_available_packet_count()) { + for (Ref<WebRTCDataChannel> F : E->get()->channels) { + if (F->get_available_packet_count()) { next_packet_peer = E->key(); return; } @@ -165,8 +165,8 @@ void WebRTCMultiplayerPeer::_find_next_peer() { E = peer_map.front(); // Before last while (E) { - for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) { - if (F->get()->get_available_packet_count()) { + for (Ref<WebRTCDataChannel> F : E->get()->channels) { + if (F->get_available_packet_count()) { next_packet_peer = E->key(); return; } @@ -213,8 +213,8 @@ int WebRTCMultiplayerPeer::get_unique_id() const { void WebRTCMultiplayerPeer::_peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dictionary &r_dict) { Array channels; - for (List<Ref<WebRTCDataChannel>>::Element *F = p_connected_peer->channels.front(); F; F = F->next()) { - channels.push_back(F->get()); + for (Ref<WebRTCDataChannel> F : p_connected_peer->channels) { + channels.push_back(F); } r_dict["connection"] = p_connected_peer->connection; r_dict["connected"] = p_connected_peer->connected; @@ -297,9 +297,9 @@ Error WebRTCMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_ _find_next_peer(); ERR_FAIL_V(ERR_UNAVAILABLE); } - for (List<Ref<WebRTCDataChannel>>::Element *E = peer_map[next_packet_peer]->channels.front(); E; E = E->next()) { - if (E->get()->get_available_packet_count()) { - Error err = E->get()->get_packet(r_buffer, r_buffer_size); + for (Ref<WebRTCDataChannel> E : peer_map[next_packet_peer]->channels) { + if (E->get_available_packet_count()) { + Error err = E->get_packet(r_buffer, r_buffer_size); _find_next_peer(); return err; } @@ -357,8 +357,8 @@ int WebRTCMultiplayerPeer::get_available_packet_count() const { } int size = 0; for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) { - for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) { - size += F->get()->get_available_packet_count(); + for (Ref<WebRTCDataChannel> F : E->get()->channels) { + size += F->get_available_packet_count(); } } return size; diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 744053b6e2..d3d0066c12 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -79,7 +79,7 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, String str = "ws://"; if (p_custom_headers.size()) { - WARN_PRINT_ONCE("Custom headers are not supported in in HTML5 platform."); + WARN_PRINT_ONCE("Custom headers are not supported in HTML5 platform."); } if (p_ssl) { str = "wss://"; diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index ddd8e190df..589bb8931a 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -65,9 +65,9 @@ void WebSocketMultiplayerPeer::_clear() { memfree(_current_packet.data); } - for (List<Packet>::Element *E = _incoming_packets.front(); E; E = E->next()) { - memfree(E->get().data); - E->get().data = nullptr; + for (Packet &E : _incoming_packets) { + memfree(E.data); + E.data = nullptr; } _incoming_packets.clear(); diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 5f794415af..1df001f86e 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -190,15 +190,15 @@ void WSLServer::poll() { remove_ids.push_back(E->key()); } } - for (List<int>::Element *E = remove_ids.front(); E; E = E->next()) { - _peer_map.erase(E->get()); + for (int &E : remove_ids) { + _peer_map.erase(E); } remove_ids.clear(); List<Ref<PendingPeer>> remove_peers; - for (List<Ref<PendingPeer>>::Element *E = _pending.front(); E; E = E->next()) { + for (Ref<PendingPeer> E : _pending) { String resource_name; - Ref<PendingPeer> ppeer = E->get(); + Ref<PendingPeer> ppeer = E; Error err = ppeer->do_handshake(_protocols, handshake_timeout, resource_name); if (err == ERR_BUSY) { continue; @@ -224,8 +224,8 @@ void WSLServer::poll() { remove_peers.push_back(ppeer); _on_connect(id, ppeer->protocol, resource_name); } - for (List<Ref<PendingPeer>>::Element *E = remove_peers.front(); E; E = E->next()) { - _pending.erase(E->get()); + for (Ref<PendingPeer> E : remove_peers) { + _pending.erase(E); } remove_peers.clear(); diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml index 9b3a063ef5..67b2b866f3 100644 --- a/modules/webxr/doc_classes/WebXRInterface.xml +++ b/modules/webxr/doc_classes/WebXRInterface.xml @@ -88,7 +88,7 @@ - Using [XRController3D] nodes and their [signal XRController3D.button_pressed] and [signal XRController3D.button_released] signals. This is how controllers are typically handled in AR/VR apps in Godot, however, this will only work with advanced VR controllers like the Oculus Touch or Index controllers, for example. The buttons codes are defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. - Using [method Node._unhandled_input] and [InputEventJoypadButton] or [InputEventJoypadMotion]. This works the same as normal joypads, except the [member InputEvent.device] starts at 100, so the left controller is 100 and the right controller is 101, and the button codes are also defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. - Using the [signal select], [signal squeeze] and related signals. This method will work for both advanced VR controllers, and non-traditional "controllers" like a tap on the screen, a spoken voice command or a button press on the device itself. The [code]controller_id[/code] passed to these signals is the same id as used in [member XRController3D.controller_id]. - You can use one or all of these methods to allow your game or app to support a wider or narrower set of devices and input methods, or to allow more advanced interations with more advanced devices. + You can use one or all of these methods to allow your game or app to support a wider or narrower set of devices and input methods, or to allow more advanced interactions with more advanced devices. </description> <tutorials> <link title="How to make a VR game for WebXR with Godot">https://www.snopekgames.com/blog/2020/how-make-vr-game-webxr-godot</link> diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 1fcc3d4a5c..af8829324b 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -334,13 +334,6 @@ bool DisplayServerAndroid::can_any_window_draw() const { return true; } -void DisplayServerAndroid::alert(const String &p_alert, const String &p_title) { - GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); - ERR_FAIL_COND(!godot_java); - - godot_java->alert(p_alert, p_title); -} - void DisplayServerAndroid::process_events() { Input::get_singleton()->flush_accumulated_events(); } @@ -361,7 +354,7 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() { DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); if (r_error != OK) { - ds->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver"); + OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver"); } return ds; } diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 46745f8030..9b9f5e99f6 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -204,8 +204,6 @@ public: virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; - virtual void alert(const String &p_alert, const String &p_title) override; - virtual void process_events() override; void process_accelerometer(const Vector3 &p_accelerometer); diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/Obfuscator.java b/platform/android/java/lib/src/com/google/android/vending/licensing/Obfuscator.java index 008c150a8e..05b452d0c1 100644 --- a/platform/android/java/lib/src/com/google/android/vending/licensing/Obfuscator.java +++ b/platform/android/java/lib/src/com/google/android/vending/licensing/Obfuscator.java @@ -20,7 +20,7 @@ package com.google.android.vending.licensing; * Interface used as part of a {@link Policy} to allow application authors to obfuscate * licensing data that will be stored into a SharedPreferences file. * <p> - * Any transformation scheme must be reversable. Implementing classes may optionally implement an + * Any transformation scheme must be reversible. Implementing classes may optionally implement an * integrity check to further prevent modification to preference data. Implementing classes * should use device-specific information as a key in the obfuscation algorithm to prevent * obfuscated preferences from being shared among devices. diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index ed6b5c3e14..49891cd739 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -41,13 +41,13 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, ERR_FAIL_COND_V(env == nullptr, false); MethodInfo *method = nullptr; - for (List<MethodInfo>::Element *E = M->get().front(); E; E = E->next()) { - if (!p_instance && !E->get()._static) { + for (MethodInfo &E : M->get()) { + if (!p_instance && !E._static) { r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; continue; } - int pc = E->get().param_types.size(); + int pc = E.param_types.size(); if (pc > p_argcount) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = pc; @@ -58,7 +58,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, r_error.argument = pc; continue; } - uint32_t *ptypes = E->get().param_types.ptrw(); + uint32_t *ptypes = E.param_types.ptrw(); bool valid = true; for (int i = 0; i < pc; i++) { @@ -107,7 +107,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, if (Object::cast_to<JavaObject>(ref.ptr())) { Ref<JavaObject> jo = ref; //could be faster - jclass c = env->FindClass(E->get().param_sigs[i].operator String().utf8().get_data()); + jclass c = env->FindClass(E.param_sigs[i].operator String().utf8().get_data()); if (!c || !env->IsInstanceOf(jo->instance, c)) { arg_expected = Variant::OBJECT; } else { @@ -138,7 +138,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, if (!valid) continue; - method = &E->get(); + method = &E; break; } @@ -474,8 +474,8 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, } break; } - for (List<jobject>::Element *E = to_free.front(); E; E = E->next()) { - env->DeleteLocalRef(E->get()); + for (jobject &E : to_free) { + env->DeleteLocalRef(E); } return success; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 222976d948..792a390e36 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -71,6 +71,13 @@ public: virtual ~AndroidLogger() {} }; +void OS_Android::alert(const String &p_alert, const String &p_title) { + GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); + ERR_FAIL_COND(!godot_java); + + godot_java->alert(p_alert, p_title); +} + void OS_Android::initialize_core() { OS_Unix::initialize_core(); diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 1e89e9211d..38f0f3edc7 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -86,6 +86,8 @@ public: virtual bool request_permissions() override; virtual Vector<String> get_granted_permissions() const override; + virtual void alert(const String &p_alert, const String &p_title) override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; virtual String get_name() const override; diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h index 6f64130b23..8ba7a69a4f 100644 --- a/platform/iphone/display_server_iphone.h +++ b/platform/iphone/display_server_iphone.h @@ -119,8 +119,6 @@ public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; - virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; - virtual int get_screen_count() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm index bd95e2c703..b4f0a32027 100644 --- a/platform/iphone/display_server_iphone.mm +++ b/platform/iphone/display_server_iphone.mm @@ -320,12 +320,6 @@ String DisplayServerIPhone::get_name() const { return "iPhone"; } -void DisplayServerIPhone::alert(const String &p_alert, const String &p_title) { - const CharString utf8_alert = p_alert.utf8(); - const CharString utf8_title = p_title.utf8(); - iOS::alert(utf8_alert.get_data(), utf8_title.get_data()); -} - int DisplayServerIPhone::get_screen_count() const { return 1; } diff --git a/platform/iphone/godot_view_gesture_recognizer.h b/platform/iphone/godot_view_gesture_recognizer.h index 48b2d5ffad..61438ef22f 100644 --- a/platform/iphone/godot_view_gesture_recognizer.h +++ b/platform/iphone/godot_view_gesture_recognizer.h @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// GLViewGestureRecognizer allows iOS gestures to work currectly by +// GLViewGestureRecognizer allows iOS gestures to work correctly by // emulating UIScrollView's UIScrollViewDelayedTouchesBeganGestureRecognizer. // It catches all gestures incoming to UIView and delays them for 150ms // (the same value used by UIScrollViewDelayedTouchesBeganGestureRecognizer) diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index f4ff909adf..8abc3b7ed5 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -92,13 +92,12 @@ public: void start(); + virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; - virtual void alert(const String &p_alert, - const String &p_title = "ALERT!") override; - virtual String get_name() const override; virtual String get_model_name() const override; diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index 1f08901082..b69996ccf0 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -114,6 +114,12 @@ OSIPhone::OSIPhone(String p_data_dir) { OSIPhone::~OSIPhone() {} +void OSIPhone::alert(const String &p_alert, const String &p_title) { + const CharString utf8_alert = p_alert.utf8(); + const CharString utf8_title = p_title.utf8(); + iOS::alert(utf8_alert.get_data(), utf8_title.get_data()); +} + void OSIPhone::initialize_core() { OS_Unix::initialize_core(); @@ -221,12 +227,6 @@ Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const return OS_Unix::get_dynamic_library_symbol_handle(p_library_handle, p_name, p_symbol_handle, p_optional); } -void OSIPhone::alert(const String &p_alert, const String &p_title) { - const CharString utf8_alert = p_alert.utf8(); - const CharString utf8_title = p_title.utf8(); - iOS::alert(utf8_alert.get_data(), utf8_title.get_data()); -} - String OSIPhone::get_name() const { return "iOS"; }; diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index 5e2b089c7f..8df81bb8cc 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -659,10 +659,6 @@ void DisplayServerJavaScript::send_window_event_callback(int p_notification) { } } -void DisplayServerJavaScript::alert(const String &p_alert, const String &p_title) { - godot_js_display_alert(p_alert.utf8().get_data()); -} - void DisplayServerJavaScript::set_icon(const Ref<Image> &p_icon) { ERR_FAIL_COND(p_icon.is_null()); Ref<Image> icon = p_icon; diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index f8acf30854..bf5e229c9a 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -109,7 +109,6 @@ public: bool check_size_force_redraw(); // from DisplayServer - virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; diff --git a/platform/javascript/js/libs/audio.worklet.js b/platform/javascript/js/libs/audio.worklet.js index 6b3f80c6a9..866f845139 100644 --- a/platform/javascript/js/libs/audio.worklet.js +++ b/platform/javascript/js/libs/audio.worklet.js @@ -115,7 +115,7 @@ class GodotProcessor extends AudioWorkletProcessor { this.input = new RingBuffer(p_data[1], avail_in); this.output = new RingBuffer(p_data[2], avail_out); } else if (p_cmd === 'stop') { - this.runing = false; + this.running = false; this.output = null; this.input = null; } diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 260bfad7a5..76102d941b 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -47,6 +47,10 @@ #include "godot_js.h" +void OS_JavaScript::alert(const String &p_alert, const String &p_title) { + godot_js_display_alert(p_alert.utf8().get_data()); +} + // Lifecycle void OS_JavaScript::initialize() { OS_Unix::initialize_core(); @@ -111,8 +115,8 @@ Error OS_JavaScript::execute(const String &p_path, const List<String> &p_argumen Error OS_JavaScript::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) { Array args; - for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { - args.push_back(E->get()); + for (const String &E : p_arguments) { + args.push_back(E); } String json_args = Variant(args).to_json_string(); int failed = godot_js_os_execute(json_args.utf8().get_data()); diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 81bb9c5f3d..efac2dbca7 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -89,6 +89,9 @@ public: String get_user_data_dir() const override; bool is_userfs_persistent() const override; + + void alert(const String &p_alert, const String &p_title = "ALERT!") override; + Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) override; void resume_audio(); diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 8f0742041c..4a32dd9646 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -136,70 +136,6 @@ String DisplayServerX11::get_name() const { return "X11"; } -void DisplayServerX11::alert(const String &p_alert, const String &p_title) { - const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" }; - - String path = OS::get_singleton()->get_environment("PATH"); - Vector<String> path_elems = path.split(":", false); - String program; - - for (int i = 0; i < path_elems.size(); i++) { - for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) { - String tested_path = path_elems[i].plus_file(message_programs[k]); - - if (FileAccess::exists(tested_path)) { - program = tested_path; - break; - } - } - - if (program.length()) { - break; - } - } - - List<String> args; - - if (program.ends_with("zenity")) { - args.push_back("--error"); - args.push_back("--width"); - args.push_back("500"); - args.push_back("--title"); - args.push_back(p_title); - args.push_back("--text"); - args.push_back(p_alert); - } - - if (program.ends_with("kdialog")) { - args.push_back("--error"); - args.push_back(p_alert); - args.push_back("--title"); - args.push_back(p_title); - } - - if (program.ends_with("Xdialog")) { - args.push_back("--title"); - args.push_back(p_title); - args.push_back("--msgbox"); - args.push_back(p_alert); - args.push_back("0"); - args.push_back("0"); - } - - if (program.ends_with("xmessage")) { - args.push_back("-center"); - args.push_back("-title"); - args.push_back(p_title); - args.push_back(p_alert); - } - - if (program.length()) { - OS::get_singleton()->execute(program, args); - } else { - print_line(p_alert); - } -} - void DisplayServerX11::_update_real_mouse_position(const WindowData &wd) { Window root_return, child_return; int root_x, root_y, win_x, win_y; @@ -871,7 +807,9 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, V void DisplayServerX11::show_window(WindowID p_id) { _THREAD_SAFE_METHOD_ - WindowData &wd = windows[p_id]; + const WindowData &wd = windows[p_id]; + + DEBUG_LOG_X11("show_window: %lu (%u) \n", wd.x11_window, p_id); XMapWindow(x11_display, wd.x11_window); } @@ -1095,6 +1033,8 @@ void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent WindowID prev_parent = wd_window.transient_parent; ERR_FAIL_COND(prev_parent == p_parent); + DEBUG_LOG_X11("window_set_transient: %lu (%u), prev_parent=%u, parent=%u\n", wd_window.x11_window, p_window, prev_parent, p_parent); + ERR_FAIL_COND_MSG(wd_window.on_top, "Windows with the 'on top' can't become transient."); if (p_parent == INVALID_WINDOW_ID) { //remove transient @@ -1109,10 +1049,10 @@ void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent XSetTransientForHint(x11_display, wd_window.x11_window, None); - // Set focus to parent sub window to avoid losing all focus with nested menus. + // Set focus to parent sub window to avoid losing all focus when closing a nested sub-menu. // RevertToPointerRoot is used to make sure we don't lose all focus in case // a subwindow and its parent are both destroyed. - if (wd_window.menu_type && !wd_window.no_focus) { + if (wd_window.menu_type && !wd_window.no_focus && wd_window.focused) { if (!wd_parent.no_focus) { XSetInputFocus(x11_display, wd_parent.x11_window, RevertToPointerRoot, CurrentTime); } @@ -2227,7 +2167,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, // still works in half the cases. (won't handle deadkeys) // For more complex input methods (deadkeys and more advanced) // you have to use XmbLookupString (??). - // So.. then you have to chosse which of both results + // So then you have to choose which of both results // you want to keep. // This is a real bizarreness and cpu waster. @@ -3673,8 +3613,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() { DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); if (r_error != OK) { - ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", + OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n" + "Please update your drivers or if you have a very old or integrated GPU upgrade it.", "Unable to initialize Video driver"); } return ds; @@ -3972,8 +3912,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } if (!_refresh_device_info()) { - alert("Your system does not support XInput 2.\n" - "Please upgrade your distribution.", + OS::get_singleton()->alert("Your system does not support XInput 2.\n" + "Please upgrade your distribution.", "Unable to initialize XInput"); r_error = ERR_UNAVAILABLE; return; diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 29c15ca2ba..052c6d6b7b 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -280,8 +280,6 @@ public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; - virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; - virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 8cd6ec43c6..08630be8b0 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -51,6 +51,70 @@ #include <sys/types.h> #include <unistd.h> +void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) { + const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" }; + + String path = get_environment("PATH"); + Vector<String> path_elems = path.split(":", false); + String program; + + for (int i = 0; i < path_elems.size(); i++) { + for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) { + String tested_path = path_elems[i].plus_file(message_programs[k]); + + if (FileAccess::exists(tested_path)) { + program = tested_path; + break; + } + } + + if (program.length()) { + break; + } + } + + List<String> args; + + if (program.ends_with("zenity")) { + args.push_back("--error"); + args.push_back("--width"); + args.push_back("500"); + args.push_back("--title"); + args.push_back(p_title); + args.push_back("--text"); + args.push_back(p_alert); + } + + if (program.ends_with("kdialog")) { + args.push_back("--error"); + args.push_back(p_alert); + args.push_back("--title"); + args.push_back(p_title); + } + + if (program.ends_with("Xdialog")) { + args.push_back("--title"); + args.push_back(p_title); + args.push_back("--msgbox"); + args.push_back(p_alert); + args.push_back("0"); + args.push_back("0"); + } + + if (program.ends_with("xmessage")) { + args.push_back("-center"); + args.push_back("-title"); + args.push_back(p_title); + args.push_back(p_alert); + } + + if (program.length()) { + execute(program, args); + } else { + print_line(p_alert); + } +} + void OS_LinuxBSD::initialize() { crash_handler.initialize(); @@ -387,7 +451,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = dir_access->make_dir_recursive(trash_path); - // Issue an error if trash can is not created proprely. + // Issue an error if trash can is not created properly. ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\""); err = dir_access->make_dir_recursive(trash_path + "/files"); ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/files"); diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index b6cf93c551..1e06587322 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -90,6 +90,8 @@ public: virtual String get_unique_id() const override; + virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; + virtual bool _check_internal_feature_support(const String &p_feature) override; void run(); diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 317e79d0ea..2393f2ea10 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -24,6 +24,7 @@ def get_opts(): return [ ("osxcross_sdk", "OSXCross SDK version", "darwin16"), ("MACOS_SDK_PATH", "Path to the macOS SDK", ""), + ("VULKAN_SDK_PATH", "Path to the Vulkan SDK", ""), BoolVariable( "use_static_mvk", "Link MoltenVK statically as Level-0 driver (better portability) or use Vulkan ICD loader (enables" @@ -190,7 +191,7 @@ def configure(env): env.Append(CPPDEFINES=["VULKAN_ENABLED"]) env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"]) if env["use_static_mvk"]: - env.Append(LINKFLAGS=["-framework", "MoltenVK"]) + env.Append(LINKFLAGS=["-L$VULKAN_SDK_PATH/MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/", "-lMoltenVK"]) env["builtin_vulkan"] = False elif not env["builtin_vulkan"]: env.Append(LIBS=["vulkan"]) diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index c7b9e411b8..6b1b777224 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -60,6 +60,10 @@ class DisplayServerOSX : public DisplayServer { _THREAD_SAFE_CLASS_ public: + void _send_event(NSEvent *p_event); + NSMenu *_get_dock_menu() const; + void _menu_callback(id p_sender); + #if defined(OPENGL_ENABLED) ContextGL_OSX *context_gles2; #endif @@ -163,7 +167,6 @@ public: String rendering_driver; - id delegate; id autoreleasePool; CGEventSourceRef eventSource; @@ -207,7 +210,6 @@ public: virtual void global_menu_remove_item(const String &p_menu_root, int p_idx) override; virtual void global_menu_clear(const String &p_menu_root) override; - virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) override; virtual Error dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) override; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index dec6da42fe..73aa013701 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -105,46 +105,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { } /*************************************************************************/ -/* GodotApplication */ -/*************************************************************************/ - -@interface GodotApplication : NSApplication -@end - -@implementation GodotApplication - -- (void)sendEvent:(NSEvent *)event { - // special case handling of command-period, which is traditionally a special - // shortcut in macOS and doesn't arrive at our regular keyDown handler. - if ([event type] == NSEventTypeKeyDown) { - if (([event modifierFlags] & NSEventModifierFlagCommand) && [event keyCode] == 0x2f) { - Ref<InputEventKey> k; - k.instantiate(); - - _get_key_modifier_state([event modifierFlags], k); - k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID); - k->set_pressed(true); - k->set_keycode(KEY_PERIOD); - k->set_physical_keycode(KEY_PERIOD); - k->set_echo([event isARepeat]); - - Input::get_singleton()->accumulate_input_event(k); - } - } - - // From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost - // This works around an AppKit bug, where key up events while holding - // down the command key don't get sent to the key window. - if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) { - [[self keyWindow] sendEvent:event]; - } else { - [super sendEvent:event]; - } -} - -@end - -/*************************************************************************/ /* GlobalMenuItem */ /*************************************************************************/ @@ -161,121 +121,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { @end /*************************************************************************/ -/* GodotApplicationDelegate */ -/*************************************************************************/ - -@interface GodotApplicationDelegate : NSObject -- (void)forceUnbundledWindowActivationHackStep1; -- (void)forceUnbundledWindowActivationHackStep2; -- (void)forceUnbundledWindowActivationHackStep3; -@end - -@implementation GodotApplicationDelegate - -- (void)forceUnbundledWindowActivationHackStep1 { - // Step1: Switch focus to macOS Dock. - // Required to perform step 2, TransformProcessType will fail if app is already the in focus. - for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { - [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; - break; - } - [self performSelector:@selector(forceUnbundledWindowActivationHackStep2) withObject:nil afterDelay:0.02]; -} - -- (void)forceUnbundledWindowActivationHackStep2 { - // Step 2: Register app as foreground process. - ProcessSerialNumber psn = { 0, kCurrentProcess }; - (void)TransformProcessType(&psn, kProcessTransformToForegroundApplication); - [self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02]; -} - -- (void)forceUnbundledWindowActivationHackStep3 { - // Step 3: Switch focus back to app window. - [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; -} - -- (void)applicationDidFinishLaunching:(NSNotification *)notice { - NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; - if (nsappname == nil) { - // If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). - [self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02]; - } -} - -- (void)applicationDidResignActive:(NSNotification *)notification { - if (OS_OSX::get_singleton()->get_main_loop()) { - OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); - } -} - -- (void)applicationDidBecomeActive:(NSNotification *)notification { - if (OS_OSX::get_singleton()->get_main_loop()) { - OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); - } -} - -- (void)globalMenuCallback:(id)sender { - if (![sender representedObject]) { - return; - } - - GlobalMenuItem *value = [sender representedObject]; - - if (value) { - if (value->checkable) { - if ([sender state] == NSControlStateValueOff) { - [sender setState:NSControlStateValueOn]; - } else { - [sender setState:NSControlStateValueOff]; - } - } - - if (value->callback != Callable()) { - Variant tag = value->meta; - Variant *tagp = &tag; - Variant ret; - Callable::CallError ce; - value->callback.call((const Variant **)&tagp, 1, ret, ce); - } - } -} - -- (NSMenu *)applicationDockMenu:(NSApplication *)sender { - return DS_OSX->dock_menu; -} - -- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { - // Note: may be called called before main loop init! - char *utfs = strdup([filename UTF8String]); - ((OS_OSX *)(OS_OSX::get_singleton()))->open_with_filename.parse_utf8(utfs); - free(utfs); - -#ifdef TOOLS_ENABLED - // Open new instance - if (OS_OSX::get_singleton()->get_main_loop()) { - List<String> args; - args.push_back(((OS_OSX *)(OS_OSX::get_singleton()))->open_with_filename); - String exec = OS::get_singleton()->get_executable_path(); - OS::get_singleton()->create_process(exec, args); - } -#endif - return YES; -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - DS_OSX->_send_window_event(DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); - return NSTerminateCancel; -} - -- (void)showAbout:(id)sender { - if (OS_OSX::get_singleton()->get_main_loop()) { - OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); - } -} - -@end - -/*************************************************************************/ /* GodotWindowDelegate */ /*************************************************************************/ @@ -1983,26 +1828,6 @@ void DisplayServerOSX::global_menu_clear(const String &p_menu_root) { } } -void DisplayServerOSX::alert(const String &p_alert, const String &p_title) { - _THREAD_SAFE_METHOD_ - - NSAlert *window = [[NSAlert alloc] init]; - NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()]; - NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()]; - - [window addButtonWithTitle:@"OK"]; - [window setMessageText:ns_title]; - [window setInformativeText:ns_alert]; - [window setAlertStyle:NSAlertStyleWarning]; - - id key_window = [[NSApplication sharedApplication] keyWindow]; - [window runModal]; - [window release]; - if (key_window) { - [key_window makeKeyAndOrderFront:nil]; - } -} - Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) { _THREAD_SAFE_METHOD_ @@ -3375,6 +3200,56 @@ void DisplayServerOSX::_release_pressed_events() { } } +NSMenu *DisplayServerOSX::_get_dock_menu() const { + return dock_menu; +} + +void DisplayServerOSX::_menu_callback(id p_sender) { + if (![p_sender representedObject]) { + return; + } + + GlobalMenuItem *value = [p_sender representedObject]; + + if (value) { + if (value->checkable) { + if ([p_sender state] == NSControlStateValueOff) { + [p_sender setState:NSControlStateValueOn]; + } else { + [p_sender setState:NSControlStateValueOff]; + } + } + + if (value->callback != Callable()) { + Variant tag = value->meta; + Variant *tagp = &tag; + Variant ret; + Callable::CallError ce; + value->callback.call((const Variant **)&tagp, 1, ret, ce); + } + } +} + +void DisplayServerOSX::_send_event(NSEvent *p_event) { + // special case handling of command-period, which is traditionally a special + // shortcut in macOS and doesn't arrive at our regular keyDown handler. + if ([p_event type] == NSEventTypeKeyDown) { + if (([p_event modifierFlags] & NSEventModifierFlagCommand) && [p_event keyCode] == 0x2f) { + Ref<InputEventKey> k; + k.instantiate(); + + _get_key_modifier_state([p_event modifierFlags], k); + k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID); + k->set_pressed(true); + k->set_keycode(KEY_PERIOD); + k->set_physical_keycode(KEY_PERIOD); + k->set_echo([p_event isARepeat]); + + Input::get_singleton()->accumulate_input_event(k); + } + } +} + void DisplayServerOSX::_process_key_events() { Ref<InputEventKey> k; for (int i = 0; i < key_event_pos; i++) { @@ -3615,7 +3490,7 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); if (r_error != OK) { - ds->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver"); + OS::get_singleton()->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver"); } return ds; } @@ -3785,12 +3660,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode CGEventSourceSetLocalEventsSuppressionInterval(eventSource, 0.0); - // Implicitly create shared NSApplication instance - [GodotApplication sharedApplication]; - - // In case we are unbundled, make us a proper UI application - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - keyboard_layout_dirty = true; displays_arrangement_dirty = true; displays_scale_dirty = true; @@ -3804,9 +3673,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode // Register to be notified on displays arrangement changes CGDisplayRegisterReconfigurationCallback(displays_arrangement_changed, nullptr); - // Menu bar setup must go between sharedApplication above and - // finishLaunching below, in order to properly emulate the behavior - // of NSApplicationMain NSMenuItem *menu_item; NSString *title; @@ -3846,32 +3712,10 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode title = [NSString stringWithFormat:NSLocalizedString(@"Quit %@", nil), nsappname]; [apple_menu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - // Setup menu bar - NSMenu *main_menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + // Add items to the menu bar + NSMenu *main_menu = [NSApp mainMenu]; menu_item = [main_menu addItemWithTitle:@"" action:nil keyEquivalent:@""]; [main_menu setSubmenu:apple_menu forItem:menu_item]; - [NSApp setMainMenu:main_menu]; - - [NSApp finishLaunching]; - - delegate = [[GodotApplicationDelegate alloc] init]; - ERR_FAIL_COND(!delegate); - [NSApp setDelegate:delegate]; - - //process application:openFile: event - while (true) { - NSEvent *event = [NSApp - nextEventMatchingMask:NSEventMaskAny - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - - if (event == nil) { - break; - } - - [NSApp sendEvent:event]; - } //!!!!!!!!!!!!!!!!!!!!!!!!!! //TODO - do Vulkan and GLES2 support checks, driver selection and fallback @@ -3924,8 +3768,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode RendererCompositorRD::make_current(); } #endif - - [NSApp activateIgnoringOtherApps:YES]; } DisplayServerOSX::~DisplayServerOSX() { diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index ea34b8a24e..131c4b821e 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -178,6 +178,7 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/calendars"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/photos_library"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/apple_events"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/debugging"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/enabled"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/network_server"), false)); @@ -845,6 +846,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p ent_f->store_line("<key>com.apple.security.automation.apple-events</key>"); ent_f->store_line("<true/>"); } + if ((bool)p_preset->get("codesign/entitlements/debugging")) { + ent_f->store_line("<key>com.apple.security.get-task-allow</key>"); + ent_f->store_line("<true/>"); + } if ((bool)p_preset->get("codesign/entitlements/app_sandbox/enabled")) { ent_f->store_line("<key>com.apple.security.app-sandbox</key>"); diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index d57940775d..37d30add78 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -72,6 +72,8 @@ protected: public: virtual String get_name() const override; + virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; virtual MainLoop *get_main_loop() const override; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index b65d84d900..c458a0264a 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -41,6 +41,137 @@ #include <mach-o/dyld.h> #include <os/log.h> +#define DS_OSX ((DisplayServerOSX *)(DisplayServerOSX::get_singleton())) + +/*************************************************************************/ +/* GodotApplication */ +/*************************************************************************/ + +@interface GodotApplication : NSApplication +@end + +@implementation GodotApplication + +- (void)sendEvent:(NSEvent *)event { + if (DS_OSX) { + DS_OSX->_send_event(event); + } + + // From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost + // This works around an AppKit bug, where key up events while holding + // down the command key don't get sent to the key window. + if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) { + [[self keyWindow] sendEvent:event]; + } else { + [super sendEvent:event]; + } +} + +@end + +/*************************************************************************/ +/* GodotApplicationDelegate */ +/*************************************************************************/ + +@interface GodotApplicationDelegate : NSObject +- (void)forceUnbundledWindowActivationHackStep1; +- (void)forceUnbundledWindowActivationHackStep2; +- (void)forceUnbundledWindowActivationHackStep3; +@end + +@implementation GodotApplicationDelegate + +- (void)forceUnbundledWindowActivationHackStep1 { + // Step1: Switch focus to macOS Dock. + // Required to perform step 2, TransformProcessType will fail if app is already the in focus. + for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { + [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; + break; + } + [self performSelector:@selector(forceUnbundledWindowActivationHackStep2) + withObject:nil + afterDelay:0.02]; +} + +- (void)forceUnbundledWindowActivationHackStep2 { + // Step 2: Register app as foreground process. + ProcessSerialNumber psn = { 0, kCurrentProcess }; + (void)TransformProcessType(&psn, kProcessTransformToForegroundApplication); + [self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02]; +} + +- (void)forceUnbundledWindowActivationHackStep3 { + // Step 3: Switch focus back to app window. + [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notice { + NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + if (nsappname == nil) { + // If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). + [self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02]; + } +} + +- (void)applicationDidResignActive:(NSNotification *)notification { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); + } +} + +- (void)applicationDidBecomeActive:(NSNotification *)notification { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); + } +} + +- (void)globalMenuCallback:(id)sender { + if (DS_OSX) { + return DS_OSX->_menu_callback(sender); + } +} + +- (NSMenu *)applicationDockMenu:(NSApplication *)sender { + if (DS_OSX) { + return DS_OSX->_get_dock_menu(); + } else { + return nullptr; + } +} + +- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { + // Note: may be called called before main loop init! + char *utfs = strdup([filename UTF8String]); + ((OS_OSX *)OS_OSX::get_singleton())->open_with_filename.parse_utf8(utfs); + free(utfs); + +#ifdef TOOLS_ENABLED + // Open new instance + if (OS_OSX::get_singleton()->get_main_loop()) { + List<String> args; + args.push_back(((OS_OSX *)OS_OSX::get_singleton())->open_with_filename); + String exec = OS_OSX::get_singleton()->get_executable_path(); + OS_OSX::get_singleton()->create_process(exec, args); + } +#endif + return YES; +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { + if (DS_OSX) { + DS_OSX->_send_window_event(DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + } + return NSTerminateCancel; +} + +- (void)showAbout:(id)sender { + if (OS_OSX::get_singleton()->get_main_loop()) { + OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); + } +} + +@end + /*************************************************************************/ /* OSXTerminalLogger */ /*************************************************************************/ @@ -119,6 +250,24 @@ String OS_OSX::get_unique_id() const { return serial_number; } +void OS_OSX::alert(const String &p_alert, const String &p_title) { + NSAlert *window = [[NSAlert alloc] init]; + NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()]; + NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()]; + + [window addButtonWithTitle:@"OK"]; + [window setMessageText:ns_title]; + [window setInformativeText:ns_alert]; + [window setAlertStyle:NSAlertStyleWarning]; + + id key_window = [[NSApplication sharedApplication] keyWindow]; + [window runModal]; + [window release]; + if (key_window) { + [key_window makeKeyAndOrderFront:nil]; + } +} + void OS_OSX::initialize_core() { OS_Unix::initialize_core(); @@ -220,7 +369,7 @@ String OS_OSX::get_cache_path() const { if (get_environment("XDG_CACHE_HOME").is_absolute_path()) { return get_environment("XDG_CACHE_HOME"); } else { - WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Libary/Caches` or `get_config_path()` per the XDG Base Directory specification."); + WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Library/Caches` or `get_config_path()` per the XDG Base Directory specification."); } } if (has_environment("HOME")) { @@ -372,6 +521,41 @@ OS_OSX::OS_OSX() { #endif DisplayServerOSX::register_osx_driver(); + + // Implicitly create shared NSApplication instance + [GodotApplication sharedApplication]; + + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + + // Menu bar setup must go between sharedApplication above and + // finishLaunching below, in order to properly emulate the behavior + // of NSApplicationMain + + NSMenu *main_menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + [NSApp setMainMenu:main_menu]; + [NSApp finishLaunching]; + + id delegate = [[GodotApplicationDelegate alloc] init]; + ERR_FAIL_COND(!delegate); + [NSApp setDelegate:delegate]; + + //process application:openFile: event + while (true) { + NSEvent *event = [NSApp + nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + + if (event == nil) { + break; + } + + [NSApp sendEvent:event]; + } + + [NSApp activateIgnoringOtherApps:YES]; } bool OS_OSX::_check_internal_feature_support(const String &p_feature) { diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 7772ba2dbe..a94f38583c 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -171,7 +171,6 @@ def setup_mingw(env): """Set up env for use with mingw""" # Nothing to do here print("Using MinGW") - pass def configure_msvc(env, manual_msvc_config): diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 4f64809abc..e78b23c509 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -79,10 +79,6 @@ String DisplayServerWindows::get_name() const { return "Windows"; } -void DisplayServerWindows::alert(const String &p_alert, const String &p_title) { - MessageBoxW(nullptr, (LPCWSTR)(p_alert.utf16().get_data()), (LPCWSTR)(p_title.utf16().get_data()), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); -} - void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) { if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN) { // Mouse is grabbed (captured or confined). @@ -3358,8 +3354,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() { DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); if (r_error != OK) { - ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", + OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n" + "Please update your drivers or if you have a very old or integrated GPU upgrade it.", "Unable to initialize Video driver"); } return ds; diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index aa1d42d6ed..06014fbabe 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -442,8 +442,6 @@ public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; - virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; - virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 56d673afc3..2c8afaf7de 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -165,6 +165,10 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) { } } +void OS_Windows::alert(const String &p_alert, const String &p_title) { + MessageBoxW(nullptr, (LPCWSTR)(p_alert.utf16().get_data()), (LPCWSTR)(p_title.utf16().get_data()), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); +} + void OS_Windows::initialize_debugging() { SetConsoleCtrlHandler(HandlerRoutine, TRUE); } @@ -407,8 +411,8 @@ String OS_Windows::_quote_command_line_argument(const String &p_text) const { Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { String path = p_path.replace("/", "\\"); String command = _quote_command_line_argument(path); - for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { - command += " " + _quote_command_line_argument(E->get()); + for (const String &E : p_arguments) { + command += " " + _quote_command_line_argument(E); } if (r_pipe) { @@ -463,8 +467,8 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, Error OS_Windows::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) { String path = p_path.replace("/", "\\"); String command = _quote_command_line_argument(path); - for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { - command += " " + _quote_command_line_argument(E->get()); + for (const String &E : p_arguments) { + command += " " + _quote_command_line_argument(E); } ProcessInfo pi; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 8f9ef254f1..ea0c263b78 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -108,6 +108,8 @@ protected: Map<ProcessID, ProcessInfo> *process_map; public: + virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index 9ee37670d1..da2ab6ada8 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -123,7 +123,7 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &property) const { } property.hint_string += String(E->get()); - if (animation == E->get()) { + if (animation == E) { current_found = true; } } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 5b12da8b57..561207c24c 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -145,8 +145,7 @@ TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; - for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { - RID body = E->get(); + for (const RID &body : exceptions) { ObjectID instance_id = PhysicsServer2D::get_singleton()->body_get_object_instance_id(body); Object *obj = ObjectDB::get_instance(instance_id); PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(obj); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index bf2f8f8947..3932f3dc78 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1596,8 +1596,8 @@ void TileMap::set_light_mask(int p_light_mask) { // Occlusion: set light mask. CanvasItem::set_light_mask(p_light_mask); for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - for (List<RID>::Element *F = E->get().canvas_items.front(); F; F = F->next()) { - RenderingServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_light_mask()); + for (const RID &F : E->get().canvas_items) { + RenderingServer::get_singleton()->canvas_item_set_light_mask(F, get_light_mask()); } } } @@ -1609,8 +1609,8 @@ void TileMap::set_material(const Ref<Material> &p_material) { // Update material for the whole tilemap. for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { TileMapQuadrant &q = E->get(); - for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - RS::get_singleton()->canvas_item_set_use_parent_material(F->get(), get_use_parent_material() || get_material().is_valid()); + for (const RID &F : q.canvas_items) { + RS::get_singleton()->canvas_item_set_use_parent_material(F, get_use_parent_material() || get_material().is_valid()); } } } @@ -1622,8 +1622,8 @@ void TileMap::set_use_parent_material(bool p_use_parent_material) { // Update use_parent_material for the whole tilemap. for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { TileMapQuadrant &q = E->get(); - for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - RS::get_singleton()->canvas_item_set_use_parent_material(F->get(), get_use_parent_material() || get_material().is_valid()); + for (const RID &F : q.canvas_items) { + RS::get_singleton()->canvas_item_set_use_parent_material(F, get_use_parent_material() || get_material().is_valid()); } } } @@ -1633,8 +1633,8 @@ void TileMap::set_texture_filter(TextureFilter p_texture_filter) { CanvasItem::set_texture_filter(p_texture_filter); for (Map<Vector2i, TileMapQuadrant>::Element *F = quadrant_map.front(); F; F = F->next()) { TileMapQuadrant &q = F->get(); - for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - RenderingServer::get_singleton()->canvas_item_set_default_texture_filter(E->get(), RS::CanvasItemTextureFilter(p_texture_filter)); + for (const RID &E : q.canvas_items) { + RenderingServer::get_singleton()->canvas_item_set_default_texture_filter(E, RS::CanvasItemTextureFilter(p_texture_filter)); _make_quadrant_dirty(F); } } @@ -1645,8 +1645,8 @@ void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) { CanvasItem::set_texture_repeat(p_texture_repeat); for (Map<Vector2i, TileMapQuadrant>::Element *F = quadrant_map.front(); F; F = F->next()) { TileMapQuadrant &q = F->get(); - for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - RenderingServer::get_singleton()->canvas_item_set_default_texture_repeat(E->get(), RS::CanvasItemTextureRepeat(p_texture_repeat)); + for (const RID &E : q.canvas_items) { + RenderingServer::get_singleton()->canvas_item_set_default_texture_repeat(E, RS::CanvasItemTextureRepeat(p_texture_repeat)); _make_quadrant_dirty(F); } } diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index dd8cb1f20d..bb8f9f8ccb 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -794,7 +794,7 @@ uint32_t AudioStreamPlayer3D::get_area_mask() const { void AudioStreamPlayer3D::set_emission_angle_enabled(bool p_enable) { emission_angle_enabled = p_enable; - update_gizmo(); + update_gizmos(); } bool AudioStreamPlayer3D::is_emission_angle_enabled() const { @@ -804,7 +804,7 @@ bool AudioStreamPlayer3D::is_emission_angle_enabled() const { void AudioStreamPlayer3D::set_emission_angle(float p_angle) { ERR_FAIL_COND(p_angle < 0 || p_angle > 90); emission_angle = p_angle; - update_gizmo(); + update_gizmos(); } float AudioStreamPlayer3D::get_emission_angle() const { diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 0c38d85a6b..2e962b96c3 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -164,7 +164,7 @@ void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_f mode = PROJECTION_PERSPECTIVE; RenderingServer::get_singleton()->camera_set_perspective(camera, fov, near, far); - update_gizmo(); + update_gizmos(); force_change = false; } @@ -181,7 +181,7 @@ void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) { force_change = false; RenderingServer::get_singleton()->camera_set_orthogonal(camera, size, near, far); - update_gizmo(); + update_gizmos(); } void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { @@ -198,7 +198,7 @@ void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float force_change = false; RenderingServer::get_singleton()->camera_set_frustum(camera, size, frustum_offset, near, far); - update_gizmo(); + update_gizmos(); } void Camera3D::set_projection(Camera3D::Projection p_mode) { @@ -755,7 +755,7 @@ void ClippedCamera3D::_notification(int p_what) { } if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { - update_gizmo(); + update_gizmos(); } } diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index 8a4f8b639b..42645f47d4 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -122,7 +122,7 @@ void CollisionPolygon3D::set_polygon(const Vector<Point2> &p_polygon) { _build_polygon(); } update_configuration_warnings(); - update_gizmo(); + update_gizmos(); } Vector<Point2> CollisionPolygon3D::get_polygon() const { @@ -136,7 +136,7 @@ AABB CollisionPolygon3D::get_item_rect() const { void CollisionPolygon3D::set_depth(real_t p_depth) { depth = p_depth; _build_polygon(); - update_gizmo(); + update_gizmos(); } real_t CollisionPolygon3D::get_depth() const { @@ -145,7 +145,7 @@ real_t CollisionPolygon3D::get_depth() const { void CollisionPolygon3D::set_disabled(bool p_disabled) { disabled = p_disabled; - update_gizmo(); + update_gizmos(); if (parent) { parent->shape_owner_set_disabled(owner_id, p_disabled); diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index be3fde8013..9643d33c86 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -117,7 +117,7 @@ void CollisionShape3D::_notification(int p_what) { } void CollisionShape3D::resource_changed(RES res) { - update_gizmo(); + update_gizmos(); } TypedArray<String> CollisionShape3D::get_configuration_warnings() const { @@ -166,7 +166,7 @@ void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) { if (!shape.is_null()) { shape->register_owner(this); } - update_gizmo(); + update_gizmos(); if (parent) { parent->shape_owner_clear_shapes(owner_id); if (shape.is_valid()) { @@ -187,7 +187,7 @@ Ref<Shape3D> CollisionShape3D::get_shape() const { void CollisionShape3D::set_disabled(bool p_disabled) { disabled = p_disabled; - update_gizmo(); + update_gizmos(); if (parent) { parent->shape_owner_set_disabled(owner_id, p_disabled); } diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index 5af7b8ca07..05f023721b 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -33,7 +33,7 @@ void Decal::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->decal_set_extents(decal, p_extents); - update_gizmo(); + update_gizmos(); } Vector3 Decal::get_extents() const { diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index f78027e6c7..44cd7c10d8 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -99,7 +99,7 @@ void GPUParticles3D::set_randomness_ratio(float p_ratio) { void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) { visibility_aabb = p_aabb; RS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb); - update_gizmo(); + update_gizmos(); } void GPUParticles3D::set_use_local_coordinates(bool p_enable) { diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 5b88a6ec9f..cc1b620025 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -73,7 +73,7 @@ void GPUParticlesCollisionSphere::_bind_methods() { void GPUParticlesCollisionSphere::set_radius(float p_radius) { radius = p_radius; RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius); - update_gizmo(); + update_gizmos(); } float GPUParticlesCollisionSphere::get_radius() const { @@ -103,7 +103,7 @@ void GPUParticlesCollisionBox::_bind_methods() { void GPUParticlesCollisionBox::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); - update_gizmo(); + update_gizmos(); } Vector3 GPUParticlesCollisionBox::get_extents() const { @@ -397,9 +397,7 @@ Ref<Image> GPUParticlesCollisionSDF::bake() { bake_step_function(0, "Finding Meshes"); } - for (List<PlotMesh>::Element *E = plot_meshes.front(); E; E = E->next()) { - const PlotMesh &pm = E->get(); - + for (const PlotMesh &pm : plot_meshes) { for (int i = 0; i < pm.mesh->get_surface_count(); i++) { if (pm.mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { continue; //only triangles @@ -545,7 +543,7 @@ float GPUParticlesCollisionSDF::get_thickness() const { void GPUParticlesCollisionSDF::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); - update_gizmo(); + update_gizmos(); } Vector3 GPUParticlesCollisionSDF::get_extents() const { @@ -554,7 +552,7 @@ Vector3 GPUParticlesCollisionSDF::get_extents() const { void GPUParticlesCollisionSDF::set_resolution(Resolution p_resolution) { resolution = p_resolution; - update_gizmo(); + update_gizmos(); } GPUParticlesCollisionSDF::Resolution GPUParticlesCollisionSDF::get_resolution() const { @@ -680,7 +678,7 @@ float GPUParticlesCollisionHeightField::get_follow_camera_push_ratio() const { void GPUParticlesCollisionHeightField::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); - update_gizmo(); + update_gizmos(); RS::get_singleton()->particles_collision_height_field_update(_get_collision()); } @@ -691,7 +689,7 @@ Vector3 GPUParticlesCollisionHeightField::get_extents() const { void GPUParticlesCollisionHeightField::set_resolution(Resolution p_resolution) { resolution = p_resolution; RS::get_singleton()->particles_collision_set_height_field_resolution(_get_collision(), RS::ParticlesCollisionHeightfieldResolution(resolution)); - update_gizmo(); + update_gizmos(); RS::get_singleton()->particles_collision_height_field_update(_get_collision()); } @@ -761,7 +759,7 @@ float GPUParticlesAttractor3D::get_attenuation() const { void GPUParticlesAttractor3D::set_directionality(float p_directionality) { directionality = p_directionality; RS::get_singleton()->particles_collision_set_attractor_directionality(collision, p_directionality); - update_gizmo(); + update_gizmos(); } float GPUParticlesAttractor3D::get_directionality() const { @@ -808,7 +806,7 @@ void GPUParticlesAttractorSphere::_bind_methods() { void GPUParticlesAttractorSphere::set_radius(float p_radius) { radius = p_radius; RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius); - update_gizmo(); + update_gizmos(); } float GPUParticlesAttractorSphere::get_radius() const { @@ -838,7 +836,7 @@ void GPUParticlesAttractorBox::_bind_methods() { void GPUParticlesAttractorBox::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); - update_gizmo(); + update_gizmos(); } Vector3 GPUParticlesAttractorBox::get_extents() const { @@ -872,7 +870,7 @@ void GPUParticlesAttractorVectorField::_bind_methods() { void GPUParticlesAttractorVectorField::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); - update_gizmo(); + update_gizmos(); } Vector3 GPUParticlesAttractorVectorField::get_extents() const { diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 8478821ba1..c2943a9606 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -45,7 +45,7 @@ void Light3D::set_param(Param p_param, float p_value) { RS::get_singleton()->light_set_param(light, RS::LightParam(p_param), p_value); if (p_param == PARAM_SPOT_ANGLE || p_param == PARAM_RANGE) { - update_gizmo(); + update_gizmos(); if (p_param == PARAM_SPOT_ANGLE) { update_configuration_warnings(); @@ -95,7 +95,7 @@ void Light3D::set_color(const Color &p_color) { color = p_color; RS::get_singleton()->light_set_color(light, p_color); // The gizmo color depends on the light color, so update it. - update_gizmo(); + update_gizmos(); } Color Light3D::get_color() const { diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 3ffb3c0393..0085c8933d 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -1250,7 +1250,7 @@ void LightmapGI::set_light_data(const Ref<LightmapGIData> &p_data) { } } - update_gizmo(); + update_gizmos(); } Ref<LightmapGIData> LightmapGI::get_light_data() const { diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 28ccbd3e68..9ca1d55d0b 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -94,8 +94,8 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { ls.sort(); - for (List<String>::Element *E = ls.front(); E; E = E->next()) { - p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "-1,1,0.00001")); + for (const String &E : ls) { + p_list->push_back(PropertyInfo(Variant::FLOAT, E, PROPERTY_HINT_RANGE, "-1,1,0.00001")); } if (mesh.is_valid()) { @@ -133,7 +133,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) { set_base(RID()); } - update_gizmo(); + update_gizmos(); notify_property_list_changed(); } @@ -356,7 +356,7 @@ Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { void MeshInstance3D::_mesh_changed() { ERR_FAIL_COND(mesh.is_null()); surface_override_materials.resize(mesh->get_surface_count()); - update_gizmo(); + update_gizmos(); } void MeshInstance3D::create_debug_tangents() { diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 19abb3f33a..2976dad39d 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -59,7 +59,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) { } } - update_gizmo(); + update_gizmos(); } bool NavigationRegion3D::is_enabled() const { @@ -134,7 +134,7 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes emit_signal(SNAME("navigation_mesh_changed")); - update_gizmo(); + update_gizmos(); update_configuration_warnings(); } @@ -211,7 +211,7 @@ void NavigationRegion3D::_bind_methods() { } void NavigationRegion3D::_navigation_changed() { - update_gizmo(); + update_gizmos(); update_configuration_warnings(); } diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index d6c6ec75b4..0daee69ee5 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -76,7 +76,7 @@ Node3DGizmo::Node3DGizmo() { void Node3D::_notify_dirty() { #ifdef TOOLS_ENABLED - if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) { + if ((!data.gizmos.is_empty() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) { #else if (data.notify_transform && !data.ignore_notification && !xform_change.in_list()) { @@ -103,14 +103,14 @@ void Node3D::_propagate_transform_changed(Node3D *p_origin) { data.children_lock++; - for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) { - if (E->get()->data.top_level_active) { + for (Node3D *&E : data.children) { + if (E->data.top_level_active) { continue; //don't propagate to a top_level } - E->get()->_propagate_transform_changed(p_origin); + E->_propagate_transform_changed(p_origin); } #ifdef TOOLS_ENABLED - if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) { + if ((!data.gizmos.is_empty() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) { #else if (data.notify_transform && !data.ignore_notification && !xform_change.in_list()) { #endif @@ -181,15 +181,14 @@ void Node3D::_notification(int p_what) { } #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) { - //get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this); get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this); - if (!data.gizmo_disabled) { - if (data.gizmo.is_valid()) { - data.gizmo->create(); + if (!data.gizmos_disabled) { + for (int i = 0; i < data.gizmos.size(); i++) { + data.gizmos.write[i]->create(); if (is_visible_in_tree()) { - data.gizmo->redraw(); + data.gizmos.write[i]->redraw(); } - data.gizmo->transform(); + data.gizmos.write[i]->transform(); } } } @@ -198,10 +197,7 @@ void Node3D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_WORLD: { #ifdef TOOLS_ENABLED - if (data.gizmo.is_valid()) { - data.gizmo->free(); - data.gizmo.unref(); - } + clear_gizmos(); #endif if (get_script_instance()) { @@ -215,8 +211,8 @@ void Node3D::_notification(int p_what) { case NOTIFICATION_TRANSFORM_CHANGED: { #ifdef TOOLS_ENABLED - if (data.gizmo.is_valid()) { - data.gizmo->transform(); + for (int i = 0; i < data.gizmos.size(); i++) { + data.gizmos.write[i]->transform(); } #endif } break; @@ -368,80 +364,119 @@ Vector3 Node3D::get_scale() const { return data.scale; } -void Node3D::update_gizmo() { +void Node3D::update_gizmos() { #ifdef TOOLS_ENABLED if (!is_inside_world()) { return; } - if (!data.gizmo.is_valid()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this); + + if (data.gizmos.is_empty()) { + return; } - if (!data.gizmo.is_valid()) { + data.gizmos_dirty = true; + MessageQueue::get_singleton()->push_callable(callable_mp(this, &Node3D::_update_gizmos)); +#endif +} + +void Node3D::clear_subgizmo_selection() { +#ifdef TOOLS_ENABLED + if (!is_inside_world()) { return; } - if (data.gizmo_dirty) { + + if (data.gizmos.is_empty()) { return; } - data.gizmo_dirty = true; - MessageQueue::get_singleton()->push_call(this, "_update_gizmo"); + + if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) { + get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_clear_subgizmo_selection, this); + } #endif } -void Node3D::set_gizmo(const Ref<Node3DGizmo> &p_gizmo) { +void Node3D::add_gizmo(Ref<Node3DGizmo> p_gizmo) { #ifdef TOOLS_ENABLED - if (data.gizmo_disabled) { + if (data.gizmos_disabled || p_gizmo.is_null()) { return; } - if (data.gizmo.is_valid() && is_inside_world()) { - data.gizmo->free(); - } - data.gizmo = p_gizmo; - if (data.gizmo.is_valid() && is_inside_world()) { - data.gizmo->create(); + data.gizmos.push_back(p_gizmo); + + if (p_gizmo.is_valid() && is_inside_world()) { + p_gizmo->create(); if (is_visible_in_tree()) { - data.gizmo->redraw(); + p_gizmo->redraw(); } - data.gizmo->transform(); + p_gizmo->transform(); } +#endif +} + +void Node3D::remove_gizmo(Ref<Node3DGizmo> p_gizmo) { +#ifdef TOOLS_ENABLED + int idx = data.gizmos.find(p_gizmo); + if (idx != -1) { + p_gizmo->free(); + data.gizmos.remove(idx); + } +#endif +} + +void Node3D::clear_gizmos() { +#ifdef TOOLS_ENABLED + for (int i = 0; i < data.gizmos.size(); i++) { + data.gizmos.write[i]->free(); + } + data.gizmos.clear(); +#endif +} + +Array Node3D::get_gizmos_bind() const { + Array ret; + +#ifdef TOOLS_ENABLED + for (int i = 0; i < data.gizmos.size(); i++) { + ret.push_back(Variant(data.gizmos[i].ptr())); + } #endif + + return ret; } -Ref<Node3DGizmo> Node3D::get_gizmo() const { +Vector<Ref<Node3DGizmo>> Node3D::get_gizmos() const { #ifdef TOOLS_ENABLED - return data.gizmo; + return data.gizmos; #else - return Ref<Node3DGizmo>(); + return Vector<Ref<Node3DGizmo>>(); #endif } -void Node3D::_update_gizmo() { +void Node3D::_update_gizmos() { #ifdef TOOLS_ENABLED - if (!is_inside_world()) { + if (data.gizmos_disabled || !is_inside_world() || !data.gizmos_dirty) { return; } - data.gizmo_dirty = false; - if (data.gizmo.is_valid()) { + data.gizmos_dirty = false; + for (int i = 0; i < data.gizmos.size(); i++) { if (is_visible_in_tree()) { - data.gizmo->redraw(); + data.gizmos.write[i]->redraw(); } else { - data.gizmo->clear(); + data.gizmos.write[i]->clear(); } } #endif } #ifdef TOOLS_ENABLED -void Node3D::set_disable_gizmo(bool p_enabled) { - data.gizmo_disabled = p_enabled; - if (!p_enabled && data.gizmo.is_valid()) { - data.gizmo = Ref<Node3DGizmo>(); +void Node3D::set_disable_gizmos(bool p_enabled) { + data.gizmos_disabled = p_enabled; + if (!p_enabled) { + clear_gizmos(); } } - #endif void Node3D::set_disable_scale(bool p_enabled) { @@ -486,13 +521,13 @@ void Node3D::_propagate_visibility_changed() { notification(NOTIFICATION_VISIBILITY_CHANGED); emit_signal(SceneStringNames::get_singleton()->visibility_changed); #ifdef TOOLS_ENABLED - if (data.gizmo.is_valid()) { - _update_gizmo(); + if (!data.gizmos.is_empty()) { + data.gizmos_dirty = true; + _update_gizmos(); } #endif - for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) { - Node3D *c = E->get(); + for (Node3D *c : data.children) { if (!c || !c->data.visible) { continue; } @@ -717,8 +752,7 @@ void Node3D::_update_visibility_parent(bool p_update_root) { RS::get_singleton()->instance_set_visibility_parent(vi->get_instance(), data.visibility_parent); } - for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) { - Node3D *c = E->get(); + for (Node3D *c : data.children) { c->_update_visibility_parent(false); } } @@ -758,11 +792,11 @@ void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_visibility_parent", "path"), &Node3D::set_visibility_parent); ClassDB::bind_method(D_METHOD("get_visibility_parent"), &Node3D::get_visibility_parent); - ClassDB::bind_method(D_METHOD("_update_gizmo"), &Node3D::_update_gizmo); - - ClassDB::bind_method(D_METHOD("update_gizmo"), &Node3D::update_gizmo); - ClassDB::bind_method(D_METHOD("set_gizmo", "gizmo"), &Node3D::set_gizmo); - ClassDB::bind_method(D_METHOD("get_gizmo"), &Node3D::get_gizmo); + ClassDB::bind_method(D_METHOD("update_gizmos"), &Node3D::update_gizmos); + ClassDB::bind_method(D_METHOD("add_gizmo", "gizmo"), &Node3D::add_gizmo); + ClassDB::bind_method(D_METHOD("get_gizmos"), &Node3D::get_gizmos_bind); + ClassDB::bind_method(D_METHOD("clear_gizmos"), &Node3D::clear_gizmos); + ClassDB::bind_method(D_METHOD("clear_subgizmo_selection"), &Node3D::clear_subgizmo_selection); ClassDB::bind_method(D_METHOD("set_visible", "visible"), &Node3D::set_visible); ClassDB::bind_method(D_METHOD("is_visible"), &Node3D::is_visible); @@ -813,7 +847,6 @@ void Node3D::_bind_methods() { ADD_GROUP("Visibility", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "Node3DGizmo", PROPERTY_USAGE_NONE), "set_gizmo", "get_gizmo"); ADD_SIGNAL(MethodInfo("visibility_changed")); } diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index fe6324c796..282f4805cc 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -90,16 +90,16 @@ class Node3D : public Node { bool disable_scale = false; #ifdef TOOLS_ENABLED - Ref<Node3DGizmo> gizmo; - bool gizmo_disabled = false; - bool gizmo_dirty = false; + Vector<Ref<Node3DGizmo>> gizmos; + bool gizmos_disabled = false; + bool gizmos_dirty = false; #endif } data; NodePath visibility_parent_path; - void _update_gizmo(); + void _update_gizmos(); void _notify_dirty(); void _propagate_transform_changed(Node3D *p_origin); @@ -154,10 +154,14 @@ public: void set_disable_scale(bool p_enabled); bool is_scale_disabled() const; - void set_disable_gizmo(bool p_enabled); - void update_gizmo(); - void set_gizmo(const Ref<Node3DGizmo> &p_gizmo); - Ref<Node3DGizmo> get_gizmo() const; + void set_disable_gizmos(bool p_enabled); + void update_gizmos(); + void clear_subgizmo_selection(); + Vector<Ref<Node3DGizmo>> get_gizmos() const; + Array get_gizmos_bind() const; + void add_gizmo(Ref<Node3DGizmo> p_gizmo); + void remove_gizmo(Ref<Node3DGizmo> p_gizmo); + void clear_gizmos(); _FORCE_INLINE_ bool is_inside_world() const { return data.inside_world; } diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index 7b736e689c..3d1a27911b 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -173,12 +173,12 @@ void OccluderInstance3D::set_occluder(const Ref<Occluder3D> &p_occluder) { set_base(RID()); } - update_gizmo(); + update_gizmos(); update_configuration_warnings(); } void OccluderInstance3D::_occluder_changed() { - update_gizmo(); + update_gizmos(); update_configuration_warnings(); } diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 54ae2cef75..6af2e7f879 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -38,7 +38,7 @@ void Path3D::_notification(int p_what) { void Path3D::_curve_changed() { if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { - update_gizmo(); + update_gizmos(); } if (is_inside_tree()) { emit_signal(SNAME("curve_changed")); diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 760dbdadca..93ecb2cd3a 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -78,8 +78,7 @@ TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; - for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { - RID body = E->get(); + for (const RID &body : exceptions) { ObjectID instance_id = PhysicsServer3D::get_singleton()->body_get_object_instance_id(body); Object *obj = ObjectDB::get_instance(instance_id); PhysicsBody3D *physics_body = Object::cast_to<PhysicsBody3D>(obj); @@ -2181,9 +2180,7 @@ bool PhysicalBone3D::_set(const StringName &p_name, const Variant &p_value) { if (joint_data) { if (joint_data->_set(p_name, p_value, joint)) { #ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) { - get_gizmo()->redraw(); - } + update_gizmos(); #endif return true; } @@ -2371,9 +2368,7 @@ void PhysicalBone3D::_update_joint_offset() { set_ignore_transform_notification(false); #ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) { - get_gizmo()->redraw(); - } + update_gizmos(); #endif } @@ -2540,9 +2535,7 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) { #ifdef TOOLS_ENABLED notify_property_list_changed(); - if (get_gizmo().is_valid()) { - get_gizmo()->redraw(); - } + update_gizmos(); #endif } diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 01f10c171f..59440bd1a8 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -348,7 +348,7 @@ void HingeJoint3D::set_param(Param p_param, real_t p_value) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value); } - update_gizmo(); + update_gizmos(); } real_t HingeJoint3D::get_param(Param p_param) const { @@ -363,7 +363,7 @@ void HingeJoint3D::set_flag(Flag p_flag, bool p_value) { PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value); } - update_gizmo(); + update_gizmos(); } bool HingeJoint3D::get_flag(Flag p_flag) const { @@ -497,7 +497,7 @@ void SliderJoint3D::set_param(Param p_param, real_t p_value) { if (is_configured()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value); } - update_gizmo(); + update_gizmos(); } real_t SliderJoint3D::get_param(Param p_param) const { @@ -602,7 +602,7 @@ void ConeTwistJoint3D::set_param(Param p_param, real_t p_value) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value); } - update_gizmo(); + update_gizmos(); } real_t ConeTwistJoint3D::get_param(Param p_param) const { @@ -857,7 +857,7 @@ void Generic6DOFJoint3D::set_param_x(Param p_param, real_t p_value) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } - update_gizmo(); + update_gizmos(); } real_t Generic6DOFJoint3D::get_param_x(Param p_param) const { @@ -871,7 +871,7 @@ void Generic6DOFJoint3D::set_param_y(Param p_param, real_t p_value) { if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } - update_gizmo(); + update_gizmos(); } real_t Generic6DOFJoint3D::get_param_y(Param p_param) const { @@ -885,7 +885,7 @@ void Generic6DOFJoint3D::set_param_z(Param p_param, real_t p_value) { if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } - update_gizmo(); + update_gizmos(); } real_t Generic6DOFJoint3D::get_param_z(Param p_param) const { @@ -899,7 +899,7 @@ void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) { if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } - update_gizmo(); + update_gizmos(); } bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const { @@ -913,7 +913,7 @@ void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) { if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } - update_gizmo(); + update_gizmos(); } bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const { @@ -927,7 +927,7 @@ void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) { if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } - update_gizmo(); + update_gizmos(); } bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const { diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index dfab3d4a17..7356ce478b 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -37,7 +37,7 @@ void RayCast3D::set_target_position(const Vector3 &p_point) { target_position = p_point; - update_gizmo(); + update_gizmos(); if (Engine::get_singleton()->is_editor_hint()) { if (is_inside_tree()) { @@ -102,7 +102,7 @@ Vector3 RayCast3D::get_collision_normal() const { void RayCast3D::set_enabled(bool p_enabled) { enabled = p_enabled; - update_gizmo(); + update_gizmos(); if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) { set_physics_process_internal(p_enabled); @@ -366,7 +366,7 @@ void RayCast3D::_update_debug_shape_vertices() { void RayCast3D::set_debug_shape_thickness(const float p_debug_shape_thickness) { debug_shape_thickness = p_debug_shape_thickness; - update_gizmo(); + update_gizmos(); if (Engine::get_singleton()->is_editor_hint()) { if (is_inside_tree()) { diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index c289fc4fd7..719dbedd94 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -101,7 +101,7 @@ void ReflectionProbe::set_extents(const Vector3 &p_extents) { RS::get_singleton()->reflection_probe_set_extents(probe, extents); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); - update_gizmo(); + update_gizmos(); } Vector3 ReflectionProbe::get_extents() const { @@ -119,7 +119,7 @@ void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) { RS::get_singleton()->reflection_probe_set_extents(probe, extents); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); - update_gizmo(); + update_gizmos(); } Vector3 ReflectionProbe::get_origin_offset() const { diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index fa3b16935c..9ce4c37457 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -264,8 +264,8 @@ void Skeleton3D::_notification(int p_what) { b.global_pose_override_amount = 0.0; } - for (List<ObjectID>::Element *E = b.nodes_bound.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->get()); + for (const ObjectID &E : b.nodes_bound) { + Object *obj = ObjectDB::get_instance(E); ERR_CONTINUE(!obj); Node3D *node_3d = Object::cast_to<Node3D>(obj); ERR_CONTINUE(!node_3d); @@ -404,7 +404,7 @@ void Skeleton3D::add_bone(const String &p_name) { process_order_dirty = true; version++; _make_dirty(); - update_gizmo(); + update_gizmos(); } int Skeleton3D::find_bone(const String &p_name) const { @@ -524,8 +524,8 @@ void Skeleton3D::bind_child_node_to_bone(int p_bone, Node *p_node) { ObjectID id = p_node->get_instance_id(); - for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { - if (E->get() == id) { + for (const ObjectID &E : bones[p_bone].nodes_bound) { + if (E == id) { return; // already here } } @@ -544,8 +544,8 @@ void Skeleton3D::unbind_child_node_from_bone(int p_bone, Node *p_node) { void Skeleton3D::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const { ERR_FAIL_INDEX(p_bone, bones.size()); - for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->get()); + for (const ObjectID &E : bones[p_bone].nodes_bound) { + Object *obj = ObjectDB::get_instance(E); ERR_CONTINUE(!obj); p_bound->push_back(Object::cast_to<Node>(obj)); } diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 05530c39a1..a7ff0842d2 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -592,8 +592,7 @@ Array SoftBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->soft_body_get_collision_exceptions(physics_rid, &exceptions); Array ret; - for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { - RID body = E->get(); + for (const RID &body : exceptions) { ObjectID instance_id = PhysicsServer3D::get_singleton()->body_get_object_instance_id(body); Object *obj = ObjectDB::get_instance(instance_id); PhysicsBody3D *physics_body = Object::cast_to<PhysicsBody3D>(obj); diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 1911e14d54..5e9265b4c3 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -84,7 +84,7 @@ real_t SpringArm3D::get_length() const { void SpringArm3D::set_length(real_t p_length) { if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) { - update_gizmo(); + update_gizmos(); } spring_length = p_length; diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 2a53dd6aca..a901920dbe 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -60,8 +60,8 @@ void SpriteBase3D::_propagate_color_changed() { color_dirty = true; _queue_update(); - for (List<SpriteBase3D *>::Element *E = children.front(); E; E = E->next()) { - E->get()->_propagate_color_changed(); + for (SpriteBase3D *&E : children) { + E->_propagate_color_changed(); } } @@ -174,7 +174,7 @@ void SpriteBase3D::_queue_update() { } triangle_mesh.unref(); - update_gizmo(); + update_gizmos(); pending_update = true; call_deferred(SceneStringNames::get_singleton()->_im_update); @@ -996,7 +996,7 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const { } property.hint_string += String(E->get()); - if (animation == E->get()) { + if (animation == E) { current_found = true; } } diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index b0e37b81a5..92c0e09947 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -149,7 +149,7 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) { void VehicleWheel3D::set_radius(real_t p_radius) { m_wheelRadius = p_radius; - update_gizmo(); + update_gizmos(); } real_t VehicleWheel3D::get_radius() const { @@ -158,7 +158,7 @@ real_t VehicleWheel3D::get_radius() const { void VehicleWheel3D::set_suspension_rest_length(real_t p_length) { m_suspensionRestLength = p_length; - update_gizmo(); + update_gizmos(); } real_t VehicleWheel3D::get_suspension_rest_length() const { diff --git a/scene/3d/visible_on_screen_notifier_3d.cpp b/scene/3d/visible_on_screen_notifier_3d.cpp index 682bcec449..6a80aa3f45 100644 --- a/scene/3d/visible_on_screen_notifier_3d.cpp +++ b/scene/3d/visible_on_screen_notifier_3d.cpp @@ -63,7 +63,7 @@ void VisibleOnScreenNotifier3D::set_aabb(const AABB &p_aabb) { RS::get_singleton()->visibility_notifier_set_aabb(get_base(), aabb); - update_gizmo(); + update_gizmos(); } AABB VisibleOnScreenNotifier3D::get_aabb() const { diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index bd47af8100..70a7021f22 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -238,8 +238,7 @@ bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> pinfo; RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - PropertyInfo pi = E->get(); + for (PropertyInfo &pi : pinfo) { bool has_def_value = false; Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); if (def_value.get_type() != Variant::NIL) { diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp index 3da59ac4c0..5cf7522667 100644 --- a/scene/3d/voxel_gi.cpp +++ b/scene/3d/voxel_gi.cpp @@ -265,7 +265,7 @@ Ref<VoxelGIData> VoxelGI::get_probe_data() const { void VoxelGI::set_subdiv(Subdiv p_subdiv) { ERR_FAIL_INDEX(p_subdiv, SUBDIV_MAX); subdiv = p_subdiv; - update_gizmo(); + update_gizmos(); } VoxelGI::Subdiv VoxelGI::get_subdiv() const { @@ -274,7 +274,7 @@ VoxelGI::Subdiv VoxelGI::get_subdiv() const { void VoxelGI::set_extents(const Vector3 &p_extents) { extents = p_extents; - update_gizmo(); + update_gizmos(); } Vector3 VoxelGI::get_extents() const { @@ -384,14 +384,14 @@ void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) { int pmc = 0; - for (List<PlotMesh>::Element *E = mesh_list.front(); E; E = E->next()) { + for (PlotMesh &E : mesh_list) { if (bake_step_function) { bake_step_function(pmc, RTR("Plotting Meshes") + " " + itos(pmc) + "/" + itos(mesh_list.size())); } pmc++; - baker.plot_mesh(E->get().local_xform, E->get().mesh, E->get().instance_materials, E->get().override_material); + baker.plot_mesh(E.local_xform, E.mesh, E.instance_materials, E.override_material); } if (bake_step_function) { bake_step_function(pmc++, RTR("Finishing Plot")); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 200a688067..4bddae3b14 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -1089,10 +1089,10 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons conns.resize(nc.size() * 3); int idx = 0; - for (List<NodeConnection>::Element *E = nc.front(); E; E = E->next()) { - conns[idx * 3 + 0] = E->get().input_node; - conns[idx * 3 + 1] = E->get().input_index; - conns[idx * 3 + 2] = E->get().output_node; + for (const NodeConnection &E : nc) { + conns[idx * 3 + 0] = E.input_node; + conns[idx * 3 + 1] = E.input_index; + conns[idx * 3 + 2] = E.output_node; idx++; } @@ -1110,8 +1110,8 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons } names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - String name = E->get(); + for (const StringName &E : names) { + String name = E; if (name != "output") { p_list->push_back(PropertyInfo(Variant::OBJECT, "nodes/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR)); } diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index b8980fd56b..56743007e4 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -252,8 +252,8 @@ void AnimationCache::set_all(float p_time, float p_delta) { List<int> indices; animation->value_track_get_key_indices(i, p_time, p_delta, &indices); - for (List<int>::Element *E = indices.front(); E; E = E->next()) { - Variant v = animation->track_get_key_value(i, E->get()); + for (int &E : indices) { + Variant v = animation->track_get_key_value(i, E); set_track_value(i, v); } } @@ -263,9 +263,9 @@ void AnimationCache::set_all(float p_time, float p_delta) { List<int> indices; animation->method_track_get_key_indices(i, p_time, p_delta, &indices); - for (List<int>::Element *E = indices.front(); E; E = E->next()) { - Vector<Variant> args = animation->method_track_get_params(i, E->get()); - StringName name = animation->method_track_get_name(i, E->get()); + for (int &E : indices) { + Vector<Variant> args = animation->method_track_get_params(i, E); + StringName name = animation->method_track_get_name(i, E); Callable::CallError err; if (!args.size()) { diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 6496331cb0..bf53b554bf 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -512,8 +512,8 @@ void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) c } advance_conditions.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = advance_conditions.front(); E; E = E->next()) { - r_list->push_back(PropertyInfo(Variant::BOOL, E->get())); + for (const StringName &E : advance_conditions) { + r_list->push_back(PropertyInfo(Variant::BOOL, E)); } } @@ -679,8 +679,8 @@ void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const { } nodes.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { - r_nodes->push_back(E->get()); + for (const StringName &E : nodes) { + r_nodes->push_back(E); } } @@ -902,8 +902,7 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c } names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - String name = E->get(); + for (const StringName &name : names) { p_list->push_back(PropertyInfo(Variant::OBJECT, "states/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::VECTOR2, "states/" + name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 14ca325c25..67b6205a65 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -176,8 +176,8 @@ void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const { anim_names.sort(); - for (List<PropertyInfo>::Element *E = anim_names.front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (const PropertyInfo &E : anim_names) { + p_list->push_back(E); } p_list->push_back(PropertyInfo(Variant::ARRAY, "blend_times", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); @@ -485,8 +485,8 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float List<int> indices; a->value_track_get_key_indices(i, p_time, p_delta, &indices); - for (List<int>::Element *F = indices.front(); F; F = F->next()) { - Variant value = a->track_get_key_value(i, F->get()); + for (int &F : indices) { + Variant value = a->track_get_key_value(i, F); switch (pa->special) { case SP_NONE: { bool valid; @@ -544,9 +544,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float a->method_track_get_key_indices(i, p_time, p_delta, &indices); - for (List<int>::Element *E = indices.front(); E; E = E->next()) { - StringName method = a->method_track_get_name(i, E->get()); - Vector<Variant> params = a->method_track_get_params(i, E->get()); + for (int &E : indices) { + StringName method = a->method_track_get_name(i, E); + Vector<Variant> params = a->method_track_get_params(i, E); int s = params.size(); @@ -1076,8 +1076,8 @@ void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const { anims.sort(); - for (List<String>::Element *E = anims.front(); E; E = E->next()) { - p_animations->push_back(E->get()); + for (const String &E : anims) { + p_animations->push_back(E); } } @@ -1118,8 +1118,8 @@ void AnimationPlayer::queue(const StringName &p_name) { Vector<String> AnimationPlayer::get_queue() { Vector<String> ret; - for (List<StringName>::Element *E = queued.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const StringName &E : queued) { + ret.push_back(E); } return ret; @@ -1502,8 +1502,8 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i if (p_idx == 0 && (p_function == "play" || p_function == "play_backwards" || p_function == "remove_animation" || p_function == "has_animation" || p_function == "queue")) { List<StringName> al; get_animation_list(&al); - for (List<StringName>::Element *E = al.front(); E; E = E->next()) { - r_options->push_back(quote_style + String(E->get()) + quote_style); + for (const StringName &E : al) { + r_options->push_back(quote_style + String(E) + quote_style); } } Node::get_argument_options(p_function, p_idx, r_options); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 72448fc4f7..00b847168d 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -76,10 +76,10 @@ void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) { Dictionary cn = get_script_instance()->call("_get_child_nodes"); List<Variant> keys; cn.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (const Variant &E : keys) { ChildNode child; - child.name = E->get(); - child.node = cn[E->get()]; + child.name = E; + child.node = cn[E]; r_child_nodes->push_back(child); } } @@ -536,8 +536,8 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { List<StringName> sname; player->get_animation_list(&sname); - for (List<StringName>::Element *E = sname.front(); E; E = E->next()) { - Ref<Animation> anim = player->get_animation(E->get()); + for (const StringName &E : sname) { + Ref<Animation> anim = player->get_animation(E); for (int i = 0; i < anim->get_track_count(); i++) { NodePath path = anim->track_get_path(i); Animation::TrackType track_type = anim->track_get_type(i); @@ -561,7 +561,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { Node *child = parent->get_node_and_resource(path, resource, leftover_path); if (!child) { - ERR_PRINT("AnimationTree: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'"); + ERR_PRINT("AnimationTree: '" + String(E) + "', couldn't resolve track: '" + String(path) + "'"); continue; } @@ -590,7 +590,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { Node3D *node_3d = Object::cast_to<Node3D>(child); if (!node_3d) { - ERR_PRINT("AnimationTree: '" + String(E->get()) + "', transform track does not point to Node3D: '" + String(path) + "'"); + ERR_PRINT("AnimationTree: '" + String(E) + "', transform track does not point to Node3D: '" + String(path) + "'"); continue; } @@ -816,9 +816,7 @@ void AnimationTree::_process_graph(float p_delta) { { bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint(); - for (List<AnimationNode::AnimationState>::Element *E = state.animation_states.front(); E; E = E->next()) { - const AnimationNode::AnimationState &as = E->get(); - + for (const AnimationNode::AnimationState &as : state.animation_states) { Ref<Animation> a = as.animation; float time = as.time; float delta = as.delta; @@ -962,8 +960,8 @@ void AnimationTree::_process_graph(float p_delta) { List<int> indices; a->value_track_get_key_indices(i, time, delta, &indices); - for (List<int>::Element *F = indices.front(); F; F = F->next()) { - Variant value = a->track_get_key_value(i, F->get()); + for (int &F : indices) { + Variant value = a->track_get_key_value(i, F); t->object->set_indexed(t->subpath, value); } } @@ -979,9 +977,9 @@ void AnimationTree::_process_graph(float p_delta) { a->method_track_get_key_indices(i, time, delta, &indices); - for (List<int>::Element *F = indices.front(); F; F = F->next()) { - StringName method = a->method_track_get_name(i, F->get()); - Vector<Variant> params = a->method_track_get_params(i, F->get()); + for (int &F : indices) { + StringName method = a->method_track_get_name(i, F); + Vector<Variant> params = a->method_track_get_params(i, F); int s = params.size(); @@ -1355,9 +1353,7 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A List<PropertyInfo> plist; node->get_parameter_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - PropertyInfo pinfo = E->get(); - + for (PropertyInfo &pinfo : plist) { StringName key = pinfo.name; if (!property_map.has(p_base_path + key)) { @@ -1373,8 +1369,8 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A List<AnimationNode::ChildNode> children; node->get_child_nodes(&children); - for (List<AnimationNode::ChildNode>::Element *E = children.front(); E; E = E->next()) { - _update_properties_for_node(p_base_path + E->get().name + "/", E->get().node); + for (const AnimationNode::ChildNode &E : children) { + _update_properties_for_node(p_base_path + E.name + "/", E.node); } } @@ -1428,17 +1424,17 @@ void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const { const_cast<AnimationTree *>(this)->_update_properties(); } - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (const PropertyInfo &E : properties) { + p_list->push_back(E); } } void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) { //rename values first - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (E->get().name.begins_with(p_base)) { - String new_name = E->get().name.replace_first(p_base, p_new_base); - property_map[new_name] = property_map[E->get().name]; + for (const PropertyInfo &E : properties) { + if (E.name.begins_with(p_base)) { + String new_name = E.name.replace_first(p_base, p_new_base); + property_map[new_name] = property_map[E.name]; } } diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 761046c14a..b31c3d57f9 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -46,8 +46,8 @@ void Tween::start_tweeners() { ERR_FAIL_MSG("Tween without commands, aborting."); } - for (List<Ref<Tweener>>::Element *E = tweeners.write[current_step].front(); E; E = E->next()) { - E->get()->start(); + for (Ref<Tweener> E : tweeners.write[current_step]) { + E->start(); } } @@ -253,11 +253,11 @@ bool Tween::step(float p_delta) { float step_delta = rem_delta; step_active = false; - for (List<Ref<Tweener>>::Element *E = tweeners.write[current_step].front(); E; E = E->next()) { + for (Ref<Tweener> E : tweeners.write[current_step]) { // Modified inside Tweener.step(). float temp_delta = rem_delta; // Turns to true if any Tweener returns true (i.e. is still not finished). - step_active = E->get()->step(temp_delta) || step_active; + step_active = E->step(temp_delta) || step_active; step_delta = MIN(temp_delta, rem_delta); } diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index fd5637be11..ce2b320c96 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -292,9 +292,9 @@ SceneDebuggerObject::SceneDebuggerObject(ObjectID p_id) { // Add base object properties. List<PropertyInfo> pinfo; obj->get_property_list(&pinfo, true); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { - properties.push_back(SceneDebuggerProperty(E->get(), obj->get(E->get().name))); + for (const PropertyInfo &E : pinfo) { + if (E.usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { + properties.push_back(SceneDebuggerProperty(E, obj->get(E.name))); } } } @@ -452,8 +452,7 @@ SceneDebuggerTree::SceneDebuggerTree(Node *p_root) { } void SceneDebuggerTree::serialize(Array &p_arr) { - for (List<RemoteNode>::Element *E = nodes.front(); E; E = E->next()) { - RemoteNode &n = E->get(); + for (const RemoteNode &n : nodes) { p_arr.push_back(n.child_count); p_arr.push_back(n.name); p_arr.push_back(n.type_name); diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index f302f64224..be5e0bf4e5 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -2128,7 +2128,7 @@ int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) c int region = (p_line <= 0 || delimiter_cache[p_line - 1].size() < 1) ? -1 : delimiter_cache[p_line - 1].back()->value(); bool in_region = region != -1 && delimiters[region].type == p_type; for (Map<int, int>::Element *E = delimiter_cache[p_line].front(); E; E = E->next()) { - /* If column is specified, loop untill the key is larger then the column. */ + /* If column is specified, loop until the key is larger then the column. */ if (p_column != -1) { if (E->key() > p_column) { break; @@ -2138,7 +2138,7 @@ int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) c continue; } - /* If no column, calulate if the entire line is a region */ + /* If no column, calculate if the entire line is a region */ /* excluding whitespace. */ const String line = get_line(p_line); if (!in_region) { @@ -2288,14 +2288,14 @@ void CodeEdit::_filter_code_completion_candidates() { TypedArray<Dictionary> completion_options_sources; completion_options_sources.resize(code_completion_option_sources.size()); int i = 0; - for (List<ScriptCodeCompletionOption>::Element *E = code_completion_option_sources.front(); E; E = E->next()) { + for (const ScriptCodeCompletionOption &E : code_completion_option_sources) { Dictionary option; - option["kind"] = E->get().kind; - option["display_text"] = E->get().display; - option["insert_text"] = E->get().insert_text; - option["font_color"] = E->get().font_color; - option["icon"] = E->get().icon; - option["default_value"] = E->get().default_value; + option["kind"] = E.kind; + option["display_text"] = E.display; + option["insert_text"] = E.insert_text; + option["font_color"] = E.font_color; + option["icon"] = E.icon; + option["default_value"] = E.default_value; completion_options_sources[i] = option; i++; } @@ -2406,9 +2406,7 @@ void CodeEdit::_filter_code_completion_candidates() { int max_width = 0; String string_to_complete_lower = string_to_complete.to_lower(); - for (List<ScriptCodeCompletionOption>::Element *E = code_completion_option_sources.front(); E; E = E->next()) { - ScriptCodeCompletionOption &option = E->get(); - + for (ScriptCodeCompletionOption &option : code_completion_option_sources) { if (single_quote && option.display.is_quoted()) { option.display = option.display.unquote().quote("'"); } @@ -2527,8 +2525,7 @@ void CodeEdit::_lines_edited_from(int p_from_line, int p_to_line) { int line_count = (p_to_line - p_from_line); List<int> breakpoints; breakpointed_lines.get_key_list(&breakpoints); - for (const List<int>::Element *E = breakpoints.front(); E; E = E->next()) { - int line = E->get(); + for (const int line : breakpoints) { if (line <= from_line) { continue; } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 032533d4a9..c19ee849d3 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -343,73 +343,73 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { { List<StringName> names; theme->get_icon_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.icon_override.has(E->get())) { + if (data.icon_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage)); } } { List<StringName> names; theme->get_stylebox_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.style_override.has(E->get())) { + if (data.style_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage)); } } { List<StringName> names; theme->get_font_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.font_override.has(E->get())) { + if (data.font_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Font", usage)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage)); } } { List<StringName> names; theme->get_font_size_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.font_size_override.has(E->get())) { + if (data.font_size_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::INT, "custom_font_sizes/" + E->get(), PROPERTY_HINT_NONE, "", usage)); + p_list->push_back(PropertyInfo(Variant::INT, "custom_font_sizes/" + E, PROPERTY_HINT_NONE, "", usage)); } } { List<StringName> names; theme->get_color_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.color_override.has(E->get())) { + if (data.color_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E->get(), PROPERTY_HINT_NONE, "", usage)); + p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E, PROPERTY_HINT_NONE, "", usage)); } } { List<StringName> names; theme->get_constant_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.constant_override.has(E->get())) { + if (data.constant_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E->get(), PROPERTY_HINT_RANGE, "-16384,16384", usage)); + p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E, PROPERTY_HINT_RANGE, "-16384,16384", usage)); } } } @@ -428,14 +428,14 @@ void Control::_validate_property(PropertyInfo &property) const { Vector<StringName> unique_names; String hint_string; - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { // Skip duplicate values. - if (unique_names.has(E->get())) { + if (unique_names.has(E)) { continue; } - hint_string += String(E->get()) + ","; - unique_names.append(E->get()); + hint_string += String(E) + ","; + unique_names.append(E); } property.hint_string = hint_string; @@ -454,6 +454,8 @@ void Control::set_layout_direction(Control::LayoutDirection p_direction) { ERR_FAIL_INDEX((int)p_direction, 4); data.layout_dir = p_direction; + data.is_rtl_dirty = true; + propagate_notification(NOTIFICATION_LAYOUT_DIRECTION_CHANGED); } @@ -462,29 +464,35 @@ Control::LayoutDirection Control::get_layout_direction() const { } bool Control::is_layout_rtl() const { - if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { - Window *parent_window = get_parent_window(); - Control *parent_control = get_parent_control(); - if (parent_control) { - return parent_control->is_layout_rtl(); - } else if (parent_window) { - return parent_window->is_layout_rtl(); - } else { + if (data.is_rtl_dirty) { + const_cast<Control *>(this)->data.is_rtl_dirty = false; + if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { + Window *parent_window = get_parent_window(); + Control *parent_control = get_parent_control(); + if (parent_control) { + const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl(); + } else if (parent_window) { + const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl(); + } else { + if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + } + } + } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - return true; + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); } - String locale = TranslationServer::get_singleton()->get_tool_locale(); - return TS->is_locale_right_to_left(locale); - } - } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { - if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - return true; + } else { + const_cast<Control *>(this)->data.is_rtl = (data.layout_dir == LAYOUT_DIRECTION_RTL); } - String locale = TranslationServer::get_singleton()->get_tool_locale(); - return TS->is_locale_right_to_left(locale); - } else { - return (data.layout_dir == LAYOUT_DIRECTION_RTL); } + return data.is_rtl; } void Control::_clear_size_warning() { @@ -534,6 +542,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_POST_ENTER_TREE: { data.minimum_size_valid = false; + data.is_rtl_dirty = true; _size_changed(); } break; case NOTIFICATION_EXIT_TREE: { @@ -548,6 +557,7 @@ void Control::_notification(int p_notification) { case NOTIFICATION_ENTER_CANVAS: { data.parent = Object::cast_to<Control>(get_parent()); data.parent_window = Object::cast_to<Window>(get_parent()); + data.is_rtl_dirty = true; Node *parent = this; //meh Control *parent_control = nullptr; @@ -613,6 +623,7 @@ void Control::_notification(int p_notification) { data.parent = nullptr; data.parent_canvas_item = nullptr; data.parent_window = nullptr; + data.is_rtl_dirty = true; } break; case NOTIFICATION_MOVED_IN_PARENT: { @@ -672,6 +683,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + data.is_rtl_dirty = true; _size_changed(); } break; } @@ -793,13 +805,13 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E->get())) { - return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E->get()); + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); } - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E->get())) { - return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E->get()); + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); } } @@ -822,17 +834,17 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E->get())) { - return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E->get()); + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E); } } } // Lastly, fall back on the items defined in the default Theme, if they exist. - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E->get())) { - return Theme::get_default()->get_theme_item(p_data_type, p_name, E->get()); + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_default()->get_theme_item(p_data_type, p_name, E); } } // If they don't exist, use any type to return the default/empty value. @@ -848,12 +860,12 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E->get())) { + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { return true; } - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E->get())) { + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { return true; } } @@ -877,16 +889,16 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E->get())) { + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { return true; } } } // Lastly, fall back on the items defined in the default Theme, if they exist. - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E->get())) { + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { return true; } } @@ -1594,7 +1606,7 @@ void Control::set_rect(const Rect2 &p_rect) { void Control::_set_size(const Size2 &p_size) { #ifdef DEBUG_ENABLED if (data.size_warning && (data.anchor[SIDE_LEFT] != data.anchor[SIDE_RIGHT] || data.anchor[SIDE_TOP] != data.anchor[SIDE_BOTTOM])) { - WARN_PRINT("Nodes with non-equal opposite anchors will have their size overriden after _ready(). \nIf you want to set size, change the anchors or consider using set_deferred()."); + WARN_PRINT("Nodes with non-equal opposite anchors will have their size overridden after _ready(). \nIf you want to set size, change the anchors or consider using set_deferred()."); } #endif set_size(p_size); @@ -2580,8 +2592,8 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List } sn.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - r_options->push_back(quote_style + E->get() + quote_style); + for (const StringName &E : sn) { + r_options->push_back(quote_style + E + quote_style); } } } diff --git a/scene/gui/control.h b/scene/gui/control.h index 51b454b334..3779f9b308 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -179,6 +179,8 @@ private: GrowDirection v_grow = GROW_DIRECTION_END; LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; + bool is_rtl_dirty = true; + bool is_rtl = false; real_t rotation = 0.0; Vector2 scale = Vector2(1, 1); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 9ed3a2244e..2e4204e171 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -552,9 +552,9 @@ void FileDialog::update_file_list() { bool match = patterns.is_empty(); String match_str; - for (List<String>::Element *E = patterns.front(); E; E = E->next()) { - if (files.front()->get().matchn(E->get())) { - match_str = E->get(); + for (const String &E : patterns) { + if (files.front()->get().matchn(E)) { + match_str = E; match = true; break; } diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 2281fb19c6..1fac2b9129 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -217,8 +217,8 @@ Error GraphEdit::connect_node(const StringName &p_from, int p_from_port, const S } bool GraphEdit::is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port) { - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) { + for (const Connection &E : connections) { + if (E.from == p_from && E.from_port == p_from_port && E.to == p_to && E.to_port == p_to_port) { return true; } } @@ -227,7 +227,7 @@ bool GraphEdit::is_node_connected(const StringName &p_from, int p_from_port, con } void GraphEdit::disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port) { - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { + for (const List<Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) { connections.erase(E); top_layer->update(); @@ -561,20 +561,20 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { if (is_in_hot_zone(pos / zoom, click_pos)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - if (E->get().from == gn->get_name() && E->get().from_port == j) { - Node *to = get_node(String(E->get().to)); + for (const Connection &E : connections) { + if (E.from == gn->get_name() && E.from_port == j) { + Node *to = get_node(String(E.to)); if (Object::cast_to<GraphNode>(to)) { - connecting_from = E->get().to; - connecting_index = E->get().to_port; + connecting_from = E.to; + connecting_index = E.to_port; connecting_out = false; - connecting_type = Object::cast_to<GraphNode>(to)->get_connection_input_type(E->get().to_port); - connecting_color = Object::cast_to<GraphNode>(to)->get_connection_input_color(E->get().to_port); + connecting_type = Object::cast_to<GraphNode>(to)->get_connection_input_type(E.to_port); + connecting_color = Object::cast_to<GraphNode>(to)->get_connection_input_color(E.to_port); connecting_target = false; connecting_to = pos; just_disconnected = true; - emit_signal(SNAME("disconnection_request"), E->get().from, E->get().from_port, E->get().to, E->get().to_port); + emit_signal(SNAME("disconnection_request"), E.from, E.from_port, E.to, E.to_port); to = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(to)) { connecting = true; @@ -603,20 +603,20 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { if (is_in_hot_zone(pos / zoom, click_pos)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - if (E->get().to == gn->get_name() && E->get().to_port == j) { - Node *fr = get_node(String(E->get().from)); + for (const Connection &E : connections) { + if (E.to == gn->get_name() && E.to_port == j) { + Node *fr = get_node(String(E.from)); if (Object::cast_to<GraphNode>(fr)) { - connecting_from = E->get().from; - connecting_index = E->get().from_port; + connecting_from = E.from; + connecting_index = E.from_port; connecting_out = true; - connecting_type = Object::cast_to<GraphNode>(fr)->get_connection_output_type(E->get().from_port); - connecting_color = Object::cast_to<GraphNode>(fr)->get_connection_output_color(E->get().from_port); + connecting_type = Object::cast_to<GraphNode>(fr)->get_connection_output_type(E.from_port); + connecting_color = Object::cast_to<GraphNode>(fr)->get_connection_output_color(E.from_port); connecting_target = false; connecting_to = pos; just_disconnected = true; - emit_signal(SNAME("disconnection_request"), E->get().from, E->get().from_port, E->get().to, E->get().to_port); + emit_signal(SNAME("disconnection_request"), E.from, E.from_port, E.to, E.to_port); fr = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(fr)) { connecting = true; @@ -1001,8 +1001,8 @@ void GraphEdit::_minimap_draw() { // Draw node connections. Color activity_color = get_theme_color(SNAME("activity")); - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - NodePath fromnp(E->get().from); + for (const Connection &E : connections) { + NodePath fromnp(E.from); Node *from = get_node(fromnp); if (!from) { @@ -1013,7 +1013,7 @@ void GraphEdit::_minimap_draw() { continue; } - NodePath tonp(E->get().to); + NodePath tonp(E.to); Node *to = get_node(tonp); if (!to) { continue; @@ -1023,16 +1023,16 @@ void GraphEdit::_minimap_draw() { continue; } - Vector2 from_slot_position = gfrom->get_position_offset() * zoom + gfrom->get_connection_output_position(E->get().from_port); + Vector2 from_slot_position = gfrom->get_position_offset() * zoom + gfrom->get_connection_output_position(E.from_port); Vector2 from_position = minimap->_convert_from_graph_position(from_slot_position - graph_offset) + minimap_offset; - Color from_color = gfrom->get_connection_output_color(E->get().from_port); - Vector2 to_slot_position = gto->get_position_offset() * zoom + gto->get_connection_input_position(E->get().to_port); + Color from_color = gfrom->get_connection_output_color(E.from_port); + Vector2 to_slot_position = gto->get_position_offset() * zoom + gto->get_connection_input_position(E.to_port); Vector2 to_position = minimap->_convert_from_graph_position(to_slot_position - graph_offset) + minimap_offset; - Color to_color = gto->get_connection_input_color(E->get().to_port); + Color to_color = gto->get_connection_input_color(E.to_port); - if (E->get().activity > 0) { - from_color = from_color.lerp(activity_color, E->get().activity); - to_color = to_color.lerp(activity_color, E->get().activity); + if (E.activity > 0) { + from_color = from_color.lerp(activity_color, E.activity); + to_color = to_color.lerp(activity_color, E.activity); } _draw_cos_line(minimap, from_position, to_position, from_color, to_color, 1.0, 0.5); } @@ -1360,15 +1360,15 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { } void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity) { - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) { - if (Math::is_equal_approx(E->get().activity, p_activity)) { + for (Connection &E : connections) { + if (E.from == p_from && E.from_port == p_from_port && E.to == p_to && E.to_port == p_to_port) { + if (Math::is_equal_approx(E.activity, p_activity)) { //update only if changed top_layer->update(); minimap->update(); connections_layer->update(); } - E->get().activity = p_activity; + E.activity = p_activity; return; } } @@ -1500,12 +1500,12 @@ Array GraphEdit::_get_connection_list() const { List<Connection> conns; get_connection_list(&conns); Array arr; - for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { + for (const Connection &E : conns) { Dictionary d; - d["from"] = E->get().from; - d["from_port"] = E->get().from_port; - d["to"] = E->get().to; - d["to_port"] = E->get().to_port; + d["from"] = E.from; + d["from_port"] = E.from_port; + d["to"] = E.to; + d["to_port"] = E.to_port; arr.push_back(d); } return arr; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 1e9baa77fc..73034dee5a 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -55,6 +55,11 @@ void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) { } } +void MenuButton::_popup_visibility_changed(bool p_visible) { + set_pressed(p_visible); + set_process_internal(p_visible); +} + void MenuButton::pressed() { Size2 size = get_size(); @@ -94,10 +99,26 @@ bool MenuButton::is_switch_on_hover() { } void MenuButton::_notification(int p_what) { - if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - if (!is_visible_in_tree()) { - popup->hide(); - } + switch (p_what) { + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible_in_tree()) { + popup->hide(); + } + } break; + case NOTIFICATION_INTERNAL_PROCESS: { + if (switch_on_hover) { + Window *window = Object::cast_to<Window>(get_viewport()); + if (window) { + Vector2i mouse_pos = DisplayServer::get_singleton()->mouse_get_position() - window->get_position(); + MenuButton *menu_btn_other = Object::cast_to<MenuButton>(window->gui_find_control(mouse_pos)); + if (menu_btn_other && menu_btn_other != this && menu_btn_other->is_switch_on_hover() && !menu_btn_other->is_disabled() && + (get_parent()->is_ancestor_of(menu_btn_other) || menu_btn_other->get_parent()->is_ancestor_of(popup))) { + popup->hide(); + menu_btn_other->pressed(); + } + } + } + } break; } } @@ -130,8 +151,8 @@ MenuButton::MenuButton() { popup = memnew(PopupMenu); popup->hide(); add_child(popup); - popup->connect("about_to_popup", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(true)); // For when switching from another MenuButton. - popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false)); + popup->connect("about_to_popup", callable_mp(this, &MenuButton::_popup_visibility_changed), varray(true)); + popup->connect("popup_hide", callable_mp(this, &MenuButton::_popup_visibility_changed), varray(false)); } MenuButton::~MenuButton() { diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index fd9ae6021e..301769b008 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -47,6 +47,8 @@ class MenuButton : public Button { void _gui_input(Ref<InputEvent> p_event) override; + void _popup_visibility_changed(bool p_visible); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index ee9e0e8ab8..7790a0970c 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -397,17 +397,17 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { - if (!item_clickable_area.has_point(m->get_position())) { - return; - } - - for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) { - if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E->get().has_point(m->get_position())) { + for (const Rect2 &E : autohide_areas) { + if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E.has_point(m->get_position())) { _close_pressed(); return; } } + if (!item_clickable_area.has_point(m->get_position())) { + return; + } + int over = _get_mouse_over(m->get_position()); int id = (over < 0 || items[over].separator || items[over].disabled) ? -1 : (items[over].id >= 0 ? items[over].id : over); @@ -747,12 +747,12 @@ void PopupMenu::_notification(int p_what) { } break; case NOTIFICATION_INTERNAL_PROCESS: { //only used when using operating system windows - if (get_window_id() != DisplayServer::INVALID_WINDOW_ID && autohide_areas.size()) { + if (!is_embedded() && autohide_areas.size()) { Point2 mouse_pos = DisplayServer::get_singleton()->mouse_get_position(); mouse_pos -= get_position(); - for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) { - if (!Rect2(Point2(), get_size()).has_point(mouse_pos) && E->get().has_point(mouse_pos)) { + for (const Rect2 &E : autohide_areas) { + if (!Rect2(Point2(), get_size()).has_point(mouse_pos) && E.has_point(mouse_pos)) { _close_pressed(); return; } @@ -786,7 +786,7 @@ void PopupMenu::_notification(int p_what) { set_process_internal(false); } else { - if (get_window_id() != DisplayServer::INVALID_WINDOW_ID) { + if (!is_embedded()) { set_process_internal(true); } diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 74718395d3..aedc5d0155 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -140,7 +140,6 @@ class PopupMenu : public Popup { void _close_pressed(); protected: - friend class MenuButton; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 99395aae30..3925e0c38e 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -238,9 +238,9 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> } int idx = 0; - for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { - ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. - ItemFrame *frame = static_cast<ItemFrame *>(E->get()); + for (Item *E : table->subitems) { + ERR_CONTINUE(E->type != ITEM_FRAME); // Children should all be frames. + ItemFrame *frame = static_cast<ItemFrame *>(E); for (int i = 0; i < frame->lines.size(); i++) { _resize_line(frame, i, p_base_font, p_base_font_size, 1); } @@ -316,9 +316,9 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> Vector2 offset; float row_height = 0.0; - for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { - ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. - ItemFrame *frame = static_cast<ItemFrame *>(E->get()); + for (Item *E : table->subitems) { + ERR_CONTINUE(E->type != ITEM_FRAME); // Children should all be frames. + ItemFrame *frame = static_cast<ItemFrame *>(E); int column = idx % col_count; @@ -472,9 +472,9 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> const int available_width = p_width - hseparation * (col_count - 1); int idx = 0; - for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { - ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. - ItemFrame *frame = static_cast<ItemFrame *>(E->get()); + for (Item *E : table->subitems) { + ERR_CONTINUE(E->type != ITEM_FRAME); // Children should all be frames. + ItemFrame *frame = static_cast<ItemFrame *>(E); int column = idx % col_count; for (int i = 0; i < frame->lines.size(); i++) { @@ -556,7 +556,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> Vector2 offset; float row_height = 0.0; - for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { + for (const List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. ItemFrame *frame = static_cast<ItemFrame *>(E->get()); @@ -783,8 +783,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o int row_count = table->rows.size(); int idx = 0; - for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { - ItemFrame *frame = static_cast<ItemFrame *>(E->get()); + for (Item *E : table->subitems) { + ItemFrame *frame = static_cast<ItemFrame *>(E); int col = idx % col_count; int row = idx / col_count; @@ -1203,8 +1203,8 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V int col_count = table->columns.size(); int row_count = table->rows.size(); - for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { - ItemFrame *frame = static_cast<ItemFrame *>(E->get()); + for (Item *E : table->subitems) { + ItemFrame *frame = static_cast<ItemFrame *>(E); int col = idx % col_count; int row = idx / col_count; @@ -2080,8 +2080,8 @@ bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) { return true; } - for (List<Item *>::Element *E = from->subitems.front(); E; E = E->next()) { - bool layout = _find_layout_subitem(E->get(), to); + for (Item *E : from->subitems) { + bool layout = _find_layout_subitem(E, to); if (layout) { return true; @@ -3448,8 +3448,8 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { } Vector<ItemFX *> fx_items; - for (List<Item *>::Element *E = main->subitems.front(); E; E = E->next()) { - Item *subitem = static_cast<Item *>(E->get()); + for (Item *E : main->subitems) { + Item *subitem = static_cast<Item *>(E); _fetch_item_fx_stack(subitem, fx_items); if (fx_items.size()) { @@ -3719,9 +3719,9 @@ String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p ItemTable *table = static_cast<ItemTable *>(it); int idx = 0; int col_count = table->columns.size(); - for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { - ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. - ItemFrame *frame = static_cast<ItemFrame *>(E->get()); + for (Item *E : table->subitems) { + ERR_CONTINUE(E->type != ITEM_FRAME); // Children should all be frames. + ItemFrame *frame = static_cast<ItemFrame *>(E); int column = idx % col_count; for (int i = 0; i < frame->lines.size(); i++) { diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 5a12480577..0a76351885 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -956,8 +956,7 @@ void CanvasItem::_notify_transform(CanvasItem *p_node) { } } - for (List<CanvasItem *>::Element *E = p_node->children_items.front(); E; E = E->next()) { - CanvasItem *ci = E->get(); + for (CanvasItem *ci : p_node->children_items) { if (ci->top_level) { continue; } @@ -1334,9 +1333,9 @@ void CanvasItem::_update_texture_filter_changed(bool p_propagate) { update(); if (p_propagate) { - for (List<CanvasItem *>::Element *E = children_items.front(); E; E = E->next()) { - if (!E->get()->top_level && E->get()->texture_filter == TEXTURE_FILTER_PARENT_NODE) { - E->get()->_update_texture_filter_changed(true); + for (CanvasItem *E : children_items) { + if (!E->top_level && E->texture_filter == TEXTURE_FILTER_PARENT_NODE) { + E->_update_texture_filter_changed(true); } } } @@ -1374,9 +1373,9 @@ void CanvasItem::_update_texture_repeat_changed(bool p_propagate) { RS::get_singleton()->canvas_item_set_default_texture_repeat(get_canvas_item(), texture_repeat_cache); update(); if (p_propagate) { - for (List<CanvasItem *>::Element *E = children_items.front(); E; E = E->next()) { - if (!E->get()->top_level && E->get()->texture_repeat == TEXTURE_REPEAT_PARENT_NODE) { - E->get()->_update_texture_repeat_changed(true); + for (CanvasItem *E : children_items) { + if (!E->top_level && E->texture_repeat == TEXTURE_REPEAT_PARENT_NODE) { + E->_update_texture_repeat_changed(true); } } } diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index f649380afa..2c6cefa771 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -220,8 +220,8 @@ bool HTTPRequest::_handle_response(bool *ret_value) { client->get_response_headers(&rheaders); response_headers.resize(0); downloaded.set(0); - for (List<String>::Element *E = rheaders.front(); E; E = E->next()) { - response_headers.push_back(E->get()); + for (const String &E : rheaders) { + response_headers.push_back(E); } if (response_code == 301 || response_code == 302) { @@ -235,9 +235,9 @@ bool HTTPRequest::_handle_response(bool *ret_value) { String new_request; - for (List<String>::Element *E = rheaders.front(); E; E = E->next()) { - if (E->get().findn("Location: ") != -1) { - new_request = E->get().substr(9, E->get().length()).strip_edges(); + for (const String &E : rheaders) { + if (E.findn("Location: ") != -1) { + new_request = E.substr(9, E.length()).strip_edges(); } } diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp index 89dac5f5a8..b5ba1899ec 100644 --- a/scene/main/instance_placeholder.cpp +++ b/scene/main/instance_placeholder.cpp @@ -42,9 +42,9 @@ bool InstancePlaceholder::_set(const StringName &p_name, const Variant &p_value) } bool InstancePlaceholder::_get(const StringName &p_name, Variant &r_ret) const { - for (const List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) { - if (E->get().name == p_name) { - r_ret = E->get().value; + for (const PropSet &E : stored_values) { + if (E.name == p_name) { + r_ret = E.value; return true; } } @@ -52,10 +52,10 @@ bool InstancePlaceholder::_get(const StringName &p_name, Variant &r_ret) const { } void InstancePlaceholder::_get_property_list(List<PropertyInfo> *p_list) const { - for (const List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) { + for (const PropSet &E : stored_values) { PropertyInfo pi; - pi.name = E->get().name; - pi.type = E->get().value.get_type(); + pi.name = E.name; + pi.type = E.value.get_type(); pi.usage = PROPERTY_USAGE_STORAGE; p_list->push_back(pi); @@ -95,8 +95,8 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene scene->set_name(get_name()); int pos = get_index(); - for (List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) { - scene->set(E->get().name, E->get().value); + for (const PropSet &E : stored_values) { + scene->set(E.name, E.value); } if (p_replace) { @@ -114,10 +114,10 @@ Dictionary InstancePlaceholder::get_stored_values(bool p_with_order) { Dictionary ret; PackedStringArray order; - for (List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) { - ret[E->get().name] = E->get().value; + for (const PropSet &E : stored_values) { + ret[E.name] = E.value; if (p_with_order) { - order.push_back(E->get().name); + order.push_back(E.name); } }; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 0d060240de..f1e5574351 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1597,8 +1597,8 @@ Array Node::_get_groups() const { Array groups; List<GroupInfo> gi; get_groups(&gi); - for (List<GroupInfo>::Element *E = gi.front(); E; E = E->next()) { - groups.push_back(E->get().name); + for (const GroupInfo &E : gi) { + groups.push_back(E.name); } return groups; @@ -1947,18 +1947,18 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const List<PropertyInfo> plist; N->get()->get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - String name = E->get().name; + String name = E.name; if (name == script_property_name) { continue; } Variant value = N->get()->get(name).duplicate(true); - if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) { + if (E.usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) { Resource *res = Object::cast_to<Resource>(value); if (res) { // Duplicate only if it's a resource current_node->set(name, res->duplicate()); @@ -1983,14 +1983,14 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const if (p_flags & DUPLICATE_GROUPS) { List<GroupInfo> gi; get_groups(&gi); - for (List<GroupInfo>::Element *E = gi.front(); E; E = E->next()) { + for (const GroupInfo &E : gi) { #ifdef TOOLS_ENABLED - if ((p_flags & DUPLICATE_FROM_EDITOR) && !E->get().persistent) { + if ((p_flags & DUPLICATE_FROM_EDITOR) && !E.persistent) { continue; } #endif - node->add_to_group(E->get().name, E->get().persistent); + node->add_to_group(E.name, E.persistent); } } @@ -2014,21 +2014,21 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } } - for (List<const Node *>::Element *E = hidden_roots.front(); E; E = E->next()) { - Node *parent = node->get_node(get_path_to(E->get()->data.parent)); + for (const Node *&E : hidden_roots) { + Node *parent = node->get_node(get_path_to(E->data.parent)); if (!parent) { memdelete(node); return nullptr; } - Node *dup = E->get()->_duplicate(p_flags, r_duplimap); + Node *dup = E->_duplicate(p_flags, r_duplimap); if (!dup) { memdelete(node); return nullptr; } parent->add_child(dup); - int pos = E->get()->get_index(); + int pos = E->get_index(); if (pos < parent->get_child_count() - 1) { parent->move_child(dup, pos); @@ -2073,17 +2073,17 @@ void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_re List<PropertyInfo> props; p_node->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant v = p_node->get(E->get().name); + Variant v = p_node->get(E.name); if (v.is_ref()) { RES res = v; if (res.is_valid()) { if (p_resource_remap.has(res)) { - p_node->set(E->get().name, p_resource_remap[res]); + p_node->set(E.name, p_resource_remap[res]); remap_nested_resources(res, p_resource_remap); } } @@ -2099,17 +2099,17 @@ void Node::remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resourc List<PropertyInfo> props; p_resource->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant v = p_resource->get(E->get().name); + Variant v = p_resource->get(E.name); if (v.is_ref()) { RES res = v; if (res.is_valid()) { if (p_resource_remap.has(res)) { - p_resource->set(E->get().name, p_resource_remap[res]); + p_resource->set(E.name, p_resource_remap[res]); remap_nested_resources(res, p_resource_remap); } } @@ -2135,13 +2135,13 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { List<Connection> conns; n->get_all_signal_connections(&conns); - for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().flags & CONNECT_PERSIST) { + for (const Connection &E : conns) { + if (E.flags & CONNECT_PERSIST) { //user connected NodePath p = p_original->get_path_to(n); Node *copy = p_copy->get_node(p); - Node *target = Object::cast_to<Node>(E->get().callable.get_object()); + Node *target = Object::cast_to<Node>(E.callable.get_object()); if (!target) { continue; } @@ -2158,9 +2158,9 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { } if (copy && copytarget) { - const Callable copy_callable = Callable(copytarget, E->get().callable.get_method()); - if (!copy->is_connected(E->get().signal.get_name(), copy_callable)) { - copy->connect(E->get().signal.get_name(), copy_callable, E->get().binds, E->get().flags); + const Callable copy_callable = Callable(copytarget, E.callable.get_method()); + if (!copy->is_connected(E.signal.get_name(), copy_callable)) { + copy->connect(E.signal.get_name(), copy_callable, E.binds, E.flags); } } } @@ -2194,8 +2194,8 @@ void Node::replace_by(Node *p_node, bool p_keep_groups) { List<GroupInfo> groups; get_groups(&groups); - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { - p_node->add_to_group(E->get().name, E->get().persistent); + for (const GroupInfo &E : groups) { + p_node->add_to_group(E.name, E.persistent); } } @@ -2241,9 +2241,7 @@ void Node::_replace_connections_target(Node *p_new_target) { List<Connection> cl; get_signals_connected_to_this(&cl); - for (List<Connection>::Element *E = cl.front(); E; E = E->next()) { - Connection &c = E->get(); - + for (const Connection &c : cl) { if (c.flags & CONNECT_PERSIST) { c.signal.get_object()->disconnect(c.signal.get_name(), Callable(this, c.callable.get_method())); bool valid = p_new_target->has_method(c.callable.get_method()) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.callable.get_method()); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 2fe5d7aa78..adba7f1a31 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -82,12 +82,19 @@ bool SceneTreeTimer::is_process_always() { return process_always; } +void SceneTreeTimer::set_ignore_time_scale(bool p_ignore) { + ignore_time_scale = p_ignore; +} + +bool SceneTreeTimer::is_ignore_time_scale() { + return ignore_time_scale; +} + void SceneTreeTimer::release_connections() { List<Connection> connections; get_all_signal_connections(&connections); - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - Connection const &connection = E->get(); + for (const Connection &connection : connections) { disconnect(connection.signal.get_name(), connection.callable); } } @@ -466,8 +473,13 @@ bool SceneTree::process(float p_time) { E = N; continue; } + float time_left = E->get()->get_time_left(); - time_left -= p_time; + if (E->get()->is_ignore_time_scale()) { + time_left -= Engine::get_singleton()->get_process_step(); + } else { + time_left -= p_time; + } E->get()->set_time_left(time_left); if (time_left < 0) { @@ -559,8 +571,8 @@ void SceneTree::finalize() { } // cleanup timers - for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E; E = E->next()) { - E->get()->release_connections(); + for (Ref<SceneTreeTimer> E : timers) { + E->release_connections(); } timers.clear(); } @@ -1134,8 +1146,8 @@ Array SceneTree::get_processed_tweens() { ret.resize(tweens.size()); int i = 0; - for (List<Ref<Tween>>::Element *E = tweens.front(); E; E = E->next()) { - ret[i] = E->get(); + for (Ref<Tween> E : tweens) { + ret[i] = E; i++; } @@ -1390,11 +1402,11 @@ SceneTree::SceneTree() { List<String> exts; ResourceLoader::get_recognized_extensions_for_type("Environment", &exts); String ext_hint; - for (List<String>::Element *E = exts.front(); E; E = E->next()) { + for (const String &E : exts) { if (ext_hint != String()) { ext_hint += ","; } - ext_hint += "*." + E->get(); + ext_hint += "*." + E; } // Get path. String env_path = GLOBAL_DEF("rendering/environment/defaults/default_environment", ""); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 0be0e185a5..c3d59663d6 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -54,6 +54,7 @@ class SceneTreeTimer : public RefCounted { float time_left = 0.0; bool process_always = true; + bool ignore_time_scale = false; protected: static void _bind_methods(); @@ -65,6 +66,9 @@ public: void set_process_always(bool p_process_always); bool is_process_always(); + void set_ignore_time_scale(bool p_ignore); + bool is_ignore_time_scale(); + void release_connections(); SceneTreeTimer(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 5a0a27520b..4231072ed9 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -502,17 +502,6 @@ void Viewport::_notification(int p_what) { RS::get_singleton()->viewport_set_active(viewport, false); RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID()); - - } break; - case NOTIFICATION_INTERNAL_PROCESS: { - if (gui.tooltip_timer >= 0) { - gui.tooltip_timer -= get_process_delta_time(); - if (gui.tooltip_timer < 0) { - _gui_show_tooltip(); - set_process_internal(false); - } - } - } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) { @@ -584,8 +573,7 @@ void Viewport::_process_picking() { // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame bool has_mouse_event = false; - for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) { - Ref<InputEventMouse> m = E->get(); + for (Ref<InputEvent> m : physics_picking_events) { if (m.is_valid()) { has_mouse_event = true; break; @@ -1489,8 +1477,10 @@ void Viewport::_gui_sort_roots() { void Viewport::_gui_cancel_tooltip() { gui.tooltip_control = nullptr; - gui.tooltip_timer = -1; - set_process_internal(false); + if (gui.tooltip_timer.is_valid()) { + gui.tooltip_timer->release_connections(); + gui.tooltip_timer = Ref<SceneTreeTimer>(); + } if (gui.tooltip_popup) { gui.tooltip_popup->queue_delete(); gui.tooltip_popup = nullptr; @@ -1710,7 +1700,7 @@ void Viewport::_gui_call_notification(Control *p_control, int p_what) { //_unblock(); } -Control *Viewport::_gui_find_control(const Point2 &p_global) { +Control *Viewport::gui_find_control(const Point2 &p_global) { //aca va subwindows _gui_sort_roots(); @@ -1850,7 +1840,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { parent_xform=data.parent_canvas_item->get_global_transform(); */ - gui.mouse_focus = _gui_find_control(pos); + gui.mouse_focus = gui_find_control(pos); gui.last_mouse_focus = gui.mouse_focus; if (!gui.mouse_focus) { @@ -1991,7 +1981,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.mouse_focus) { over = gui.mouse_focus; } else { - over = _gui_find_control(mpos); + over = gui_find_control(mpos); } if (gui.mouse_focus_mask == 0 && over != gui.mouse_over) { @@ -2074,7 +2064,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.mouse_focus) { over = gui.mouse_focus; } else { - over = _gui_find_control(mpos); + over = gui_find_control(mpos); } if (over != gui.mouse_over) { @@ -2139,10 +2129,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } if (can_tooltip && !is_tooltip_shown) { + if (gui.tooltip_timer.is_valid()) { + gui.tooltip_timer->release_connections(); + gui.tooltip_timer = Ref<SceneTreeTimer>(); + } gui.tooltip_control = over; gui.tooltip_pos = over->get_screen_transform().xform(pos); - gui.tooltip_timer = gui.tooltip_delay; - set_process_internal(true); + gui.tooltip_timer = get_tree()->create_timer(gui.tooltip_delay); + gui.tooltip_timer->set_ignore_time_scale(true); + gui.tooltip_timer->connect("timeout", callable_mp(this, &Viewport::_gui_show_tooltip)); } } @@ -2262,7 +2257,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Transform2D ai = (viewport_under->get_final_transform().affine_inverse() * viewport_under->_get_input_pre_xform()); viewport_pos = ai.xform(viewport_pos); //find control under at pos - gui.drag_mouse_over = viewport_under->_gui_find_control(viewport_pos); + gui.drag_mouse_over = viewport_under->gui_find_control(viewport_pos); if (gui.drag_mouse_over) { Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse(); gui.drag_mouse_over_pos = localizer.xform(viewport_pos); @@ -2290,7 +2285,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (touch_event.is_valid()) { Size2 pos = touch_event->get_position(); if (touch_event->is_pressed()) { - Control *over = _gui_find_control(pos); + Control *over = gui_find_control(pos); if (over) { if (over->can_process()) { touch_event = touch_event->xformed_by(Transform2D()); //make a copy @@ -2325,7 +2320,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Size2 pos = gesture_event->get_position(); - Control *over = _gui_find_control(pos); + Control *over = gui_find_control(pos); if (over) { if (over->can_process()) { gesture_event = gesture_event->xformed_by(Transform2D()); //make a copy @@ -2346,7 +2341,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (drag_event.is_valid()) { Control *over = gui.mouse_focus; if (!over) { - over = _gui_find_control(drag_event->get_position()); + over = gui_find_control(drag_event->get_position()); } if (over) { if (over->can_process()) { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 32b6ba84b5..b5c49a8a97 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -50,6 +50,7 @@ class Label; class Timer; class Viewport; class CollisionObject3D; +class SceneTreeTimer; class ViewportTexture : public Texture2D { GDCLASS(ViewportTexture, Texture2D); @@ -373,7 +374,7 @@ private: bool drag_attempted = false; Variant drag_data; ObjectID drag_preview_id; - float tooltip_timer = -1.0; + Ref<SceneTreeTimer> tooltip_timer; float tooltip_delay = 0.0; Transform2D focus_inv_xform; bool roots_order_dirty = false; @@ -404,7 +405,6 @@ private: void _gui_call_notification(Control *p_control, int p_what); void _gui_sort_roots(); - Control *_gui_find_control(const Point2 &p_global); Control *_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform); void _gui_input_event(Ref<InputEvent> p_event); @@ -629,6 +629,8 @@ public: bool gui_is_dragging() const; + Control *gui_find_control(const Point2 &p_global); + void set_sdf_oversize(SDFOversize p_sdf_oversize); SDFOversize get_sdf_oversize() const; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index bf7512e8eb..ab1846660b 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1356,14 +1356,14 @@ void Window::_validate_property(PropertyInfo &property) const { Vector<StringName> unique_names; String hint_string; - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { // Skip duplicate values. - if (unique_names.has(E->get())) { + if (unique_names.has(E)) { continue; } - hint_string += String(E->get()) + ","; - unique_names.append(E->get()); + hint_string += String(E) + ","; + unique_names.append(E); } property.hint_string = hint_string; diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 1484007333..920ee2e5ab 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -228,8 +228,8 @@ private: value_track_get_key_indices(p_track, p_time, p_delta, &idxs); Vector<int> idxr; - for (List<int>::Element *E = idxs.front(); E; E = E->next()) { - idxr.push_back(E->get()); + for (int &E : idxs) { + idxr.push_back(E); } return idxr; } @@ -238,8 +238,8 @@ private: method_track_get_key_indices(p_track, p_time, p_delta, &idxs); Vector<int> idxr; - for (List<int>::Element *E = idxs.front(); E; E = E->next()) { - idxr.push_back(E->get()); + for (int &E : idxs) { + idxr.push_back(E); } return idxr; } diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 53979e16df..c13db83d6d 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -729,8 +729,8 @@ void Curve2D::_bake() const { Vector2 *w = baked_point_cache.ptrw(); int idx = 0; - for (List<Vector2>::Element *E = pointlist.front(); E; E = E->next()) { - w[idx] = E->get(); + for (const Vector2 &E : pointlist) { + w[idx] = E; idx++; } } @@ -1239,9 +1239,9 @@ void Curve3D::_bake() const { Vector3 prev_up = Vector3(0, 1, 0); Vector3 prev_forward = Vector3(0, 0, 1); - for (List<Plane>::Element *E = pointlist.front(); E; E = E->next()) { - w[idx] = E->get().normal; - wt[idx] = E->get().d; + for (const Plane &E : pointlist) { + w[idx] = E.normal; + wt[idx] = E.d; if (!up_vector_enabled) { idx++; diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp index ebe65605f8..05d1a7bf94 100644 --- a/scene/resources/immediate_mesh.cpp +++ b/scene/resources/immediate_mesh.cpp @@ -146,7 +146,7 @@ void ImmediateMesh::surface_add_vertex_2d(const Vector2 &p_vertex) { } void ImmediateMesh::surface_end() { ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it."); - ERR_FAIL_COND_MSG(!vertices.size(), "No vertices were added, surface cant be created."); + ERR_FAIL_COND_MSG(!vertices.size(), "No vertices were added, surface can't be created."); uint32_t format = ARRAY_FORMAT_VERTEX; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 7d49533afd..08f7274ff6 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -278,8 +278,8 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id if (shader.is_valid()) { List<PropertyInfo> pl; shader->get_param_list(&pl); - for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) { - r_options->push_back(quote_style + E->get().name.replace_first("shader_param/", "") + quote_style); + for (const PropertyInfo &E : pl) { + r_options->push_back(quote_style + E.name.replace_first("shader_param/", "") + quote_style); } } } diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index d2be2bdba1..ddc50c0490 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -329,9 +329,7 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { Vector3 *tw = tmeshfaces.ptrw(); int tidx = 0; - for (List<Face3>::Element *E = faces.front(); E; E = E->next()) { - const Face3 &f = E->get(); - + for (const Face3 &f : faces) { for (int j = 0; j < 3; j++) { tw[tidx++] = f.vertex[j]; _EdgeKey ek; @@ -366,8 +364,8 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { { Vector3 *w = varr.ptrw(); int idx = 0; - for (List<Vector3>::Element *E = lines.front(); E; E = E->next()) { - w[idx++] = E->get(); + for (const Vector3 &E : lines) { + w[idx++] = E; } } diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 9bb2a4ddb8..eddbb9a842 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -206,8 +206,8 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { node->set(snames[nprops[j].name], props[nprops[j].value], &valid); //restore old state for new script, if exists - for (List<Pair<StringName, Variant>>::Element *E = old_state.front(); E; E = E->next()) { - node->set(E->get().first, E->get().second); + for (const Pair<StringName, Variant> &E : old_state) { + node->set(E.first, E.second); } } else { Variant value = props[nprops[j].value]; @@ -477,13 +477,13 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map script->update_exports(); } - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - String name = E->get().name; - Variant value = p_node->get(E->get().name); + String name = E.name; + Variant value = p_node->get(E.name); bool isdefault = false; Variant default_value = ClassDB::class_get_default_property_value(type, name); @@ -497,7 +497,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map } // the version above makes more sense, because it does not rely on placeholder or usage flag // in the script, just the default value function. - // if (E->get().usage & PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE) { + // if (E.usage & PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE) { // isdefault = true; //is script default value // } @@ -507,7 +507,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map // only save what has been changed // only save changed properties in instance - if ((E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE) || E->get().name == "__meta__") { + if ((E.usage & PROPERTY_USAGE_NO_INSTANCE_STATE) || E.name == "__meta__") { //property has requested that no instance state is saved, sorry //also, meta won't be overridden or saved continue; @@ -520,7 +520,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map //check all levels of pack to see if the property exists somewhere const PackState &ps = F->get(); - original = ps.state->get_property_value(ps.node, E->get().name, exists); + original = ps.state->get_property_value(ps.node, E.name, exists); if (exists) { break; } @@ -565,9 +565,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map List<Node::GroupInfo> groups; p_node->get_groups(&groups); - for (List<Node::GroupInfo>::Element *E = groups.front(); E; E = E->next()) { - Node::GroupInfo &gi = E->get(); - + for (const Node::GroupInfo &gi : groups) { if (!gi.persistent) { continue; } @@ -577,9 +575,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map */ bool skip = false; - for (List<PackState>::Element *F = pack_state_stack.front(); F; F = F->next()) { + for (const PackState &F : pack_state_stack) { //check all levels of pack to see if the group was added somewhere - const PackState &ps = F->get(); + const PackState &ps = F; if (ps.state->is_node_in_group(ps.node, gi.name)) { skip = true; break; @@ -679,14 +677,14 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName //ERR_FAIL_COND_V( !node_map.has(p_node), ERR_BUG); //NodeData &nd = nodes[node_map[p_node]]; - for (List<MethodInfo>::Element *E = _signals.front(); E; E = E->next()) { + for (const MethodInfo &E : _signals) { List<Node::Connection> conns; - p_node->get_signal_connection_list(E->get().name, &conns); + p_node->get_signal_connection_list(E.name, &conns); conns.sort(); - for (List<Node::Connection>::Element *F = conns.front(); F; F = F->next()) { - const Node::Connection &c = F->get(); + for (const Node::Connection &F : conns) { + const Node::Connection &c = F; if (!(c.flags & CONNECT_PERSIST)) { //only persistent connections get saved continue; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index ee61e64ed3..3f6e926aa7 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -35,8 +35,9 @@ #include "core/io/resource_format_binary.h" #include "core/version.h" -//version 2: changed names for basis, aabb, Vectors, etc. -#define FORMAT_VERSION 2 +// Version 2: changed names for Basis, AABB, Vectors, etc. +// Version 3: new string ID for ext/subresources, breaks forward compat. +#define FORMAT_VERSION 3 #include "core/io/dir_access.h" #include "core/version.h" @@ -56,22 +57,23 @@ Ref<Resource> ResourceLoaderText::get_resource() { Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); - if (token.type != VariantParser::TK_NUMBER) { - r_err_str = "Expected number (sub-resource index)"; + if (token.type != VariantParser::TK_NUMBER && token.type != VariantParser::TK_STRING) { + r_err_str = "Expected number (old style) or string (sub-resource index)"; return ERR_PARSE_ERROR; } - int index = token.value; + String unique_id = token.value; - if (!p_data->resource_map.has(index)) { + if (!p_data->resource_map.has(unique_id)) { Ref<DummyResource> dr; dr.instantiate(); - dr->set_subindex(index); - p_data->resource_map[index] = dr; - p_data->resource_set.insert(dr); + dr->set_scene_unique_id(unique_id); + p_data->resource_map[unique_id] = dr; + uint32_t im_size = p_data->resource_index_map.size(); + p_data->resource_index_map.insert(dr, im_size); } - r_res = p_data->resource_map[index]; + r_res = p_data->resource_map[unique_id]; VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -85,12 +87,12 @@ Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, Varia Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); - if (token.type != VariantParser::TK_NUMBER) { - r_err_str = "Expected number (sub-resource index)"; + if (token.type != VariantParser::TK_NUMBER && token.type != VariantParser::TK_STRING) { + r_err_str = "Expected number (old style sub-resource index) or String (ext-resource ID)"; return ERR_PARSE_ERROR; } - int id = token.value; + String id = token.value; ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR); @@ -108,14 +110,14 @@ Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, Varia Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); - if (token.type != VariantParser::TK_NUMBER) { - r_err_str = "Expected number (sub-resource index)"; + if (token.type != VariantParser::TK_NUMBER && token.type != VariantParser::TK_STRING) { + r_err_str = "Expected number (old style sub-resource index) or string"; return ERR_PARSE_ERROR; } - int index = token.value; - ERR_FAIL_COND_V(!int_resources.has(index), ERR_INVALID_PARAMETER); - r_res = int_resources[index]; + String id = token.value; + ERR_FAIL_COND_V(!int_resources.has(id), ERR_INVALID_PARAMETER); + r_res = int_resources[id]; VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -129,16 +131,16 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); - if (token.type != VariantParser::TK_NUMBER) { - r_err_str = "Expected number (sub-resource index)"; + if (token.type != VariantParser::TK_NUMBER && token.type != VariantParser::TK_STRING) { + r_err_str = "Expected number (old style sub-resource index) or String (ext-resource ID)"; return ERR_PARSE_ERROR; } - int id = token.value; + String id = token.value; if (!ignore_resource_parsing) { if (!ext_resources.has(id)) { - r_err_str = "Can't load cached ext-resource #" + itos(id); + r_err_str = "Can't load cached ext-resource id: " + id; return ERR_PARSE_ERROR; } @@ -409,7 +411,18 @@ Error ResourceLoaderText::load() { String path = next_tag.fields["path"]; String type = next_tag.fields["type"]; - int index = next_tag.fields["id"]; + String id = next_tag.fields["id"]; + + if (next_tag.fields.has("uid")) { + String uidt = next_tag.fields["uid"]; + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(uidt); + if (uid != ResourceUID::INVALID_ID && ResourceUID::get_singleton()->has_id(uid)) { + // If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path. + path = ResourceUID::get_singleton()->get_id_path(uid); + } else { + WARN_PRINT(String(res_path + ":" + itos(lines) + " - ext_resource, invalid UUID: " + uidt + " - using text path instead: " + path).utf8().get_data()); + } + } if (path.find("://") == -1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path @@ -453,14 +466,14 @@ Error ResourceLoaderText::load() { } else { #ifdef TOOLS_ENABLED //remember ID for saving - res->set_id_for_path(local_path, index); + res->set_id_for_path(local_path, id); #endif } er.cache = res; } - ext_resources[index] = er; + ext_resources[id] = er; error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); @@ -489,15 +502,15 @@ Error ResourceLoaderText::load() { if (!next_tag.fields.has("id")) { error = ERR_FILE_CORRUPT; - error_text = "Missing 'index' in external resource tag"; + error_text = "Missing 'id' in external resource tag"; _printerr(); return error; } String type = next_tag.fields["type"]; - int id = next_tag.fields["id"]; + String id = next_tag.fields["id"]; - String path = local_path + "::" + itos(id); + String path = local_path + "::" + id; //bool exists=ResourceCache::has(path); @@ -575,7 +588,7 @@ Error ResourceLoaderText::load() { int_resources[id] = res; //always assign int resources if (do_assign && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); - res->set_subindex(id); + res->set_scene_unique_id(id); } if (progress && resources_total > 0) { @@ -736,7 +749,7 @@ void ResourceLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_depen if (!next_tag.fields.has("id")) { error = ERR_FILE_CORRUPT; - error_text = "Missing 'index' in external resource tag"; + error_text = "Missing 'id' in external resource tag"; _printerr(); return; } @@ -744,7 +757,18 @@ void ResourceLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_depen String path = next_tag.fields["path"]; String type = next_tag.fields["type"]; - if (path.find("://") == -1 && path.is_rel_path()) { + bool using_uid = false; + if (next_tag.fields.has("uid")) { + //if uid exists, return uid in text format, not the path + String uidt = next_tag.fields["uid"]; + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(uidt); + if (uid != ResourceUID::INVALID_ID) { + path = ResourceUID::get_singleton()->id_to_text(uid); + using_uid = true; + } + } + + if (!using_uid && path.find("://") == -1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path path = ProjectSettings::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path)); } @@ -814,9 +838,17 @@ Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_p } String path = next_tag.fields["path"]; - int index = next_tag.fields["id"]; + String id = next_tag.fields["id"]; String type = next_tag.fields["type"]; + if (next_tag.fields.has("uid")) { + String uidt = next_tag.fields["uid"]; + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(uidt); + if (uid != ResourceUID::INVALID_ID && ResourceUID::get_singleton()->has_id(uid)) { + // If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path. + path = ResourceUID::get_singleton()->get_id_path(uid); + } + } bool relative = false; if (!path.begins_with("res://")) { path = base_path.plus_file(path).simplify_path(); @@ -833,7 +865,14 @@ Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_p path = base_path.path_to_file(path); } - fw->store_line("[ext_resource path=\"" + path + "\" type=\"" + type + "\" id=" + itos(index) + "]"); + String s = "[ext_resource type=\"" + type + "\""; + + ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(path); + if (uid != ResourceUID::INVALID_ID) { + s += " uid=\"" + ResourceUID::get_singleton()->id_to_text(uid) + "\""; + } + s += " path=\"" + path + "\" id=\"" + id + "\"]"; + fw->store_line(s); // Bundled. tag_end = f->get_position(); } @@ -919,6 +958,12 @@ void ResourceLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) { return; } + if (tag.fields.has("uid")) { + res_uid = ResourceUID::get_singleton()->text_to_id(tag.fields["uid"]); + } else { + res_uid = ResourceUID::INVALID_ID; + } + if (tag.fields.has("load_steps")) { resources_total = tag.fields["load_steps"]; } else { @@ -974,7 +1019,12 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) bs_save_unicode_string(wf.f, is_scene ? "PackedScene" : resource_type); wf->store_64(0); //offset to import metadata, this is no longer used - for (int i = 0; i < 14; i++) { + + f->store_32(ResourceFormatSaverBinaryInstance::FORMAT_FLAG_NAMED_SCENE_IDS | ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS); + + f->store_64(res_uid); + + for (int i = 0; i < 5; i++) { wf->store_32(0); // reserved } @@ -1015,17 +1065,23 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) String path = next_tag.fields["path"]; String type = next_tag.fields["type"]; - int index = next_tag.fields["id"]; + String id = next_tag.fields["id"]; + ResourceUID::ID uid = ResourceUID::INVALID_ID; + if (next_tag.fields.has("uid")) { + String uidt = next_tag.fields["uid"]; + uid = ResourceUID::get_singleton()->text_to_id(uidt); + } bs_save_unicode_string(wf.f, type); bs_save_unicode_string(wf.f, path); + wf.f->store_64(uid); int lindex = dummy_read.external_resources.size(); Ref<DummyResource> dr; dr.instantiate(); dr->set_path("res://dummy" + itos(lindex)); //anything is good to detect it for saving as external dummy_read.external_resources[dr] = lindex; - dummy_read.rev_external_resources[index] = dr; + dummy_read.rev_external_resources[id] = dr; error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); @@ -1069,7 +1125,7 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) if (!next_tag.fields.has("id")) { error = ERR_FILE_CORRUPT; - error_text = "Missing 'index' in external resource tag"; + error_text = "Missing 'id' in external resource tag"; _printerr(); return error; } @@ -1114,7 +1170,7 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) if (assign != String()) { Map<StringName, int> empty_string_map; //unused bs_save_unicode_string(wf2, assign, true); - ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map); + ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map); prop_count++; } else if (next_tag.name != String()) { @@ -1165,17 +1221,17 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) int prop_count = 0; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (const PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - String name = E->get().name; + String name = E.name; Variant value = packed_scene->get(name); Map<StringName, int> empty_string_map; //unused bs_save_unicode_string(wf2, name, true); - ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map); + ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map); prop_count++; } @@ -1255,6 +1311,32 @@ String ResourceLoaderText::recognize(FileAccess *p_f) { return tag.fields["type"]; } +ResourceUID::ID ResourceLoaderText::get_uid(FileAccess *p_f) { + error = OK; + + lines = 1; + f = p_f; + + stream.f = f; + + ignore_resource_parsing = true; + + VariantParser::Tag tag; + Error err = VariantParser::parse_tag(&stream, lines, error_text, tag); + + if (err) { + _printerr(); + return ResourceUID::INVALID_ID; + } + + if (tag.fields.has("uid")) { //field is optional + String uidt = tag.fields["uid"]; + return ResourceUID::get_singleton()->text_to_id(uidt); + } + + return ResourceUID::INVALID_ID; +} + ///////////////////// RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { @@ -1275,7 +1357,6 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.progress = r_progress; loader.res_path = loader.local_path; - //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); loader.open(f); err = loader.load(); if (r_error) { @@ -1318,7 +1399,7 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const { return String(); } - //for anyhting else must test.. + // ...for anything else must test... FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { @@ -1328,11 +1409,28 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const { ResourceLoaderText loader; loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); loader.res_path = loader.local_path; - //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); String r = loader.recognize(f); return ClassDB::get_compatibility_remapped_class(r); } +ResourceUID::ID ResourceFormatLoaderText::get_resource_uid(const String &p_path) const { + String ext = p_path.get_extension().to_lower(); + + if (ext != "tscn" && ext != "tres") { + return ResourceUID::INVALID_ID; + } + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ); + if (!f) { + return ResourceUID::INVALID_ID; //could not read + } + + ResourceLoaderText loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + return loader.get_uid(f); +} + void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { @@ -1342,7 +1440,6 @@ void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<Strin ResourceLoaderText loader; loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); loader.res_path = loader.local_path; - //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); loader.get_dependencies(f, p_dependencies, p_add_types); } @@ -1355,7 +1452,6 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const ResourceLoaderText loader; loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); loader.res_path = loader.local_path; - //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); return loader.rename_dependencies(f, p_path, p_map); } @@ -1371,7 +1467,6 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &path = p_src_path; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.res_path = loader.local_path; - //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); loader.open(f); return loader.save_as_binary(f, p_dst_path); } @@ -1394,10 +1489,10 @@ String ResourceFormatSaverTextInstance::_write_resources(void *ud, const RES &p_ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) { if (external_resources.has(res)) { - return "ExtResource( " + itos(external_resources[res]) + " )"; + return "ExtResource( \"" + external_resources[res] + "\" )"; } else { if (internal_resources.has(res)) { - return "SubResource( " + itos(internal_resources[res]) + " )"; + return "SubResource( \"" + internal_resources[res] + "\" )"; } else if (res->get_path().length() && res->get_path().find("::") == -1) { if (res->get_path() == local_path) { //circular reference attempt return "null"; @@ -1426,8 +1521,11 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, ERR_PRINT("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded."); return; } - int index = external_resources.size(); - external_resources[res] = index; + + // Use a numeric ID as a base, because they are sorted in natural order before saving. + // This increases the chances of thread loading to fetch them first. + String id = itos(external_resources.size() + 1) + "_" + Resource::generate_scene_unique_id(); + external_resources[res] = id; return; } @@ -1483,8 +1581,8 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, Dictionary d = p_variant; List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - Variant v = d[E->get()]; + for (const Variant &E : keys) { + Variant v = d[E]; _find_resources(v); } } break; @@ -1513,11 +1611,11 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r takeover_paths = false; } - // save resources + // Save resources. _find_resources(p_resource, true); if (packed_scene.is_valid()) { - //add instances to external resources if saving a packed scene + // Add instances to external resources if saving a packed scene. for (int i = 0; i < packed_scene->get_state()->get_node_count(); i++) { if (packed_scene->get_state()->is_node_instance_placeholder(i)) { continue; @@ -1525,8 +1623,8 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r Ref<PackedScene> instance = packed_scene->get_state()->get_node_instance(i); if (instance.is_valid() && !external_resources.has(instance)) { - int index = external_resources.size(); - external_resources[instance] = index; + int index = external_resources.size() + 1; + external_resources[instance] = itos(index) + "_" + Resource::generate_scene_unique_id(); // Keep the order for improved thread loading performance. } } } @@ -1537,64 +1635,74 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r title += "type=\"" + p_resource->get_class() + "\" "; } int load_steps = saved_resources.size() + external_resources.size(); - /* - if (packed_scene.is_valid()) { - load_steps+=packed_scene->get_node_count(); - } - //no, better to not use load steps from nodes, no point to that - */ if (load_steps > 1) { title += "load_steps=" + itos(load_steps) + " "; } title += "format=" + itos(FORMAT_VERSION) + ""; + ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(local_path, true); + + if (uid != ResourceUID::INVALID_ID) { + title += " uid=\"" + ResourceUID::get_singleton()->id_to_text(uid) + "\""; + } + f->store_string(title); - f->store_line("]\n"); //one empty line + f->store_line("]\n"); // One empty line. } #ifdef TOOLS_ENABLED - //keep order from cached ids - Set<int> cached_ids_found; - for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) { - int cached_id = E->key()->get_id_for_path(local_path); - if (cached_id < 0 || cached_ids_found.has(cached_id)) { - E->get() = -1; //reset + // Keep order from cached ids. + Set<String> cached_ids_found; + for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { + String cached_id = E->key()->get_id_for_path(local_path); + if (cached_id == "" || cached_ids_found.has(cached_id)) { + int sep_pos = E->get().find("_"); + if (sep_pos != -1) { + E->get() = E->get().substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance. + } else { + E->get() = ""; + } + } else { E->get() = cached_id; cached_ids_found.insert(cached_id); } } - //create IDs for non cached resources - for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) { - if (cached_ids_found.has(E->get())) { //already cached, go on + // Create IDs for non cached resources. + for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { + if (cached_ids_found.has(E->get())) { // Already cached, go on. continue; } - int attempt = 1; //start from one, more readable format - while (cached_ids_found.has(attempt)) { - attempt++; + String attempt; + while (true) { + attempt = E->get() + Resource::generate_scene_unique_id(); + if (!cached_ids_found.has(attempt)) { + break; + } } cached_ids_found.insert(attempt); E->get() = attempt; - //update also in resource + // Update also in resource. Ref<Resource> res = E->key(); res->set_id_for_path(local_path, attempt); } #else - //make sure to start from one, as it makes format more readable - for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) { - E->get() = E->get() + 1; + // Make sure to start from one, as it makes format more readable. + int counter = 1; + for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { + E->get() = itos(counter++); } #endif Vector<ResourceSort> sorted_er; - for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) { + for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { ResourceSort rs; rs.resource = E->key(); - rs.index = E->get(); + rs.id = E->get(); sorted_er.push_back(rs); } @@ -1603,23 +1711,30 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r for (int i = 0; i < sorted_er.size(); i++) { String p = sorted_er[i].resource->get_path(); - f->store_string("[ext_resource path=\"" + p + "\" type=\"" + sorted_er[i].resource->get_save_class() + "\" id=" + itos(sorted_er[i].index) + "]\n"); //bundled + String s = "[ext_resource type=\"" + sorted_er[i].resource->get_save_class() + "\""; + + ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(p, false); + if (uid != ResourceUID::INVALID_ID) { + s += " uid=\"" + ResourceUID::get_singleton()->id_to_text(uid) + "\""; + } + s += " path=\"" + p + "\" id=\"" + sorted_er[i].id + "\"]\n"; + f->store_string(s); // Bundled. } if (external_resources.size()) { - f->store_line(String()); //separate + f->store_line(String()); // Separate. } - Set<int> used_indices; + Set<String> used_unique_ids; for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { RES res = E->get(); if (E->next() && (res->get_path() == "" || res->get_path().find("::") != -1)) { - if (res->get_subindex() != 0) { - if (used_indices.has(res->get_subindex())) { - res->set_subindex(0); //repeated + if (res->get_scene_unique_id() != "") { + if (used_unique_ids.has(res->get_scene_unique_id())) { + res->set_scene_unique_id(""); // Repeated. } else { - used_indices.insert(res->get_subindex()); + used_unique_ids.insert(res->get_scene_unique_id()); } } } @@ -1631,31 +1746,35 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r bool main = (E->next() == nullptr); if (main && packed_scene.is_valid()) { - break; //save as a scene + break; // Save as a scene. } if (main) { f->store_line("[resource]"); } else { String line = "[sub_resource "; - if (res->get_subindex() == 0) { - int new_subindex = 1; - if (used_indices.size()) { - new_subindex = used_indices.back()->get() + 1; + if (res->get_scene_unique_id() == "") { + String new_id; + while (true) { + new_id = res->get_class() + "_" + Resource::generate_scene_unique_id(); + + if (!used_unique_ids.has(new_id)) { + break; + } } - res->set_subindex(new_subindex); - used_indices.insert(new_subindex); + res->set_scene_unique_id(new_id); + used_unique_ids.insert(new_id); } - int idx = res->get_subindex(); - line += "type=\"" + res->get_class() + "\" id=" + itos(idx); - f->store_line(line + "]"); + String id = res->get_scene_unique_id(); + line += "type=\"" + res->get_class() + "\" id=\"" + id; + f->store_line(line + "\"]"); if (takeover_paths) { - res->set_path(p_path + "::" + itos(idx), true); + res->set_path(p_path + "::" + id, true); } - internal_resources[res] = idx; + internal_resources[res] = id; #ifdef TOOLS_ENABLED res->set_edited(false); #endif @@ -1663,7 +1782,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r List<PropertyInfo> property_list; res->get_property_list(&property_list); - //property_list.sort(); for (List<PropertyInfo>::Element *PE = property_list.front(); PE; PE = PE->next()) { if (skip_editor && PE->get().name.begins_with("__editor")) { continue; @@ -1704,7 +1822,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } if (packed_scene.is_valid()) { - //if this is a scene, save nodes and connections! + // If this is a scene, save nodes and connections! Ref<SceneState> state = packed_scene->get_state(); for (int i = 0; i < state->get_node_count(); i++) { StringName type = state->get_node_type(i); @@ -1812,7 +1930,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } f->close(); - //memdelete(f); return OK; } diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index f5d9cca859..373e71b2c4 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -58,10 +58,8 @@ class ResourceLoaderText { bool ignore_resource_parsing = false; - //Map<String,String> remaps; - - Map<int, ExtResource> ext_resources; - Map<int, RES> int_resources; + Map<String, ExtResource> ext_resources; + Map<String, RES> int_resources; int resources_total = 0; int resource_current = 0; @@ -76,8 +74,9 @@ class ResourceLoaderText { mutable int lines = 0; + ResourceUID::ID res_uid = ResourceUID::INVALID_ID; + Map<String, String> remaps; - //void _printerr(); static Error _parse_sub_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceLoaderText *>(p_self)->_parse_sub_resource(p_stream, r_res, line, r_err_str); } static Error _parse_ext_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceLoaderText *>(p_self)->_parse_ext_resource(p_stream, r_res, line, r_err_str); } @@ -92,9 +91,9 @@ class ResourceLoaderText { struct DummyReadData { Map<RES, int> external_resources; - Map<int, RES> rev_external_resources; - Set<RES> resource_set; - Map<int, RES> resource_map; + Map<String, RES> rev_external_resources; + Map<RES, int> resource_index_map; + Map<String, RES> resource_map; }; static Error _parse_sub_resource_dummys(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return _parse_sub_resource_dummy((DummyReadData *)(p_self), p_stream, r_res, line, r_err_str); } @@ -123,6 +122,7 @@ public: void open(FileAccess *p_f, bool p_skip_first_tag = false); String recognize(FileAccess *p_f); + ResourceUID::ID get_uid(FileAccess *p_f); void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); Error rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map); @@ -139,6 +139,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); @@ -168,14 +169,14 @@ class ResourceFormatSaverTextInstance { Set<RES> resource_set; List<RES> saved_resources; - Map<RES, int> external_resources; - Map<RES, int> internal_resources; + Map<RES, String> external_resources; + Map<RES, String> internal_resources; struct ResourceSort { RES resource; - int index = 0; + String id; bool operator<(const ResourceSort &p_right) const { - return index < p_right.index; + return id.naturalnocasecmp_to(p_right.id) < 0; } }; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index f19d08dbb1..424a54f344 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -72,13 +72,12 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const { params_cache.clear(); params_cache_dirty = false; - for (List<PropertyInfo>::Element *E = local.front(); E; E = E->next()) { - PropertyInfo pi = E->get(); + for (PropertyInfo &pi : local) { if (default_textures.has(pi.name)) { //do not show default textures continue; } pi.name = "shader_param/" + pi.name; - params_cache[pi.name] = E->get().name; + params_cache[pi.name] = pi.name; if (p_params) { //small little hack if (pi.type == Variant::RID) { diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index df80084c5c..e9adf67559 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -100,8 +100,8 @@ Vector<String> SpriteFrames::_get_animation_list() const { Vector<String> ret; List<StringName> al; get_animation_list(&al); - for (List<StringName>::Element *E = al.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const StringName &E : al) { + ret.push_back(E); } return ret; diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index bf889d7a1c..173ce2adce 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -529,8 +529,8 @@ void CodeHighlighter::set_color_regions(const Dictionary &p_color_regions) { List<Variant> keys; p_color_regions.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - String key = E->get(); + for (const Variant &E : keys) { + String key = E; String start_key = key.get_slice(" ", 0); String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String(); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 303bbf38f4..e4a731c7f7 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -447,8 +447,8 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const { // Sort and store properties. list.sort(); - for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (const PropertyInfo &E : list) { + p_list->push_back(E); } } @@ -1275,15 +1275,15 @@ void Theme::get_type_variation_list(const StringName &p_base_type, List<StringNa return; } - for (const List<StringName>::Element *E = variation_base_map[p_base_type].front(); E; E = E->next()) { + for (const StringName &E : variation_base_map[p_base_type]) { // Prevent infinite loops if variants were set to be cross-dependent (that's still invalid usage, but handling for stability sake). - if (p_list->find(E->get())) { + if (p_list->find(E)) { continue; } - p_list->push_back(E->get()); + p_list->push_back(E); // Continue looking for sub-variations. - get_type_variation_list(E->get(), p_list); + get_type_variation_list(E, p_list); } } diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index f9b5a4cfec..737b47ed95 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -2728,7 +2728,7 @@ TileSet::TileSet() { tile_lines_mesh.instantiate(); tile_filled_mesh.instantiate(); - // Instanciate and list all plugins. + // Instantiate and list all plugins. tile_set_plugins_vector.append(memnew(TileSetPluginAtlasRendering)); tile_set_plugins_vector.append(memnew(TileSetPluginAtlasPhysics)); tile_set_plugins_vector.append(memnew(TileSetPluginAtlasNavigation)); @@ -4357,14 +4357,14 @@ void TileSetPluginAtlasRendering::update_dirty_quadrants(TileMap *p_tile_map, Se RenderingServer *rs = RenderingServer::get_singleton(); // Free the canvas items. - for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - rs->free(E->get()); + for (const RID &E : q.canvas_items) { + rs->free(E); } q.canvas_items.clear(); // Free the occluders. - for (List<RID>::Element *E = q.occluders.front(); E; E = E->next()) { - rs->free(E->get()); + for (const RID &E : q.occluders) { + rs->free(E); } q.occluders.clear(); @@ -4473,8 +4473,8 @@ void TileSetPluginAtlasRendering::update_dirty_quadrants(TileMap *p_tile_map, Se // Sort the quadrants for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E = world_to_map.front(); E; E = E->next()) { TileMapQuadrant &q = quadrant_map[E->value()]; - for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - RS::get_singleton()->canvas_item_set_draw_index(F->get(), index++); + for (const RID &F : q.canvas_items) { + RS::get_singleton()->canvas_item_set_draw_index(F, index++); } } @@ -4491,14 +4491,14 @@ void TileSetPluginAtlasRendering::create_quadrant(TileMap *p_tile_map, TileMapQu void TileSetPluginAtlasRendering::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { // Free the canvas items. - for (List<RID>::Element *E = p_quadrant->canvas_items.front(); E; E = E->next()) { - RenderingServer::get_singleton()->free(E->get()); + for (const RID &E : p_quadrant->canvas_items) { + RenderingServer::get_singleton()->free(E); } p_quadrant->canvas_items.clear(); // Free the occluders. - for (List<RID>::Element *E = p_quadrant->occluders.front(); E; E = E->next()) { - RenderingServer::get_singleton()->free(E->get()); + for (const RID &E : p_quadrant->occluders) { + RenderingServer::get_singleton()->free(E); } p_quadrant->occluders.clear(); } diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index ef380ab233..7292728251 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -628,8 +628,8 @@ bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_p ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false); const Graph *g = &graph[p_type]; - for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { - if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { + 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) { return true; } } @@ -642,12 +642,12 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod const VisualShader::Node &node = p_graph->nodes[p_node]; - for (const List<int>::Element *E = node.prev_connected_nodes.front(); E; E = E->next()) { - if (E->get() == p_target) { + for (const int &E : node.prev_connected_nodes) { + if (E == p_target) { return true; } - result = is_nodes_connected_relatively(p_graph, E->get(), p_target); + result = is_nodes_connected_relatively(p_graph, E, p_target); if (result) { break; } @@ -686,8 +686,8 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po return false; } - for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { - if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { + 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) { return false; } } @@ -739,8 +739,8 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port, 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."); - for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { - if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { + 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) { ERR_FAIL_V(ERR_ALREADY_EXISTS); } } @@ -763,7 +763,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por ERR_FAIL_INDEX(p_type, TYPE_MAX); Graph *g = &graph[p_type]; - for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { + for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { g->connections.erase(E); g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node); @@ -780,12 +780,12 @@ Array VisualShader::_get_node_connections(Type p_type) const { const Graph *g = &graph[p_type]; Array ret; - for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { + for (const Connection &E : g->connections) { Dictionary d; - d["from_node"] = E->get().from_node; - d["from_port"] = E->get().from_port; - d["to_node"] = E->get().to_node; - d["to_port"] = E->get().to_port; + d["from_node"] = E.from_node; + d["from_port"] = E.from_port; + d["to_node"] = E.to_node; + d["to_port"] = E.to_port; ret.push_back(d); } @@ -796,8 +796,8 @@ void VisualShader::get_node_connections(Type p_type, List<Connection> *r_connect ERR_FAIL_INDEX(p_type, TYPE_MAX); const Graph *g = &graph[p_type]; - for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { - r_connections->push_back(E->get()); + for (const Connection &E : g->connections) { + r_connections->push_back(E); } } @@ -1190,11 +1190,11 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { String index = name.get_slicec('/', 2); if (index == "connections") { Vector<int> conns; - for (const List<Connection>::Element *E = graph[type].connections.front(); E; E = E->next()) { - conns.push_back(E->get().from_node); - conns.push_back(E->get().from_port); - conns.push_back(E->get().to_node); - conns.push_back(E->get().to_port); + for (const Connection &E : graph[type].connections) { + conns.push_back(E.from_node); + conns.push_back(E.from_port); + conns.push_back(E.to_node); + conns.push_back(E.to_port); } r_ret = conns; @@ -1791,8 +1791,8 @@ void VisualShader::_update_shader() const { ERR_FAIL_COND(err != OK); if (emitters.has(i)) { - for (List<int>::Element *E = emitters[i].front(); E; E = E->next()) { - err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E->get(), processed, false, classes); + for (int &E : emitters[i]) { + err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes); ERR_FAIL_COND(err != OK); } } @@ -2586,8 +2586,8 @@ void VisualShaderNodeUniformRef::clear_uniforms() { } bool VisualShaderNodeUniformRef::has_uniform(const String &p_name) { - for (List<VisualShaderNodeUniformRef::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().name == p_name) { + for (const VisualShaderNodeUniformRef::Uniform &E : uniforms) { + if (E.name == p_name) { return true; } } diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index d53d155cce..b8173c9623 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -136,6 +136,7 @@ SceneStringNames::SceneStringNames() { _spatial_editor_group = StaticCString::create("_spatial_editor_group"); _request_gizmo = StaticCString::create("_request_gizmo"); + _clear_subgizmo_selection = StaticCString::create("_clear_subgizmo_selection"); offset = StaticCString::create("offset"); unit_offset = StaticCString::create("unit_offset"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index a141c2b3aa..eddb0c33eb 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -156,6 +156,7 @@ public: StringName _spatial_editor_group; StringName _request_gizmo; + StringName _clear_subgizmo_selection; StringName offset; StringName unit_offset; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index be2a813fd1..3d44484033 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -346,8 +346,6 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_menu_remove_item", "menu_root", "idx"), &DisplayServer::global_menu_remove_item); ClassDB::bind_method(D_METHOD("global_menu_clear", "menu_root"), &DisplayServer::global_menu_clear); - ClassDB::bind_method(D_METHOD("alert", "text", "title"), &DisplayServer::alert, DEFVAL("Alert!")); - ClassDB::bind_method(D_METHOD("mouse_set_mode", "mouse_mode"), &DisplayServer::mouse_set_mode); ClassDB::bind_method(D_METHOD("mouse_get_mode"), &DisplayServer::mouse_get_mode); diff --git a/servers/display_server.h b/servers/display_server.h index 8d289b10fd..788206768c 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -143,8 +143,6 @@ public: virtual void global_menu_remove_item(const String &p_menu_root, int p_idx); virtual void global_menu_clear(const String &p_menu_root); - virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0; - enum MouseMode { MOUSE_MODE_VISIBLE, MOUSE_MODE_HIDDEN, diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h index 870401b180..d9ee91084f 100644 --- a/servers/display_server_headless.h +++ b/servers/display_server_headless.h @@ -55,8 +55,6 @@ public: bool has_feature(Feature p_feature) const override { return false; } String get_name() const override { return "headless"; } - void alert(const String &p_alert, const String &p_title = "ALERT!") override {} - int get_screen_count() const override { return 0; } Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Point2i(); } Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Size2i(); } diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index 6f244deb1e..7aa2f9b7de 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -532,13 +532,13 @@ void Body2DSW::integrate_velocities(real_t p_step) { } void Body2DSW::wakeup_neighbours() { - for (List<Pair<Constraint2DSW *, int>>::Element *E = constraint_list.front(); E; E = E->next()) { - const Constraint2DSW *c = E->get().first; + for (const Pair<Constraint2DSW *, int> &E : constraint_list) { + const Constraint2DSW *c = E.first; Body2DSW **n = c->get_body_ptr(); int bc = c->get_body_count(); for (int i = 0; i < bc; i++) { - if (i == E->get().second) { + if (i == E.second) { continue; } Body2DSW *b = n[i]; diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp index b8cb4cddc5..8b30160cc1 100644 --- a/servers/physics_2d/step_2d_sw.cpp +++ b/servers/physics_2d/step_2d_sw.cpp @@ -46,8 +46,8 @@ void Step2DSW::_populate_island(Body2DSW *p_body, LocalVector<Body2DSW *> &p_bod p_body_island.push_back(p_body); } - for (const List<Pair<Constraint2DSW *, int>>::Element *E = p_body->get_constraint_list().front(); E; E = E->next()) { - Constraint2DSW *constraint = (Constraint2DSW *)E->get().first; + for (const Pair<Constraint2DSW *, int> &E : p_body->get_constraint_list()) { + Constraint2DSW *constraint = (Constraint2DSW *)E.first; if (constraint->get_island_step() == _step) { continue; // Already processed. } @@ -56,7 +56,7 @@ void Step2DSW::_populate_island(Body2DSW *p_body, LocalVector<Body2DSW *> &p_bod all_constraints.push_back(constraint); for (int i = 0; i < constraint->get_body_count(); i++) { - if (i == E->get().second) { + if (i == E.second) { continue; } Body2DSW *other_body = constraint->get_body_ptr()[i]; diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h index d46437e782..d0f3dbbd35 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h @@ -322,12 +322,12 @@ public: m_angularLimits[2].m_hiLimit = angularUpper.z; } - //! Retrieves the angular limit informacion + //! Retrieves the angular limit information. G6DOFRotationalLimitMotor3DSW *getRotationalLimitMotor(int index) { return &m_angularLimits[index]; } - //! Retrieves the limit informacion + //! Retrieves the limit information. G6DOFTranslationalLimitMotor3DSW *getTranslationalLimitMotor() { return &m_linearLimits; } diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/slider_joint_3d_sw.cpp index db9bdb2986..1895fe1e2e 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/slider_joint_3d_sw.cpp @@ -200,7 +200,7 @@ void SliderJoint3DSW::solve(real_t p_step) { real_t softness = (i) ? m_softnessOrthoLin : (m_solveLinLim ? m_softnessLimLin : m_softnessDirLin); real_t restitution = (i) ? m_restitutionOrthoLin : (m_solveLinLim ? m_restitutionLimLin : m_restitutionDirLin); real_t damping = (i) ? m_dampingOrthoLin : (m_solveLinLim ? m_dampingLimLin : m_dampingDirLin); - // calcutate and apply impulse + // Calculate and apply impulse. real_t normalImpulse = softness * (restitution * depth / p_step - damping * rel_vel) * m_jacLinDiagABInv[i]; Vector3 impulse_vector = normal * normalImpulse; if (dynamic_A) { diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h index ebb81abdad..797a02a978 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.h +++ b/servers/rendering/renderer_rd/cluster_builder_rd.h @@ -235,7 +235,7 @@ public: Transform3D xform = view_xform * p_transform; float radius = xform.basis.get_uniform_scale(); - if (radius > 0.98 || radius < 1.02) { + if (radius > 0.98 && radius < 1.02) { xform.basis.orthonormalize(); } diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 5cf8895c8e..5dab066262 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -383,6 +383,8 @@ void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i } void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer."); + memset(©.push_constant, 0, sizeof(CopyPushConstant)); uint32_t base_flags = 0; @@ -416,6 +418,8 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back } void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian glow with the mobile renderer."); + memset(©.push_constant, 0, sizeof(CopyPushConstant)); CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; @@ -449,6 +453,57 @@ void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const RD::get_singleton()->compute_list_end(); } +void EffectsRD::gaussian_glow_raster(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the fragment version of the gaussian glow with the clustered renderer."); + + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + + BlurRasterMode blur_mode = p_first_pass && p_auto_exposure.is_valid() ? BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : BLUR_MODE_GAUSSIAN_GLOW; + uint32_t base_flags = 0; + + blur_raster.push_constant.pixel_size[0] = p_pixel_size.x; + blur_raster.push_constant.pixel_size[1] = p_pixel_size.y; + + blur_raster.push_constant.glow_strength = p_strength; + blur_raster.push_constant.glow_bloom = p_bloom; + blur_raster.push_constant.glow_hdr_threshold = p_hdr_bleed_treshold; + blur_raster.push_constant.glow_hdr_scale = p_hdr_bleed_scale; + blur_raster.push_constant.glow_exposure = p_exposure; + blur_raster.push_constant.glow_white = 0; //actually unused + blur_raster.push_constant.glow_luminance_cap = p_luminance_cap; + + blur_raster.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also + + //HORIZONTAL + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); + if (p_auto_exposure.is_valid() && p_first_pass) { + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_auto_exposure), 1); + } + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + + blur_raster.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + + blur_mode = BLUR_MODE_GAUSSIAN_GLOW; + + //VERTICAL + draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + + blur_raster.push_constant.flags = base_flags; + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -736,6 +791,8 @@ void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Tone } void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of luminance reduction with the mobile renderer."); + luminance_reduce.push_constant.source_size[0] = p_source_size.x; luminance_reduce.push_constant.source_size[1] = p_source_size.y; luminance_reduce.push_constant.max_luminance = p_max_luminance; @@ -774,7 +831,41 @@ void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_ RD::get_singleton()->compute_list_end(); } +void EffectsRD::luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use fragment version of luminance reduction with the clustered renderer."); + ERR_FAIL_COND_MSG(p_reduce.size() != p_fb.size(), "Incorrect frame buffer account for luminance reduction."); + + luminance_reduce_raster.push_constant.max_luminance = p_max_luminance; + luminance_reduce_raster.push_constant.min_luminance = p_min_luminance; + luminance_reduce_raster.push_constant.exposure_adjust = p_adjust; + + for (int i = 0; i < p_reduce.size(); i++) { + luminance_reduce_raster.push_constant.source_size[0] = i == 0 ? p_source_size.x : luminance_reduce_raster.push_constant.dest_size[0]; + luminance_reduce_raster.push_constant.source_size[1] = i == 0 ? p_source_size.y : luminance_reduce_raster.push_constant.dest_size[1]; + luminance_reduce_raster.push_constant.dest_size[0] = MAX(luminance_reduce_raster.push_constant.source_size[0] / 8, 1); + luminance_reduce_raster.push_constant.dest_size[1] = MAX(luminance_reduce_raster.push_constant.source_size[1] / 8, 1); + + bool final = !p_set && (luminance_reduce_raster.push_constant.dest_size[0] == 1) && (luminance_reduce_raster.push_constant.dest_size[1] == 1); + LuminanceReduceRasterMode mode = final ? LUMINANCE_REDUCE_FRAGMENT_FINAL : (i == 0 ? LUMINANCE_REDUCE_FRAGMENT_FIRST : LUMINANCE_REDUCE_FRAGMENT); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, luminance_reduce_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_fb[i]))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(i == 0 ? p_source_texture : p_reduce[i - 1]), 0); + if (final) { + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_prev_luminance), 1); + } + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &luminance_reduce_raster.push_constant, sizeof(LuminanceReduceRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + } +} + void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of BOKEH DOF with the mobile renderer."); + bokeh.push_constant.blur_far_active = p_dof_far; bokeh.push_constant.blur_far_begin = p_dof_far_begin; bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; @@ -924,6 +1015,78 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_end(); } +void EffectsRD::blur_dof_raster(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_base_fb, RID p_secondary_texture, RID p_secondary_fb, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_dof_blur_amount, RS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use blur DOF with the clustered renderer."); + + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + + BlurRasterMode blur_mode; + int qsteps[4] = { 4, 4, 10, 20 }; + uint32_t base_flags = p_cam_orthogonal ? BLUR_FLAG_USE_ORTHOGONAL_PROJECTION : 0; + + Vector2 pixel_size = Vector2(1.0 / p_base_texture_size.width, 1.0 / p_base_texture_size.height); + + blur_raster.push_constant.dof_radius = (p_dof_blur_amount * p_dof_blur_amount) / qsteps[p_quality]; + blur_raster.push_constant.pixel_size[0] = pixel_size.x; + blur_raster.push_constant.pixel_size[1] = pixel_size.y; + blur_raster.push_constant.camera_z_far = p_cam_zfar; + blur_raster.push_constant.camera_z_near = p_cam_znear; + + if (p_dof_far || p_dof_near) { + if (p_quality == RS::DOF_BLUR_QUALITY_HIGH) { + blur_mode = BLUR_MODE_DOF_HIGH; + } else if (p_quality == RS::DOF_BLUR_QUALITY_MEDIUM) { + blur_mode = BLUR_MODE_DOF_MEDIUM; + } else { // for LOW or VERYLOW we use LOW + blur_mode = BLUR_MODE_DOF_LOW; + } + + if (p_dof_far) { + base_flags |= BLUR_FLAG_DOF_FAR; + blur_raster.push_constant.dof_far_begin = p_dof_far_begin; + blur_raster.push_constant.dof_far_end = p_dof_far_begin + p_dof_far_size; + } + + if (p_dof_near) { + base_flags |= BLUR_FLAG_DOF_NEAR; + blur_raster.push_constant.dof_near_begin = p_dof_near_begin; + blur_raster.push_constant.dof_near_end = p_dof_near_begin - p_dof_near_size; + } + + //HORIZONTAL + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_secondary_fb, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_secondary_fb))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base_texture), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_depth_texture), 1); + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + + blur_raster.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL; + blur_raster.push_constant.dof_dir[0] = 1.0; + blur_raster.push_constant.dof_dir[1] = 0.0; + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + + //VERTICAL + draw_list = RD::get_singleton()->draw_list_begin(p_base_fb, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_base_fb))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_secondary_texture), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_depth_texture), 1); + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + + blur_raster.push_constant.flags = base_flags; + blur_raster.push_constant.dof_dir[0] = 0.0; + blur_raster.push_constant.dof_dir[1] = 1.0; + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + } +} + void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) { RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0); if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) { @@ -1464,7 +1627,35 @@ void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { RD::get_singleton()->compute_list_end(); } -EffectsRD::EffectsRD() { +EffectsRD::EffectsRD(bool p_prefer_raster_effects) { + prefer_raster_effects = p_prefer_raster_effects; + + if (prefer_raster_effects) { + // init blur shader (on compute use copy shader) + + Vector<String> blur_modes; + blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); // BLUR_MODE_GAUSSIAN_BLUR + blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); // BLUR_MODE_GAUSSIAN_GLOW + blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); // BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE + blur_modes.push_back("\n#define MODE_DOF_BLUR\n#define DOF_QUALITY_LOW\n"); // BLUR_MODE_DOF_LOW + blur_modes.push_back("\n#define MODE_DOF_BLUR\n#define DOF_QUALITY_MEDIUM\n"); // BLUR_MODE_DOF_MEDIUM + blur_modes.push_back("\n#define MODE_DOF_BLUR\n#define DOF_QUALITY_HIGH\n"); // BLUR_MODE_DOF_HIGH + + blur_raster.shader.initialize(blur_modes); + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + blur_raster.shader_version = blur_raster.shader.version_create(); + + for (int i = 0; i < BLUR_MODE_MAX; i++) { + blur_raster.pipelines[i].setup(blur_raster.shader.version_get_shader(blur_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } + + } else { + // not used in clustered + for (int i = 0; i < BLUR_MODE_MAX; i++) { + blur_raster.pipelines[i].clear(); + } + } + { // Initialize copy Vector<String> copy_modes; copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); @@ -1483,10 +1674,21 @@ EffectsRD::EffectsRD() { copy.shader.initialize(copy_modes); memset(©.push_constant, 0, sizeof(CopyPushConstant)); + + if (prefer_raster_effects) { + // disable shaders we can't use + copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_COPY, false); + copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_COPY_8BIT, false); + copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_GLOW, false); + copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, false); + } + copy.shader_version = copy.shader.version_create(); for (int i = 0; i < COPY_MODE_MAX; i++) { - copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i)); + if (copy.shader.is_variant_enabled(i)) { + copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i)); + } } } { @@ -1551,7 +1753,20 @@ EffectsRD::EffectsRD() { } } - { + if (prefer_raster_effects) { + Vector<String> luminance_reduce_modes; + luminance_reduce_modes.push_back("\n#define FIRST_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FIRST + luminance_reduce_modes.push_back("\n"); // LUMINANCE_REDUCE_FRAGMENT + luminance_reduce_modes.push_back("\n#define FINAL_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FINAL + + luminance_reduce_raster.shader.initialize(luminance_reduce_modes); + memset(&luminance_reduce_raster.push_constant, 0, sizeof(LuminanceReduceRasterPushConstant)); + luminance_reduce_raster.shader_version = luminance_reduce_raster.shader.version_create(); + + for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) { + luminance_reduce_raster.pipelines[i].setup(luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } + } else { // Initialize luminance_reduce Vector<String> luminance_reduce_modes; luminance_reduce_modes.push_back("\n#define READ_TEXTURE\n"); @@ -1565,6 +1780,10 @@ EffectsRD::EffectsRD() { for (int i = 0; i < LUMINANCE_REDUCE_MAX; i++) { luminance_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, i)); } + + for (int i = 0; i < LUMINANCE_REDUCE_FRAGMENT_MAX; i++) { + luminance_reduce_raster.pipelines[i].clear(); + } } { @@ -1583,7 +1802,9 @@ EffectsRD::EffectsRD() { cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0); } - { + if (prefer_raster_effects) { + // not supported + } else { // Initialize bokeh Vector<String> bokeh_modes; bokeh_modes.push_back("\n#define MODE_GEN_BLUR_SIZE\n"); @@ -1974,13 +2195,18 @@ EffectsRD::~EffectsRD() { RD::get_singleton()->free(ssao.gather_constants_buffer); RD::get_singleton()->free(ssao.importance_map_load_counter); - bokeh.shader.version_free(bokeh.shader_version); + if (prefer_raster_effects) { + blur_raster.shader.version_free(blur_raster.shader_version); + luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version); + } else { + bokeh.shader.version_free(bokeh.shader_version); + luminance_reduce.shader.version_free(luminance_reduce.shader_version); + } copy.shader.version_free(copy.shader_version); copy_to_fb.shader.version_free(copy_to_fb.shader_version); cube_to_dp.shader.version_free(cube_to_dp.shader_version); cubemap_downsampler.shader.version_free(cubemap_downsampler.shader_version); filter.shader.version_free(filter.shader_version); - luminance_reduce.shader.version_free(luminance_reduce.shader_version); resolve.shader.version_free(resolve.shader_version); roughness.shader.version_free(roughness.shader_version); roughness_limiter.shader.version_free(roughness_limiter.shader_version); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 33d32f0c57..d072564c23 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -33,6 +33,7 @@ #include "core/math/camera_matrix.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/shaders/blur_raster.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/bokeh_dof.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/copy.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/copy_to_fb.glsl.gen.h" @@ -41,6 +42,7 @@ #include "servers/rendering/renderer_rd/shaders/cubemap_filter.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/resolve.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h" @@ -60,6 +62,63 @@ #include "servers/rendering_server.h" class EffectsRD { + enum BlurRasterMode { + BLUR_MODE_GAUSSIAN_BLUR, + BLUR_MODE_GAUSSIAN_GLOW, + BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, + + BLUR_MODE_DOF_LOW, + BLUR_MODE_DOF_MEDIUM, + BLUR_MODE_DOF_HIGH, + + BLUR_MODE_MAX + }; + + enum { + BLUR_FLAG_HORIZONTAL = (1 << 0), + BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 1), + BLUR_FLAG_GLOW_FIRST_PASS = (1 << 2), + BLUR_FLAG_DOF_FAR = (1 << 3), + BLUR_FLAG_DOF_NEAR = (1 << 4), + }; + + struct BlurRasterPushConstant { + float pixel_size[2]; + uint32_t flags; + uint32_t pad; + + //glow + float glow_strength; + float glow_bloom; + float glow_hdr_threshold; + float glow_hdr_scale; + + float glow_exposure; + float glow_white; + float glow_luminance_cap; + float glow_auto_exposure_grey; + + //dof + float dof_far_begin; + float dof_far_end; + float dof_near_begin; + float dof_near_end; + + float dof_radius; + float dof_pad[3]; + + float dof_dir[2]; + float camera_z_far; + float camera_z_near; + }; + + struct BlurRaster { + BlurRasterPushConstant push_constant; + BlurRasterShaderRD shader; + RID shader_version; + PipelineCacheRD pipelines[BLUR_MODE_MAX]; + } blur_raster; + enum CopyMode { COPY_MODE_GAUSSIAN_COPY, COPY_MODE_GAUSSIAN_COPY_8BIT, @@ -239,6 +298,29 @@ class EffectsRD { RID pipelines[LUMINANCE_REDUCE_MAX]; } luminance_reduce; + enum LuminanceReduceRasterMode { + LUMINANCE_REDUCE_FRAGMENT_FIRST, + LUMINANCE_REDUCE_FRAGMENT, + LUMINANCE_REDUCE_FRAGMENT_FINAL, + LUMINANCE_REDUCE_FRAGMENT_MAX + }; + + struct LuminanceReduceRasterPushConstant { + int32_t source_size[2]; + int32_t dest_size[2]; + float exposure_adjust; + float min_luminance; + float max_luminance; + float pad[1]; + }; + + struct LuminanceReduceFragment { + LuminanceReduceRasterPushConstant push_constant; + LuminanceReduceRasterShaderRD shader; + RID shader_version; + PipelineCacheRD pipelines[LUMINANCE_REDUCE_FRAGMENT_MAX]; + } luminance_reduce_raster; + struct CopyToDPPushConstant { float z_far; float z_near; @@ -656,6 +738,8 @@ class EffectsRD { RID _get_compute_uniform_set_from_texture_pair(RID p_texture, RID p_texture2, bool p_use_mipmaps = false); RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2); + bool prefer_raster_effects; + public: void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID()); void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false); @@ -666,12 +750,16 @@ public: void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false); void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false); void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); + void gaussian_glow_raster(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); + void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); + void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); + void blur_dof_raster(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_base_fb, RID p_secondary_texture, RID p_secondary_fb, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_dof_blur_amount, RS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); struct TonemapSettings { bool use_glow = false; @@ -751,7 +839,7 @@ public: void sort_buffer(RID p_uniform_set, int p_size); - EffectsRD(); + EffectsRD(bool p_prefer_raster_effects); ~EffectsRD(); }; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 438bbff53c..5f6d9465c7 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -96,10 +96,6 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b RD::DataFormat color_format = RenderForwardMobile::singleton->_render_buffers_get_color_format(); if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) { - if (color_format == RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32) { - // @TODO add a second color buffer for alpha as this format is RGB only - } - Vector<RID> fb; fb.push_back(p_color_buffer); fb.push_back(depth); @@ -164,16 +160,13 @@ bool RenderForwardMobile::free(RID p_rid) { /* Render functions */ RD::DataFormat RenderForwardMobile::_render_buffers_get_color_format() { - // Using 32bit buffers enables AFBC on mobile devices which should have a definate performance improvement (MALI G710 and newer support this on 64bit RTs) - // NO ALPHA and unsigned float. - // @TODO No alpha is an issue, recommendation here is to add a second RT for alpha + // Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs) return RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32; } bool RenderForwardMobile::_render_buffers_can_be_storage() { - // Using 32bit buffers enables AFBC on mobile devices which should have a definate performance improvement (MALI G710 and newer support this on 64bit RTs) - // NO ALPHA and unsigned float. - // @TODO No alpha is an issue, recommendation here is to add a second RT for alpha + // Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs) + // Doesn't support storage return false; } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 6a66e9fa01..18c1fe02a0 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -620,7 +620,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array); RD::get_singleton()->draw_list_draw(p_draw_list, true); - //restore if overrided + // Restore if overridden. push_constant.color_texture_pixel_size[0] = texpixel_size.x; push_constant.color_texture_pixel_size[1] = texpixel_size.y; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index e6ae66d56f..a7ee0dd141 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -280,6 +280,9 @@ RendererCompositorRD::RendererCompositorRD() { // default to our high end renderer scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered(storage)); } + + // now we're ready to create our effects, + storage->init_effects(!scene->_render_buffers_can_be_storage()); } RendererCompositorRD::~RendererCompositorRD() { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 4870f5f397..2e0e7c3c43 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1383,12 +1383,20 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { uint32_t mipmaps_required = Image::get_image_required_mipmaps(rb->width, rb->height, Image::FORMAT_RGBAH); + // TODO make sure texture_create_shared_from_slice works for multiview + RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.format = _render_buffers_get_color_format(); // RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = rb->width; tf.height = rb->height; - tf.texture_type = RD::TEXTURE_TYPE_2D; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + tf.texture_type = rb->view_count > 1 ? RD::TEXTURE_TYPE_2D_ARRAY : RD::TEXTURE_TYPE_2D; + tf.array_layers = rb->view_count; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + if (_render_buffers_can_be_storage()) { + tf.usage_bits += RD::TEXTURE_USAGE_STORAGE_BIT; + } else { + tf.usage_bits += RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + } tf.mipmaps = mipmaps_required; rb->blur[0].texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -1408,11 +1416,40 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { mm.width = base_width; mm.height = base_height; + if (!_render_buffers_can_be_storage()) { + Vector<RID> fb; + fb.push_back(mm.texture); + + mm.fb = RD::get_singleton()->framebuffer_create(fb); + } + + if (!_render_buffers_can_be_storage()) { + // and half texture, this is an intermediate result so just allocate a texture, is this good enough? + tf.width = MAX(1, base_width >> 1); + tf.height = base_height; + tf.mipmaps = 1; // 1 or 0? + + mm.half_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + Vector<RID> half_fb; + half_fb.push_back(mm.half_texture); + mm.half_fb = RD::get_singleton()->framebuffer_create(half_fb); + } + rb->blur[0].mipmaps.push_back(mm); if (i > 0) { mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1); + if (!_render_buffers_can_be_storage()) { + Vector<RID> fb; + fb.push_back(mm.texture); + + mm.fb = RD::get_singleton()->framebuffer_create(fb); + + // We can re-use the half texture here as it is an intermediate result + } + rb->blur[1].mipmaps.push_back(mm); } @@ -1435,26 +1472,48 @@ void RendererSceneRenderRD::_allocate_luminance_textures(RenderBuffers *rb) { tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = w; tf.height = h; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; bool final = w == 1 && h == 1; - if (final) { - tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT; + if (_render_buffers_can_be_storage()) { + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; + if (final) { + tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT; + } + } else { + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; } RID texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); rb->luminance.reduce.push_back(texture); + if (!_render_buffers_can_be_storage()) { + Vector<RID> fb; + fb.push_back(texture); + + rb->luminance.fb.push_back(RD::get_singleton()->framebuffer_create(fb)); + } if (final) { rb->luminance.current = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + if (!_render_buffers_can_be_storage()) { + Vector<RID> fb; + fb.push_back(rb->luminance.current); + + rb->luminance.current_fb = RD::get_singleton()->framebuffer_create(fb); + } break; } } } void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { + if (rb->texture_fb.is_valid()) { + RD::get_singleton()->free(rb->texture_fb); + rb->texture_fb = RID(); + } + if (rb->texture.is_valid()) { RD::get_singleton()->free(rb->texture); rb->texture = RID(); @@ -1466,19 +1525,43 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { } for (int i = 0; i < 2; i++) { + for (int m = 0; m < rb->blur[i].mipmaps.size(); m++) { + // do we free the texture slice here? or is it enough to free the main texture? + + // do free the mobile extra stuff + if (rb->blur[i].mipmaps[m].fb.is_valid()) { + RD::get_singleton()->free(rb->blur[i].mipmaps[m].fb); + } + if (rb->blur[i].mipmaps[m].half_fb.is_valid()) { + RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_fb); + } + if (rb->blur[i].mipmaps[m].half_texture.is_valid()) { + RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_texture); + } + } + rb->blur[i].mipmaps.clear(); + if (rb->blur[i].texture.is_valid()) { RD::get_singleton()->free(rb->blur[i].texture); rb->blur[i].texture = RID(); - rb->blur[i].mipmaps.clear(); } } + for (int i = 0; i < rb->luminance.fb.size(); i++) { + RD::get_singleton()->free(rb->luminance.fb[i]); + } + rb->luminance.fb.clear(); + for (int i = 0; i < rb->luminance.reduce.size(); i++) { RD::get_singleton()->free(rb->luminance.reduce[i]); } - rb->luminance.reduce.clear(); + if (rb->luminance.current_fb.is_valid()) { + RD::get_singleton()->free(rb->luminance.current_fb); + rb->luminance.current_fb = RID(); + } + if (rb->luminance.current.is_valid()) { RD::get_singleton()->free(rb->luminance.current); rb->luminance.current = RID(); @@ -1750,17 +1833,27 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende CameraEffects *camfx = camera_effects_owner.getornull(p_render_data->camera_effects); bool can_use_effects = rb->width >= 8 && rb->height >= 8; + bool can_use_storage = _render_buffers_can_be_storage(); + + // @TODO IMPLEMENT MULTIVIEW, all effects need to support stereo buffers or effects are only applied to the left eye if (can_use_effects && camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0) { + RD::get_singleton()->draw_command_begin_label("DOF"); if (rb->blur[0].texture.is_null()) { _allocate_blur_textures(rb); } - float bokeh_size = camfx->dof_blur_amount * 64.0; - storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); + if (can_use_storage) { + float bokeh_size = camfx->dof_blur_amount * 64.0; + storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); + } else { + storage->get_effects()->blur_dof_raster(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->texture_fb, rb->blur[0].mipmaps[0].texture, rb->blur[0].mipmaps[0].fb, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, camfx->dof_blur_amount, dof_blur_quality, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); + } + RD::get_singleton()->draw_command_end_label(); } if (can_use_effects && env && env->auto_exposure) { + RD::get_singleton()->draw_command_begin_label("Auto exposure"); if (rb->luminance.current.is_null()) { _allocate_luminance_textures(rb); } @@ -1769,16 +1862,26 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende rb->auto_exposure_version = env->auto_exposure_version; double step = env->auto_exp_speed * time_step; - storage->get_effects()->luminance_reduction(rb->texture, Size2i(rb->width, rb->height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); - + if (can_use_storage) { + storage->get_effects()->luminance_reduction(rb->texture, Size2i(rb->width, rb->height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + } else { + storage->get_effects()->luminance_reduction_raster(rb->texture, Size2i(rb->width, rb->height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + } //swap final reduce with prev luminance SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]); + if (!can_use_storage) { + SWAP(rb->luminance.current_fb, rb->luminance.fb.write[rb->luminance.fb.size() - 1]); + } + RenderingServerDefault::redraw_request(); //redraw all the time if auto exposure rendering is on + RD::get_singleton()->draw_command_end_label(); } int max_glow_level = -1; if (can_use_effects && env && env->glow_enabled) { + RD::get_singleton()->draw_command_begin_label("Gaussian Glow"); + /* see that blur textures are allocated */ if (rb->blur[1].texture.is_null()) { @@ -1804,14 +1907,26 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende if (env->auto_exposure && rb->luminance.current.is_valid()) { luminance_texture = rb->luminance.current; } - storage->get_effects()->gaussian_glow(rb->texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + if (can_use_storage) { + storage->get_effects()->gaussian_glow(rb->texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + } else { + storage->get_effects()->gaussian_glow_raster(rb->texture, rb->blur[1].mipmaps[i].half_fb, rb->blur[1].mipmaps[i].half_texture, rb->blur[1].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + } } else { - storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + if (can_use_storage) { + storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + } else { + storage->get_effects()->gaussian_glow_raster(rb->blur[1].mipmaps[i - 1].texture, rb->blur[1].mipmaps[i].half_fb, rb->blur[1].mipmaps[i].half_texture, rb->blur[1].mipmaps[i].fb, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength, glow_high_quality); + } } } + + RD::get_singleton()->draw_command_end_label(); } { + RD::get_singleton()->draw_command_begin_label("Tonemap"); + //tonemap EffectsRD::TonemapSettings tonemap; @@ -1870,6 +1985,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.view_count = p_render_data->view_count; storage->get_effects()->tonemapper(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), tonemap); + + RD::get_singleton()->draw_command_end_label(); } storage->render_target_disable_clear_request(rb->render_target); @@ -2133,7 +2250,7 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() { } void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) { - ERR_FAIL_COND_MSG(p_view_count == 0, "Must have atleast 1 view"); + ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view"); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); rb->width = p_width; @@ -2197,6 +2314,14 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p rb->depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); } + if (!_render_buffers_can_be_storage()) { + // ONLY USED ON MOBILE RENDERER, ONLY USED FOR POST EFFECTS! + Vector<RID> fb; + fb.push_back(rb->texture); + + rb->texture_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, rb->view_count); + } + rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa, p_view_count); if (is_clustered_enabled()) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 5e0281002d..bb06eb608f 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -450,6 +450,7 @@ private: RID texture; //main texture for rendering to, must be filled after done rendering RID depth_texture; //main depth texture + RID texture_fb; // framebuffer for the main texture, ONLY USED FOR MOBILE RENDERER POST EFFECTS, DO NOT USE FOR RENDERING 3D!!! RendererSceneGIRD::SDFGI *sdfgi = nullptr; VolumetricFog *volumetric_fog = nullptr; @@ -465,6 +466,11 @@ private: RID texture; int width; int height; + + // only used on mobile renderer + RID fb; + RID half_texture; + RID half_fb; }; Vector<Mipmap> mipmaps; @@ -475,6 +481,10 @@ private: struct Luminance { Vector<RID> reduce; RID current; + + // used only on mobile renderer + Vector<RID> fb; + RID current_fb; } luminance; struct SSAO { diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 2657fa3ae8..d5c7db6fd2 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -2716,9 +2716,7 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su mesh->surfaces[mesh->surface_count] = s; mesh->surface_count++; - for (List<MeshInstance *>::Element *E = mesh->instances.front(); E; E = E->next()) { - //update instances - MeshInstance *mi = E->get(); + for (MeshInstance *mi : mesh->instances) { _mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1); } @@ -3029,8 +3027,7 @@ void RendererStorageRD::mesh_clear(RID p_mesh) { mesh->surface_count = 0; mesh->material_cache.clear(); //clear instance data - for (List<MeshInstance *>::Element *E = mesh->instances.front(); E; E = E->next()) { - MeshInstance *mi = E->get(); + for (MeshInstance *mi : mesh->instances) { _mesh_instance_clear(mi); } mesh->has_bone_weights = false; @@ -4962,7 +4959,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); - effects.sort_buffer(particles->particles_sort_uniform_set, particles->amount); + effects->sort_buffer(particles->particles_sort_uniform_set, particles->amount); } copy_push_constant.total_particles *= copy_push_constant.total_particles; @@ -7538,7 +7535,7 @@ void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, c //single texture copy for backbuffer //RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true); - effects.copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true); + effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true); if (!p_gen_mipmaps) { return; @@ -7554,7 +7551,7 @@ void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, c region.size.y = MAX(1, region.size.y >> 1); const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i]; - effects.gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true); + effects->gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true); prev_texture = mm.mipmap; } } @@ -7577,7 +7574,7 @@ void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, con } //single texture copy for backbuffer - effects.set_color(rt->backbuffer_mipmap0, p_color, region, true); + effects->set_color(rt->backbuffer_mipmap0, p_color, region, true); } void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) { @@ -7607,7 +7604,7 @@ void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_targe region.size.y = MAX(1, region.size.y >> 1); const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i]; - effects.gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true); + effects->gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true); prev_texture = mm.mipmap; } } @@ -7928,14 +7925,14 @@ void RendererStorageRD::_update_decal_atlas() { while ((K = decal_atlas.textures.next(K))) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); Texture *src_tex = texture_owner.getornull(*K); - effects.copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); + effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); } RD::get_singleton()->draw_list_end(); prev_texture = mm.texture; } else { - effects.copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size)); + effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size)); prev_texture = mm.texture; } } else { @@ -8413,10 +8410,10 @@ void RendererStorageRD::global_variables_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); - for (List<PropertyInfo>::Element *E = settings.front(); E; E = E->next()) { - if (E->get().name.begins_with("shader_globals/")) { - StringName name = E->get().name.get_slice("/", 1); - Dictionary d = ProjectSettings::get_singleton()->get(E->get().name); + for (const PropertyInfo &E : settings) { + if (E.name.begins_with("shader_globals/")) { + StringName name = E.name.get_slice("/", 1); + Dictionary d = ProjectSettings::get_singleton()->get(E.name); ERR_CONTINUE(!d.has("type")); ERR_CONTINUE(!d.has("value")); @@ -8584,8 +8581,8 @@ void RendererStorageRD::_update_global_variables() { if (global_variables.must_update_buffer_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (List<RID>::Element *E = global_variables.materials_using_buffer.front(); E; E = E->next()) { - Material *material = material_owner.getornull(E->get()); + for (const RID &E : global_variables.materials_using_buffer) { + Material *material = material_owner.getornull(E); ERR_CONTINUE(!material); //wtf _material_queue_update(material, true, false); @@ -8597,8 +8594,8 @@ void RendererStorageRD::_update_global_variables() { if (global_variables.must_update_texture_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (List<RID>::Element *E = global_variables.materials_using_texture.front(); E; E = E->next()) { - Material *material = material_owner.getornull(E->get()); + for (const RID &E : global_variables.materials_using_texture) { + Material *material = material_owner.getornull(E); ERR_CONTINUE(!material); //wtf _material_queue_update(material, false, true); @@ -8807,8 +8804,13 @@ bool RendererStorageRD::free(RID p_rid) { return true; } +void RendererStorageRD::init_effects(bool p_prefer_raster_effects) { + effects = memnew(EffectsRD(p_prefer_raster_effects)); +} + EffectsRD *RendererStorageRD::get_effects() { - return &effects; + ERR_FAIL_NULL_V_MSG(effects, nullptr, "Effects haven't been initialised yet."); + return effects; } void RendererStorageRD::capture_timestamps_begin() { @@ -9538,4 +9540,9 @@ RendererStorageRD::~RendererStorageRD() { if (decal_atlas.texture.is_valid()) { RD::get_singleton()->free(decal_atlas.texture); } + + if (effects) { + memdelete(effects); + effects = NULL; + } } diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index f471874c8e..b290c07705 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -1290,7 +1290,7 @@ private: void _update_global_variables(); /* EFFECTS */ - EffectsRD effects; + EffectsRD *effects = NULL; public: virtual bool can_create_resources_async() const; @@ -2374,6 +2374,7 @@ public: static RendererStorageRD *base_singleton; + void init_effects(bool p_prefer_raster_effects); EffectsRD *get_effects(); RendererStorageRD(); diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 1dde92d8ff..9c1068ea2e 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -571,7 +571,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge max_texture_uniforms++; } else { if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; //instances are indexed directly, dont need index uniforms + continue; // Instances are indexed directly, don't need index uniforms. } max_uniforms++; @@ -605,7 +605,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge if (uniform.scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { //insert, but don't generate any code. p_actions.uniforms->insert(uniform_name, uniform); - continue; //instances are indexed directly, dont need index uniforms + continue; // Instances are indexed directly, don't need index uniforms. } if (SL::is_sampler_type(uniform.type)) { ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_order) + ") uniform "; @@ -760,11 +760,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge if (var_frag_to_light.size() > 0) { String gcode = "\n\nstruct {\n"; - for (List<Pair<StringName, SL::ShaderNode::Varying>>::Element *E = var_frag_to_light.front(); E; E = E->next()) { - gcode += "\t" + _prestr(E->get().second.precision) + _typestr(E->get().second.type) + " " + _mkid(E->get().first); - if (E->get().second.array_size > 0) { + for (const Pair<StringName, SL::ShaderNode::Varying> &E : var_frag_to_light) { + gcode += "\t" + _prestr(E.second.precision) + _typestr(E.second.type) + " " + _mkid(E.first); + if (E.second.array_size > 0) { gcode += "["; - gcode += itos(E->get().second.array_size); + gcode += itos(E.second.array_size); gcode += "]"; } gcode += ";\n"; @@ -1394,8 +1394,8 @@ void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) { ShaderLanguage::get_builtin_funcs(&func_list); - for (List<String>::Element *E = func_list.front(); E; E = E->next()) { - internal_functions.insert(E->get()); + for (const String &E : func_list) { + internal_functions.insert(E); } texture_functions.insert("texture"); texture_functions.insert("textureProj"); diff --git a/servers/rendering/renderer_rd/shaders/blur_raster.glsl b/servers/rendering/renderer_rd/shaders/blur_raster.glsl new file mode 100644 index 0000000000..b1d1c2365e --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/blur_raster.glsl @@ -0,0 +1,228 @@ +/* clang-format off */ +#[vertex] + +#version 450 + +#VERSION_DEFINES + +#include "blur_raster_inc.glsl" + +layout(location = 0) out vec2 uv_interp; +/* clang-format on */ + +void main() { + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv_interp = base_arr[gl_VertexIndex]; + + gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); +} + +/* clang-format off */ +#[fragment] + +#version 450 + +#VERSION_DEFINES + +#include "blur_raster_inc.glsl" + +layout(location = 0) in vec2 uv_interp; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform sampler2D source_color; + +#ifdef GLOW_USE_AUTO_EXPOSURE +layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; +#endif + +layout(location = 0) out vec4 frag_color; + +//DOF +#ifdef MODE_DOF_BLUR + +layout(set = 1, binding = 0) uniform sampler2D dof_source_depth; + +#ifdef DOF_QUALITY_LOW +const int dof_kernel_size = 5; +const int dof_kernel_from = 2; +const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388); +#endif + +#ifdef DOF_QUALITY_MEDIUM +const int dof_kernel_size = 11; +const int dof_kernel_from = 5; +const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037); + +#endif + +#ifdef DOF_QUALITY_HIGH +const int dof_kernel_size = 21; +const int dof_kernel_from = 10; +const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174); +#endif + +#endif + +void main() { +#ifdef MODE_MIPMAP + + vec2 pix_size = blur.pixel_size; + vec4 color = texture(source_color, uv_interp + vec2(-0.5, -0.5) * pix_size); + color += texture(source_color, uv_interp + vec2(0.5, -0.5) * pix_size); + color += texture(source_color, uv_interp + vec2(0.5, 0.5) * pix_size); + color += texture(source_color, uv_interp + vec2(-0.5, 0.5) * pix_size); + frag_color = color / 4.0; + +#endif + +#ifdef MODE_GAUSSIAN_BLUR + + //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect + + if (bool(blur.flags & FLAG_HORIZONTAL)) { + vec2 pix_size = blur.pixel_size; + pix_size *= 0.5; //reading from larger buffer, so use more samples + vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607; + color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879; + color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514; + color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303; + color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879; + color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514; + color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303; + frag_color = color; + } else { + vec2 pix_size = blur.pixel_size; + vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774; + color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477; + color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136; + color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477; + color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136; + frag_color = color; + } +#endif + +#ifdef MODE_GAUSSIAN_GLOW + + //Glow uses larger sigma 1 for a more rounded blur effect + +#define GLOW_ADD(m_ofs, m_mult) \ + { \ + vec2 ofs = uv_interp + m_ofs * pix_size; \ + vec4 c = texture(source_color, ofs) * m_mult; \ + if (any(lessThan(ofs, vec2(0.0))) || any(greaterThan(ofs, vec2(1.0)))) { \ + c *= 0.0; \ + } \ + color += c; \ + } + + if (bool(blur.flags & FLAG_HORIZONTAL)) { + vec2 pix_size = blur.pixel_size; + pix_size *= 0.5; //reading from larger buffer, so use more samples + vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.174938; + GLOW_ADD(vec2(1.0, 0.0), 0.165569); + GLOW_ADD(vec2(2.0, 0.0), 0.140367); + GLOW_ADD(vec2(3.0, 0.0), 0.106595); + GLOW_ADD(vec2(-1.0, 0.0), 0.165569); + GLOW_ADD(vec2(-2.0, 0.0), 0.140367); + GLOW_ADD(vec2(-3.0, 0.0), 0.106595); + color *= blur.glow_strength; + frag_color = color; + } else { + vec2 pix_size = blur.pixel_size; + vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.288713; + GLOW_ADD(vec2(0.0, 1.0), 0.233062); + GLOW_ADD(vec2(0.0, 2.0), 0.122581); + GLOW_ADD(vec2(0.0, -1.0), 0.233062); + GLOW_ADD(vec2(0.0, -2.0), 0.122581); + color *= blur.glow_strength; + frag_color = color; + } + +#undef GLOW_ADD + + if (bool(blur.flags & FLAG_GLOW_FIRST_PASS)) { +#ifdef GLOW_USE_AUTO_EXPOSURE + + frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / blur.glow_auto_exposure_grey; +#endif + frag_color *= blur.glow_exposure; + + float luminance = max(frag_color.r, max(frag_color.g, frag_color.b)); + float feedback = max(smoothstep(blur.glow_hdr_threshold, blur.glow_hdr_threshold + blur.glow_hdr_scale, luminance), blur.glow_bloom); + + frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap)); + } + +#endif + +#ifdef MODE_DOF_BLUR + + vec4 color_accum = vec4(0.0); + + float depth = texture(dof_source_depth, uv_interp, 0.0).r; + depth = depth * 2.0 - 1.0; + + if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { + depth = ((depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; + } else { + depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near)); + } + + // mix near and far blur amount + float amount = 1.0; + if (bool(blur.flags & FLAG_DOF_FAR)) { + amount *= 1.0 - smoothstep(blur.dof_far_begin, blur.dof_far_end, depth); + } + if (bool(blur.flags & FLAG_DOF_NEAR)) { + amount *= smoothstep(blur.dof_near_end, blur.dof_near_begin, depth); + } + amount = 1.0 - amount; + + if (amount > 0.0) { + float k_accum = 0.0; + + for (int i = 0; i < dof_kernel_size; i++) { + int int_ofs = i - dof_kernel_from; + vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * amount * blur.dof_radius; + + float tap_k = dof_kernel[i]; + + float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; + tap_depth = tap_depth * 2.0 - 1.0; + + if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { + tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; + } else { + tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near)); + } + + // mix near and far blur amount + float tap_amount = 1.0; + if (bool(blur.flags & FLAG_DOF_FAR)) { + tap_amount *= mix(1.0 - smoothstep(blur.dof_far_begin, blur.dof_far_end, tap_depth), 0.0, int_ofs == 0); + } + if (bool(blur.flags & FLAG_DOF_NEAR)) { + tap_amount *= mix(smoothstep(blur.dof_near_end, blur.dof_near_begin, tap_depth), 0.0, int_ofs == 0); + } + tap_amount = 1.0 - tap_amount; + + tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect + + vec4 tap_color = texture(source_color, tap_uv, 0.0) * tap_k; + + k_accum += tap_k * tap_amount; + color_accum += tap_color * tap_amount; + } + + if (k_accum > 0.0) { + color_accum /= k_accum; + } + + frag_color = color_accum; ///k_accum; + } else { + // we are in focus, don't waste time + frag_color = texture(source_color, uv_interp, 0.0); + } + +#endif +} diff --git a/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl new file mode 100644 index 0000000000..6ea968e595 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl @@ -0,0 +1,36 @@ +#define FLAG_HORIZONTAL (1 << 0) +#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 1) +#define FLAG_GLOW_FIRST_PASS (1 << 2) +#define FLAG_DOF_FAR (1 << 3) +#define FLAG_DOF_NEAR (1 << 4) + +layout(push_constant, binding = 1, std430) uniform Blur { + vec2 pixel_size; + uint flags; + uint pad; + + // Glow. + float glow_strength; + float glow_bloom; + float glow_hdr_threshold; + float glow_hdr_scale; + + float glow_exposure; + float glow_white; + float glow_luminance_cap; + float glow_auto_exposure_grey; + + // DOF. + float dof_far_begin; + float dof_far_end; + float dof_near_begin; + float dof_near_end; + + float dof_radius; + float dof_pad[3]; + + vec2 dof_dir; + float camera_z_far; + float camera_z_near; +} +blur; diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl new file mode 100644 index 0000000000..29ebd74a90 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl @@ -0,0 +1,74 @@ +/* clang-format off */ +#[vertex] + +#version 450 + +#VERSION_DEFINES + +#include "luminance_reduce_raster_inc.glsl" + +layout(location = 0) out vec2 uv_interp; +/* clang-format on */ + +void main() { + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv_interp = base_arr[gl_VertexIndex]; + + gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); +} + +/* clang-format off */ +#[fragment] + +#version 450 + +#VERSION_DEFINES + +#include "luminance_reduce_raster_inc.glsl" + +layout(location = 0) in vec2 uv_interp; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform sampler2D source_exposure; + +#ifdef FINAL_PASS +layout(set = 1, binding = 0) uniform sampler2D prev_luminance; +#endif + +layout(location = 0) out highp float luminance; + +void main() { + ivec2 dest_pos = ivec2(uv_interp * settings.dest_size); + ivec2 src_pos = ivec2(uv_interp * settings.source_size); + + ivec2 next_pos = (dest_pos + ivec2(1)) * settings.source_size / settings.dest_size; + next_pos = max(next_pos, src_pos + ivec2(1)); //so it at least reads one pixel + + highp vec3 source_color = vec3(0.0); + for (int i = src_pos.x; i < next_pos.x; i++) { + for (int j = src_pos.y; j < next_pos.y; j++) { + source_color += texelFetch(source_exposure, ivec2(i, j), 0).rgb; + } + } + + source_color /= float((next_pos.x - src_pos.x) * (next_pos.y - src_pos.y)); + +#ifdef FIRST_PASS + luminance = max(source_color.r, max(source_color.g, source_color.b)); + + // This formula should be more "accurate" but gave an overexposed result when testing. + // Leaving it here so we can revisit it if we want. + // luminance = source_color.r * 0.21 + source_color.g * 0.71 + source_color.b * 0.07; +#else + luminance = source_color.r; +#endif + +#ifdef FINAL_PASS + // Obtain our target luminance + luminance = clamp(luminance, settings.min_luminance, settings.max_luminance); + + // Now smooth to our transition + highp float prev_lum = texelFetch(prev_luminance, ivec2(0, 0), 0).r; //1 pixel previous luminance + luminance = prev_lum + (luminance - prev_lum) * clamp(settings.exposure_adjust, 0.0, 1.0); +#endif +} diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl new file mode 100644 index 0000000000..ed389ffe56 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl @@ -0,0 +1,11 @@ + +layout(push_constant, binding = 1, std430) uniform PushConstant { + ivec2 source_size; + ivec2 dest_size; + + float exposure_adjust; + float min_luminance; + float max_luminance; + float pad; +} +settings; diff --git a/servers/rendering/renderer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl index 4dceeea995..e88e68b511 100644 --- a/servers/rendering/renderer_rd/shaders/particles_copy.glsl +++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl @@ -138,7 +138,7 @@ void main() { if (bool(particles.data[particle].flags & PARTICLE_FLAG_ACTIVE) || bool(particles.data[particle].flags & PARTICLE_FLAG_TRAILED)) { txform = particles.data[particle].xform; if (params.trail_size > 1) { - // since the steps dont fit precisely in the history frames, must do a tiny bit of + // Since the steps don't fit precisely in the history frames, must do a tiny bit of // interpolation to get them close to their intended location. uint part_ofs = particle % params.trail_size; float natural_ofs = fract((float(part_ofs) / float(params.trail_size)) * float(params.trail_total)) * params.frame_delta; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index ef1c9bacfb..b3a349c948 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -1214,7 +1214,7 @@ void main() { specular_light *= specular * metallic * albedo * 2.0; #else - // scales the specular reflections, needs to be be computed before lighting happens, + // scales the specular reflections, needs to be computed before lighting happens, // but after environment, GI, and reflection probes are added // Environment brdf approximation (Lazarov 2013) // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl index 3a05275652..b53bf6a6d4 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -177,7 +177,7 @@ layout(set = 1, binding = 0, std140) uniform SceneData { uint cluster_type_size; uint max_cluster_element_count_div_32; - //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted + // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. vec4 directional_penumbra_shadow_kernel[32]; vec4 directional_soft_shadow_kernel[32]; vec4 penumbra_shadow_kernel[32]; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 7e72ece5dc..70900a847c 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -981,7 +981,7 @@ void main() { specular_light *= specular * metallic * albedo * 2.0; #else - // scales the specular reflections, needs to be be computed before lighting happens, + // scales the specular reflections, needs to be computed before lighting happens, // but after environment, GI, and reflection probes are added // Environment brdf approximation (Lazarov 2013) // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index 1b8e21551c..d9682d7b23 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -138,7 +138,7 @@ layout(set = 1, binding = 0, std140) uniform SceneData { vec2 viewport_size; vec2 screen_pixel_size; - //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted + // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. vec4 directional_penumbra_shadow_kernel[32]; vec4 directional_soft_shadow_kernel[32]; vec4 penumbra_shadow_kernel[32]; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index 99db35bb34..d6e5c6a92e 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -20,10 +20,10 @@ layout(set = 0, binding = 3, std430) restrict readonly buffer DispatchData { dispatch_data; struct ProcessVoxel { - uint position; //xyz 7 bit packed, extra 11 bits for neigbours - uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours - uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours - uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours + uint position; // xyz 7 bit packed, extra 11 bits for neighbors. + uint albedo; // rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors. + uint light; // rgbe8985 encoded total saved light, extra 2 bits for neighbors. + uint light_aniso; // 55555 light anisotropy, extra 2 bits for neighbors. //total neighbours: 26 }; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl index bc376e9522..eedd28959c 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl @@ -266,9 +266,9 @@ void main() { } else if (params.sky_mode == SKY_MODE_SKY) { #ifdef USE_CUBEMAP_ARRAY - light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates + light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates. #else - light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), ray_dir, 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates + light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), ray_dir, 2.0).rgb; // Use second mipmap because we don't usually throw a lot of rays, so this compensates. #endif light.rgb *= params.sky_energy; light.a = 0.0; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl index aa4ded146f..4d9fa85a74 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl @@ -101,7 +101,7 @@ layout(set = 0, binding = 10, std430) restrict buffer DispatchData { dispatch_data; struct ProcessVoxel { - uint position; //xyz 7 bit packed, extra 11 bits for neigbours + uint position; // xyz 7 bit packed, extra 11 bits for neighbors. uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours @@ -134,7 +134,7 @@ layout(set = 0, binding = 5, std430) restrict buffer readonly DispatchData { dispatch_data; struct ProcessVoxel { - uint position; //xyz 7 bit packed, extra 11 bits for neigbours + uint position; // xyz 7 bit packed, extra 11 bits for neighbors. uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours @@ -183,7 +183,7 @@ void main() { ivec3 write_pos = read_pos + params.scroll; if (any(lessThan(write_pos, ivec3(0))) || any(greaterThanEqual(write_pos, ivec3(params.grid_size)))) { - return; //fits outside the 3D texture, dont do anything + return; // Fits outside the 3D texture, don't do anything. } uint albedo = ((src_process_voxels.data[index].albedo & 0x7FFF) << 1) | 1; //add solid bit diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 3336623f21..83d1b33bf2 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1259,7 +1259,7 @@ void RendererSceneCull::_update_instance_visibility_depth(Instance *p_instance) } if (cycle_detected) { - ERR_PRINT("Cycle detected in the visibility dependecies tree."); + ERR_PRINT("Cycle detected in the visibility dependencies tree."); for (Set<Instance *>::Element *E = traversed_nodes.front(); E; E = E->next()) { Instance *instance = E->get(); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); @@ -2876,8 +2876,8 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c Vector<Instance *> lights_with_shadow; - for (List<Instance *>::Element *E = scenario->directional_lights.front(); E; E = E->next()) { - if (!E->get()->visible) { + for (Instance *E : scenario->directional_lights) { + if (!E->visible) { continue; } @@ -2885,13 +2885,13 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c break; } - InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); + InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data); //check shadow.. if (light) { - if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base) && !(RSG::storage->light_get_type(E->get()->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_is_sky_only(E->get()->base))) { - lights_with_shadow.push_back(E->get()); + if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->base) && !(RSG::storage->light_get_type(E->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_is_sky_only(E->base))) { + lights_with_shadow.push_back(E); } //add to list directional_lights.push_back(light->instance); @@ -3391,8 +3391,7 @@ void RendererSceneCull::render_probes() { idx++; } - for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) { - Instance *instance = E->get(); + for (const Instance *instance : probe->owner->scenario->directional_lights) { InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { continue; @@ -3465,8 +3464,7 @@ void RendererSceneCull::render_probes() { idx++; } - for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) { - Instance *instance = E->get(); + for (const Instance *instance : probe->owner->scenario->directional_lights) { InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { continue; @@ -3573,26 +3571,26 @@ void RendererSceneCull::render_particle_colliders() { void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { List<RendererStorage::InstanceShaderParam> plist; RSG::storage->material_get_instance_shader_parameters(p_material, &plist); - for (List<RendererStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) { - StringName name = E->get().info.name; + for (const RendererStorage::InstanceShaderParam &E : plist) { + StringName name = E.info.name; if (isparams.has(name)) { - if (isparams[name].info.type != E->get().info.type) { - WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different data types. Only the first one (in order) will display correctly."); + if (isparams[name].info.type != E.info.type) { + WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E.info.name + "', but they do it with different data types. Only the first one (in order) will display correctly."); } - if (isparams[name].index != E->get().index) { - WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different indices. Only the first one (in order) will display correctly."); + if (isparams[name].index != E.index) { + WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E.info.name + "', but they do it with different indices. Only the first one (in order) will display correctly."); } continue; //first one found always has priority } Instance::InstanceShaderParameter isp; - isp.index = E->get().index; - isp.info = E->get().info; - isp.default_value = E->get().default_value; + isp.index = E.index; + isp.info = E.info; + isp.default_value = E.default_value; if (existing_isparams.has(name)) { isp.value = existing_isparams[name].value; } else { - isp.value = E->get().default_value; + isp.value = E.default_value; } isparams[name] = isp; } diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index 4c31880faf..75a91d8419 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -388,9 +388,9 @@ protected: versions.clear(); List<Variant> keys; p_versions.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - StringName name = E->get(); - Ref<RDShaderBytecode> bc = p_versions[E->get()]; + for (const Variant &E : keys) { + StringName name = E; + Ref<RDShaderBytecode> bc = p_versions[E]; ERR_CONTINUE(bc.is_null()); versions[name] = bc; } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index e620677866..ed7406db86 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -4466,12 +4466,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons String member_name = String(ident.ptr()); if (shader->structs.has(st)) { StructNode *n = shader->structs[st].shader_struct; - for (List<MemberNode *>::Element *E = n->members.front(); E; E = E->next()) { - if (String(E->get()->name) == member_name) { - member_type = E->get()->datatype; - array_size = E->get()->array_size; + for (const MemberNode *E : n->members) { + if (String(E->name) == member_name) { + member_type = E->datatype; + array_size = E->array_size; if (member_type == TYPE_STRUCT) { - member_struct_name = E->get()->struct_name; + member_struct_name = E->struct_name; } ok = true; break; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index a39d0e89ee..1f01f47fff 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -53,15 +53,15 @@ Array RenderingServer::_texture_debug_usage_bind() { List<TextureInfo> list; texture_debug_usage(&list); Array arr; - for (const List<TextureInfo>::Element *E = list.front(); E; E = E->next()) { + for (const TextureInfo &E : list) { Dictionary dict; - dict["texture"] = E->get().texture; - dict["width"] = E->get().width; - dict["height"] = E->get().height; - dict["depth"] = E->get().depth; - dict["format"] = E->get().format; - dict["bytes"] = E->get().bytes; - dict["path"] = E->get().path; + dict["texture"] = E.texture; + dict["width"] = E.width; + dict["height"] = E.height; + dict["depth"] = E.depth; + dict["format"] = E.format; + dict["bytes"] = E.bytes; + dict["path"] = E.path; arr.push_back(dict); } return arr; @@ -972,10 +972,10 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa if (index_array_len) { List<Variant> keys; p_lods.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - float distance = E->get(); + for (const Variant &E : keys) { + float distance = E; ERR_CONTINUE(distance <= 0.0); - Vector<int> indices = p_lods[E->get()]; + Vector<int> indices = p_lods[E]; ERR_CONTINUE(indices.size() == 0); uint32_t index_count = indices.size(); ERR_CONTINUE(index_count >= (uint32_t)index_array_len); //should be smaller.. diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 6031bd7003..6b248c9554 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -41,7 +41,7 @@ struct BlitToScreen; /** @author Bastiaan Olij <mux213@gmail.com> - The XR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs. + The XR interface is a template class on top of which we build interface to different AR, VR and tracking SDKs. The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server. diff --git a/tests/test_class_db.h b/tests/test_class_db.h index 29edf5a4a0..ea680da5d6 100644 --- a/tests/test_class_db.h +++ b/tests/test_class_db.h @@ -108,9 +108,9 @@ struct ExposedClass { List<SignalData> signals_; const PropertyData *find_property_by_name(const StringName &p_name) const { - for (const List<PropertyData>::Element *E = properties.front(); E; E = E->next()) { - if (E->get().name == p_name) { - return &E->get(); + for (const PropertyData &E : properties) { + if (E.name == p_name) { + return &E; } } @@ -118,9 +118,9 @@ struct ExposedClass { } const MethodData *find_method_by_name(const StringName &p_name) const { - for (const List<MethodData>::Element *E = methods.front(); E; E = E->next()) { - if (E->get().name == p_name) { - return &E->get(); + for (const MethodData &E : methods) { + if (E.name == p_name) { + return &E; } } @@ -395,8 +395,8 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons } } - for (const List<ArgumentData>::Element *F = p_method.arguments.front(); F; F = F->next()) { - const ArgumentData &arg = F->get(); + for (const ArgumentData &F : p_method.arguments) { + const ArgumentData &arg = F; const ExposedClass *arg_class = p_context.find_exposed_class(arg.type); if (arg_class) { @@ -427,8 +427,8 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons } void validate_signal(const Context &p_context, const ExposedClass &p_class, const SignalData &p_signal) { - for (const List<ArgumentData>::Element *F = p_signal.arguments.front(); F; F = F->next()) { - const ArgumentData &arg = F->get(); + for (const ArgumentData &F : p_signal.arguments) { + const ArgumentData &arg = F; const ExposedClass *arg_class = p_context.find_exposed_class(arg.type); if (arg_class) { @@ -469,16 +469,16 @@ void validate_class(const Context &p_context, const ExposedClass &p_exposed_clas TEST_FAIL_COND((is_derived_type && !p_context.exposed_classes.has(p_exposed_class.base)), "Base type '", p_exposed_class.base.operator String(), "' does not exist, for class '", p_exposed_class.name, "'."); - for (const List<PropertyData>::Element *F = p_exposed_class.properties.front(); F; F = F->next()) { - validate_property(p_context, p_exposed_class, F->get()); + for (const PropertyData &F : p_exposed_class.properties) { + validate_property(p_context, p_exposed_class, F); } - for (const List<MethodData>::Element *F = p_exposed_class.methods.front(); F; F = F->next()) { - validate_method(p_context, p_exposed_class, F->get()); + for (const MethodData &F : p_exposed_class.methods) { + validate_method(p_context, p_exposed_class, F); } - for (const List<SignalData>::Element *F = p_exposed_class.signals_.front(); F; F = F->next()) { - validate_signal(p_context, p_exposed_class, F->get()); + for (const SignalData &F : p_exposed_class.signals_) { + validate_signal(p_context, p_exposed_class, F); } } @@ -526,9 +526,7 @@ void add_exposed_classes(Context &r_context) { Map<StringName, StringName> accessor_methods; - for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { - const PropertyInfo &property = E->get(); - + for (const PropertyInfo &property : property_list) { if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY) { continue; } @@ -561,8 +559,8 @@ void add_exposed_classes(Context &r_context) { ClassDB::get_method_list(class_name, &method_list, true); method_list.sort(); - for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { - const MethodInfo &method_info = E->get(); + for (const MethodInfo &E : method_list) { + const MethodInfo &method_info = E; int argc = method_info.arguments.size(); @@ -667,8 +665,8 @@ void add_exposed_classes(Context &r_context) { // Methods starting with an underscore are ignored unless they're virtual or used as a property setter or getter. if (!method.is_virtual && String(method.name)[0] == '_') { - for (const List<PropertyData>::Element *F = exposed_class.properties.front(); F; F = F->next()) { - const PropertyData &prop = F->get(); + for (const PropertyData &F : exposed_class.properties) { + const PropertyData &prop = F; if (prop.setter == method.name || prop.getter == method.name) { exposed_class.methods.push_back(method); @@ -752,8 +750,8 @@ void add_exposed_classes(Context &r_context) { enum_.name = *k; const List<StringName> &enum_constants = enum_map.get(*k); - for (const List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) { - const StringName &constant_name = E->get(); + for (const StringName &E : enum_constants) { + const StringName &constant_name = E; TEST_FAIL_COND(String(constant_name).find("::") != -1, "Enum constant contains '::', check bindings to remove the scope: '", String(class_name), ".", String(enum_.name), ".", String(constant_name), "'."); @@ -774,12 +772,12 @@ void add_exposed_classes(Context &r_context) { r_context.enum_types.push_back(String(class_name) + "." + String(*k)); } - for (const List<String>::Element *E = constants.front(); E; E = E->next()) { - const String &constant_name = E->get(); + for (const String &E : constants) { + const String &constant_name = E; TEST_FAIL_COND(constant_name.find("::") != -1, "Constant contains '::', check bindings to remove the scope: '", String(class_name), ".", constant_name, "'."); - int *value = class_info->constant_map.getptr(StringName(E->get())); + int *value = class_info->constant_map.getptr(StringName(E)); TEST_FAIL_COND(!value, "Missing constant value: '", String(class_name), ".", String(constant_name), "'."); ConstantData constant; @@ -829,8 +827,8 @@ void add_global_enums(Context &r_context) { } } - for (List<EnumData>::Element *E = r_context.global_enums.front(); E; E = E->next()) { - r_context.enum_types.push_back(E->get().name); + for (const EnumData &E : r_context.global_enums) { + r_context.enum_types.push_back(E.name); } } @@ -840,10 +838,10 @@ void add_global_enums(Context &r_context) { hardcoded_enums.push_back("Vector2i.Axis"); hardcoded_enums.push_back("Vector3.Axis"); hardcoded_enums.push_back("Vector3i.Axis"); - for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) { + for (const StringName &E : hardcoded_enums) { // These enums are not generated and must be written manually (e.g.: Vector3.Axis) // Here, we assume core types do not begin with underscore - r_context.enum_types.push_back(E->get()); + r_context.enum_types.push_back(E); } } diff --git a/tests/test_math.cpp b/tests/test_math.cpp index 67d9a52539..d0b9fdef4b 100644 --- a/tests/test_math.cpp +++ b/tests/test_math.cpp @@ -549,8 +549,8 @@ MainLoop *test() { List<StringName> tl; ClassDB::get_class_list(&tl); - for (List<StringName>::Element *E = tl.front(); E; E = E->next()) { - Vector<uint8_t> m5b = E->get().operator String().md5_buffer(); + for (const StringName &E : tl) { + Vector<uint8_t> m5b = E.operator String().md5_buffer(); hashes.push_back(hashes.size()); } diff --git a/tests/test_object.h b/tests/test_object.h index 36f9ef2a51..a18adf31b6 100644 --- a/tests/test_object.h +++ b/tests/test_object.h @@ -139,7 +139,7 @@ TEST_CASE("[Object] Metadata") { Color(object.get_meta(meta_path)).is_equal_approx(Color(0, 1, 0)), "The returned object metadata after setting should match the expected value."); - List<String> meta_list; + List<StringName> meta_list; object.get_meta_list(&meta_list); CHECK_MESSAGE( meta_list.size() == 1, @@ -154,7 +154,7 @@ TEST_CASE("[Object] Metadata") { "The returned object metadata after removing should match the expected value."); ERR_PRINT_ON; - List<String> meta_list2; + List<StringName> meta_list2; object.get_meta_list(&meta_list2); CHECK_MESSAGE( meta_list2.size() == 0, diff --git a/tests/test_render.cpp b/tests/test_render.cpp index fe223ca258..00ce187847 100644 --- a/tests/test_render.cpp +++ b/tests/test_render.cpp @@ -210,12 +210,12 @@ public: //return quit; - for (List<InstanceInfo>::Element *E = instances.front(); E; E = E->next()) { - Transform3D pre(Basis(E->get().rot_axis, ofs), Vector3()); - vs->instance_set_transform(E->get().instance, pre * E->get().base); + for (const InstanceInfo &E : instances) { + Transform3D pre(Basis(E.rot_axis, ofs), Vector3()); + vs->instance_set_transform(E.instance, pre * E.base); /* if( !E->next() ) { - vs->free( E->get().instance ); + vs->free( E.instance ); instances.erase(E ); }*/ } diff --git a/thirdparty/enet/godot.cpp b/thirdparty/enet/godot.cpp index f6a56f1f5d..3e353d7eec 100644 --- a/thirdparty/enet/godot.cpp +++ b/thirdparty/enet/godot.cpp @@ -353,8 +353,8 @@ public: } // Remove disconnected peers from map. - for (List<String>::Element *E = remove.front(); E; E = E->next()) { - peers.erase(E->get()); + for (String &E : remove) { + peers.erase(E); } return err; // OK, ERR_BUSY, or possibly an error. |