Переглянути джерело

Add ConstIterator to Dictionary.

Yufeng Ying 4 місяців тому
батько
коміт
bebe037abf

+ 2 - 5
core/extension/gdextension_interface.cpp

@@ -1555,11 +1555,8 @@ static void gdextension_placeholder_script_instance_update(GDExtensionScriptInst
 		properties_list.push_back(PropertyInfo::from_dict(d));
 	}
 
-	List<Variant> keys;
-	values.get_key_list(&keys);
-
-	for (const Variant &E : keys) {
-		values_map.insert(E, values[E]);
+	for (const KeyValue<Variant, Variant> &kv : values) {
+		values_map.insert(kv.key, kv.value);
 	}
 
 	placeholder->update(properties_list, values_map);

+ 3 - 6
core/io/json.cpp

@@ -922,12 +922,9 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_
 
 			ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ret, "Variant is too deep. Bailing.");
 
-			List<Variant> keys;
-			dict.get_key_list(&keys);
-
-			for (const Variant &key : keys) {
-				args.push_back(_from_native(key, p_full_objects, p_depth + 1));
-				args.push_back(_from_native(dict[key], p_full_objects, p_depth + 1));
+			for (const KeyValue<Variant, Variant> &kv : dict) {
+				args.push_back(_from_native(kv.key, p_full_objects, p_depth + 1));
+				args.push_back(_from_native(kv.value, p_full_objects, p_depth + 1));
 			}
 
 			return ret;

+ 3 - 6
core/io/marshalls.cpp

@@ -1849,19 +1849,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 			}
 			r_len += 4;
 
-			List<Variant> keys;
-			dict.get_key_list(&keys);
-
-			for (const Variant &key : keys) {
+			for (const KeyValue<Variant, Variant> &kv : dict) {
 				int len;
-				Error err = encode_variant(key, buf, len, p_full_objects, p_depth + 1);
+				Error err = encode_variant(kv.key, buf, len, p_full_objects, p_depth + 1);
 				ERR_FAIL_COND_V(err, err);
 				ERR_FAIL_COND_V(len % 4, ERR_BUG);
 				r_len += len;
 				if (buf) {
 					buf += len;
 				}
-				const Variant *value = dict.getptr(key);
+				const Variant *value = dict.getptr(kv.key);
 				ERR_FAIL_NULL_V(value, ERR_BUG);
 				err = encode_variant(*value, buf, len, p_full_objects, p_depth + 1);
 				ERR_FAIL_COND_V(err, err);

+ 3 - 5
core/io/packed_data_container.cpp

@@ -268,14 +268,12 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
 			encode_uint32(TYPE_DICT, &tmpdata.write[pos + 0]);
 			encode_uint32(len, &tmpdata.write[pos + 4]);
 
-			List<Variant> keys;
-			d.get_key_list(&keys);
 			List<DictKey> sortk;
 
-			for (const Variant &key : keys) {
+			for (const KeyValue<Variant, Variant> &kv : d) {
 				DictKey dk;
-				dk.hash = key.hash();
-				dk.key = key;
+				dk.hash = kv.key.hash();
+				dk.key = kv.key;
 				sortk.push_back(dk);
 			}
 

+ 3 - 5
core/io/resource.cpp

@@ -322,11 +322,9 @@ void Resource::_find_sub_resources(const Variant &p_variant, HashSet<Ref<Resourc
 		} break;
 		case Variant::DICTIONARY: {
 			Dictionary d = p_variant;
-			List<Variant> keys;
-			d.get_key_list(&keys);
-			for (const Variant &k : keys) {
-				_find_sub_resources(k, p_resources_found);
-				_find_sub_resources(d[k], p_resources_found);
+			for (const KeyValue<Variant, Variant> &kv : d) {
+				_find_sub_resources(kv.key, p_resources_found);
+				_find_sub_resources(kv.value, p_resources_found);
 			}
 		} break;
 		case Variant::OBJECT: {

+ 6 - 12
core/io/resource_format_binary.cpp

@@ -1876,12 +1876,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V
 			Dictionary d = p_property;
 			f->store_32(uint32_t(d.size()));
 
-			List<Variant> keys;
-			d.get_key_list(&keys);
-
-			for (const Variant &E : keys) {
-				write_variant(f, E, resource_map, external_resources, string_map);
-				write_variant(f, d[E], resource_map, external_resources, string_map);
+			for (const KeyValue<Variant, Variant> &kv : d) {
+				write_variant(f, kv.key, resource_map, external_resources, string_map);
+				write_variant(f, kv.value, resource_map, external_resources, string_map);
 			}
 
 		} break;
@@ -2086,12 +2083,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
 			Dictionary d = p_variant;
 			_find_resources(d.get_typed_key_script());
 			_find_resources(d.get_typed_value_script());
-			List<Variant> keys;
-			d.get_key_list(&keys);
-			for (const Variant &E : keys) {
-				_find_resources(E);
-				Variant v = d[E];
-				_find_resources(v);
+			for (const KeyValue<Variant, Variant> &kv : d) {
+				_find_resources(kv.key);
+				_find_resources(kv.value);
 			}
 		} break;
 		case Variant::NODE_PATH: {

+ 3 - 5
core/io/resource_loader.cpp

@@ -1339,10 +1339,8 @@ void ResourceLoader::load_translation_remaps() {
 	}
 
 	Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps");
-	List<Variant> keys;
-	remaps.get_key_list(&keys);
-	for (const Variant &E : keys) {
-		Array langs = remaps[E];
+	for (const KeyValue<Variant, Variant> &kv : remaps) {
+		Array langs = kv.value;
 		Vector<String> lang_remaps;
 		lang_remaps.resize(langs.size());
 		String *lang_remaps_ptrw = lang_remaps.ptrw();
@@ -1350,7 +1348,7 @@ void ResourceLoader::load_translation_remaps() {
 			*lang_remaps_ptrw++ = lang;
 		}
 
-		translation_remaps[String(E)] = lang_remaps;
+		translation_remaps[String(kv.key)] = lang_remaps;
 	}
 }
 

+ 3 - 5
core/object/object.cpp

@@ -1640,12 +1640,10 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) {
 		} break;
 		case Variant::DICTIONARY: {
 			Dictionary d = p_var;
-			List<Variant> keys;
-			d.get_key_list(&keys);
 
-			for (const Variant &E : keys) {
-				_clear_internal_resource_paths(E);
-				_clear_internal_resource_paths(d[E]);
+			for (const KeyValue<Variant, Variant> &kv : d) {
+				_clear_internal_resource_paths(kv.key);
+				_clear_internal_resource_paths(kv.value);
 			}
 		} break;
 		default: {

+ 2 - 4
core/object/script_language_extension.h

@@ -192,10 +192,8 @@ public:
 	virtual void get_constants(HashMap<StringName, Variant> *p_constants) override {
 		Dictionary constants;
 		GDVIRTUAL_CALL(_get_constants, constants);
-		List<Variant> keys;
-		constants.get_key_list(&keys);
-		for (const Variant &K : keys) {
-			p_constants->insert(K, constants[K]);
+		for (const KeyValue<Variant, Variant> &kv : constants) {
+			p_constants->insert(kv.key, kv.value);
 		}
 	}
 	GDVIRTUAL0RC_REQUIRED(TypedArray<StringName>, _get_members)

+ 2 - 4
core/string/translation.cpp

@@ -67,10 +67,8 @@ Vector<String> Translation::get_translated_message_list() const {
 }
 
 void Translation::_set_messages(const Dictionary &p_messages) {
-	List<Variant> keys;
-	p_messages.get_key_list(&keys);
-	for (const Variant &E : keys) {
-		translation_map[E] = p_messages[E];
+	for (const KeyValue<Variant, Variant> &kv : p_messages) {
+		translation_map[kv.key] = kv.value;
 	}
 }
 

+ 6 - 10
core/string/translation_po.cpp

@@ -86,20 +86,16 @@ Dictionary TranslationPO::_get_messages() const {
 void TranslationPO::_set_messages(const Dictionary &p_messages) {
 	// Construct translation_map from a Dictionary.
 
-	List<Variant> context_l;
-	p_messages.get_key_list(&context_l);
-	for (const Variant &ctx : context_l) {
-		const Dictionary &id_str_map = p_messages[ctx];
+	for (const KeyValue<Variant, Variant> &kv : p_messages) {
+		const Dictionary &id_str_map = kv.value;
 
 		HashMap<StringName, Vector<StringName>> temp_map;
-		List<Variant> id_l;
-		id_str_map.get_key_list(&id_l);
-		for (List<Variant>::Element *E2 = id_l.front(); E2; E2 = E2->next()) {
-			StringName id = E2->get();
-			temp_map[id] = id_str_map[id];
+		for (const KeyValue<Variant, Variant> &kv_id : id_str_map) {
+			StringName id = kv_id.key;
+			temp_map[id] = kv_id.value;
 		}
 
-		translation_map[ctx] = temp_map;
+		translation_map[kv.key] = temp_map;
 	}
 }
 

+ 2 - 4
core/string/ustring.cpp

@@ -4029,11 +4029,9 @@ String String::format(const Variant &values, const String &placeholder) const {
 		}
 	} else if (values.get_type() == Variant::DICTIONARY) {
 		Dictionary d = values;
-		List<Variant> keys;
-		d.get_key_list(&keys);
 
-		for (const Variant &key : keys) {
-			new_string = new_string.replace(placeholder.replace("_", key), d[key]);
+		for (const KeyValue<Variant, Variant> &kv : d) {
+			new_string = new_string.replace(placeholder.replace("_", kv.key), kv.value);
 		}
 	} else if (values.get_type() == Variant::OBJECT) {
 		Object *obj = values.get_validated_object();

+ 8 - 0
core/variant/dictionary.cpp

@@ -49,6 +49,14 @@ struct DictionaryPrivate {
 	Variant *typed_fallback = nullptr; // Allows a typed dictionary to return dummy values when attempting an invalid access.
 };
 
+Dictionary::ConstIterator Dictionary::begin() const {
+	return _p->variant_map.begin();
+}
+
+Dictionary::ConstIterator Dictionary::end() const {
+	return _p->variant_map.end();
+}
+
 void Dictionary::get_key_list(List<Variant> *p_keys) const {
 	if (_p->variant_map.is_empty()) {
 		return;

+ 8 - 0
core/variant/dictionary.h

@@ -31,6 +31,7 @@
 #pragma once
 
 #include "core/string/ustring.h"
+#include "core/templates/hash_map.h"
 #include "core/templates/list.h"
 #include "core/templates/pair.h"
 #include "core/variant/array.h"
@@ -39,6 +40,8 @@ class Variant;
 
 struct ContainerType;
 struct DictionaryPrivate;
+struct StringLikeVariantComparator;
+struct VariantHasher;
 
 class Dictionary {
 	mutable DictionaryPrivate *_p;
@@ -47,6 +50,11 @@ class Dictionary {
 	void _unref() const;
 
 public:
+	using ConstIterator = HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator;
+
+	ConstIterator begin() const;
+	ConstIterator end() const;
+
 	void get_key_list(List<Variant> *p_keys) const;
 	Variant get_key_at_index(int p_index) const;
 	Variant get_value_at_index(int p_index) const;

+ 3 - 5
core/variant/variant.cpp

@@ -1654,15 +1654,13 @@ String Variant::stringify(int recursion_count) const {
 			// Add leading and trailing space to Dictionary printing. This distinguishes it
 			// from array printing on fonts that have similar-looking {} and [] characters.
 			String str("{ ");
-			List<Variant> keys;
-			d.get_key_list(&keys);
 
 			Vector<_VariantStrPair> pairs;
 
-			for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
+			for (const KeyValue<Variant, Variant> &kv : d) {
 				_VariantStrPair sp;
-				sp.key = stringify_variant_clean(E->get(), recursion_count);
-				sp.value = stringify_variant_clean(d[E->get()], recursion_count);
+				sp.key = stringify_variant_clean(kv.key, recursion_count);
+				sp.value = stringify_variant_clean(kv.value, recursion_count);
 
 				pairs.push_back(sp);
 			}

+ 3 - 5
core/variant/variant_setget.cpp

@@ -1288,11 +1288,9 @@ Variant Variant::get(const Variant &p_index, bool *r_valid, VariantGetError *err
 void Variant::get_property_list(List<PropertyInfo> *p_list) const {
 	if (type == DICTIONARY) {
 		const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
-		List<Variant> keys;
-		dic->get_key_list(&keys);
-		for (const Variant &E : keys) {
-			if (E.is_string()) {
-				p_list->push_back(PropertyInfo(dic->get_valid(E).get_type(), E));
+		for (const KeyValue<Variant, Variant> &kv : *dic) {
+			if (kv.key.is_string()) {
+				p_list->push_back(PropertyInfo(dic->get_valid(kv.key).get_type(), kv.key));
 			}
 		}
 	} else if (type == OBJECT) {

+ 2 - 4
editor/editor_build_profile.cpp

@@ -297,11 +297,9 @@ Error EditorBuildProfile::load_from_file(const String &p_path) {
 
 	if (data.has("disabled_build_options")) {
 		Dictionary disabled_build_options_arr = data["disabled_build_options"];
-		List<Variant> keys;
-		disabled_build_options_arr.get_key_list(&keys);
 
-		for (const Variant &K : keys) {
-			String key = K;
+		for (const KeyValue<Variant, Variant> &kv : disabled_build_options_arr) {
+			String key = kv.key;
 
 			for (int i = 0; i < BUILD_OPTION_MAX; i++) {
 				String f = build_option_identifiers[i];

+ 6 - 12
editor/editor_data.cpp

@@ -336,12 +336,8 @@ void EditorData::set_editor_plugin_states(const Dictionary &p_states) {
 		return;
 	}
 
-	List<Variant> keys;
-	p_states.get_key_list(&keys);
-
-	List<Variant>::Element *E = keys.front();
-	for (; E; E = E->next()) {
-		String name = E->get();
+	for (const KeyValue<Variant, Variant> &kv : p_states) {
+		String name = kv.key;
 		int idx = -1;
 		for (int i = 0; i < editor_plugins.size(); i++) {
 			if (editor_plugins[i]->get_plugin_name() == name) {
@@ -353,7 +349,7 @@ void EditorData::set_editor_plugin_states(const Dictionary &p_states) {
 		if (idx == -1) {
 			continue;
 		}
-		editor_plugins[idx]->set_state(p_states[name]);
+		editor_plugins[idx]->set_state(kv.value);
 	}
 }
 
@@ -1071,12 +1067,10 @@ void EditorData::script_class_load_icon_paths() {
 #ifndef DISABLE_DEPRECATED
 	if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) {
 		Dictionary d = GLOBAL_GET("_global_script_class_icons");
-		List<Variant> keys;
-		d.get_key_list(&keys);
 
-		for (const Variant &E : keys) {
-			String name = E.operator String();
-			_script_class_icon_paths[name] = d[name];
+		for (const KeyValue<Variant, Variant> &kv : d) {
+			String name = kv.key.operator String();
+			_script_class_icon_paths[name] = kv.value;
 
 			String path = ScriptServer::get_global_class_path(name);
 			script_class_set_name(path, name);

+ 2 - 4
editor/editor_file_system.cpp

@@ -2824,11 +2824,9 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin
 	if (load_default && ProjectSettings::get_singleton()->has_setting("importer_defaults/" + importer->get_importer_name())) {
 		//use defaults if exist
 		Dictionary d = GLOBAL_GET("importer_defaults/" + importer->get_importer_name());
-		List<Variant> v;
-		d.get_key_list(&v);
 
-		for (const Variant &E : v) {
-			params[E] = d[E];
+		for (const KeyValue<Variant, Variant> &kv : d) {
+			params[kv.key] = kv.value;
 		}
 	}
 

+ 4 - 9
editor/editor_node.cpp

@@ -1587,10 +1587,8 @@ void EditorNode::_save_editor_states(const String &p_file, int p_idx) {
 		md = editor_data.get_scene_editor_states(p_idx);
 	}
 
-	List<Variant> keys;
-	md.get_key_list(&keys);
-	for (const Variant &E : keys) {
-		cf->set_value("editor_states", E, md[E]);
+	for (const KeyValue<Variant, Variant> &kv : md) {
+		cf->set_value("editor_states", kv.key, kv.value);
 	}
 
 	// Save the currently selected nodes.
@@ -1664,11 +1662,8 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, HashMap<Ref<Res
 			} break;
 			case Variant::DICTIONARY: {
 				Dictionary d = obj->get(E.name);
-				List<Variant> keys;
-				d.get_key_list(&keys);
-				for (const Variant &F : keys) {
-					Variant v = d[F];
-					Ref<Resource> res = v;
+				for (const KeyValue<Variant, Variant> &kv : d) {
+					Ref<Resource> res = kv.value;
 					if (_find_and_save_resource(res, processed, flags)) {
 						ret_changed = true;
 					}

+ 3 - 4
editor/editor_properties.cpp

@@ -3036,15 +3036,14 @@ static bool _find_recursive_resources(const Variant &v, HashSet<Resource *> &res
 		} break;
 		case Variant::DICTIONARY: {
 			Dictionary d = v;
-			List<Variant> keys;
-			d.get_key_list(&keys);
-			for (const Variant &k : keys) {
+			for (const KeyValue<Variant, Variant> &kv : d) {
+				const Variant &k = kv.key;
+				const Variant &v2 = kv.value;
 				if (k.get_type() == Variant::ARRAY || k.get_type() == Variant::DICTIONARY || k.get_type() == Variant::OBJECT) {
 					if (_find_recursive_resources(k, resources_found)) {
 						return true;
 					}
 				}
-				Variant v2 = d[k];
 				if (v2.get_type() == Variant::ARRAY || v2.get_type() == Variant::DICTIONARY || v2.get_type() == Variant::OBJECT) {
 					if (_find_recursive_resources(v2, resources_found)) {
 						return true;

+ 2 - 4
editor/import/editor_import_plugin.cpp

@@ -205,10 +205,8 @@ bool EditorImportPlugin::can_import_threaded() const {
 
 Error EditorImportPlugin::_append_import_external_resource(const String &p_file, const Dictionary &p_custom_options, const String &p_custom_importer, Variant p_generator_parameters) {
 	HashMap<StringName, Variant> options;
-	List<Variant> keys;
-	p_custom_options.get_key_list(&keys);
-	for (const Variant &K : keys) {
-		options.insert(K, p_custom_options[K]);
+	for (const KeyValue<Variant, Variant> &kv : p_custom_options) {
+		options.insert(kv.key, kv.value);
 	}
 	return append_import_external_resource(p_file, options, p_custom_importer, p_generator_parameters);
 }

+ 6 - 10
editor/import_dock.cpp

@@ -297,13 +297,11 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
 		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 (const Variant &F : v) {
-				int f = d[F];
+			for (const KeyValue<Variant, Variant> &kv : d) {
+				int f = kv.value;
 				if (f > freq) {
-					value = F;
+					value = kv.key;
 				}
 			}
 
@@ -456,16 +454,14 @@ void ImportDock::_preset_selected(int p_idx) {
 			ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting(setting_name));
 
 			Dictionary import_settings = GLOBAL_GET(setting_name);
-			List<Variant> keys;
-			import_settings.get_key_list(&keys);
 
 			if (params->checking) {
 				params->checked.clear();
 			}
-			for (const Variant &E : keys) {
-				params->values[E] = import_settings[E];
+			for (const KeyValue<Variant, Variant> &kv : import_settings) {
+				params->values[kv.key] = kv.value;
 				if (params->checking) {
-					params->checked.insert(E);
+					params->checked.insert(kv.key);
 				}
 			}
 			params->update();

+ 2 - 4
editor/localization_editor.cpp

@@ -539,11 +539,9 @@ void LocalizationEditor::update_translations() {
 
 	if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) {
 		Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps");
-		List<Variant> rk;
-		remaps.get_key_list(&rk);
 		Vector<String> keys;
-		for (const Variant &E : rk) {
-			keys.push_back(E);
+		for (const KeyValue<Variant, Variant> &kv : remaps) {
+			keys.push_back(kv.key);
 		}
 		keys.sort();
 

+ 3 - 5
editor/plugins/node_3d_editor_plugin.cpp

@@ -6619,17 +6619,15 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
 
 	if (d.has("gizmos_status")) {
 		Dictionary gizmos_status = d["gizmos_status"];
-		List<Variant> keys;
-		gizmos_status.get_key_list(&keys);
 
 		for (int j = 0; j < gizmo_plugins_by_name.size(); ++j) {
 			if (!gizmo_plugins_by_name[j]->can_be_hidden()) {
 				continue;
 			}
 			int state = EditorNode3DGizmoPlugin::VISIBLE;
-			for (const Variant &key : keys) {
-				if (gizmo_plugins_by_name.write[j]->get_gizmo_name() == String(key)) {
-					state = gizmos_status[key];
+			for (const KeyValue<Variant, Variant> &kv : gizmos_status) {
+				if (gizmo_plugins_by_name.write[j]->get_gizmo_name() == String(kv.key)) {
+					state = kv.value;
 					break;
 				}
 			}

+ 3 - 5
modules/interactive_music/audio_stream_interactive.cpp

@@ -173,11 +173,9 @@ int AudioStreamInteractive::get_clip_auto_advance_next_clip(int p_clip) const {
 // TRANSITIONS
 
 void AudioStreamInteractive::_set_transitions(const Dictionary &p_transitions) {
-	List<Variant> keys;
-	p_transitions.get_key_list(&keys);
-	for (const Variant &K : keys) {
-		Vector2i k = K;
-		Dictionary data = p_transitions[K];
+	for (const KeyValue<Variant, Variant> &kv : p_transitions) {
+		Vector2i k = kv.key;
+		Dictionary data = kv.value;
 		ERR_CONTINUE(!data.has("from_time"));
 		ERR_CONTINUE(!data.has("to_time"));
 		ERR_CONTINUE(!data.has("fade_mode"));

+ 3 - 5
scene/animation/animation_mixer.cpp

@@ -77,11 +77,9 @@ bool AnimationMixer::_set(const StringName &p_name, const Variant &p_value) {
 		while (animation_libraries.size()) {
 			remove_animation_library(animation_libraries[0].name);
 		}
-		List<Variant> keys;
-		d.get_key_list(&keys);
-		for (const Variant &K : keys) {
-			Ref<AnimationLibrary> lib = d[K];
-			add_animation_library(K, lib);
+		for (const KeyValue<Variant, Variant> &kv : d) {
+			Ref<AnimationLibrary> lib = kv.value;
+			add_animation_library(kv.key, lib);
 		}
 		emit_signal(SNAME("animation_libraries_updated"));
 

+ 3 - 5
scene/animation/animation_tree.cpp

@@ -121,12 +121,10 @@ AnimationNode::NodeTimeInfo AnimationNode::get_node_time_info() const {
 void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
 	Dictionary cn;
 	if (GDVIRTUAL_CALL(_get_child_nodes, cn)) {
-		List<Variant> keys;
-		cn.get_key_list(&keys);
-		for (const Variant &E : keys) {
+		for (const KeyValue<Variant, Variant> &kv : cn) {
 			ChildNode child;
-			child.name = E;
-			child.node = cn[E];
+			child.name = kv.key;
+			child.node = kv.value;
 			r_child_nodes->push_back(child);
 		}
 	}

+ 4 - 6
scene/resources/3d/importer_mesh.cpp

@@ -91,13 +91,11 @@ void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_a
 		s.blend_shape_data.push_back(bs);
 	}
 
-	List<Variant> lods;
-	p_lods.get_key_list(&lods);
-	for (const Variant &E : lods) {
-		ERR_CONTINUE(!E.is_num());
+	for (const KeyValue<Variant, Variant> &kv : p_lods) {
+		ERR_CONTINUE(!kv.key.is_num());
 		Surface::LOD lod;
-		lod.distance = E;
-		lod.indices = p_lods[E];
+		lod.distance = kv.key;
+		lod.indices = kv.value;
 		ERR_CONTINUE(lod.indices.is_empty());
 		s.lods.push_back(lod);
 	}

+ 2 - 4
scene/resources/animation_library.cpp

@@ -134,10 +134,8 @@ void AnimationLibrary::_set_data(const Dictionary &p_data) {
 		K.value->disconnect_changed(callable_mp(this, &AnimationLibrary::_animation_changed));
 	}
 	animations.clear();
-	List<Variant> keys;
-	p_data.get_key_list(&keys);
-	for (const Variant &K : keys) {
-		add_animation(K, p_data[K]);
+	for (const KeyValue<Variant, Variant> &kv : p_data) {
+		add_animation(kv.key, kv.value);
 	}
 }
 

+ 3 - 6
scene/resources/resource_format_text.cpp

@@ -1674,14 +1674,11 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
 			Dictionary d = p_variant;
 			_find_resources(d.get_typed_key_script());
 			_find_resources(d.get_typed_value_script());
-			List<Variant> keys;
-			d.get_key_list(&keys);
-			for (const Variant &E : keys) {
+			for (const KeyValue<Variant, Variant> &kv : d) {
 				// Of course keys should also be cached, after all we can't prevent users from using resources as keys, right?
 				// See also ResourceFormatSaverBinaryInstance::_find_resources (when p_variant is of type Variant::DICTIONARY)
-				_find_resources(E);
-				Variant v = d[E];
-				_find_resources(v);
+				_find_resources(kv.key);
+				_find_resources(kv.value);
 			}
 		} break;
 		case Variant::PACKED_BYTE_ARRAY: {

+ 3 - 6
scene/resources/syntax_highlighter.cpp

@@ -537,16 +537,13 @@ bool CodeHighlighter::has_color_region(const String &p_start_key) const {
 void CodeHighlighter::set_color_regions(const Dictionary &p_color_regions) {
 	color_regions.clear();
 
-	List<Variant> keys;
-	p_color_regions.get_key_list(&keys);
-
-	for (const Variant &E : keys) {
-		String key = E;
+	for (const KeyValue<Variant, Variant> &kv : p_color_regions) {
+		String key = kv.key;
 
 		String start_key = key.get_slicec(' ', 0);
 		String end_key = key.get_slice_count(" ") > 1 ? key.get_slicec(' ', 1) : String();
 
-		add_color_region(start_key, end_key, p_color_regions[key], end_key.is_empty());
+		add_color_region(start_key, end_key, kv.value, end_key.is_empty());
 	}
 	clear_highlighting_cache();
 }

+ 3 - 5
servers/rendering/rendering_device_binds.h

@@ -425,11 +425,9 @@ protected:
 	}
 	void _set_versions(const Dictionary &p_versions) {
 		versions.clear();
-		List<Variant> keys;
-		p_versions.get_key_list(&keys);
-		for (const Variant &E : keys) {
-			StringName vname = E;
-			Ref<RDShaderSPIRV> bc = p_versions[E];
+		for (const KeyValue<Variant, Variant> &kv : p_versions) {
+			StringName vname = kv.key;
+			Ref<RDShaderSPIRV> bc = kv.value;
 			ERR_CONTINUE(bc.is_null());
 			versions[vname] = bc;
 		}

+ 17 - 0
tests/core/variant/test_dictionary.h

@@ -593,4 +593,21 @@ TEST_CASE("[Dictionary] Typed copying") {
 	d6.clear();
 }
 
+TEST_CASE("[Dictionary] Iteration") {
+	Dictionary a1 = build_dictionary(1, 2, 3, 4, 5, 6);
+	Dictionary a2 = build_dictionary(1, 2, 3, 4, 5, 6);
+
+	int idx = 0;
+
+	for (const KeyValue<Variant, Variant> &kv : (const Dictionary &)a1) {
+		CHECK_EQ(int(a2[kv.key]), int(kv.value));
+		idx++;
+	}
+
+	CHECK_EQ(idx, a1.size());
+
+	a1.clear();
+	a2.clear();
+}
+
 } // namespace TestDictionary