Browse Source

Merge pull request #61194 from reduz/new-hash-set

Add a new HashSet template
Rémi Verschelde 3 years ago
parent
commit
8adf048045
100 changed files with 762 additions and 273 deletions
  1. 1 1
      core/config/project_settings.h
  2. 3 3
      core/debugger/local_debugger.cpp
  3. 1 1
      core/debugger/script_debugger.cpp
  4. 3 3
      core/debugger/script_debugger.h
  5. 1 0
      core/input/input.h
  6. 2 2
      core/io/file_access_pack.h
  7. 2 2
      core/io/json.cpp
  8. 1 1
      core/io/json.h
  9. 4 4
      core/io/logger.cpp
  10. 1 1
      core/io/resource.h
  11. 1 1
      core/io/resource_format_binary.cpp
  12. 1 1
      core/io/resource_format_binary.h
  13. 2 2
      core/io/resource_importer.cpp
  14. 1 1
      core/io/resource_loader.h
  15. 12 12
      core/math/a_star.cpp
  16. 5 2
      core/math/a_star.h
  17. 1 1
      core/math/quick_hull.cpp
  18. 1 1
      core/math/quick_hull.h
  19. 1 1
      core/math/static_raycaster.h
  20. 2 2
      core/multiplayer/multiplayer_api.h
  21. 1 1
      core/object/class_db.cpp
  22. 3 2
      core/object/class_db.h
  23. 3 3
      core/object/object.h
  24. 1 1
      core/object/script_language.cpp
  25. 2 2
      core/object/script_language.h
  26. 2 2
      core/object/script_language_extension.h
  27. 2 2
      core/string/translation.h
  28. 473 0
      core/templates/hash_set.h
  29. 3 0
      core/templates/rb_set.h
  30. 1 1
      core/templates/rid_owner.h
  31. 1 1
      doc/classes/CodeEdit.xml
  32. 2 2
      drivers/gles3/storage/config.h
  33. 1 1
      drivers/gles3/storage/material_storage.cpp
  34. 2 2
      drivers/gles3/storage/material_storage.h
  35. 1 1
      drivers/gles3/storage/mesh_storage.h
  36. 7 7
      drivers/vulkan/rendering_device_vulkan.cpp
  37. 4 4
      drivers/vulkan/rendering_device_vulkan.h
  38. 10 10
      editor/animation_bezier_editor.cpp
  39. 3 2
      editor/animation_bezier_editor.h
  40. 1 1
      editor/animation_track_editor.cpp
  41. 1 1
      editor/create_dialog.h
  42. 1 1
      editor/debugger/editor_debugger_inspector.cpp
  43. 1 1
      editor/debugger/editor_debugger_inspector.h
  44. 1 1
      editor/debugger/editor_debugger_node.h
  45. 1 1
      editor/debugger/editor_debugger_tree.h
  46. 1 1
      editor/debugger/editor_performance_profiler.cpp
  47. 1 1
      editor/debugger/editor_profiler.cpp
  48. 1 1
      editor/debugger/editor_profiler.h
  49. 1 1
      editor/doc_tools.cpp
  50. 1 1
      editor/editor_asset_installer.cpp
  51. 2 2
      editor/editor_data.cpp
  52. 1 1
      editor/editor_data.h
  53. 1 1
      editor/editor_dir_dialog.h
  54. 11 11
      editor/editor_export.cpp
  55. 11 11
      editor/editor_export.h
  56. 2 2
      editor/editor_feature_profile.cpp
  57. 4 4
      editor/editor_feature_profile.h
  58. 5 5
      editor/editor_file_system.cpp
  59. 8 8
      editor/editor_file_system.h
  60. 6 6
      editor/editor_folding.cpp
  61. 3 3
      editor/editor_folding.h
  62. 1 1
      editor/editor_help.cpp
  63. 4 4
      editor/editor_inspector.cpp
  64. 2 2
      editor/editor_inspector.h
  65. 4 4
      editor/editor_node.cpp
  66. 5 5
      editor/editor_node.h
  67. 13 12
      editor/editor_resource_picker.cpp
  68. 2 2
      editor/editor_resource_picker.h
  69. 2 1
      editor/editor_settings.h
  70. 2 2
      editor/editor_themes.cpp
  71. 2 2
      editor/editor_translation_parser.cpp
  72. 2 1
      editor/export_template_manager.cpp
  73. 1 1
      editor/fileserver/editor_file_server.cpp
  74. 1 1
      editor/fileserver/editor_file_server.h
  75. 1 1
      editor/filesystem_dock.cpp
  76. 1 1
      editor/filesystem_dock.h
  77. 3 3
      editor/find_in_files.cpp
  78. 3 3
      editor/find_in_files.h
  79. 5 5
      editor/import/collada.cpp
  80. 1 1
      editor/import/collada.h
  81. 1 0
      editor/import/dynamic_font_import_settings.h
  82. 6 6
      editor/import/editor_import_collada.cpp
  83. 2 2
      editor/import/resource_importer_scene.cpp
  84. 1 1
      editor/import/resource_importer_scene.h
  85. 2 2
      editor/import/scene_import_settings.h
  86. 2 2
      editor/import_dock.cpp
  87. 1 1
      editor/inspector_dock.cpp
  88. 7 6
      editor/plugins/animation_blend_tree_editor_plugin.cpp
  89. 4 4
      editor/plugins/animation_state_machine_editor.cpp
  90. 2 2
      editor/plugins/animation_state_machine_editor.h
  91. 2 2
      editor/plugins/editor_preview_plugins.cpp
  92. 2 2
      editor/plugins/gdextension_export_plugin.h
  93. 8 7
      editor/plugins/mesh_instance_3d_editor_plugin.cpp
  94. 1 1
      editor/plugins/node_3d_editor_gizmos.cpp
  95. 22 21
      editor/plugins/node_3d_editor_plugin.cpp
  96. 1 1
      editor/plugins/packed_scene_translation_parser_plugin.h
  97. 1 1
      editor/plugins/root_motion_editor_plugin.cpp
  98. 4 4
      editor/plugins/script_editor_plugin.cpp
  99. 2 2
      editor/plugins/script_editor_plugin.h
  100. 3 3
      editor/plugins/script_text_editor.cpp

+ 1 - 1
core/config/project_settings.h

@@ -91,7 +91,7 @@ protected:
 	bool using_datapack = false;
 	List<String> input_presets;
 
-	RBSet<String> custom_features;
+	HashSet<String> custom_features;
 	HashMap<StringName, StringName> feature_overrides;
 
 	HashMap<StringName, AutoloadInfo> autoloads;

+ 3 - 3
core/debugger/local_debugger.cpp

@@ -241,15 +241,15 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
 
 		} else if (line.begins_with("br") || line.begins_with("break")) {
 			if (line.get_slice_count(" ") <= 1) {
-				const HashMap<int, RBSet<StringName>> &breakpoints = script_debugger->get_breakpoints();
+				const HashMap<int, HashSet<StringName>> &breakpoints = script_debugger->get_breakpoints();
 				if (breakpoints.size() == 0) {
 					print_line("No Breakpoints.");
 					continue;
 				}
 
 				print_line("Breakpoint(s): " + itos(breakpoints.size()));
-				for (const KeyValue<int, RBSet<StringName>> &E : breakpoints) {
-					print_line("\t" + String(E.value.front()->get()) + ":" + itos(E.key));
+				for (const KeyValue<int, HashSet<StringName>> &E : breakpoints) {
+					print_line("\t" + String(*E.value.begin()) + ":" + itos(E.key));
 				}
 
 			} else {

+ 1 - 1
core/debugger/script_debugger.cpp

@@ -50,7 +50,7 @@ int ScriptDebugger::get_depth() const {
 
 void ScriptDebugger::insert_breakpoint(int p_line, const StringName &p_source) {
 	if (!breakpoints.has(p_line)) {
-		breakpoints[p_line] = RBSet<StringName>();
+		breakpoints[p_line] = HashSet<StringName>();
 	}
 	breakpoints[p_line].insert(p_source);
 }

+ 3 - 3
core/debugger/script_debugger.h

@@ -33,8 +33,8 @@
 
 #include "core/object/script_language.h"
 #include "core/string/string_name.h"
+#include "core/templates/hash_set.h"
 #include "core/templates/rb_map.h"
-#include "core/templates/rb_set.h"
 #include "core/templates/vector.h"
 
 class ScriptDebugger {
@@ -44,7 +44,7 @@ class ScriptDebugger {
 	int depth = -1;
 	bool skip_breakpoints = false;
 
-	HashMap<int, RBSet<StringName>> breakpoints;
+	HashMap<int, HashSet<StringName>> breakpoints;
 
 	ScriptLanguage *break_lang = nullptr;
 	Vector<StackInfo> error_stack_info;
@@ -66,7 +66,7 @@ public:
 	bool is_breakpoint(int p_line, const StringName &p_source) const;
 	bool is_breakpoint_line(int p_line) const;
 	void clear_breakpoints();
-	const HashMap<int, RBSet<StringName>> &get_breakpoints() const { return breakpoints; }
+	const HashMap<int, HashSet<StringName>> &get_breakpoints() const { return breakpoints; }
 
 	void debug(ScriptLanguage *p_lang, bool p_can_continue = true, bool p_is_error_breakpoint = false);
 	ScriptLanguage *get_break_language() const;

+ 1 - 0
core/input/input.h

@@ -35,6 +35,7 @@
 #include "core/object/object.h"
 #include "core/os/keyboard.h"
 #include "core/os/thread_safe.h"
+#include "core/templates/rb_set.h"
 
 class Input : public Object {
 	GDCLASS(Input, Object);

+ 2 - 2
core/io/file_access_pack.h

@@ -34,9 +34,9 @@
 #include "core/io/dir_access.h"
 #include "core/io/file_access.h"
 #include "core/string/print_string.h"
+#include "core/templates/hash_set.h"
 #include "core/templates/list.h"
 #include "core/templates/rb_map.h"
-#include "core/templates/rb_set.h"
 
 // Godot's packed file magic header ("GDPC" in ASCII).
 #define PACK_HEADER_MAGIC 0x43504447
@@ -73,7 +73,7 @@ private:
 		PackedDir *parent = nullptr;
 		String name;
 		HashMap<String, PackedDir *> subdirs;
-		RBSet<String> files;
+		HashSet<String> files;
 	};
 
 	struct PathMD5 {

+ 2 - 2
core/io/json.cpp

@@ -55,7 +55,7 @@ String JSON::_make_indent(const String &p_indent, int p_size) {
 	return indent_text;
 }
 
-String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, RBSet<const void *> &p_markers, bool p_full_precision) {
+String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, HashSet<const void *> &p_markers, bool p_full_precision) {
 	String colon = ":";
 	String end_statement = "";
 
@@ -529,7 +529,7 @@ Error JSON::_parse_string(const String &p_json, Variant &r_ret, String &r_err_st
 }
 
 String JSON::stringify(const Variant &p_var, const String &p_indent, bool p_sort_keys, bool p_full_precision) {
-	RBSet<const void *> markers;
+	HashSet<const void *> markers;
 	return _stringify(p_var, p_indent, 0, p_sort_keys, markers, p_full_precision);
 }
 

+ 1 - 1
core/io/json.h

@@ -70,7 +70,7 @@ class JSON : public RefCounted {
 	static const char *tk_name[];
 
 	static String _make_indent(const String &p_indent, int p_size);
-	static String _stringify(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, RBSet<const void *> &p_markers, bool p_full_precision = false);
+	static String _stringify(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, HashSet<const void *> &p_markers, bool p_full_precision = false);
 	static Error _get_token(const char32_t *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
 	static Error _parse_value(Variant &value, Token &token, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str);
 	static Error _parse_array(Array &array, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str);

+ 4 - 4
core/io/logger.cpp

@@ -128,7 +128,7 @@ void RotatedFileLogger::clear_old_backups() {
 
 	da->list_dir_begin();
 	String f = da->get_next();
-	RBSet<String> backups;
+	HashSet<String> backups;
 	while (!f.is_empty()) {
 		if (!da->current_is_dir() && f.begins_with(basename) && f.get_extension() == extension && f != base_path.get_file()) {
 			backups.insert(f);
@@ -137,12 +137,12 @@ void RotatedFileLogger::clear_old_backups() {
 	}
 	da->list_dir_end();
 
-	if (backups.size() > max_backups) {
+	if (backups.size() > (uint32_t)max_backups) {
 		// since backups are appended with timestamp and Set iterates them in sorted order,
 		// first backups are the oldest
 		int to_delete = backups.size() - max_backups;
-		for (RBSet<String>::Element *E = backups.front(); E && to_delete > 0; E = E->next(), --to_delete) {
-			da->remove(E->get());
+		for (HashSet<String>::Iterator E = backups.begin(); E && to_delete > 0; ++E, --to_delete) {
+			da->remove(*E);
 		}
 	}
 }

+ 1 - 1
core/io/resource.h

@@ -54,7 +54,7 @@ public:
 	virtual String get_base_extension() const { return "res"; }
 
 private:
-	RBSet<ObjectID> owners;
+	HashSet<ObjectID> owners;
 
 	friend class ResBase;
 	friend class ResourceCache;

+ 1 - 1
core/io/resource_format_binary.cpp

@@ -2022,7 +2022,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re
 	// save internal resource table
 	f->store_32(saved_resources.size()); //amount of internal resources
 	Vector<uint64_t> ofs_pos;
-	RBSet<String> used_unique_ids;
+	HashSet<String> used_unique_ids;
 
 	for (Ref<Resource> &r : saved_resources) {
 		if (r->is_built_in()) {

+ 1 - 1
core/io/resource_format_binary.h

@@ -127,7 +127,7 @@ class ResourceFormatSaverBinaryInstance {
 	bool big_endian;
 	bool takeover_paths;
 	String magic;
-	RBSet<Ref<Resource>> resource_set;
+	HashSet<Ref<Resource>> resource_set;
 
 	struct NonPersistentKey { //for resource properties generated on the fly
 		Ref<Resource> base;

+ 2 - 2
core/io/resource_importer.cpp

@@ -139,7 +139,7 @@ Ref<Resource> ResourceFormatImporter::load(const String &p_path, const String &p
 }
 
 void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extensions) const {
-	RBSet<String> found;
+	HashSet<String> found;
 
 	for (int i = 0; i < importers.size(); i++) {
 		List<String> local_exts;
@@ -159,7 +159,7 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
 		return;
 	}
 
-	RBSet<String> found;
+	HashSet<String> found;
 
 	for (int i = 0; i < importers.size(); i++) {
 		String res_type = importers[i]->get_resource_type();

+ 1 - 1
core/io/resource_loader.h

@@ -145,7 +145,7 @@ private:
 		bool start_next = true;
 		int requests = 0;
 		int poll_requests = 0;
-		RBSet<String> sub_tasks;
+		HashSet<String> sub_tasks;
 	};
 
 	static void _thread_load_function(void *p_userdata);

+ 12 - 12
core/math/a_star.cpp

@@ -151,15 +151,15 @@ void AStar3D::connect_points(int p_id, int p_with_id, bool bidirectional) {
 		s.direction = Segment::BIDIRECTIONAL;
 	}
 
-	RBSet<Segment>::Element *element = segments.find(s);
-	if (element != nullptr) {
-		s.direction |= element->get().direction;
+	HashSet<Segment, Segment>::Iterator element = segments.find(s);
+	if (element) {
+		s.direction |= element->direction;
 		if (s.direction == Segment::BIDIRECTIONAL) {
 			// Both are neighbours of each other now
 			a->unlinked_neighbours.remove(b->id);
 			b->unlinked_neighbours.remove(a->id);
 		}
-		segments.erase(element);
+		segments.remove(element);
 	}
 
 	segments.insert(s);
@@ -177,16 +177,16 @@ void AStar3D::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
 	Segment s(p_id, p_with_id);
 	int remove_direction = bidirectional ? (int)Segment::BIDIRECTIONAL : s.direction;
 
-	RBSet<Segment>::Element *element = segments.find(s);
-	if (element != nullptr) {
+	HashSet<Segment, Segment>::Iterator element = segments.find(s);
+	if (element) {
 		// s is the new segment
 		// Erase the directions to be removed
-		s.direction = (element->get().direction & ~remove_direction);
+		s.direction = (element->direction & ~remove_direction);
 
 		a->neighbours.remove(b->id);
 		if (bidirectional) {
 			b->neighbours.remove(a->id);
-			if (element->get().direction != Segment::BIDIRECTIONAL) {
+			if (element->direction != Segment::BIDIRECTIONAL) {
 				a->unlinked_neighbours.remove(b->id);
 				b->unlinked_neighbours.remove(a->id);
 			}
@@ -198,7 +198,7 @@ void AStar3D::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
 			}
 		}
 
-		segments.erase(element);
+		segments.remove(element);
 		if (s.direction != Segment::NONE) {
 			segments.insert(s);
 		}
@@ -235,10 +235,10 @@ Vector<int> AStar3D::get_point_connections(int p_id) {
 
 bool AStar3D::are_points_connected(int p_id, int p_with_id, bool bidirectional) const {
 	Segment s(p_id, p_with_id);
-	const RBSet<Segment>::Element *element = segments.find(s);
+	const HashSet<Segment, Segment>::Iterator element = segments.find(s);
 
-	return element != nullptr &&
-			(bidirectional || (element->get().direction & s.direction) == s.direction);
+	return element &&
+			(bidirectional || (element->direction & s.direction) == s.direction);
 }
 
 void AStar3D::clear() {

+ 5 - 2
core/math/a_star.h

@@ -92,7 +92,10 @@ class AStar3D : public RefCounted {
 		};
 		unsigned char direction = NONE;
 
-		bool operator<(const Segment &p_s) const { return key < p_s.key; }
+		static uint32_t hash(const Segment &p_seg) {
+			return hash_one_uint64(p_seg.key);
+		}
+		bool operator==(const Segment &p_s) const { return key == p_s.key; }
 
 		Segment() {}
 		Segment(int p_from, int p_to) {
@@ -112,7 +115,7 @@ class AStar3D : public RefCounted {
 	uint64_t pass = 1;
 
 	OAHashMap<int, Point *> points;
-	RBSet<Segment> segments;
+	HashSet<Segment, Segment> segments;
 
 	bool _solve(Point *begin_point, Point *end_point);
 

+ 1 - 1
core/math/quick_hull.cpp

@@ -52,7 +52,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
 
 	Vector<bool> valid_points;
 	valid_points.resize(p_points.size());
-	RBSet<Vector3> valid_cache;
+	HashSet<Vector3> valid_cache;
 
 	for (int i = 0; i < p_points.size(); i++) {
 		Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001));

+ 1 - 1
core/math/quick_hull.h

@@ -33,8 +33,8 @@
 
 #include "core/math/aabb.h"
 #include "core/math/geometry_3d.h"
+#include "core/templates/hash_set.h"
 #include "core/templates/list.h"
-#include "core/templates/rb_set.h"
 
 class QuickHull {
 public:

+ 1 - 1
core/math/static_raycaster.h

@@ -102,7 +102,7 @@ public:
 	virtual void add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) = 0;
 	virtual void commit() = 0;
 
-	virtual void set_mesh_filter(const RBSet<int> &p_mesh_ids) = 0;
+	virtual void set_mesh_filter(const HashSet<int> &p_mesh_ids) = 0;
 	virtual void clear_mesh_filter() = 0;
 
 	static Ref<StaticRaycaster> create();

+ 2 - 2
core/multiplayer/multiplayer_api.h

@@ -113,7 +113,7 @@ public:
 
 private:
 	Ref<MultiplayerPeer> multiplayer_peer;
-	RBSet<int> connected_peers;
+	HashSet<int> connected_peers;
 	int remote_sender_id = 0;
 	int remote_sender_override = 0;
 
@@ -172,7 +172,7 @@ public:
 
 	bool has_multiplayer_peer() const { return multiplayer_peer.is_valid(); }
 	Vector<int> get_peer_ids() const;
-	const RBSet<int> get_connected_peers() const { return connected_peers; }
+	const HashSet<int> get_connected_peers() const { return connected_peers; }
 	int get_remote_sender_id() const { return remote_sender_override ? remote_sender_override : remote_sender_id; }
 	void set_remote_sender_override(int p_id) { remote_sender_override = p_id; }
 	int get_unique_id() const;

+ 1 - 1
core/object/class_db.cpp

@@ -1390,7 +1390,7 @@ void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p
 }
 
 HashMap<StringName, HashMap<StringName, Variant>> ClassDB::default_values;
-RBSet<StringName> ClassDB::default_values_cached;
+HashSet<StringName> ClassDB::default_values_cached;
 
 Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid) {
 	if (!default_values_cached.has(p_class)) {

+ 3 - 2
core/object/class_db.h

@@ -38,6 +38,7 @@
 // Makes callable_mp readily available in all classes connecting signals.
 // Needs to come after method_bind and object have been included.
 #include "core/object/callable_method_pointer.h"
+#include "core/templates/hash_set.h"
 
 #define DEFVAL(m_defval) (m_defval)
 
@@ -110,7 +111,7 @@ public:
 #ifdef DEBUG_METHODS_ENABLED
 		List<StringName> constant_order;
 		List<StringName> method_order;
-		RBSet<StringName> methods_in_properties;
+		HashSet<StringName> methods_in_properties;
 		List<MethodInfo> virtual_methods;
 		HashMap<StringName, MethodInfo> virtual_methods_map;
 		HashMap<StringName, Vector<Error>> method_error_values;
@@ -149,7 +150,7 @@ public:
 	static void _add_class2(const StringName &p_class, const StringName &p_inherits);
 
 	static HashMap<StringName, HashMap<StringName, Variant>> default_values;
-	static RBSet<StringName> default_values_cached;
+	static HashSet<StringName> default_values_cached;
 
 	// Native structs, used by binder
 	struct NativeStruct {

+ 3 - 3
core/object/object.h

@@ -37,9 +37,9 @@
 #include "core/os/rw_lock.h"
 #include "core/os/spin_lock.h"
 #include "core/templates/hash_map.h"
+#include "core/templates/hash_set.h"
 #include "core/templates/list.h"
 #include "core/templates/rb_map.h"
-#include "core/templates/rb_set.h"
 #include "core/templates/safe_refcount.h"
 #include "core/templates/vmap.h"
 #include "core/variant/callable_bind.h"
@@ -510,7 +510,7 @@ private:
 #ifdef TOOLS_ENABLED
 	bool _edited = false;
 	uint32_t _edited_version = 0;
-	RBSet<String> editor_section_folding;
+	HashSet<String> editor_section_folding;
 #endif
 	ScriptInstance *script_instance = nullptr;
 	Variant script; // Reference does not exist yet, store it in a Variant.
@@ -815,7 +815,7 @@ public:
 #ifdef TOOLS_ENABLED
 	void editor_set_section_unfold(const String &p_section, bool p_unfolded);
 	bool editor_is_section_unfolded(const String &p_section);
-	const RBSet<String> &editor_get_section_folding() const { return editor_section_folding; }
+	const HashSet<String> &editor_get_section_folding() const { return editor_section_folding; }
 	void editor_clear_section_folding() { editor_section_folding.clear(); }
 
 #endif

+ 1 - 1
core/object/script_language.cpp

@@ -475,7 +475,7 @@ bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const {
 }
 
 void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, const HashMap<StringName, Variant> &p_values) {
-	RBSet<StringName> new_values;
+	HashSet<StringName> new_values;
 	for (const PropertyInfo &E : p_properties) {
 		StringName n = E.name;
 		new_values.insert(n);

+ 2 - 2
core/object/script_language.h

@@ -155,7 +155,7 @@ public:
 	virtual int get_member_line(const StringName &p_member) const { return -1; }
 
 	virtual void get_constants(HashMap<StringName, Variant> *p_constants) {}
-	virtual void get_members(RBSet<StringName> *p_constants) {}
+	virtual void get_members(HashSet<StringName> *p_constants) {}
 
 	virtual bool is_placeholder_fallback_enabled() const { return false; }
 
@@ -283,7 +283,7 @@ public:
 	virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const { return Ref<Script>(); }
 	virtual Vector<ScriptTemplate> get_built_in_templates(StringName p_object) { return Vector<ScriptTemplate>(); }
 	virtual bool is_using_templates() { return false; }
-	virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, RBSet<int> *r_safe_lines = nullptr) const = 0;
+	virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, HashSet<int> *r_safe_lines = nullptr) const = 0;
 	virtual String validate_path(const String &p_path) const { return ""; }
 	virtual Script *create_script() const = 0;
 	virtual bool has_named_classes() const = 0;

+ 2 - 2
core/object/script_language_extension.h

@@ -163,7 +163,7 @@ public:
 		}
 	}
 	GDVIRTUAL0RC(TypedArray<StringName>, _get_members)
-	virtual void get_members(RBSet<StringName> *p_members) override {
+	virtual void get_members(HashSet<StringName> *p_members) override {
 		TypedArray<StringName> members;
 		GDVIRTUAL_REQUIRED_CALL(_get_members, members);
 		for (int i = 0; i < members.size(); i++) {
@@ -282,7 +282,7 @@ public:
 	EXBIND0R(bool, is_using_templates)
 
 	GDVIRTUAL6RC(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool)
-	virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, RBSet<int> *r_safe_lines = nullptr) const override {
+	virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, HashSet<int> *r_safe_lines = nullptr) const override {
 		Dictionary ret;
 		GDVIRTUAL_REQUIRED_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret);
 		if (!ret.has("valid")) {

+ 2 - 2
core/string/translation.h

@@ -74,7 +74,7 @@ class TranslationServer : public Object {
 	String locale = "en";
 	String fallback;
 
-	RBSet<Ref<Translation>> translations;
+	HashSet<Ref<Translation>> translations;
 	Ref<Translation> tool_translation;
 	Ref<Translation> doc_translation;
 
@@ -111,7 +111,7 @@ class TranslationServer : public Object {
 		String name;
 		String script;
 		String default_country;
-		RBSet<String> supported_countries;
+		HashSet<String> supported_countries;
 	};
 	static Vector<LocaleScriptInfo> locale_script_info;
 

+ 473 - 0
core/templates/hash_set.h

@@ -0,0 +1,473 @@
+/*************************************************************************/
+/*  hash_set.h                                                           */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef HASH_SET_H
+#define HASH_SET_H
+
+#include "core/math/math_funcs.h"
+#include "core/os/memory.h"
+#include "core/templates/hash_map.h"
+#include "core/templates/hashfuncs.h"
+#include "core/templates/paged_allocator.h"
+
+/**
+ * Implementation of Set using a bidi indexed hash map.
+ * Use RBSet instead of this only if the following conditions are met:
+ *
+ * - You need to keep an iterator or const pointer to Key and you intend to add/remove elements in the meantime.
+ * - Iteration order does matter (via operator<)
+ *
+ */
+
+template <class TKey,
+		class Hasher = HashMapHasherDefault,
+		class Comparator = HashMapComparatorDefault<TKey>>
+class HashSet {
+public:
+	static constexpr uint32_t MIN_CAPACITY_INDEX = 2; // Use a prime.
+	static constexpr float MAX_OCCUPANCY = 0.75;
+	static constexpr uint32_t EMPTY_HASH = 0;
+
+private:
+	TKey *keys = nullptr;
+	uint32_t *hash_to_key = nullptr;
+	uint32_t *key_to_hash = nullptr;
+	uint32_t *hashes = nullptr;
+
+	uint32_t capacity_index = 0;
+	uint32_t num_elements = 0;
+
+	_FORCE_INLINE_ uint32_t _hash(const TKey &p_key) const {
+		uint32_t hash = Hasher::hash(p_key);
+
+		if (unlikely(hash == EMPTY_HASH)) {
+			hash = EMPTY_HASH + 1;
+		}
+
+		return hash;
+	}
+
+	_FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash, uint32_t p_capacity) const {
+		uint32_t original_pos = p_hash % p_capacity;
+		return (p_pos - original_pos + p_capacity) % p_capacity;
+	}
+
+	bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const {
+		if (keys == nullptr) {
+			return false; // Failed lookups, no elements
+		}
+
+		uint32_t capacity = hash_table_size_primes[capacity_index];
+		uint32_t hash = _hash(p_key);
+		uint32_t pos = hash % capacity;
+		uint32_t distance = 0;
+
+		while (true) {
+			if (hashes[pos] == EMPTY_HASH) {
+				return false;
+			}
+
+			if (distance > _get_probe_length(pos, hashes[pos], capacity)) {
+				return false;
+			}
+
+			if (hashes[pos] == hash && Comparator::compare(keys[hash_to_key[pos]], p_key)) {
+				r_pos = hash_to_key[pos];
+				return true;
+			}
+
+			pos = (pos + 1) % capacity;
+			distance++;
+		}
+	}
+
+	uint32_t _insert_with_hash(uint32_t p_hash, uint32_t p_index) {
+		uint32_t capacity = hash_table_size_primes[capacity_index];
+		uint32_t hash = p_hash;
+		uint32_t index = p_index;
+		uint32_t distance = 0;
+		uint32_t pos = hash % capacity;
+
+		while (true) {
+			if (hashes[pos] == EMPTY_HASH) {
+				hashes[pos] = hash;
+				key_to_hash[index] = pos;
+				hash_to_key[pos] = index;
+				return pos;
+			}
+
+			// Not an empty slot, let's check the probing length of the existing one.
+			uint32_t existing_probe_len = _get_probe_length(pos, hashes[pos], capacity);
+			if (existing_probe_len < distance) {
+				key_to_hash[index] = pos;
+				SWAP(hash, hashes[pos]);
+				SWAP(index, hash_to_key[pos]);
+				distance = existing_probe_len;
+			}
+
+			pos = (pos + 1) % capacity;
+			distance++;
+		}
+	}
+
+	void _resize_and_rehash(uint32_t p_new_capacity_index) {
+		// Capacity can't be 0.
+		capacity_index = MAX((uint32_t)MIN_CAPACITY_INDEX, p_new_capacity_index);
+
+		uint32_t capacity = hash_table_size_primes[capacity_index];
+
+		uint32_t *old_hashes = hashes;
+		uint32_t *old_key_to_hash = key_to_hash;
+
+		hashes = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+		keys = reinterpret_cast<TKey *>(Memory::realloc_static(keys, sizeof(TKey) * capacity));
+		key_to_hash = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+		hash_to_key = reinterpret_cast<uint32_t *>(Memory::realloc_static(hash_to_key, sizeof(uint32_t) * capacity));
+
+		for (uint32_t i = 0; i < capacity; i++) {
+			hashes[i] = EMPTY_HASH;
+		}
+
+		for (uint32_t i = 0; i < num_elements; i++) {
+			uint32_t h = old_hashes[old_key_to_hash[i]];
+			_insert_with_hash(h, i);
+		}
+
+		Memory::free_static(old_hashes);
+		Memory::free_static(old_key_to_hash);
+	}
+
+	_FORCE_INLINE_ int32_t _insert(const TKey &p_key) {
+		uint32_t capacity = hash_table_size_primes[capacity_index];
+		if (unlikely(keys == nullptr)) {
+			// Allocate on demand to save memory.
+
+			hashes = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+			keys = reinterpret_cast<TKey *>(Memory::alloc_static(sizeof(TKey) * capacity));
+			key_to_hash = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+			hash_to_key = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+
+			for (uint32_t i = 0; i < capacity; i++) {
+				hashes[i] = EMPTY_HASH;
+			}
+		}
+
+		uint32_t pos = 0;
+		bool exists = _lookup_pos(p_key, pos);
+
+		if (exists) {
+			return pos;
+		} else {
+			if (num_elements + 1 > MAX_OCCUPANCY * capacity) {
+				ERR_FAIL_COND_V_MSG(capacity_index + 1 == HASH_TABLE_SIZE_MAX, -1, "Hash table maximum capacity reached, aborting insertion.");
+				_resize_and_rehash(capacity_index + 1);
+			}
+
+			uint32_t hash = _hash(p_key);
+			memnew_placement(&keys[num_elements], TKey(p_key));
+			_insert_with_hash(hash, num_elements);
+			num_elements++;
+			return num_elements - 1;
+		}
+	}
+
+	void _init_from(const HashSet &p_other) {
+		capacity_index = p_other.capacity_index;
+		num_elements = p_other.num_elements;
+
+		if (p_other.num_elements == 0) {
+			return;
+		}
+
+		uint32_t capacity = hash_table_size_primes[capacity_index];
+
+		hashes = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+		keys = reinterpret_cast<TKey *>(Memory::alloc_static(sizeof(TKey) * capacity));
+		key_to_hash = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+		hash_to_key = reinterpret_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
+
+		for (uint32_t i = 0; i < num_elements; i++) {
+			memnew_placement(&keys[i], TKey(p_other.keys[i]));
+			key_to_hash[i] = p_other.key_to_hash[i];
+		}
+
+		for (uint32_t i = 0; i < capacity; i++) {
+			hashes[i] = p_other.hashes[i];
+			hash_to_key[i] = p_other.hash_to_key[i];
+		}
+	}
+
+public:
+	_FORCE_INLINE_ uint32_t get_capacity() const { return hash_table_size_primes[capacity_index]; }
+	_FORCE_INLINE_ uint32_t size() const { return num_elements; }
+
+	/* Standard Godot Container API */
+
+	bool is_empty() const {
+		return num_elements == 0;
+	}
+
+	void clear() {
+		if (keys == nullptr) {
+			return;
+		}
+		uint32_t capacity = hash_table_size_primes[capacity_index];
+		for (uint32_t i = 0; i < capacity; i++) {
+			hashes[i] = EMPTY_HASH;
+		}
+		for (uint32_t i = 0; i < num_elements; i++) {
+			keys[i].~TKey();
+		}
+
+		num_elements = 0;
+	}
+
+	_FORCE_INLINE_ bool has(const TKey &p_key) const {
+		uint32_t _pos = 0;
+		return _lookup_pos(p_key, _pos);
+	}
+
+	bool erase(const TKey &p_key) {
+		uint32_t pos = 0;
+		bool exists = _lookup_pos(p_key, pos);
+
+		if (!exists) {
+			return false;
+		}
+
+		uint32_t key_pos = pos;
+		pos = key_to_hash[pos]; //make hash pos
+
+		uint32_t capacity = hash_table_size_primes[capacity_index];
+		uint32_t next_pos = (pos + 1) % capacity;
+		while (hashes[next_pos] != EMPTY_HASH && _get_probe_length(next_pos, hashes[next_pos], capacity) != 0) {
+			uint32_t kpos = hash_to_key[pos];
+			uint32_t kpos_next = hash_to_key[next_pos];
+			SWAP(key_to_hash[kpos], key_to_hash[kpos_next]);
+			SWAP(hashes[next_pos], hashes[pos]);
+			SWAP(hash_to_key[next_pos], hash_to_key[pos]);
+
+			pos = next_pos;
+			next_pos = (pos + 1) % capacity;
+		}
+
+		hashes[pos] = EMPTY_HASH;
+		keys[key_pos].~TKey();
+		num_elements--;
+		if (key_pos < num_elements) {
+			// Not the last key, move the last one here to keep keys lineal
+			memnew_placement(&keys[key_pos], TKey(keys[num_elements]));
+			keys[num_elements].~TKey();
+			key_to_hash[key_pos] = key_to_hash[num_elements];
+			hash_to_key[key_to_hash[num_elements]] = key_pos;
+		}
+
+		return true;
+	}
+
+	// Reserves space for a number of elements, useful to avoid many resizes and rehashes.
+	// If adding a known (possibly large) number of elements at once, must be larger than old capacity.
+	void reserve(uint32_t p_new_capacity) {
+		uint32_t new_index = capacity_index;
+
+		while (hash_table_size_primes[new_index] < p_new_capacity) {
+			ERR_FAIL_COND_MSG(new_index + 1 == (uint32_t)HASH_TABLE_SIZE_MAX, nullptr);
+			new_index++;
+		}
+
+		if (new_index == capacity_index) {
+			return;
+		}
+
+		if (keys == nullptr) {
+			capacity_index = new_index;
+			return; // Unallocated yet.
+		}
+		_resize_and_rehash(new_index);
+	}
+
+	/** Iterator API **/
+
+	struct Iterator {
+		_FORCE_INLINE_ const TKey &operator*() const {
+			return keys[index];
+		}
+		_FORCE_INLINE_ const TKey *operator->() const {
+			return &keys[index];
+		}
+		_FORCE_INLINE_ Iterator &operator++() {
+			index++;
+			if (index >= (int32_t)num_keys) {
+				index = -1;
+				keys = nullptr;
+				num_keys = 0;
+			}
+			return *this;
+		}
+		_FORCE_INLINE_ Iterator &operator--() {
+			index--;
+			if (index < 0) {
+				index = -1;
+				keys = nullptr;
+				num_keys = 0;
+			}
+			return *this;
+		}
+
+		_FORCE_INLINE_ bool operator==(const Iterator &b) const { return keys == b.keys && index == b.index; }
+		_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return keys != b.keys || index != b.index; }
+
+		_FORCE_INLINE_ explicit operator bool() const {
+			return keys != nullptr;
+		}
+
+		_FORCE_INLINE_ Iterator(const TKey *p_keys, uint32_t p_num_keys, int32_t p_index = -1) {
+			keys = p_keys;
+			num_keys = p_num_keys;
+			index = p_index;
+		}
+		_FORCE_INLINE_ Iterator() {}
+		_FORCE_INLINE_ Iterator(const Iterator &p_it) {
+			keys = p_it.keys;
+			num_keys = p_it.num_keys;
+			index = p_it.index;
+		}
+		_FORCE_INLINE_ void operator=(const Iterator &p_it) {
+			keys = p_it.keys;
+			num_keys = p_it.num_keys;
+			index = p_it.index;
+		}
+
+	private:
+		const TKey *keys = nullptr;
+		uint32_t num_keys = 0;
+		int32_t index = -1;
+	};
+
+	_FORCE_INLINE_ Iterator begin() const {
+		return num_elements ? Iterator(keys, num_elements, 0) : Iterator();
+	}
+	_FORCE_INLINE_ Iterator end() const {
+		return Iterator();
+	}
+	_FORCE_INLINE_ Iterator last() const {
+		if (num_elements == 0) {
+			return Iterator();
+		}
+		return Iterator(keys, num_elements, num_elements - 1);
+	}
+
+	_FORCE_INLINE_ Iterator find(const TKey &p_key) const {
+		uint32_t pos = 0;
+		bool exists = _lookup_pos(p_key, pos);
+		if (!exists) {
+			return end();
+		}
+		return Iterator(keys, num_elements, pos);
+	}
+
+	_FORCE_INLINE_ void remove(const Iterator &p_iter) {
+		if (p_iter) {
+			erase(*p_iter);
+		}
+	}
+
+	/* Insert */
+
+	Iterator insert(const TKey &p_key) {
+		uint32_t pos = _insert(p_key);
+		return Iterator(keys, num_elements, pos);
+	}
+
+	/* Constructors */
+
+	HashSet(const HashSet &p_other) {
+		_init_from(p_other);
+	}
+
+	void operator=(const HashSet &p_other) {
+		if (this == &p_other) {
+			return; // Ignore self assignment.
+		}
+
+		clear();
+
+		if (keys != nullptr) {
+			Memory::free_static(keys);
+			Memory::free_static(key_to_hash);
+			Memory::free_static(hash_to_key);
+			Memory::free_static(hashes);
+			keys = nullptr;
+			hashes = nullptr;
+			hash_to_key = nullptr;
+			key_to_hash = nullptr;
+		}
+
+		_init_from(p_other);
+	}
+
+	HashSet(uint32_t p_initial_capacity) {
+		// Capacity can't be 0.
+		capacity_index = 0;
+		reserve(p_initial_capacity);
+	}
+	HashSet() {
+		capacity_index = MIN_CAPACITY_INDEX;
+	}
+
+	void reset() {
+		clear();
+
+		if (keys != nullptr) {
+			Memory::free_static(keys);
+			Memory::free_static(key_to_hash);
+			Memory::free_static(hash_to_key);
+			Memory::free_static(hashes);
+			keys = nullptr;
+			hashes = nullptr;
+			hash_to_key = nullptr;
+			key_to_hash = nullptr;
+		}
+		capacity_index = MIN_CAPACITY_INDEX;
+	}
+
+	~HashSet() {
+		clear();
+
+		if (keys != nullptr) {
+			Memory::free_static(keys);
+			Memory::free_static(key_to_hash);
+			Memory::free_static(hash_to_key);
+			Memory::free_static(hashes);
+		}
+	}
+};
+
+#endif // HASH_SET_H

+ 3 - 0
core/templates/rb_set.h

@@ -99,6 +99,7 @@ public:
 		_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
 		_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
 
+		explicit operator bool() const { return E != nullptr; }
 		Iterator(Element *p_E) { E = p_E; }
 		Iterator() {}
 		Iterator(const Iterator &p_it) { E = p_it.E; }
@@ -128,6 +129,8 @@ public:
 		_FORCE_INLINE_ ConstIterator() {}
 		_FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; }
 
+		explicit operator bool() const { return E != nullptr; }
+
 	private:
 		const Element *E = nullptr;
 	};

+ 1 - 1
core/templates/rid_owner.h

@@ -34,9 +34,9 @@
 #include "core/os/memory.h"
 #include "core/os/spin_lock.h"
 #include "core/string/print_string.h"
+#include "core/templates/hash_set.h"
 #include "core/templates/list.h"
 #include "core/templates/oa_hash_map.h"
-#include "core/templates/rb_set.h"
 #include "core/templates/rid.h"
 #include "core/templates/safe_refcount.h"
 

+ 1 - 1
doc/classes/CodeEdit.xml

@@ -478,7 +478,7 @@
 		<member name="indent_automatic" type="bool" setter="set_auto_indent_enabled" getter="is_auto_indent_enabled" default="false">
 			Sets whether automatic indent are enabled, this will add an extra indent if a prefix or brace is found.
 		</member>
-		<member name="indent_automatic_prefixes" type="String[]" setter="set_auto_indent_prefixes" getter="get_auto_indent_prefixes" default="[&quot;(&quot;, &quot;:&quot;, &quot;[&quot;, &quot;{&quot;]">
+		<member name="indent_automatic_prefixes" type="String[]" setter="set_auto_indent_prefixes" getter="get_auto_indent_prefixes" default="[&quot;:&quot;, &quot;{&quot;, &quot;[&quot;, &quot;(&quot;]">
 			Prefixes to trigger an automatic indent.
 		</member>
 		<member name="indent_size" type="int" setter="set_indent_size" getter="get_indent_size" default="4">

+ 2 - 2
drivers/gles3/storage/config.h

@@ -34,7 +34,7 @@
 #ifdef GLES3_ENABLED
 
 #include "core/string/ustring.h"
-#include "core/templates/rb_set.h"
+#include "core/templates/hash_set.h"
 
 // This must come first to avoid windows.h mess
 #include "platform_config.h"
@@ -65,7 +65,7 @@ public:
 	// TODO implement wireframe in OpenGL
 	// bool generate_wireframes;
 
-	RBSet<String> extensions;
+	HashSet<String> extensions;
 
 	bool float_texture_supported = false;
 	bool s3tc_supported = false;

+ 1 - 1
drivers/gles3/storage/material_storage.cpp

@@ -2381,7 +2381,7 @@ void MaterialStorage::shader_free(RID p_rid) {
 
 	//make material unreference this
 	while (shader->owners.size()) {
-		material_set_shader(shader->owners.front()->get()->self, RID());
+		material_set_shader((*shader->owners.begin())->self, RID());
 	}
 
 	//clear data if exists

+ 2 - 2
drivers/gles3/storage/material_storage.h

@@ -89,7 +89,7 @@ struct Shader {
 	String code;
 	RS::ShaderMode mode;
 	HashMap<StringName, HashMap<int, RID>> default_texture_parameter;
-	RBSet<Material *> owners;
+	HashSet<Material *> owners;
 };
 
 /* Material structs */
@@ -384,7 +384,7 @@ struct GlobalVariables {
 		BUFFER_DIRTY_REGION_SIZE = 1024
 	};
 	struct Variable {
-		RBSet<RID> texture_materials; // materials using this
+		HashSet<RID> texture_materials; // materials using this
 
 		RS::GlobalVariableType type;
 		Variant value;

+ 1 - 1
drivers/gles3/storage/mesh_storage.h

@@ -123,7 +123,7 @@ struct Mesh {
 	List<MeshInstance *> instances;
 
 	RID shadow_mesh;
-	RBSet<Mesh *> shadow_owners;
+	HashSet<Mesh *> shadow_owners;
 
 	RendererStorage::Dependency dependency;
 };

+ 7 - 7
drivers/vulkan/rendering_device_vulkan.cpp

@@ -132,13 +132,13 @@ static void update_external_dependency_for_store(VkSubpassDependency &dependency
 
 void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) {
 	if (!dependency_map.has(p_depends_on)) {
-		dependency_map[p_depends_on] = RBSet<RID>();
+		dependency_map[p_depends_on] = HashSet<RID>();
 	}
 
 	dependency_map[p_depends_on].insert(p_id);
 
 	if (!reverse_dependency_map.has(p_id)) {
-		reverse_dependency_map[p_id] = RBSet<RID>();
+		reverse_dependency_map[p_id] = HashSet<RID>();
 	}
 
 	reverse_dependency_map[p_id].insert(p_depends_on);
@@ -147,10 +147,10 @@ void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) {
 void RenderingDeviceVulkan::_free_dependencies(RID p_id) {
 	//direct dependencies must be freed
 
-	HashMap<RID, RBSet<RID>>::Iterator E = dependency_map.find(p_id);
+	HashMap<RID, HashSet<RID>>::Iterator E = dependency_map.find(p_id);
 	if (E) {
 		while (E->value.size()) {
-			free(E->value.front()->get());
+			free(*E->value.begin());
 		}
 		dependency_map.remove(E);
 	}
@@ -160,7 +160,7 @@ void RenderingDeviceVulkan::_free_dependencies(RID p_id) {
 
 	if (E) {
 		for (const RID &F : E->value) {
-			HashMap<RID, RBSet<RID>>::Iterator G = dependency_map.find(F);
+			HashMap<RID, HashSet<RID>>::Iterator G = dependency_map.find(F);
 			ERR_CONTINUE(!G);
 			ERR_CONTINUE(!G->value.has(p_id));
 			G->value.erase(p_id);
@@ -4138,7 +4138,7 @@ RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(cons
 	vdcache.bindings = memnew_arr(VkVertexInputBindingDescription, p_vertex_formats.size());
 	vdcache.attributes = memnew_arr(VkVertexInputAttributeDescription, p_vertex_formats.size());
 
-	RBSet<int> used_locations;
+	HashSet<int> used_locations;
 	for (int i = 0; i < p_vertex_formats.size(); i++) {
 		ERR_CONTINUE(p_vertex_formats[i].format >= DATA_FORMAT_MAX);
 		ERR_FAIL_COND_V(used_locations.has(p_vertex_formats[i].location), INVALID_ID);
@@ -5468,7 +5468,7 @@ RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataF
 
 RenderingDeviceVulkan::DescriptorPool *RenderingDeviceVulkan::_descriptor_pool_allocate(const DescriptorPoolKey &p_key) {
 	if (!descriptor_pools.has(p_key)) {
-		descriptor_pools[p_key] = RBSet<DescriptorPool *>();
+		descriptor_pools[p_key] = HashSet<DescriptorPool *>();
 	}
 
 	DescriptorPool *pool = nullptr;

+ 4 - 4
drivers/vulkan/rendering_device_vulkan.h

@@ -101,8 +101,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
 
 	VkDevice device = VK_NULL_HANDLE;
 
-	HashMap<RID, RBSet<RID>> dependency_map; //IDs to IDs that depend on it
-	HashMap<RID, RBSet<RID>> reverse_dependency_map; //same as above, but in reverse
+	HashMap<RID, HashSet<RID>> dependency_map; //IDs to IDs that depend on it
+	HashMap<RID, HashSet<RID>> reverse_dependency_map; //same as above, but in reverse
 
 	void _add_dependency(RID p_id, RID p_depends_on);
 	void _free_dependencies(RID p_id);
@@ -702,7 +702,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
 		uint32_t usage;
 	};
 
-	RBMap<DescriptorPoolKey, RBSet<DescriptorPool *>> descriptor_pools;
+	RBMap<DescriptorPoolKey, HashSet<DescriptorPool *>> descriptor_pools;
 	uint32_t max_descriptors_per_pool = 0;
 
 	DescriptorPool *_descriptor_pool_allocate(const DescriptorPoolKey &p_key);
@@ -923,7 +923,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
 		};
 
 		struct State {
-			RBSet<Texture *> textures_to_sampled_layout;
+			HashSet<Texture *> textures_to_sampled_layout;
 			SetState sets[MAX_UNIFORM_SETS];
 			uint32_t set_count = 0;
 			RID pipeline;

+ 10 - 10
editor/animation_bezier_editor.cpp

@@ -792,8 +792,8 @@ void AnimationBezierTrackEdit::_clear_selection() {
 void AnimationBezierTrackEdit::_change_selected_keys_handle_mode(Animation::HandleMode p_mode) {
 	undo_redo->create_action(TTR("Update Selected Key Handles"));
 	double ratio = timeline->get_zoom_scale() * v_zoom;
-	for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) {
-		const IntPair track_key_pair = E->get();
+	for (const IntPair &E : selection) {
+		const IntPair track_key_pair = E;
 		undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_handle_mode", track_key_pair.first, track_key_pair.second, animation->bezier_track_get_key_handle_mode(track_key_pair.first, track_key_pair.second), ratio);
 		undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_handle_mode", track_key_pair.first, track_key_pair.second, p_mode, ratio);
 	}
@@ -851,14 +851,14 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
 					focused_keys.insert(key_pair);
 				}
 			} else {
-				for (SelectionSet::Element *E = selection.front(); E; E = E->next()) {
-					focused_keys.insert(E->get());
-					if (E->get().second > 0) {
-						IntPair previous_key = IntPair(E->get().first, E->get().second - 1);
+				for (const IntPair &E : selection) {
+					focused_keys.insert(E);
+					if (E.second > 0) {
+						IntPair previous_key = IntPair(E.first, E.second - 1);
 						focused_keys.insert(previous_key);
 					}
-					if (E->get().second < animation->track_get_key_count(E->get().first) - 1) {
-						IntPair next_key = IntPair(E->get().first, E->get().second + 1);
+					if (E.second < animation->track_get_key_count(E.first) - 1) {
+						IntPair next_key = IntPair(E.first, E.second + 1);
 						focused_keys.insert(next_key);
 					}
 				}
@@ -873,8 +873,8 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
 			float minimum_value = INFINITY;
 			float maximum_value = -INFINITY;
 
-			for (SelectionSet::Element *E = focused_keys.front(); E; E = E->next()) {
-				IntPair key_pair = E->get();
+			for (const IntPair &E : selection) {
+				IntPair key_pair = E;
 
 				float time = animation->track_get_key_time(key_pair.first, key_pair.second);
 				float value = animation->bezier_track_get_key_value(key_pair.first, key_pair.second);

+ 3 - 2
editor/animation_bezier_editor.h

@@ -32,6 +32,7 @@
 #define ANIMATION_BEZIER_EDITOR_H
 
 #include "animation_track_editor.h"
+#include "core/templates/rb_set.h"
 
 class ViewPanner;
 
@@ -71,8 +72,8 @@ class AnimationBezierTrackEdit : public Control {
 	};
 
 	RBMap<int, RBMap<int, Rect2>> subtrack_icons;
-	RBSet<int> locked_tracks;
-	RBSet<int> hidden_tracks;
+	HashSet<int> locked_tracks;
+	HashSet<int> hidden_tracks;
 	int solo_track = -1;
 	bool is_filtered = false;
 

+ 1 - 1
editor/animation_track_editor.cpp

@@ -5906,7 +5906,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
 			undo_redo->create_action(TTR("Anim Add RESET Keys"));
 			Ref<Animation> reset = _create_and_get_reset_animation();
 			int reset_tracks = reset->get_track_count();
-			RBSet<int> tracks_added;
+			HashSet<int> tracks_added;
 
 			for (const KeyValue<SelectedKey, KeyInfo> &E : selection) {
 				const SelectedKey &sk = E.key;

+ 1 - 1
editor/create_dialog.h

@@ -64,7 +64,7 @@ class CreateDialog : public ConfirmationDialog {
 	HashMap<String, String> custom_type_parents;
 	HashMap<String, int> custom_type_indices;
 	List<StringName> type_list;
-	RBSet<StringName> type_blacklist;
+	HashSet<StringName> type_blacklist;
 
 	void _update_search();
 	bool _should_hide_type(const String &p_type) const;

+ 1 - 1
editor/debugger/editor_debugger_inspector.cpp

@@ -146,7 +146,7 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) {
 
 	debugObj->prop_list.clear();
 	int new_props_added = 0;
-	RBSet<String> changed;
+	HashSet<String> changed;
 	for (int i = 0; i < obj.properties.size(); i++) {
 		PropertyInfo &pinfo = obj.properties[i].first;
 		Variant &var = obj.properties[i].second;

+ 1 - 1
editor/debugger/editor_debugger_inspector.h

@@ -69,7 +69,7 @@ class EditorDebuggerInspector : public EditorInspector {
 private:
 	ObjectID inspected_object_id;
 	HashMap<ObjectID, EditorDebuggerRemoteObject *> remote_objects;
-	RBSet<Ref<Resource>> remote_dependencies;
+	HashSet<Ref<Resource>> remote_dependencies;
 	EditorDebuggerRemoteObject *variables = nullptr;
 
 	void _object_selected(ObjectID p_object);

+ 1 - 1
editor/debugger/editor_debugger_node.h

@@ -112,7 +112,7 @@ private:
 	CameraOverride camera_override = OVERRIDE_NONE;
 	HashMap<Breakpoint, bool, Breakpoint> breakpoints;
 
-	RBSet<Ref<Script>> debugger_plugins;
+	HashSet<Ref<Script>> debugger_plugins;
 
 	ScriptEditorDebugger *_add_debugger();
 	EditorDebuggerRemoteObject *get_inspected_remote_object();

+ 1 - 1
editor/debugger/editor_debugger_tree.h

@@ -48,7 +48,7 @@ private:
 	ObjectID inspected_object_id;
 	int debugger_id = 0;
 	bool updating_scene_tree = false;
-	RBSet<ObjectID> unfold_cache;
+	HashSet<ObjectID> unfold_cache;
 	PopupMenu *item_menu = nullptr;
 	EditorFileDialog *file_dialog = nullptr;
 	String last_filter;

+ 1 - 1
editor/debugger/editor_performance_profiler.cpp

@@ -203,7 +203,7 @@ void EditorPerformanceProfiler::_monitor_draw() {
 }
 
 void EditorPerformanceProfiler::_build_monitor_tree() {
-	RBSet<StringName> monitor_checked;
+	HashSet<StringName> monitor_checked;
 	for (KeyValue<StringName, Monitor> &E : monitors) {
 		if (E.value.item && E.value.item->is_checked(0)) {
 			monitor_checked.insert(E.key);

+ 1 - 1
editor/debugger/editor_profiler.cpp

@@ -515,7 +515,7 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
 	}
 
 	// Different metrics may contain different number of categories.
-	RBSet<StringName> possible_signatures;
+	HashSet<StringName> possible_signatures;
 	for (int i = 0; i < frame_metrics.size(); i++) {
 		const Metric &m = frame_metrics[i];
 		if (!m.valid) {

+ 1 - 1
editor/debugger/editor_profiler.h

@@ -98,7 +98,7 @@ private:
 	Tree *variables = nullptr;
 	HSplitContainer *h_split = nullptr;
 
-	RBSet<StringName> plot_sigs;
+	HashSet<StringName> plot_sigs;
 
 	OptionButton *display_mode = nullptr;
 	OptionButton *display_time = nullptr;

+ 1 - 1
editor/doc_tools.cpp

@@ -331,7 +331,7 @@ void DocTools::generate(bool p_basic_types) {
 	bool skip_setter_getter_methods = true;
 
 	while (classes.size()) {
-		RBSet<StringName> setters_getters;
+		HashSet<StringName> setters_getters;
 
 		String name = classes.front()->get();
 		if (!ClassDB::is_class_exposed(name)) {

+ 1 - 1
editor/editor_asset_installer.cpp

@@ -62,7 +62,7 @@ void EditorAssetInstaller::_check_propagated_to_item(Object *p_obj, int column)
 
 void EditorAssetInstaller::open(const String &p_path, int p_depth) {
 	package_path = p_path;
-	RBSet<String> files_sorted;
+	HashSet<String> files_sorted;
 
 	Ref<FileAccess> io_fa;
 	zlib_filefunc_def io = zipio_create_io(&io_fa);

+ 2 - 2
editor/editor_data.cpp

@@ -549,7 +549,7 @@ void EditorData::remove_scene(int p_idx) {
 	edited_scene.remove_at(p_idx);
 }
 
-bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, RBSet<String> &checked_paths) {
+bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, HashSet<String> &checked_paths) {
 	Ref<SceneState> ss;
 
 	if (p_node == p_root) {
@@ -587,7 +587,7 @@ bool EditorData::check_and_update_scene(int p_idx) {
 		return false;
 	}
 
-	RBSet<String> checked_scenes;
+	HashSet<String> checked_scenes;
 
 	bool must_reload = _find_updated_instances(edited_scene[p_idx].root, edited_scene[p_idx].root, checked_scenes);
 

+ 1 - 1
editor/editor_data.h

@@ -139,7 +139,7 @@ private:
 	Vector<EditedScene> edited_scene;
 	int current_edited_scene;
 
-	bool _find_updated_instances(Node *p_root, Node *p_node, RBSet<String> &checked_paths);
+	bool _find_updated_instances(Node *p_root, Node *p_node, HashSet<String> &checked_paths);
 
 	HashMap<StringName, String> _script_class_icon_paths;
 	HashMap<String, StringName> _script_class_file_to_path;

+ 1 - 1
editor/editor_dir_dialog.h

@@ -44,7 +44,7 @@ class EditorDirDialog : public ConfirmationDialog {
 	AcceptDialog *mkdirerr = nullptr;
 
 	Button *makedir = nullptr;
-	RBSet<String> opened_paths;
+	HashSet<String> opened_paths;
 
 	Tree *tree = nullptr;
 	bool updating = false;

+ 11 - 11
editor/editor_export.cpp

@@ -446,7 +446,7 @@ Ref<EditorExportPreset> EditorExportPlatform::create_preset() {
 	return preset;
 }
 
-void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_dir, RBSet<String> &p_paths) {
+void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_dir, HashSet<String> &p_paths) {
 	for (int i = 0; i < p_dir->get_subdir_count(); i++) {
 		_export_find_resources(p_dir->get_subdir(i), p_paths);
 	}
@@ -459,7 +459,7 @@ void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_d
 	}
 }
 
-void EditorExportPlatform::_export_find_dependencies(const String &p_path, RBSet<String> &p_paths) {
+void EditorExportPlatform::_export_find_dependencies(const String &p_path, HashSet<String> &p_paths) {
 	if (p_paths.has(p_path)) {
 		return;
 	}
@@ -480,7 +480,7 @@ void EditorExportPlatform::_export_find_dependencies(const String &p_path, RBSet
 	}
 }
 
-void EditorExportPlatform::_edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, RBSet<String> &r_list, bool exclude) {
+void EditorExportPlatform::_edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude) {
 	da->list_dir_begin();
 	String cur_dir = da->get_current_dir().replace("\\", "/");
 	if (!cur_dir.ends_with("/")) {
@@ -528,7 +528,7 @@ void EditorExportPlatform::_edit_files_with_filter(Ref<DirAccess> &da, const Vec
 	}
 }
 
-void EditorExportPlatform::_edit_filter_list(RBSet<String> &r_list, const String &p_filter, bool exclude) {
+void EditorExportPlatform::_edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude) {
 	if (p_filter.is_empty()) {
 		return;
 	}
@@ -648,10 +648,10 @@ void EditorExportPlugin::_export_end_script() {
 	GDVIRTUAL_CALL(_export_end);
 }
 
-void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const RBSet<String> &p_features) {
+void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) {
 }
 
-void EditorExportPlugin::_export_begin(const RBSet<String> &p_features, bool p_debug, const String &p_path, int p_flags) {
+void EditorExportPlugin::_export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags) {
 }
 
 void EditorExportPlugin::skip() {
@@ -739,7 +739,7 @@ EditorExportPlatform::ExportNotifier::~ExportNotifier() {
 
 Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
 	//figure out paths of files that will be exported
-	RBSet<String> paths;
+	HashSet<String> paths;
 	Vector<String> path_remaps;
 
 	if (p_preset->get_export_filter() == EditorExportPreset::EXPORT_ALL_RESOURCES) {
@@ -872,7 +872,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 	}
 
 	FeatureContainers feature_containers = get_feature_containers(p_preset, p_debug);
-	RBSet<String> &features = feature_containers.features;
+	HashSet<String> &features = feature_containers.features;
 	Vector<String> &features_pv = feature_containers.features_pv;
 
 	//store everything in the export medium
@@ -910,7 +910,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 			List<String> remaps;
 			config->get_section_keys("remap", &remaps);
 
-			RBSet<String> remap_features;
+			HashSet<String> remap_features;
 
 			for (const String &F : remaps) {
 				String remap = F;
@@ -1934,7 +1934,7 @@ void EditorExportPlatformPC::get_platform_features(List<String> *r_features) {
 	r_features->push_back(get_os_name().to_lower()); //OS name is a feature
 }
 
-void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, RBSet<String> &p_features) {
+void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) {
 	if (p_features.has("bptc")) {
 		if (p_preset->has("texture_format/no_bptc_fallbacks")) {
 			p_features.erase("s3tc");
@@ -1952,7 +1952,7 @@ void EditorExportPlatformPC::set_chmod_flags(int p_flags) {
 
 ///////////////////////
 
-void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const RBSet<String> &p_features) {
+void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) {
 	String extension = p_path.get_extension().to_lower();
 	if (extension != "tres" && extension != "tscn") {
 		return;

+ 11 - 11
editor/editor_export.h

@@ -66,7 +66,7 @@ private:
 	String export_path;
 
 	String exporter;
-	RBSet<String> selected_files;
+	HashSet<String> selected_files;
 	bool runnable = false;
 
 	friend class EditorExport;
@@ -196,19 +196,19 @@ private:
 	};
 
 	struct FeatureContainers {
-		RBSet<String> features;
+		HashSet<String> features;
 		Vector<String> features_pv;
 	};
 
-	void _export_find_resources(EditorFileSystemDirectory *p_dir, RBSet<String> &p_paths);
-	void _export_find_dependencies(const String &p_path, RBSet<String> &p_paths);
+	void _export_find_resources(EditorFileSystemDirectory *p_dir, HashSet<String> &p_paths);
+	void _export_find_dependencies(const String &p_path, HashSet<String> &p_paths);
 
 	void gen_debug_flags(Vector<String> &r_flags, int p_flags);
 	static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
 	static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
 
-	void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, RBSet<String> &r_list, bool exclude);
-	void _edit_filter_list(RBSet<String> &r_list, const String &p_filter, bool exclude);
+	void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude);
+	void _edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude);
 
 	static Error _add_shared_object(void *p_userdata, const SharedObject &p_so);
 
@@ -279,7 +279,7 @@ public:
 	virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
 	virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
 	virtual void get_platform_features(List<String> *r_features) = 0;
-	virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, RBSet<String> &p_features) = 0;
+	virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) = 0;
 	virtual String get_debug_protocol() const { return "tcp://"; }
 
 	EditorExportPlatform();
@@ -349,8 +349,8 @@ protected:
 
 	void skip();
 
-	virtual void _export_file(const String &p_path, const String &p_type, const RBSet<String> &p_features);
-	virtual void _export_begin(const RBSet<String> &p_features, bool p_debug, const String &p_path, int p_flags);
+	virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features);
+	virtual void _export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags);
 
 	static void _bind_methods();
 
@@ -454,7 +454,7 @@ public:
 
 	void add_platform_feature(const String &p_feature);
 	virtual void get_platform_features(List<String> *r_features) override;
-	virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, RBSet<String> &p_features) override;
+	virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override;
 
 	int get_chmod_flags() const;
 	void set_chmod_flags(int p_flags);
@@ -468,7 +468,7 @@ class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin {
 	GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin);
 
 public:
-	virtual void _export_file(const String &p_path, const String &p_type, const RBSet<String> &p_features) override;
+	virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) override;
 	EditorExportTextSceneToBinaryPlugin();
 };
 

+ 2 - 2
editor/editor_feature_profile.cpp

@@ -101,7 +101,7 @@ bool EditorFeatureProfile::is_class_editor_disabled(const StringName &p_class) c
 void EditorFeatureProfile::set_disable_class_property(const StringName &p_class, const StringName &p_property, bool p_disabled) {
 	if (p_disabled) {
 		if (!disabled_properties.has(p_class)) {
-			disabled_properties[p_class] = RBSet<StringName>();
+			disabled_properties[p_class] = HashSet<StringName>();
 		}
 
 		disabled_properties[p_class].insert(p_property);
@@ -181,7 +181,7 @@ Error EditorFeatureProfile::save_to_file(const String &p_path) {
 
 	Array dis_props;
 
-	for (KeyValue<StringName, RBSet<StringName>> &E : disabled_properties) {
+	for (KeyValue<StringName, HashSet<StringName>> &E : disabled_properties) {
 		for (const StringName &F : E.value) {
 			dis_props.push_back(String(E.key) + ":" + String(F));
 		}

+ 4 - 4
editor/editor_feature_profile.h

@@ -56,11 +56,11 @@ public:
 	};
 
 private:
-	RBSet<StringName> disabled_classes;
-	RBSet<StringName> disabled_editors;
-	HashMap<StringName, RBSet<StringName>> disabled_properties;
+	HashSet<StringName> disabled_classes;
+	HashSet<StringName> disabled_editors;
+	HashMap<StringName, HashSet<StringName>> disabled_properties;
 
-	RBSet<StringName> collapsed_classes;
+	HashSet<StringName> collapsed_classes;
 
 	bool features_disabled[FEATURE_MAX];
 	static const char *feature_names[FEATURE_MAX];

+ 5 - 5
editor/editor_file_system.cpp

@@ -1636,7 +1636,7 @@ void EditorFileSystem::update_file(const String &p_file) {
 	_queue_update_script_classes();
 }
 
-RBSet<String> EditorFileSystem::get_valid_extensions() const {
+HashSet<String> EditorFileSystem::get_valid_extensions() const {
 	return valid_extensions;
 }
 
@@ -2047,7 +2047,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String
 	EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
 }
 
-void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, HashMap<String, Vector<String>> &group_files, RBSet<String> &groups_to_reimport) {
+void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, HashMap<String, Vector<String>> &group_files, HashSet<String> &groups_to_reimport) {
 	int fc = efd->files.size();
 	const EditorFileSystemDirectory::FileInfo *const *files = efd->files.ptr();
 	for (int i = 0; i < fc; i++) {
@@ -2079,7 +2079,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
 
 	Vector<ImportFile> reimport_files;
 
-	RBSet<String> groups_to_reimport;
+	HashSet<String> groups_to_reimport;
 
 	for (int i = 0; i < p_files.size(); i++) {
 		String file = p_files[i];
@@ -2290,7 +2290,7 @@ ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const
 	}
 }
 
-static void _scan_extensions_dir(EditorFileSystemDirectory *d, RBSet<String> &extensions) {
+static void _scan_extensions_dir(EditorFileSystemDirectory *d, HashSet<String> &extensions) {
 	int fc = d->get_file_count();
 	for (int i = 0; i < fc; i++) {
 		if (d->get_file_type(i) == SNAME("NativeExtension")) {
@@ -2304,7 +2304,7 @@ static void _scan_extensions_dir(EditorFileSystemDirectory *d, RBSet<String> &ex
 }
 bool EditorFileSystem::_scan_extensions() {
 	EditorFileSystemDirectory *d = get_filesystem();
-	RBSet<String> extensions;
+	HashSet<String> extensions;
 
 	_scan_extensions_dir(d, extensions);
 

+ 8 - 8
editor/editor_file_system.h

@@ -34,7 +34,7 @@
 #include "core/io/dir_access.h"
 #include "core/os/thread.h"
 #include "core/os/thread_safe.h"
-#include "core/templates/rb_set.h"
+#include "core/templates/hash_set.h"
 #include "core/templates/safe_refcount.h"
 #include "core/templates/thread_work_pool.h"
 #include "scene/main/node.h"
@@ -180,7 +180,7 @@ class EditorFileSystem : public Node {
 
 	void _scan_filesystem();
 
-	RBSet<String> late_update_files;
+	HashSet<String> late_update_files;
 
 	void _save_late_updated_files();
 
@@ -221,9 +221,9 @@ class EditorFileSystem : public Node {
 
 	void _delete_internal_files(String p_file);
 
-	RBSet<String> textfile_extensions;
-	RBSet<String> valid_extensions;
-	RBSet<String> import_extensions;
+	HashSet<String> textfile_extensions;
+	HashSet<String> valid_extensions;
+	HashSet<String> import_extensions;
 
 	void _scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAccess> &da, const ScanProgress &p_progress);
 
@@ -269,11 +269,11 @@ class EditorFileSystem : public Node {
 
 	bool using_fat32_or_exfat; // Workaround for projects in FAT32 or exFAT filesystem (pendrives, most of the time)
 
-	void _find_group_files(EditorFileSystemDirectory *efd, HashMap<String, Vector<String>> &group_files, RBSet<String> &groups_to_reimport);
+	void _find_group_files(EditorFileSystemDirectory *efd, HashMap<String, Vector<String>> &group_files, HashSet<String> &groups_to_reimport);
 
 	void _move_group_files(EditorFileSystemDirectory *efd, const String &p_group_file, const String &p_new_location);
 
-	RBSet<String> group_file_cache;
+	HashSet<String> group_file_cache;
 
 	ThreadWorkPool import_threads;
 
@@ -306,7 +306,7 @@ public:
 	void scan();
 	void scan_changes();
 	void update_file(const String &p_file);
-	RBSet<String> get_valid_extensions() const;
+	HashSet<String> get_valid_extensions() const;
 
 	EditorFileSystemDirectory *get_filesystem_path(const String &p_path);
 	String get_file_type(const String &p_file) const;

+ 6 - 6
editor/editor_folding.cpp

@@ -87,7 +87,7 @@ void EditorFolding::load_resource_folding(Ref<Resource> p_resource, const String
 	_set_unfolds(p_resource.ptr(), unfolds);
 }
 
-void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, RBSet<Ref<Resource>> &resources) {
+void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, HashSet<Ref<Resource>> &resources) {
 	if (p_root != p_node) {
 		if (!p_node->get_owner()) {
 			return; //not owned, bye
@@ -140,7 +140,7 @@ void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path
 	config.instantiate();
 
 	Array unfolds, res_unfolds;
-	RBSet<Ref<Resource>> resources;
+	HashSet<Ref<Resource>> resources;
 	Array nodes_folded;
 	_fill_folds(p_scene, p_scene, unfolds, res_unfolds, nodes_folded, resources);
 
@@ -220,13 +220,13 @@ bool EditorFolding::has_folding_data(const String &p_path) {
 	return FileAccess::exists(file);
 }
 
-void EditorFolding::_do_object_unfolds(Object *p_object, RBSet<Ref<Resource>> &resources) {
+void EditorFolding::_do_object_unfolds(Object *p_object, HashSet<Ref<Resource>> &resources) {
 	List<PropertyInfo> plist;
 	p_object->get_property_list(&plist);
 	String group_base;
 	String group;
 
-	RBSet<String> unfold_group;
+	HashSet<String> unfold_group;
 
 	for (const PropertyInfo &E : plist) {
 		if (E.usage & PROPERTY_USAGE_CATEGORY) {
@@ -275,7 +275,7 @@ void EditorFolding::_do_object_unfolds(Object *p_object, RBSet<Ref<Resource>> &r
 	}
 }
 
-void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, RBSet<Ref<Resource>> &resources) {
+void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, HashSet<Ref<Resource>> &resources) {
 	if (p_root != p_node) {
 		if (!p_node->get_owner()) {
 			return; //not owned, bye
@@ -293,7 +293,7 @@ void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, RBSet<Ref<Resou
 }
 
 void EditorFolding::unfold_scene(Node *p_scene) {
-	RBSet<Ref<Resource>> resources;
+	HashSet<Ref<Resource>> resources;
 	_do_node_unfolds(p_scene, p_scene, resources);
 }
 

+ 3 - 3
editor/editor_folding.h

@@ -37,10 +37,10 @@ class EditorFolding {
 	Vector<String> _get_unfolds(const Object *p_object);
 	void _set_unfolds(Object *p_object, const Vector<String> &p_unfolds);
 
-	void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, RBSet<Ref<Resource>> &resources);
+	void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Array &nodes_folded, HashSet<Ref<Resource>> &resources);
 
-	void _do_object_unfolds(Object *p_object, RBSet<Ref<Resource>> &resources);
-	void _do_node_unfolds(Node *p_root, Node *p_node, RBSet<Ref<Resource>> &resources);
+	void _do_object_unfolds(Object *p_object, HashSet<Ref<Resource>> &resources);
+	void _do_node_unfolds(Node *p_root, Node *p_node, HashSet<Ref<Resource>> &resources);
 
 public:
 	void save_resource_folding(const Ref<Resource> &p_resource, const String &p_path);

+ 1 - 1
editor/editor_help.cpp

@@ -648,7 +648,7 @@ void EditorHelp::_update_doc() {
 	}
 
 	// Properties overview
-	RBSet<String> skip_methods;
+	HashSet<String> skip_methods;
 	bool property_descr = false;
 
 	bool has_properties = cd.properties.size() != 0;

+ 4 - 4
editor/editor_inspector.cpp

@@ -839,7 +839,7 @@ void EditorProperty::_update_pin_flags() {
 		}
 		pin_hidden = false;
 		{
-			RBSet<StringName> storable_properties;
+			HashSet<StringName> storable_properties;
 			node->get_storable_properties(storable_properties);
 			if (storable_properties.has(node->get_property_store_alias(property))) {
 				can_pin = true;
@@ -3543,7 +3543,7 @@ void EditorInspector::_notification(int p_what) {
 
 			} else {
 				while (pending.size()) {
-					StringName prop = pending.front()->get();
+					StringName prop = *pending.begin();
 					if (editor_property_map.has(prop)) {
 						for (EditorProperty *E : editor_property_map[prop]) {
 							E->update_property();
@@ -3551,7 +3551,7 @@ void EditorInspector::_notification(int p_what) {
 							E->update_cache();
 						}
 					}
-					pending.erase(pending.front());
+					pending.remove(pending.begin());
 				}
 			}
 
@@ -3638,7 +3638,7 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li
 		break;
 	}
 
-	RBSet<StringName> added;
+	HashSet<StringName> added;
 	for (const Ref<Script> &s : classes) {
 		String path = s->get_path();
 		String name = EditorNode::get_editor_data().script_class_get_name(path);

+ 2 - 2
editor/editor_inspector.h

@@ -437,7 +437,7 @@ class EditorInspector : public ScrollContainer {
 	//map use to cache the instantiated editors
 	HashMap<StringName, List<EditorProperty *>> editor_property_map;
 	List<EditorInspectorSection *> sections;
-	RBSet<StringName> pending;
+	HashSet<StringName> pending;
 
 	void _clear();
 	Object *object = nullptr;
@@ -470,7 +470,7 @@ class EditorInspector : public ScrollContainer {
 
 	HashMap<StringName, HashMap<StringName, String>> descr_cache;
 	HashMap<StringName, String> class_descr_cache;
-	RBSet<StringName> restart_request_props;
+	HashSet<StringName> restart_request_props;
 
 	HashMap<ObjectID, int> scroll_cache;
 

+ 4 - 4
editor/editor_node.cpp

@@ -800,7 +800,7 @@ void EditorNode::_notification(int p_what) {
 				main_editor_buttons.write[i]->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts")));
 			}
 
-			RBSet<String> updated_textfile_extensions;
+			HashSet<String> updated_textfile_extensions;
 			bool extensions_match = true;
 			const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false);
 			for (const String &E : textfile_ext) {
@@ -1622,7 +1622,7 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod
 	return false;
 }
 
-static bool _find_edited_resources(const Ref<Resource> &p_resource, RBSet<Ref<Resource>> &edited_resources) {
+static bool _find_edited_resources(const Ref<Resource> &p_resource, HashSet<Ref<Resource>> &edited_resources) {
 	if (p_resource->is_edited()) {
 		edited_resources.insert(p_resource);
 		return true;
@@ -1659,7 +1659,7 @@ int EditorNode::_save_external_resources() {
 	}
 	flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
 
-	RBSet<Ref<Resource>> edited_subresources;
+	HashSet<Ref<Resource>> edited_subresources;
 	int saved = 0;
 	List<Ref<Resource>> cached;
 	ResourceCache::get_cached_resources(&cached);
@@ -3678,7 +3678,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
 
 	dependency_errors.erase(lpath); // At least not self path.
 
-	for (KeyValue<String, RBSet<String>> &E : dependency_errors) {
+	for (KeyValue<String, HashSet<String>> &E : dependency_errors) {
 		String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E.key) + "\n";
 		for (const String &F : E.value) {
 			txt += "\t" + F + "\n";

+ 5 - 5
editor/editor_node.h

@@ -394,7 +394,7 @@ private:
 	BackgroundProgress *progress_hb = nullptr;
 
 	DependencyErrorDialog *dependency_error = nullptr;
-	HashMap<String, RBSet<String>> dependency_errors;
+	HashMap<String, HashSet<String>> dependency_errors;
 	DependencyEditor *dependency_fixer = nullptr;
 	OrphanResourcesDialog *orphan_resources = nullptr;
 	ConfirmationDialog *open_imported = nullptr;
@@ -470,9 +470,9 @@ private:
 
 	String import_reload_fn;
 
-	RBSet<String> textfile_extensions;
-	RBSet<FileDialog *> file_dialogs;
-	RBSet<EditorFileDialog *> editor_file_dialogs;
+	HashSet<String> textfile_extensions;
+	HashSet<FileDialog *> file_dialogs;
+	HashSet<EditorFileDialog *> editor_file_dialogs;
 
 	Vector<Ref<EditorResourceConversionPlugin>> resource_conversion_plugins;
 	PrintHandlerList print_handler;
@@ -489,7 +489,7 @@ private:
 	static void _dependency_error_report(void *ud, const String &p_path, const String &p_dep, const String &p_type) {
 		EditorNode *en = static_cast<EditorNode *>(ud);
 		if (!en->dependency_errors.has(p_path)) {
-			en->dependency_errors[p_path] = RBSet<String>();
+			en->dependency_errors[p_path] = HashSet<String>();
 		}
 		en->dependency_errors[p_path].insert(p_dep + "::" + p_type);
 	}

+ 13 - 12
editor/editor_resource_picker.cpp

@@ -240,7 +240,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
 				ResourceLoader::get_recognized_extensions_for_type(base, &extensions);
 			}
 
-			RBSet<String> valid_extensions;
+			HashSet<String> valid_extensions;
 			for (const String &E : extensions) {
 				valid_extensions.insert(E);
 			}
@@ -409,7 +409,7 @@ void EditorResourcePicker::set_create_options(Object *p_menu_node) {
 	if (!base_type.is_empty()) {
 		int idx = 0;
 
-		RBSet<String> allowed_types;
+		HashSet<String> allowed_types;
 		_get_allowed_types(false, &allowed_types);
 
 		Vector<EditorData::CustomType> custom_resources;
@@ -491,7 +491,7 @@ void EditorResourcePicker::_button_input(const Ref<InputEvent> &p_event) {
 	}
 }
 
-void EditorResourcePicker::_get_allowed_types(bool p_with_convert, RBSet<String> *p_vector) const {
+void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<String> *p_vector) const {
 	Vector<String> allowed_types = base_type.split(",");
 	int size = allowed_types.size();
 
@@ -568,7 +568,7 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const {
 		res = drag_data["resource"];
 	}
 
-	RBSet<String> allowed_types;
+	HashSet<String> allowed_types;
 	_get_allowed_types(true, &allowed_types);
 
 	if (res.is_valid() && _is_type_valid(res->get_class(), allowed_types)) {
@@ -598,7 +598,7 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const {
 	return false;
 }
 
-bool EditorResourcePicker::_is_type_valid(const String p_type_name, RBSet<String> p_allowed_types) const {
+bool EditorResourcePicker::_is_type_valid(const String p_type_name, HashSet<String> p_allowed_types) const {
 	for (const String &E : p_allowed_types) {
 		String at = E.strip_edges();
 		if (p_type_name == at || ClassDB::is_parent_class(p_type_name, at) || EditorNode::get_editor_data().script_class_is_parent(p_type_name, at)) {
@@ -646,7 +646,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
 	}
 
 	if (dropped_resource.is_valid()) {
-		RBSet<String> allowed_types;
+		HashSet<String> allowed_types;
 		_get_allowed_types(false, &allowed_types);
 
 		// If the accepted dropped resource is from the extended list, it requires conversion.
@@ -768,7 +768,7 @@ void EditorResourcePicker::set_base_type(const String &p_base_type) {
 	// There is a possibility that the new base type is conflicting with the existing value.
 	// Keep the value, but warn the user that there is a potential mistake.
 	if (!base_type.is_empty() && edited_resource.is_valid()) {
-		RBSet<String> allowed_types;
+		HashSet<String> allowed_types;
 		_get_allowed_types(true, &allowed_types);
 
 		StringName custom_class;
@@ -784,7 +784,7 @@ void EditorResourcePicker::set_base_type(const String &p_base_type) {
 		}
 	} else {
 		// Call the method to build the cache immediately.
-		RBSet<String> allowed_types;
+		HashSet<String> allowed_types;
 		_get_allowed_types(false, &allowed_types);
 	}
 }
@@ -794,7 +794,7 @@ String EditorResourcePicker::get_base_type() const {
 }
 
 Vector<String> EditorResourcePicker::get_allowed_types() const {
-	RBSet<String> allowed_types;
+	HashSet<String> allowed_types;
 	_get_allowed_types(false, &allowed_types);
 
 	Vector<String> types;
@@ -802,8 +802,9 @@ Vector<String> EditorResourcePicker::get_allowed_types() const {
 
 	int i = 0;
 	String *w = types.ptrw();
-	for (RBSet<String>::Element *E = allowed_types.front(); E; E = E->next(), i++) {
-		w[i] = E->get();
+	for (const String &E : allowed_types) {
+		w[i] = E;
+		i++;
 	}
 
 	return types;
@@ -817,7 +818,7 @@ void EditorResourcePicker::set_edited_resource(Ref<Resource> p_resource) {
 	}
 
 	if (!base_type.is_empty()) {
-		RBSet<String> allowed_types;
+		HashSet<String> allowed_types;
 		_get_allowed_types(true, &allowed_types);
 
 		StringName custom_class;

+ 2 - 2
editor/editor_resource_picker.h

@@ -89,9 +89,9 @@ class EditorResourcePicker : public HBoxContainer {
 	void _button_draw();
 	void _button_input(const Ref<InputEvent> &p_event);
 
-	void _get_allowed_types(bool p_with_convert, RBSet<String> *p_vector) const;
+	void _get_allowed_types(bool p_with_convert, HashSet<String> *p_vector) const;
 	bool _is_drop_valid(const Dictionary &p_drag_data) const;
-	bool _is_type_valid(const String p_type_name, RBSet<String> p_allowed_types) const;
+	bool _is_type_valid(const String p_type_name, HashSet<String> p_allowed_types) const;
 
 	Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
 	bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;

+ 2 - 1
editor/editor_settings.h

@@ -34,6 +34,7 @@
 #include "core/io/config_file.h"
 #include "core/io/resource.h"
 #include "core/os/thread_safe.h"
+#include "core/templates/rb_set.h"
 
 class EditorPlugin;
 class InputEvent;
@@ -77,7 +78,7 @@ private:
 
 	static Ref<EditorSettings> singleton;
 
-	RBSet<String> changed_settings;
+	HashSet<String> changed_settings;
 
 	HashMap<String, PropertyInfo> hints;
 	HashMap<String, VariantContainer> props;

+ 2 - 2
editor/editor_themes.cpp

@@ -148,7 +148,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
 
 	// The names of the icons to never convert, even if one of their colors
 	// are contained in the dictionary above.
-	RBSet<StringName> exceptions;
+	HashSet<StringName> exceptions;
 
 	// Some of the colors below are listed for completeness sake.
 	// This can be a basis for proper palette validation later.
@@ -290,7 +290,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
 
 	// Use the accent color for some icons (checkbox, radio, toggle, etc.).
 	Dictionary accent_color_icon_color_dictionary;
-	RBSet<StringName> accent_color_icons;
+	HashSet<StringName> accent_color_icons;
 
 	const Color accent_color = p_theme->get_color(SNAME("accent_color"), SNAME("Editor"));
 	accent_color_icon_color_dictionary[Color::html("699ce8")] = accent_color;

+ 2 - 2
editor/editor_translation_parser.cpp

@@ -33,7 +33,7 @@
 #include "core/error/error_macros.h"
 #include "core/io/file_access.h"
 #include "core/object/script_language.h"
-#include "core/templates/rb_set.h"
+#include "core/templates/hash_set.h"
 
 EditorTranslationParser *EditorTranslationParser::singleton = nullptr;
 
@@ -84,7 +84,7 @@ void EditorTranslationParserPlugin::_bind_methods() {
 /////////////////////////
 
 void EditorTranslationParser::get_recognized_extensions(List<String> *r_extensions) const {
-	RBSet<String> extensions;
+	HashSet<String> extensions;
 	List<String> temp;
 	for (int i = 0; i < standard_parsers.size(); i++) {
 		standard_parsers[i]->get_recognized_extensions(&temp);

+ 2 - 1
editor/export_template_manager.cpp

@@ -35,6 +35,7 @@
 #include "core/io/json.h"
 #include "core/io/zip_io.h"
 #include "core/os/keyboard.h"
+#include "core/templates/rb_set.h"
 #include "core/version.h"
 #include "editor/editor_node.h"
 #include "editor/editor_paths.h"
@@ -694,7 +695,7 @@ Error ExportTemplateManager::install_android_template_from_file(const String &p_
 
 	ProgressDialog::get_singleton()->add_task("uncompress_src", TTR("Uncompressing Android Build Sources"), total_files);
 
-	RBSet<String> dirs_tested;
+	HashSet<String> dirs_tested;
 	int idx = 0;
 	while (ret == UNZ_OK) {
 		// Get file path.

+ 1 - 1
editor/fileserver/editor_file_server.cpp

@@ -282,7 +282,7 @@ void EditorFileServer::_thread_start(void *s) {
 
 		self->wait_mutex.lock();
 		while (self->to_wait.size()) {
-			Thread *w = self->to_wait.front()->get();
+			Thread *w = *self->to_wait.begin();
 			self->to_wait.erase(w);
 			self->wait_mutex.unlock();
 			w->wait_to_finish();

+ 1 - 1
editor/fileserver/editor_file_server.h

@@ -55,7 +55,7 @@ class EditorFileServer : public Object {
 	};
 
 	Ref<TCPServer> server;
-	RBSet<Thread *> to_wait;
+	HashSet<Thread *> to_wait;
 
 	static void _close_client(ClientData *cd);
 	static void _subthread_start(void *s);

+ 1 - 1
editor/filesystem_dock.cpp

@@ -726,7 +726,7 @@ void FileSystemDock::_sort_file_info_list(List<FileSystemDock::FileInfo> &r_file
 
 void FileSystemDock::_update_file_list(bool p_keep_selection) {
 	// Register the previously selected items.
-	RBSet<String> cselection;
+	HashSet<String> cselection;
 	if (p_keep_selection) {
 		for (int i = 0; i < files->get_item_count(); i++) {
 			if (files->is_selected(i)) {

+ 1 - 1
editor/filesystem_dock.h

@@ -108,7 +108,7 @@ private:
 	VSplitContainer *split_box = nullptr;
 	VBoxContainer *file_list_vb = nullptr;
 
-	RBSet<String> favorites;
+	HashSet<String> favorites;
 
 	Button *button_toggle_display_mode = nullptr;
 	Button *button_reload = nullptr;

+ 3 - 3
editor/find_in_files.cpp

@@ -99,7 +99,7 @@ void FindInFiles::set_folder(String folder) {
 	_root_dir = folder;
 }
 
-void FindInFiles::set_filter(const RBSet<String> &exts) {
+void FindInFiles::set_filter(const HashSet<String> &exts) {
 	_extension_filter = exts;
 }
 
@@ -443,9 +443,9 @@ String FindInFilesDialog::get_folder() const {
 	return text.strip_edges();
 }
 
-RBSet<String> FindInFilesDialog::get_filter() const {
+HashSet<String> FindInFilesDialog::get_filter() const {
 	// Could check the _filters_preferences but it might not have been generated yet.
-	RBSet<String> filters;
+	HashSet<String> filters;
 	for (int i = 0; i < _filters_container->get_child_count(); ++i) {
 		CheckBox *cb = static_cast<CheckBox *>(_filters_container->get_child(i));
 		if (cb->is_pressed()) {

+ 3 - 3
editor/find_in_files.h

@@ -46,7 +46,7 @@ public:
 	void set_whole_words(bool p_whole_word);
 	void set_match_case(bool p_match_case);
 	void set_folder(String folder);
-	void set_filter(const RBSet<String> &exts);
+	void set_filter(const HashSet<String> &exts);
 
 	String get_search_text() const { return _pattern; }
 
@@ -72,7 +72,7 @@ private:
 
 	// Config
 	String _pattern;
-	RBSet<String> _extension_filter;
+	HashSet<String> _extension_filter;
 	String _root_dir;
 	bool _whole_words = true;
 	bool _match_case = true;
@@ -115,7 +115,7 @@ public:
 	bool is_match_case() const;
 	bool is_whole_words() const;
 	String get_folder() const;
-	RBSet<String> get_filter() const;
+	HashSet<String> get_filter() const;
 
 protected:
 	void _notification(int p_what);

+ 5 - 5
editor/import/collada.cpp

@@ -2029,7 +2029,7 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
 		NodeGeometry *gnode = static_cast<NodeGeometry *>(p_node);
 		if (gnode->controller) {
 			// recount skeletons used
-			RBSet<NodeSkeleton *> skeletons;
+			HashSet<NodeSkeleton *> skeletons;
 
 			for (int i = 0; i < gnode->skeletons.size(); i++) {
 				String nodeid = gnode->skeletons[i];
@@ -2049,11 +2049,11 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
 
 			if (skeletons.size() > 1) {
 				//do the merger!!
-				RBSet<NodeSkeleton *>::Element *E = skeletons.front();
-				NodeSkeleton *base = E->get();
+				HashSet<NodeSkeleton *>::Iterator E = skeletons.begin();
+				NodeSkeleton *base = *E;
 
-				for (E = E->next(); E; E = E->next()) {
-					NodeSkeleton *merged = E->get();
+				for (++E; E; ++E) {
+					NodeSkeleton *merged = *E;
 					_remove_node(p_vscene, merged);
 					for (int i = 0; i < merged->children.size(); i++) {
 						_joint_set_owner(merged->children[i], base);

+ 1 - 1
editor/import/collada.h

@@ -493,7 +493,7 @@ public:
 
 		HashMap<String, VisualScene> visual_scene_map;
 		HashMap<String, Node *> scene_map;
-		RBSet<String> idref_joints;
+		HashSet<String> idref_joints;
 		HashMap<String, String> sid_to_node_map;
 		//RBMap<String,NodeJoint*> bone_map;
 

+ 1 - 0
editor/import/dynamic_font_import_settings.h

@@ -33,6 +33,7 @@
 
 #include "editor/import/resource_importer_dynamic_font.h"
 
+#include "core/templates/rb_set.h"
 #include "scene/gui/dialogs.h"
 #include "scene/gui/item_list.h"
 #include "scene/gui/option_button.h"

+ 6 - 6
editor/import/editor_import_collada.cpp

@@ -76,12 +76,12 @@ struct ColladaImport {
 
 	HashMap<Skeleton3D *, HashMap<String, int>> skeleton_bone_map;
 
-	RBSet<String> valid_animated_nodes;
+	HashSet<String> valid_animated_nodes;
 	Vector<int> valid_animated_properties;
 	HashMap<String, bool> bones_with_animation;
 
-	RBSet<String> mesh_unique_names;
-	RBSet<String> material_unique_names;
+	HashSet<String> mesh_unique_names;
+	HashSet<String> material_unique_names;
 
 	Error _populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p_node, int &r_bone, int p_parent);
 	Error _create_scene_skeletons(Collada::Node *p_node);
@@ -94,7 +94,7 @@ struct ColladaImport {
 	void create_animation(int p_clip, bool p_import_value_tracks);
 	void create_animations(bool p_import_value_tracks);
 
-	RBSet<String> tracks_in_clips;
+	HashSet<String> tracks_in_clips;
 	Vector<String> missing_textures;
 
 	void _pre_process_lights(Collada::Node *p_node);
@@ -875,7 +875,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
 		Vector<Collada::Vertex> vertex_array; //there we go, vertex array
 
 		vertex_array.resize(vertex_set.size());
-		for (Collada::Vertex &F : vertex_set) {
+		for (const Collada::Vertex &F : vertex_set) {
 			vertex_array.write[F.idx] = F;
 		}
 
@@ -1452,7 +1452,7 @@ void ColladaImport::create_animation(int p_clip, bool p_import_value_tracks) {
 		//main anim
 	}
 
-	RBSet<int> track_filter;
+	HashSet<int> track_filter;
 
 	if (p_clip == -1) {
 		for (int i = 0; i < collada.state.animation_clips.size(); i++) {

+ 2 - 2
editor/import/resource_importer_scene.cpp

@@ -704,7 +704,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, HashMap<R
 	return p_node;
 }
 
-Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, RBSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) {
+Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) {
 	// children first
 	for (int i = 0; i < p_node->get_child_count(); i++) {
 		Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps);
@@ -1994,7 +1994,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
 		animation_data = subresources["animations"];
 	}
 
-	RBSet<Ref<ImporterMesh>> scanned_meshes;
+	HashSet<Ref<ImporterMesh>> scanned_meshes;
 	HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
 	Pair<PackedVector3Array, PackedInt32Array> occluder_arrays;
 	List<Pair<NodePath, Node *>> node_renames;

+ 1 - 1
editor/import/resource_importer_scene.h

@@ -272,7 +272,7 @@ public:
 	virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; }
 
 	Node *_pre_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames);
-	Node *_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, RBSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
+	Node *_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
 
 	Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks);
 	void _create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all);

+ 2 - 2
editor/import/scene_import_settings.h

@@ -139,8 +139,8 @@ class SceneImportSettings : public ConfirmationDialog {
 	void _fill_animation(Tree *p_tree, const Ref<Animation> &p_anim, const String &p_name, TreeItem *p_parent);
 	void _fill_scene(Node *p_node, TreeItem *p_parent_item);
 
-	RBSet<Ref<Mesh>> mesh_set;
-	RBSet<Ref<Material>> material_set;
+	HashSet<Ref<Mesh>> mesh_set;
+	HashSet<Ref<Material>> material_set;
 
 	String selected_type;
 	String selected_id;

+ 2 - 2
editor/import_dock.cpp

@@ -43,7 +43,7 @@ public:
 	List<PropertyInfo> properties;
 	Ref<ResourceImporter> importer;
 	Vector<String> paths;
-	RBSet<StringName> checked;
+	HashSet<StringName> checked;
 	bool checking;
 	String base_options_path;
 
@@ -194,7 +194,7 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
 
 	// Use the value that is repeated the most.
 	HashMap<String, Dictionary> value_frequency;
-	RBSet<String> extensions;
+	HashSet<String> extensions;
 
 	for (int i = 0; i < p_paths.size(); i++) {
 		Ref<ConfigFile> config;

+ 1 - 1
editor/inspector_dock.cpp

@@ -307,7 +307,7 @@ void InspectorDock::_prepare_history() {
 	history_menu->get_popup()->clear();
 
 	Ref<Texture2D> base_icon = get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
-	RBSet<ObjectID> already;
+	HashSet<ObjectID> already;
 	for (int i = editor_history->get_history_len() - 1; i >= history_to; i--) {
 		ObjectID id = editor_history->get_history_obj(i);
 		Object *obj = ObjectDB::get_instance(id);

+ 7 - 6
editor/plugins/animation_blend_tree_editor_plugin.cpp

@@ -563,7 +563,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
 
 	updating = true;
 
-	RBSet<String> paths;
+	HashSet<String> paths;
 	HashMap<String, RBSet<String>> types;
 	{
 		List<StringName> animations;
@@ -698,11 +698,12 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
 				//just a node, not a property track
 				String types_text = "[";
 				if (types.has(path)) {
-					RBSet<String>::Element *F = types[path].front();
-					types_text += F->get();
-					while (F->next()) {
-						F = F->next();
-						types_text += " / " + F->get();
+					RBSet<String>::Iterator F = types[path].begin();
+					types_text += *F;
+					while (F) {
+						types_text += " / " + *F;
+						;
+						++F;
 					}
 				}
 				types_text += "]";

+ 4 - 4
editor/plugins/animation_state_machine_editor.cpp

@@ -494,7 +494,7 @@ Control::CursorShape AnimationNodeStateMachineEditor::get_cursor_shape(const Poi
 
 void AnimationNodeStateMachineEditor::_group_selected_nodes() {
 	if (!selected_nodes.is_empty()) {
-		if (selected_nodes.size() == 1 && (selected_nodes.front()->get() == state_machine->start_node || selected_nodes.front()->get() == state_machine->end_node))
+		if (selected_nodes.size() == 1 && (*selected_nodes.begin() == state_machine->start_node || *selected_nodes.begin() == state_machine->end_node))
 			return;
 
 		Ref<AnimationNodeStateMachine> group_sm = memnew(AnimationNodeStateMachine);
@@ -609,7 +609,7 @@ void AnimationNodeStateMachineEditor::_group_selected_nodes() {
 
 void AnimationNodeStateMachineEditor::_ungroup_selected_nodes() {
 	bool find = false;
-	RBSet<StringName> new_selected_nodes;
+	HashSet<StringName> new_selected_nodes;
 
 	for (const StringName &E : selected_nodes) {
 		Ref<AnimationNodeStateMachine> group_sm = state_machine->get_node(E);
@@ -1846,7 +1846,7 @@ void AnimationNodeStateMachineEditor::_update_mode() {
 	if (tool_select->is_pressed()) {
 		tool_erase_hb->show();
 		bool nothing_selected = selected_nodes.is_empty() && selected_transition_from == StringName() && selected_transition_to == StringName();
-		bool start_end_selected = selected_nodes.size() == 1 && (selected_nodes.front()->get() == state_machine->start_node || selected_nodes.front()->get() == state_machine->end_node);
+		bool start_end_selected = selected_nodes.size() == 1 && (*selected_nodes.begin() == state_machine->start_node || *selected_nodes.begin() == state_machine->end_node);
 		tool_erase->set_disabled(nothing_selected || start_end_selected);
 
 		if (selected_nodes.is_empty() || start_end_selected) {
@@ -1854,7 +1854,7 @@ void AnimationNodeStateMachineEditor::_update_mode() {
 			tool_group->set_visible(true);
 			tool_ungroup->set_visible(false);
 		} else {
-			Ref<AnimationNodeStateMachine> ansm = state_machine->get_node(selected_nodes.front()->get());
+			Ref<AnimationNodeStateMachine> ansm = state_machine->get_node(*selected_nodes.begin());
 
 			if (selected_nodes.size() == 1 && ansm.is_valid()) {
 				tool_group->set_disabled(true);

+ 2 - 2
editor/plugins/animation_state_machine_editor.h

@@ -64,7 +64,7 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
 	PanelContainer *panel = nullptr;
 
 	StringName selected_node;
-	RBSet<StringName> selected_nodes;
+	HashSet<StringName> selected_nodes;
 
 	HScrollBar *h_scroll = nullptr;
 	VScrollBar *v_scroll = nullptr;
@@ -105,7 +105,7 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
 	Point2 box_selecting_from;
 	Point2 box_selecting_to;
 	Rect2 box_selecting_rect;
-	RBSet<StringName> previous_selected;
+	HashSet<StringName> previous_selected;
 
 	bool dragging_selected_attempt = false;
 	bool dragging_selected = false;

+ 2 - 2
editor/plugins/editor_preview_plugins.cpp

@@ -481,8 +481,8 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from,
 	List<String> kwors;
 	scr->get_language()->get_reserved_words(&kwors);
 
-	RBSet<String> control_flow_keywords;
-	RBSet<String> keywords;
+	HashSet<String> control_flow_keywords;
+	HashSet<String> keywords;
 
 	for (const String &E : kwors) {
 		if (scr->get_language()->is_control_flow_keyword(E)) {

+ 2 - 2
editor/plugins/gdextension_export_plugin.h

@@ -35,10 +35,10 @@
 
 class GDExtensionExportPlugin : public EditorExportPlugin {
 protected:
-	virtual void _export_file(const String &p_path, const String &p_type, const RBSet<String> &p_features);
+	virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features);
 };
 
-void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p_type, const RBSet<String> &p_features) {
+void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) {
 	if (p_type != "NativeExtension") {
 		return;
 	}

+ 8 - 7
editor/plugins/mesh_instance_3d_editor_plugin.cpp

@@ -349,12 +349,13 @@ struct MeshInstance3DEditorEdgeSort {
 	Vector2 a;
 	Vector2 b;
 
-	bool operator<(const MeshInstance3DEditorEdgeSort &p_b) const {
-		if (a == p_b.a) {
-			return b < p_b.b;
-		} else {
-			return a < p_b.a;
-		}
+	static uint32_t hash(const MeshInstance3DEditorEdgeSort &p_edge) {
+		uint32_t h = hash_djb2_one_32(HashMapHasherDefault::hash(p_edge.a));
+		return hash_djb2_one_32(HashMapHasherDefault::hash(p_edge.b), h);
+	}
+
+	bool operator==(const MeshInstance3DEditorEdgeSort &p_b) const {
+		return a == p_b.a && b == p_b.b;
 	}
 
 	MeshInstance3DEditorEdgeSort() {}
@@ -373,7 +374,7 @@ void MeshInstance3DEditor::_create_uv_lines(int p_layer) {
 	Ref<Mesh> mesh = node->get_mesh();
 	ERR_FAIL_COND(!mesh.is_valid());
 
-	RBSet<MeshInstance3DEditorEdgeSort> edges;
+	HashSet<MeshInstance3DEditorEdgeSort, MeshInstance3DEditorEdgeSort> edges;
 	uv_lines.clear();
 	for (int i = 0; i < mesh->get_surface_count(); i++) {
 		if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {

+ 1 - 1
editor/plugins/node_3d_editor_gizmos.cpp

@@ -3799,7 +3799,7 @@ void LightmapGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 	p_gizmo->clear();
 
 	Vector<Vector3> lines;
-	RBSet<Vector2i> lines_found;
+	HashSet<Vector2i> lines_found;
 
 	Vector<Vector3> points = data->get_capture_points();
 	if (points.size() == 0) {

+ 22 - 21
editor/plugins/node_3d_editor_plugin.cpp

@@ -518,7 +518,7 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) {
 	}
 
 	Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario());
-	RBSet<Ref<EditorNode3DGizmo>> found_gizmos;
+	HashSet<Ref<EditorNode3DGizmo>> found_gizmos;
 
 	Node *edited_scene = get_tree()->get_edited_scene_root();
 	ObjectID closest;
@@ -581,7 +581,7 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayRe
 	Vector3 pos = _get_ray_pos(p_pos);
 
 	Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario());
-	RBSet<Node3D *> found_nodes;
+	HashSet<Node3D *> found_nodes;
 
 	for (int i = 0; i < instances.size(); i++) {
 		Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
@@ -764,7 +764,7 @@ void Node3DEditorViewport::_select_region() {
 	}
 
 	Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world_3d()->get_scenario());
-	RBSet<Node3D *> found_nodes;
+	HashSet<Node3D *> found_nodes;
 	Vector<Node *> selected;
 
 	Node *edited_scene = get_tree()->get_edited_scene_root();
@@ -6685,8 +6685,8 @@ void Node3DEditor::_refresh_menu_icons() {
 }
 
 template <typename T>
-RBSet<T *> _get_child_nodes(Node *parent_node) {
-	RBSet<T *> nodes = RBSet<T *>();
+HashSet<T *> _get_child_nodes(Node *parent_node) {
+	HashSet<T *> nodes = HashSet<T *>();
 	T *node = Node::cast_to<T>(parent_node);
 	if (node) {
 		nodes.insert(node);
@@ -6694,22 +6694,22 @@ RBSet<T *> _get_child_nodes(Node *parent_node) {
 
 	for (int i = 0; i < parent_node->get_child_count(); i++) {
 		Node *child_node = parent_node->get_child(i);
-		RBSet<T *> child_nodes = _get_child_nodes<T>(child_node);
-		for (typename RBSet<T *>::Element *I = child_nodes.front(); I; I = I->next()) {
-			nodes.insert(I->get());
+		HashSet<T *> child_nodes = _get_child_nodes<T>(child_node);
+		for (T *I : child_nodes) {
+			nodes.insert(I);
 		}
 	}
 
 	return nodes;
 }
 
-RBSet<RID> _get_physics_bodies_rid(Node *node) {
-	RBSet<RID> rids = RBSet<RID>();
+HashSet<RID> _get_physics_bodies_rid(Node *node) {
+	HashSet<RID> rids = HashSet<RID>();
 	PhysicsBody3D *pb = Node::cast_to<PhysicsBody3D>(node);
 	if (pb) {
 		rids.insert(pb->get_rid());
 	}
-	RBSet<PhysicsBody3D *> child_nodes = _get_child_nodes<PhysicsBody3D>(node);
+	HashSet<PhysicsBody3D *> child_nodes = _get_child_nodes<PhysicsBody3D>(node);
 	for (const PhysicsBody3D *I : child_nodes) {
 		rids.insert(I->get_rid());
 	}
@@ -6728,20 +6728,21 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
 			Vector3 position_offset = Vector3();
 
 			// Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin
-			RBSet<VisualInstance3D *> vi = _get_child_nodes<VisualInstance3D>(sp);
-			RBSet<CollisionShape3D *> cs = _get_child_nodes<CollisionShape3D>(sp);
+			HashSet<VisualInstance3D *> vi = _get_child_nodes<VisualInstance3D>(sp);
+			HashSet<CollisionShape3D *> cs = _get_child_nodes<CollisionShape3D>(sp);
 			bool found_valid_shape = false;
 
 			if (cs.size()) {
 				AABB aabb;
-				RBSet<CollisionShape3D *>::Element *I = cs.front();
-				if (I->get()->get_shape().is_valid()) {
-					CollisionShape3D *collision_shape = cs.front()->get();
+				HashSet<CollisionShape3D *>::Iterator I = cs.begin();
+				if ((*I)->get_shape().is_valid()) {
+					CollisionShape3D *collision_shape = *cs.begin();
 					aabb = collision_shape->get_global_transform().xform(collision_shape->get_shape()->get_debug_mesh()->get_aabb());
 					found_valid_shape = true;
 				}
-				for (I = I->next(); I; I = I->next()) {
-					CollisionShape3D *col_shape = I->get();
+
+				for (++I; I; ++I) {
+					CollisionShape3D *col_shape = *I;
 					if (col_shape->get_shape().is_valid()) {
 						aabb.merge_with(col_shape->get_global_transform().xform(col_shape->get_shape()->get_debug_mesh()->get_aabb()));
 						found_valid_shape = true;
@@ -6754,7 +6755,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
 				}
 			}
 			if (!found_valid_shape && vi.size()) {
-				AABB aabb = vi.front()->get()->get_transformed_aabb();
+				AABB aabb = (*vi.begin())->get_transformed_aabb();
 				for (const VisualInstance3D *I : vi) {
 					aabb.merge_with(I->get_transformed_aabb());
 				}
@@ -6798,7 +6799,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
 			Dictionary d = snap_data[node];
 			Vector3 from = d["from"];
 			Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
-			RBSet<RID> excluded = _get_physics_bodies_rid(sp);
+			HashSet<RID> excluded = _get_physics_bodies_rid(sp);
 
 			PhysicsDirectSpaceState3D::RayParameters ray_params;
 			ray_params.from = from;
@@ -6820,7 +6821,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
 				Dictionary d = snap_data[node];
 				Vector3 from = d["from"];
 				Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
-				RBSet<RID> excluded = _get_physics_bodies_rid(sp);
+				HashSet<RID> excluded = _get_physics_bodies_rid(sp);
 
 				PhysicsDirectSpaceState3D::RayParameters ray_params;
 				ray_params.from = from;

+ 1 - 1
editor/plugins/packed_scene_translation_parser_plugin.h

@@ -37,7 +37,7 @@ class PackedSceneEditorTranslationParserPlugin : public EditorTranslationParserP
 	GDCLASS(PackedSceneEditorTranslationParserPlugin, EditorTranslationParserPlugin);
 
 	// Scene Node's properties that contain translation strings.
-	RBSet<String> lookup_properties;
+	HashSet<String> lookup_properties;
 	// Properties from specific Nodes that should be ignored.
 	HashMap<String, Vector<String>> exception_list;
 

+ 1 - 1
editor/plugins/root_motion_editor_plugin.cpp

@@ -65,7 +65,7 @@ void EditorPropertyRootMotion::_node_assign() {
 		return;
 	}
 
-	RBSet<String> paths;
+	HashSet<String> paths;
 	{
 		List<StringName> animations;
 		player->get_animation_list(&animations);

+ 4 - 4
editor/plugins/script_editor_plugin.cpp

@@ -1715,7 +1715,7 @@ void ScriptEditor::notify_script_changed(const Ref<Script> &p_script) {
 }
 
 void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
-	RBSet<String> loaded_scripts;
+	HashSet<String> loaded_scripts;
 	for (int i = 0; i < tab_container->get_tab_count(); i++) {
 		ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
 		if (!se) {
@@ -1800,7 +1800,7 @@ void ScriptEditor::ensure_select_current() {
 	_update_selected_editor_menu();
 }
 
-void ScriptEditor::_find_scripts(Node *p_base, Node *p_current, RBSet<Ref<Script>> &used) {
+void ScriptEditor::_find_scripts(Node *p_base, Node *p_current, HashSet<Ref<Script>> &used) {
 	if (p_current != p_base && p_current->get_owner() != p_base) {
 		return;
 	}
@@ -1980,7 +1980,7 @@ void ScriptEditor::_update_script_names() {
 		return;
 	}
 
-	RBSet<Ref<Script>> used;
+	HashSet<Ref<Script>> used;
 	Node *edited = EditorNode::get_singleton()->get_edited_scene();
 	if (edited) {
 		_find_scripts(edited, edited, used);
@@ -3143,7 +3143,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
 
 	restoring_layout = true;
 
-	RBSet<String> loaded_scripts;
+	HashSet<String> loaded_scripts;
 	List<String> extensions;
 	ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
 

+ 2 - 2
editor/plugins/script_editor_plugin.h

@@ -414,7 +414,7 @@ class ScriptEditor : public PanelContainer {
 	void _update_help_overview();
 	void _help_overview_selected(int p_idx);
 
-	void _find_scripts(Node *p_base, Node *p_current, RBSet<Ref<Script>> &used);
+	void _find_scripts(Node *p_base, Node *p_current, HashSet<Ref<Script>> &used);
 
 	void _tree_changed();
 
@@ -454,7 +454,7 @@ class ScriptEditor : public PanelContainer {
 	Ref<Script> _get_current_script();
 	Array _get_open_scripts() const;
 
-	RBSet<String> textfile_extensions;
+	HashSet<String> textfile_extensions;
 	Ref<TextFile> _load_text_file(const String &p_path, Error *r_error) const;
 	Error _save_text_file(Ref<TextFile> p_text_file, const String &p_path);
 

+ 3 - 3
editor/plugins/script_text_editor.cpp

@@ -664,7 +664,7 @@ static Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Scri
 	return nullptr;
 }
 
-static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_current, RBSet<Ref<Script>> &r_scripts) {
+static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_current, HashSet<Ref<Script>> &r_scripts) {
 	if (p_current->get_owner() != p_base && p_base != p_current) {
 		return;
 	}
@@ -686,7 +686,7 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo
 
 	ERR_FAIL_COND(!get_tree());
 
-	RBSet<Ref<Script>> scripts;
+	HashSet<Ref<Script>> scripts;
 
 	Node *base = get_tree()->get_edited_scene_root();
 	if (base) {
@@ -970,7 +970,7 @@ void ScriptTextEditor::_update_connected_methods() {
 	}
 
 	Vector<Node *> nodes = _find_all_node_for_script(base, base, script);
-	RBSet<StringName> methods_found;
+	HashSet<StringName> methods_found;
 	for (int i = 0; i < nodes.size(); i++) {
 		List<Connection> connections;
 		nodes[i]->get_signals_connected_to_this(&connections);

Some files were not shown because too many files changed in this diff