Add a new HashMap implementation

Adds a new, cleaned up, HashMap implementation.

* Uses Robin Hood Hashing (https://en.wikipedia.org/wiki/Hash_table#Robin_Hood_hashing).
* Keeps elements in a double linked list for simpler, ordered, iteration.
* Allows keeping iterators for later use in removal (Unlike Map<>, it does not do much
  for performance vs keeping the key, but helps replace old code).
* Uses a more modern C++ iterator API, deprecates the old one.
* Supports custom allocator (in case there is a wish to use a paged one).

This class aims to unify all the associative template usage and replace it by this one:
* Map<> (whereas key order does not matter, which is 99% of cases)
* HashMap<>
* OrderedHashMap<>
* OAHashMap<>
This commit is contained in:
reduz 2022-05-08 10:09:19 +02:00 committed by Rémi Verschelde
parent 9b7e16a6b8
commit 8b7c7f5a75
95 changed files with 1434 additions and 1874 deletions

View File

@ -1091,7 +1091,7 @@ bool ProjectSettings::has_custom_feature(const String &p_feature) const {
return custom_features.has(p_feature); return custom_features.has(p_feature);
} }
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> ProjectSettings::get_autoload_list() const { const HashMap<StringName, ProjectSettings::AutoloadInfo> &ProjectSettings::get_autoload_list() const {
return autoloads; return autoloads;
} }
@ -1135,13 +1135,13 @@ void ProjectSettings::_bind_methods() {
void ProjectSettings::_add_builtin_input_map() { void ProjectSettings::_add_builtin_input_map() {
if (InputMap::get_singleton()) { if (InputMap::get_singleton()) {
OrderedHashMap<String, List<Ref<InputEvent>>> builtins = InputMap::get_singleton()->get_builtins(); HashMap<String, List<Ref<InputEvent>>> builtins = InputMap::get_singleton()->get_builtins();
for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) { for (KeyValue<String, List<Ref<InputEvent>>> &E : builtins) {
Array events; Array events;
// Convert list of input events into array // Convert list of input events into array
for (List<Ref<InputEvent>>::Element *I = E.get().front(); I; I = I->next()) { for (List<Ref<InputEvent>>::Element *I = E.value.front(); I; I = I->next()) {
events.push_back(I->get()); events.push_back(I->get());
} }
@ -1149,7 +1149,7 @@ void ProjectSettings::_add_builtin_input_map() {
action["deadzone"] = Variant(0.5f); action["deadzone"] = Variant(0.5f);
action["events"] = events; action["events"] = events;
String action_name = "input/" + E.key(); String action_name = "input/" + E.key;
GLOBAL_DEF(action_name, action); GLOBAL_DEF(action_name, action);
input_presets.push_back(action_name); input_presets.push_back(action_name);
} }

View File

@ -33,7 +33,7 @@
#include "core/object/class_db.h" #include "core/object/class_db.h"
#include "core/os/thread_safe.h" #include "core/os/thread_safe.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
#include "core/templates/set.h" #include "core/templates/set.h"
class ProjectSettings : public Object { class ProjectSettings : public Object {
@ -94,7 +94,7 @@ protected:
Set<String> custom_features; Set<String> custom_features;
Map<StringName, StringName> feature_overrides; Map<StringName, StringName> feature_overrides;
OrderedHashMap<StringName, AutoloadInfo> autoloads; HashMap<StringName, AutoloadInfo> autoloads;
String project_data_dir_name; String project_data_dir_name;
@ -181,7 +181,7 @@ public:
bool has_custom_feature(const String &p_feature) const; bool has_custom_feature(const String &p_feature) const;
OrderedHashMap<StringName, AutoloadInfo> get_autoload_list() const; const HashMap<StringName, AutoloadInfo> &get_autoload_list() const;
void add_autoload(const AutoloadInfo &p_autoload); void add_autoload(const AutoloadInfo &p_autoload);
void remove_autoload(const StringName &p_autoload); void remove_autoload(const StringName &p_autoload);
bool has_autoload(const StringName &p_autoload) const; bool has_autoload(const StringName &p_autoload) const;

View File

@ -636,21 +636,21 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
} }
} }
for (OrderedHashMap<StringName, InputMap::Action>::ConstElement E = InputMap::get_singleton()->get_action_map().front(); E; E = E.next()) { for (const KeyValue<StringName, InputMap::Action> &E : InputMap::get_singleton()->get_action_map()) {
if (InputMap::get_singleton()->event_is_action(p_event, E.key())) { if (InputMap::get_singleton()->event_is_action(p_event, E.key)) {
// If not echo and action pressed state has changed // If not echo and action pressed state has changed
if (!p_event->is_echo() && is_action_pressed(E.key(), false) != p_event->is_action_pressed(E.key())) { if (!p_event->is_echo() && is_action_pressed(E.key, false) != p_event->is_action_pressed(E.key)) {
Action action; Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames(); action.physics_frame = Engine::get_singleton()->get_physics_frames();
action.process_frame = Engine::get_singleton()->get_process_frames(); action.process_frame = Engine::get_singleton()->get_process_frames();
action.pressed = p_event->is_action_pressed(E.key()); action.pressed = p_event->is_action_pressed(E.key);
action.strength = 0.0f; action.strength = 0.0f;
action.raw_strength = 0.0f; action.raw_strength = 0.0f;
action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key(), true); action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key, true);
action_state[E.key()] = action; action_state[E.key] = action;
} }
action_state[E.key()].strength = p_event->get_action_strength(E.key()); action_state[E.key].strength = p_event->get_action_strength(E.key);
action_state[E.key()].raw_strength = p_event->get_action_raw_strength(E.key()); action_state[E.key].raw_strength = p_event->get_action_raw_strength(E.key);
} }
} }

View File

@ -119,8 +119,8 @@ List<StringName> InputMap::get_actions() const {
return actions; return actions;
} }
for (OrderedHashMap<StringName, Action>::Element E = input_map.front(); E; E = E.next()) { for (const KeyValue<StringName, Action> &E : input_map) {
actions.push_back(E.key()); actions.push_back(E.key);
} }
return actions; return actions;
@ -203,12 +203,12 @@ Array InputMap::_action_get_events(const StringName &p_action) {
} }
const List<Ref<InputEvent>> *InputMap::action_get_events(const StringName &p_action) { const List<Ref<InputEvent>> *InputMap::action_get_events(const StringName &p_action) {
const OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action); HashMap<StringName, Action>::Iterator E = input_map.find(p_action);
if (!E) { if (!E) {
return nullptr; return nullptr;
} }
return &E.get().inputs; return &E->value.inputs;
} }
bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const { bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const {
@ -216,7 +216,7 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
} }
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength) const { bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action); HashMap<StringName, Action>::Iterator E = input_map.find(p_action);
ERR_FAIL_COND_V_MSG(!E, false, suggest_actions(p_action)); ERR_FAIL_COND_V_MSG(!E, false, suggest_actions(p_action));
Ref<InputEventAction> input_event_action = p_event; Ref<InputEventAction> input_event_action = p_event;
@ -235,11 +235,11 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
return input_event_action->get_action() == p_action; return input_event_action->get_action() == p_action;
} }
List<Ref<InputEvent>>::Element *event = _find_event(E.get(), p_event, p_exact_match, r_pressed, r_strength, r_raw_strength); List<Ref<InputEvent>>::Element *event = _find_event(E->value, p_event, p_exact_match, r_pressed, r_strength, r_raw_strength);
return event != nullptr; return event != nullptr;
} }
const OrderedHashMap<StringName, InputMap::Action> &InputMap::get_action_map() const { const HashMap<StringName, InputMap::Action> &InputMap::get_action_map() const {
return input_map; return input_map;
} }
@ -360,7 +360,7 @@ String InputMap::get_builtin_display_name(const String &p_name) const {
return p_name; return p_name;
} }
const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() { const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
// Return cache if it has already been built. // Return cache if it has already been built.
if (default_builtin_cache.size()) { if (default_builtin_cache.size()) {
return default_builtin_cache; return default_builtin_cache;
@ -686,19 +686,19 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
return default_builtin_cache; return default_builtin_cache;
} }
const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with_feature_overrides_applied() { const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with_feature_overrides_applied() {
if (default_builtin_with_overrides_cache.size() > 0) { if (default_builtin_with_overrides_cache.size() > 0) {
return default_builtin_with_overrides_cache; return default_builtin_with_overrides_cache;
} }
OrderedHashMap<String, List<Ref<InputEvent>>> builtins = get_builtins(); HashMap<String, List<Ref<InputEvent>>> builtins = get_builtins();
// Get a list of all built in inputs which are valid overrides for the OS // Get a list of all built in inputs which are valid overrides for the OS
// Key = builtin name (e.g. ui_accept) // Key = builtin name (e.g. ui_accept)
// Value = override/feature names (e.g. macos, if it was defined as "ui_accept.macos" and the platform supports that feature) // Value = override/feature names (e.g. macos, if it was defined as "ui_accept.macos" and the platform supports that feature)
Map<String, Vector<String>> builtins_with_overrides; Map<String, Vector<String>> builtins_with_overrides;
for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) { for (const KeyValue<String, List<Ref<InputEvent>>> &E : builtins) {
String fullname = E.key(); String fullname = E.key;
Vector<String> split = fullname.split("."); Vector<String> split = fullname.split(".");
String name = split[0]; String name = split[0];
@ -709,8 +709,8 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with
} }
} }
for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) { for (const KeyValue<String, List<Ref<InputEvent>>> &E : builtins) {
String fullname = E.key(); String fullname = E.key;
Vector<String> split = fullname.split("."); Vector<String> split = fullname.split(".");
String name = split[0]; String name = split[0];
@ -726,22 +726,22 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with
continue; continue;
} }
default_builtin_with_overrides_cache.insert(name, E.value()); default_builtin_with_overrides_cache.insert(name, E.value);
} }
return default_builtin_with_overrides_cache; return default_builtin_with_overrides_cache;
} }
void InputMap::load_default() { void InputMap::load_default() {
OrderedHashMap<String, List<Ref<InputEvent>>> builtins = get_builtins_with_feature_overrides_applied(); HashMap<String, List<Ref<InputEvent>>> builtins = get_builtins_with_feature_overrides_applied();
for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) { for (const KeyValue<String, List<Ref<InputEvent>>> &E : builtins) {
String name = E.key(); String name = E.key;
add_action(name); add_action(name);
List<Ref<InputEvent>> inputs = E.get(); const List<Ref<InputEvent>> &inputs = E.value;
for (List<Ref<InputEvent>>::Element *I = inputs.front(); I; I = I->next()) { for (const List<Ref<InputEvent>>::Element *I = inputs.front(); I; I = I->next()) {
Ref<InputEventKey> iek = I->get(); Ref<InputEventKey> iek = I->get();
// For the editor, only add keyboard actions. // For the editor, only add keyboard actions.

View File

@ -34,7 +34,7 @@
#include "core/input/input_event.h" #include "core/input/input_event.h"
#include "core/object/class_db.h" #include "core/object/class_db.h"
#include "core/object/object.h" #include "core/object/object.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
class InputMap : public Object { class InputMap : public Object {
GDCLASS(InputMap, Object); GDCLASS(InputMap, Object);
@ -54,9 +54,9 @@ public:
private: private:
static InputMap *singleton; static InputMap *singleton;
mutable OrderedHashMap<StringName, Action> input_map; mutable HashMap<StringName, Action> input_map;
OrderedHashMap<String, List<Ref<InputEvent>>> default_builtin_cache; HashMap<String, List<Ref<InputEvent>>> default_builtin_cache;
OrderedHashMap<String, List<Ref<InputEvent>>> default_builtin_with_overrides_cache; HashMap<String, List<Ref<InputEvent>>> default_builtin_with_overrides_cache;
List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const; List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const;
@ -85,7 +85,7 @@ public:
bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false) const; bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false) const;
bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const; bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const;
const OrderedHashMap<StringName, Action> &get_action_map() const; const HashMap<StringName, Action> &get_action_map() const;
void load_from_project_settings(); void load_from_project_settings();
void load_default(); void load_default();
@ -93,8 +93,8 @@ public:
String get_builtin_display_name(const String &p_name) const; String get_builtin_display_name(const String &p_name) const;
// Use an Ordered Map so insertion order is preserved. We want the elements to be 'grouped' somewhat. // Use an Ordered Map so insertion order is preserved. We want the elements to be 'grouped' somewhat.
const OrderedHashMap<String, List<Ref<InputEvent>>> &get_builtins(); const HashMap<String, List<Ref<InputEvent>>> &get_builtins();
const OrderedHashMap<String, List<Ref<InputEvent>>> &get_builtins_with_feature_overrides_applied(); const HashMap<String, List<Ref<InputEvent>>> &get_builtins_with_feature_overrides_applied();
InputMap(); InputMap();
~InputMap(); ~InputMap();

View File

@ -73,7 +73,7 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V
} else { } else {
if (!values.has(p_section)) { if (!values.has(p_section)) {
values[p_section] = OrderedHashMap<String, Variant>(); values[p_section] = HashMap<String, Variant>();
} }
values[p_section][p_key] = p_value; values[p_section][p_key] = p_value;
@ -102,16 +102,16 @@ bool ConfigFile::has_section_key(const String &p_section, const String &p_key) c
} }
void ConfigFile::get_sections(List<String> *r_sections) const { void ConfigFile::get_sections(List<String> *r_sections) const {
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::ConstElement E = values.front(); E; E = E.next()) { for (const KeyValue<String, HashMap<String, Variant>> &E : values) {
r_sections->push_back(E.key()); r_sections->push_back(E.key);
} }
} }
void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const { void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot get keys from nonexistent section \"%s\".", p_section)); ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot get keys from nonexistent section \"%s\".", p_section));
for (OrderedHashMap<String, Variant>::ConstElement E = values[p_section].front(); E; E = E.next()) { for (const KeyValue<String, Variant> &E : values[p_section]) {
r_keys->push_back(E.key()); r_keys->push_back(E.key);
} }
} }
@ -174,18 +174,21 @@ Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass
} }
Error ConfigFile::_internal_save(Ref<FileAccess> file) { Error ConfigFile::_internal_save(Ref<FileAccess> file) {
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) { bool first = true;
if (E != values.front()) { for (const KeyValue<String, HashMap<String, Variant>> &E : values) {
if (first) {
first = false;
} else {
file->store_string("\n"); file->store_string("\n");
} }
if (!E.key().is_empty()) { if (!E.key.is_empty()) {
file->store_string("[" + E.key() + "]\n\n"); file->store_string("[" + E.key + "]\n\n");
} }
for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) { for (const KeyValue<String, Variant> &F : E.value) {
String vstr; String vstr;
VariantWriter::write_to_string(F.get(), vstr); VariantWriter::write_to_string(F.value, vstr);
file->store_string(F.key().property_name_encode() + "=" + vstr + "\n"); file->store_string(F.key.property_name_encode() + "=" + vstr + "\n");
} }
} }

View File

@ -33,13 +33,13 @@
#include "core/io/file_access.h" #include "core/io/file_access.h"
#include "core/object/ref_counted.h" #include "core/object/ref_counted.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
#include "core/variant/variant_parser.h" #include "core/variant/variant_parser.h"
class ConfigFile : public RefCounted { class ConfigFile : public RefCounted {
GDCLASS(ConfigFile, RefCounted); GDCLASS(ConfigFile, RefCounted);
OrderedHashMap<String, OrderedHashMap<String, Variant>> values; HashMap<String, HashMap<String, Variant>> values;
PackedStringArray _get_sections() const; PackedStringArray _get_sections() const;
PackedStringArray _get_section_keys(const String &p_section) const; PackedStringArray _get_section_keys(const String &p_section) const;

View File

@ -53,8 +53,8 @@ bool MissingResource::_get(const StringName &p_name, Variant &r_ret) const {
} }
void MissingResource::_get_property_list(List<PropertyInfo> *p_list) const { void MissingResource::_get_property_list(List<PropertyInfo> *p_list) const {
for (OrderedHashMap<StringName, Variant>::ConstElement E = properties.front(); E; E = E.next()) { for (const KeyValue<StringName, Variant> &E : properties) {
p_list->push_back(PropertyInfo(E.value().get_type(), E.key())); p_list->push_back(PropertyInfo(E.value.get_type(), E.key));
} }
} }

View File

@ -38,7 +38,7 @@
class MissingResource : public Resource { class MissingResource : public Resource {
GDCLASS(MissingResource, Resource) GDCLASS(MissingResource, Resource)
OrderedHashMap<StringName, Variant> properties; HashMap<StringName, Variant> properties;
String original_class; String original_class;
bool recording_properties = false; bool recording_properties = false;

View File

@ -478,10 +478,8 @@ void ResourceCache::clear() {
if (resources.size()) { if (resources.size()) {
ERR_PRINT("Resources still in use at exit (run with --verbose for details)."); ERR_PRINT("Resources still in use at exit (run with --verbose for details).");
if (OS::get_singleton()->is_stdout_verbose()) { if (OS::get_singleton()->is_stdout_verbose()) {
const String *K = nullptr; for (const KeyValue<String, Resource *> &E : resources) {
while ((K = resources.next(K))) { print_line(vformat("Resource still in use: %s (%s)", E.key, E.value->get_class()));
Resource *r = resources[*K];
print_line(vformat("Resource still in use: %s (%s)", *K, r->get_class()));
} }
} }
} }
@ -516,10 +514,8 @@ Resource *ResourceCache::get(const String &p_path) {
void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) { void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) {
lock.read_lock(); lock.read_lock();
const String *K = nullptr; for (KeyValue<String, Resource *> &E : resources) {
while ((K = resources.next(K))) { p_resources->push_back(Ref<Resource>(E.value));
Resource *r = resources[*K];
p_resources->push_back(Ref<Resource>(r));
} }
lock.read_unlock(); lock.read_unlock();
} }
@ -544,9 +540,8 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
ERR_FAIL_COND_MSG(f.is_null(), "Cannot create file at path '" + String::utf8(p_file) + "'."); ERR_FAIL_COND_MSG(f.is_null(), "Cannot create file at path '" + String::utf8(p_file) + "'.");
} }
const String *K = nullptr; for (KeyValue<String, Resource *> &E : resources) {
while ((K = resources.next(K))) { Resource *r = E.value;
Resource *r = resources[*K];
if (!type_count.has(r->get_class())) { if (!type_count.has(r->get_class())) {
type_count[r->get_class()] = 0; type_count[r->get_class()] = 0;

View File

@ -149,12 +149,12 @@ Error ResourceUID::save_to_cache() {
cache_entries = 0; cache_entries = 0;
for (OrderedHashMap<ID, Cache>::Element E = unique_ids.front(); E; E = E.next()) { for (KeyValue<ID, Cache> &E : unique_ids) {
f->store_64(E.key()); f->store_64(E.key);
uint32_t s = E.get().cs.length(); uint32_t s = E.value.cs.length();
f->store_32(s); f->store_32(s);
f->store_buffer((const uint8_t *)E.get().cs.ptr(), s); f->store_buffer((const uint8_t *)E.value.cs.ptr(), s);
E.get().saved_to_cache = true; E.value.saved_to_cache = true;
cache_entries++; cache_entries++;
} }
@ -202,8 +202,8 @@ Error ResourceUID::update_cache() {
MutexLock l(mutex); MutexLock l(mutex);
Ref<FileAccess> f; Ref<FileAccess> f;
for (OrderedHashMap<ID, Cache>::Element E = unique_ids.front(); E; E = E.next()) { for (KeyValue<ID, Cache> &E : unique_ids) {
if (!E.get().saved_to_cache) { if (!E.value.saved_to_cache) {
if (f.is_null()) { if (f.is_null()) {
f = FileAccess::open(get_cache_file(), FileAccess::READ_WRITE); //append f = FileAccess::open(get_cache_file(), FileAccess::READ_WRITE); //append
if (f.is_null()) { if (f.is_null()) {
@ -211,11 +211,11 @@ Error ResourceUID::update_cache() {
} }
f->seek_end(); f->seek_end();
} }
f->store_64(E.key()); f->store_64(E.key);
uint32_t s = E.get().cs.length(); uint32_t s = E.value.cs.length();
f->store_32(s); f->store_32(s);
f->store_buffer((const uint8_t *)E.get().cs.ptr(), s); f->store_buffer((const uint8_t *)E.value.cs.ptr(), s);
E.get().saved_to_cache = true; E.value.saved_to_cache = true;
cache_entries++; cache_entries++;
} }
} }

View File

@ -33,7 +33,7 @@
#include "core/object/ref_counted.h" #include "core/object/ref_counted.h"
#include "core/string/string_name.h" #include "core/string/string_name.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
class ResourceUID : public Object { class ResourceUID : public Object {
GDCLASS(ResourceUID, Object) GDCLASS(ResourceUID, Object)
@ -53,7 +53,7 @@ private:
bool saved_to_cache = false; bool saved_to_cache = false;
}; };
OrderedHashMap<ID, Cache> unique_ids; //unique IDs and utf8 paths (less memory used) HashMap<ID, Cache> unique_ids; //unique IDs and utf8 paths (less memory used)
static ResourceUID *singleton; static ResourceUID *singleton;
uint32_t cache_entries = 0; uint32_t cache_entries = 0;

View File

@ -90,10 +90,8 @@ bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inh
void ClassDB::get_class_list(List<StringName> *p_classes) { void ClassDB::get_class_list(List<StringName> *p_classes) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
const StringName *k = nullptr; for (const KeyValue<StringName, ClassInfo> &E : classes) {
p_classes->push_back(E.key);
while ((k = classes.next(k))) {
p_classes->push_back(*k);
} }
p_classes->sort(); p_classes->sort();
@ -102,11 +100,9 @@ void ClassDB::get_class_list(List<StringName> *p_classes) {
void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) { void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
const StringName *k = nullptr; for (const KeyValue<StringName, ClassInfo> &E : classes) {
if (E.key != p_class && _is_parent_class(E.key, p_class)) {
while ((k = classes.next(k))) { p_classes->push_back(E.key);
if (*k != p_class && _is_parent_class(*k, p_class)) {
p_classes->push_back(*k);
} }
} }
} }
@ -114,11 +110,9 @@ void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringNa
void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) { void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
const StringName *k = nullptr; for (const KeyValue<StringName, ClassInfo> &E : classes) {
if (E.key != p_class && _get_parent_class(E.key) == p_class) {
while ((k = classes.next(k))) { p_classes->push_back(E.key);
if (*k != p_class && _get_parent_class(*k) == p_class) {
p_classes->push_back(*k);
} }
} }
} }
@ -172,17 +166,12 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG));
List<StringName> names; List<StringName> class_list;
ClassDB::get_class_list(&class_list);
// Must be alphabetically sorted for hash to compute.
class_list.sort_custom<StringName::AlphCompare>();
const StringName *k = nullptr; for (const StringName &E : class_list) {
while ((k = classes.next(k))) {
names.push_back(*k);
}
//must be alphabetically sorted for hash to compute
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
ClassInfo *t = classes.getptr(E); ClassInfo *t = classes.getptr(E);
ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E) + "'."); ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E) + "'.");
if (t->api != p_api || !t->exposed) { if (t->api != p_api || !t->exposed) {
@ -195,10 +184,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, MethodBind *> &F : t->method_map) {
String name = F.key.operator String();
while ((k = t->method_map.next(k))) {
String name = k->operator String();
ERR_CONTINUE(name.is_empty()); ERR_CONTINUE(name.is_empty());
@ -206,7 +193,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
continue; // Ignore non-virtual methods that start with an underscore continue; // Ignore non-virtual methods that start with an underscore
} }
snames.push_back(*k); snames.push_back(F.key);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();
@ -241,10 +228,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, int> &F : t->constant_map) {
snames.push_back(F.key);
while ((k = t->constant_map.next(k))) {
snames.push_back(*k);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();
@ -259,10 +244,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, MethodInfo> &F : t->signal_map) {
snames.push_back(F.key);
while ((k = t->signal_map.next(k))) {
snames.push_back(*k);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();
@ -280,10 +263,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, PropertySetGet> &F : t->property_setget) {
snames.push_back(F.key);
while ((k = t->property_setget.next(k))) {
snames.push_back(*k);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();
@ -474,10 +455,8 @@ void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_met
#else #else
const StringName *K = nullptr; for (KeyValue<StringName, MethodBind *> &E : type->method_map) {
MethodBind *m = E.value;
while ((K = type->method_map.next(K))) {
MethodBind *m = type->method_map[*K];
MethodInfo minfo = info_from_bind(m); MethodInfo minfo = info_from_bind(m);
p_methods->push_back(minfo); p_methods->push_back(minfo);
} }
@ -603,10 +582,9 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List<String>
p_constants->push_back(E); p_constants->push_back(E);
} }
#else #else
const StringName *K = nullptr;
while ((K = type->constant_map.next(K))) { for (const KeyValue<StringName, int> &E : type->constant_map) {
p_constants->push_back(*K); p_constants->push_back(E.key);
} }
#endif #endif
@ -667,12 +645,11 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S
ClassInfo *type = classes.getptr(p_class); ClassInfo *type = classes.getptr(p_class);
while (type) { while (type) {
const StringName *k = nullptr; for (KeyValue<StringName, List<StringName>> &E : type->enum_map) {
while ((k = type->enum_map.next(k))) { List<StringName> &constants_list = E.value;
List<StringName> &constants_list = type->enum_map.get(*k);
const List<StringName>::Element *found = constants_list.find(p_name); const List<StringName>::Element *found = constants_list.find(p_name);
if (found) { if (found) {
return *k; return E.key;
} }
} }
@ -692,9 +669,8 @@ void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums
ClassInfo *type = classes.getptr(p_class); ClassInfo *type = classes.getptr(p_class);
while (type) { while (type) {
const StringName *k = nullptr; for (KeyValue<StringName, List<StringName>> &E : type->enum_map) {
while ((k = type->enum_map.next(k))) { p_enums->push_back(E.key);
p_enums->push_back(*k);
} }
if (p_no_inheritance) { if (p_no_inheritance) {
@ -800,9 +776,8 @@ void ClassDB::get_signal_list(const StringName &p_class, List<MethodInfo> *p_sig
ClassInfo *check = type; ClassInfo *check = type;
while (check) { while (check) {
const StringName *S = nullptr; for (KeyValue<StringName, MethodInfo> &E : check->signal_map) {
while ((S = check->signal_map.next(S))) { p_signals->push_back(E.value);
p_signals->push_back(check->signal_map[*S]);
} }
if (p_no_inheritance) { if (p_no_inheritance) {
@ -1397,10 +1372,8 @@ void ClassDB::add_resource_base_extension(const StringName &p_extension, const S
} }
void ClassDB::get_resource_base_extensions(List<String> *p_extensions) { void ClassDB::get_resource_base_extensions(List<String> *p_extensions) {
const StringName *K = nullptr; for (const KeyValue<StringName, StringName> &E : resource_base_extensions) {
p_extensions->push_back(E.key);
while ((K = resource_base_extensions.next(K))) {
p_extensions->push_back(*K);
} }
} }
@ -1409,12 +1382,9 @@ bool ClassDB::is_resource_extension(const StringName &p_extension) {
} }
void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p_extensions) { void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p_extensions) {
const StringName *K = nullptr; for (const KeyValue<StringName, StringName> &E : resource_base_extensions) {
if (is_parent_class(p_class, E.value) || is_parent_class(E.value, p_class)) {
while ((K = resource_base_extensions.next(K))) { p_extensions->push_back(E.key);
StringName cmp = resource_base_extensions[*K];
if (is_parent_class(p_class, cmp) || is_parent_class(cmp, p_class)) {
p_extensions->push_back(*K);
} }
} }
} }
@ -1556,14 +1526,11 @@ void ClassDB::cleanup_defaults() {
void ClassDB::cleanup() { void ClassDB::cleanup() {
//OBJTYPE_LOCK; hah not here //OBJTYPE_LOCK; hah not here
const StringName *k = nullptr; for (KeyValue<StringName, ClassInfo> &E : classes) {
ClassInfo &ti = E.value;
while ((k = classes.next(k))) { for (KeyValue<StringName, MethodBind *> &F : ti.method_map) {
ClassInfo &ti = classes[*k]; memdelete(F.value);
const StringName *m = nullptr;
while ((m = ti.method_map.next(m))) {
memdelete(ti.method_map[*m]);
} }
} }
classes.clear(); classes.clear();

View File

@ -417,9 +417,9 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
return; return;
} else { } else {
OrderedHashMap<StringName, Variant>::Element *E = metadata_properties.getptr(p_name); Variant **V = metadata_properties.getptr(p_name);
if (E) { if (V) {
E->get() = p_value; **V = p_value;
if (r_valid) { if (r_valid) {
*r_valid = true; *r_valid = true;
} }
@ -508,10 +508,10 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
return ret; return ret;
} }
const OrderedHashMap<StringName, Variant>::Element *E = metadata_properties.getptr(p_name); const Variant *const *V = metadata_properties.getptr(p_name);
if (E) { if (V) {
ret = E->get(); ret = **V;
if (r_valid) { if (r_valid) {
*r_valid = true; *r_valid = true;
} }
@ -666,9 +666,9 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
script_instance->get_property_list(p_list); script_instance->get_property_list(p_list);
} }
for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) { for (const KeyValue<StringName, Variant> &K : metadata) {
PropertyInfo pi = PropertyInfo(K.value().get_type(), "metadata/" + K.key().operator String()); PropertyInfo pi = PropertyInfo(K.value.get_type(), "metadata/" + K.key.operator String());
if (K.value().get_type() == Variant::OBJECT) { if (K.value.get_type() == Variant::OBJECT) {
pi.hint = PROPERTY_HINT_RESOURCE_TYPE; pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "Resource"; pi.hint_string = "Resource";
} }
@ -944,13 +944,13 @@ void Object::set_meta(const StringName &p_name, const Variant &p_value) {
return; return;
} }
OrderedHashMap<StringName, Variant>::Element E = metadata.find(p_name); HashMap<StringName, Variant>::Iterator E = metadata.find(p_name);
if (E) { if (E) {
E.value() = p_value; E->value = p_value;
} else { } else {
ERR_FAIL_COND(!p_name.operator String().is_valid_identifier()); ERR_FAIL_COND(!p_name.operator String().is_valid_identifier());
E = metadata.insert(p_name, p_value); Variant *V = &metadata.insert(p_name, p_value)->value;
metadata_properties["metadata/" + p_name.operator String()] = E; metadata_properties["metadata/" + p_name.operator String()] = V;
notify_property_list_changed(); notify_property_list_changed();
} }
} }
@ -993,16 +993,16 @@ Array Object::_get_method_list_bind() const {
Vector<StringName> Object::_get_meta_list_bind() const { Vector<StringName> Object::_get_meta_list_bind() const {
Vector<StringName> _metaret; Vector<StringName> _metaret;
for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) { for (const KeyValue<StringName, Variant> &K : metadata) {
_metaret.push_back(K.key()); _metaret.push_back(K.key);
} }
return _metaret; return _metaret;
} }
void Object::get_meta_list(List<StringName> *p_list) const { void Object::get_meta_list(List<StringName> *p_list) const {
for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) { for (const KeyValue<StringName, Variant> &K : metadata) {
p_list->push_back(K.key()); p_list->push_back(K.key);
} }
} }
@ -1250,21 +1250,18 @@ void Object::get_signal_list(List<MethodInfo> *p_signals) const {
ClassDB::get_signal_list(get_class_name(), p_signals); ClassDB::get_signal_list(get_class_name(), p_signals);
//find maybe usersignals? //find maybe usersignals?
const StringName *S = nullptr;
while ((S = signal_map.next(S))) { for (const KeyValue<StringName, SignalData> &E : signal_map) {
if (!signal_map[*S].user.name.is_empty()) { if (!E.value.user.name.is_empty()) {
//user signal //user signal
p_signals->push_back(signal_map[*S].user); p_signals->push_back(E.value.user);
} }
} }
} }
void Object::get_all_signal_connections(List<Connection> *p_connections) const { void Object::get_all_signal_connections(List<Connection> *p_connections) const {
const StringName *S = nullptr; for (const KeyValue<StringName, SignalData> &E : signal_map) {
const SignalData *s = &E.value;
while ((S = signal_map.next(S))) {
const SignalData *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) { for (int i = 0; i < s->slot_map.size(); i++) {
p_connections->push_back(s->slot_map.getv(i).conn); p_connections->push_back(s->slot_map.getv(i).conn);
@ -1285,10 +1282,9 @@ void Object::get_signal_connection_list(const StringName &p_signal, List<Connect
int Object::get_persistent_signal_connection_count() const { int Object::get_persistent_signal_connection_count() const {
int count = 0; int count = 0;
const StringName *S = nullptr;
while ((S = signal_map.next(S))) { for (const KeyValue<StringName, SignalData> &E : signal_map) {
const SignalData *s = &signal_map[*S]; const SignalData *s = &E.value;
for (int i = 0; i < s->slot_map.size(); i++) { for (int i = 0; i < s->slot_map.size(); i++) {
if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) { if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) {
@ -1866,15 +1862,15 @@ Object::~Object() {
_extension_instance = nullptr; _extension_instance = nullptr;
} }
const StringName *S = nullptr;
if (_emitting) { if (_emitting) {
//@todo this may need to actually reach the debugger prioritarily somehow because it may crash before //@todo this may need to actually reach the debugger prioritarily somehow because it may crash before
ERR_PRINT("Object " + to_string() + " was freed or unreferenced while a signal is being emitted from it. Try connecting to the signal using 'CONNECT_DEFERRED' flag, or use queue_free() to free the object (if this object is a Node) to avoid this error and potential crashes."); ERR_PRINT("Object " + to_string() + " was freed or unreferenced while a signal is being emitted from it. Try connecting to the signal using 'CONNECT_DEFERRED' flag, or use queue_free() to free the object (if this object is a Node) to avoid this error and potential crashes.");
} }
while ((S = signal_map.next(nullptr))) { while (signal_map.size()) {
SignalData *s = &signal_map[*S]; // Avoid regular iteration so erasing is safe.
KeyValue<StringName, SignalData> &E = *signal_map.begin();
SignalData *s = &E.value;
//brute force disconnect for performance //brute force disconnect for performance
int slot_count = s->slot_map.size(); int slot_count = s->slot_map.size();
@ -1884,7 +1880,7 @@ Object::~Object() {
slot_list[i].value.conn.callable.get_object()->connections.erase(slot_list[i].value.cE); slot_list[i].value.conn.callable.get_object()->connections.erase(slot_list[i].value.cE);
} }
signal_map.erase(*S); signal_map.erase(E.key);
} }
//signals from nodes that connect to this node //signals from nodes that connect to this node

View File

@ -39,7 +39,6 @@
#include "core/templates/hash_map.h" #include "core/templates/hash_map.h"
#include "core/templates/list.h" #include "core/templates/list.h"
#include "core/templates/map.h" #include "core/templates/map.h"
#include "core/templates/ordered_hash_map.h"
#include "core/templates/safe_refcount.h" #include "core/templates/safe_refcount.h"
#include "core/templates/set.h" #include "core/templates/set.h"
#include "core/templates/vmap.h" #include "core/templates/vmap.h"
@ -515,8 +514,8 @@ private:
#endif #endif
ScriptInstance *script_instance = nullptr; ScriptInstance *script_instance = nullptr;
Variant script; // Reference does not exist yet, store it in a Variant. Variant script; // Reference does not exist yet, store it in a Variant.
OrderedHashMap<StringName, Variant> metadata; HashMap<StringName, Variant> metadata;
HashMap<StringName, OrderedHashMap<StringName, Variant>::Element> metadata_properties; HashMap<StringName, Variant *> metadata_properties;
mutable StringName _class_name; mutable StringName _class_name;
mutable const StringName *_class_ptr = nullptr; mutable const StringName *_class_ptr = nullptr;

View File

@ -253,10 +253,9 @@ StringName ScriptServer::get_global_class_native_base(const String &p_class) {
} }
void ScriptServer::get_global_class_list(List<StringName> *r_global_classes) { void ScriptServer::get_global_class_list(List<StringName> *r_global_classes) {
const StringName *K = nullptr;
List<StringName> classes; List<StringName> classes;
while ((K = global_classes.next(K))) { for (const KeyValue<StringName, GlobalScriptClass> &E : global_classes) {
classes.push_back(*K); classes.push_back(E.key);
} }
classes.sort_custom<StringName::AlphCompare>(); classes.sort_custom<StringName::AlphCompare>();
for (const StringName &E : classes) { for (const StringName &E : classes) {

View File

@ -197,4 +197,12 @@ struct _GlobalNilClass {
static _GlobalNil _nil; static _GlobalNil _nil;
}; };
template <class T>
class DefaultTypedAllocator {
public:
template <class... Args>
_FORCE_INLINE_ T *new_allocation(const Args &&...p_args) { return memnew(T(p_args...)); }
_FORCE_INLINE_ void delete_allocation(T *p_allocation) { memdelete(p_allocation); }
};
#endif // MEMORY_H #endif // MEMORY_H

View File

@ -70,21 +70,14 @@ Dictionary TranslationPO::_get_messages() const {
Dictionary d; Dictionary d;
List<StringName> context_l; for (const KeyValue<StringName, HashMap<StringName, Vector<StringName>>> &E : translation_map) {
translation_map.get_key_list(&context_l);
for (const StringName &ctx : context_l) {
const HashMap<StringName, Vector<StringName>> &id_str_map = translation_map[ctx];
Dictionary d2; Dictionary d2;
List<StringName> id_l;
id_str_map.get_key_list(&id_l); for (const KeyValue<StringName, Vector<StringName>> &E2 : E.value) {
// Save list of id and strs associated with a context in a temporary dictionary. d2[E2.key] = E2.value;
for (List<StringName>::Element *E2 = id_l.front(); E2; E2 = E2->next()) {
StringName id = E2->get();
d2[id] = id_str_map[id];
} }
d[ctx] = d2; d[E.key] = d2;
} }
return d; return d;
@ -274,31 +267,24 @@ void TranslationPO::get_message_list(List<StringName> *r_messages) const {
// OptimizedTranslation uses this function to get the list of msgid. // OptimizedTranslation uses this function to get the list of msgid.
// Return all the keys of translation_map under "" context. // Return all the keys of translation_map under "" context.
List<StringName> context_l; for (const KeyValue<StringName, HashMap<StringName, Vector<StringName>>> &E : translation_map) {
translation_map.get_key_list(&context_l); if (E.key != StringName()) {
for (const StringName &E : context_l) {
if (String(E) != "") {
continue; continue;
} }
List<StringName> msgid_l; for (const KeyValue<StringName, Vector<StringName>> &E2 : E.value) {
translation_map[E].get_key_list(&msgid_l); r_messages->push_back(E2.key);
for (List<StringName>::Element *E2 = msgid_l.front(); E2; E2 = E2->next()) {
r_messages->push_back(E2->get());
} }
} }
} }
int TranslationPO::get_message_count() const { int TranslationPO::get_message_count() const {
List<StringName> context_l;
translation_map.get_key_list(&context_l);
int count = 0; int count = 0;
for (const StringName &E : context_l) {
count += translation_map[E].size(); for (const KeyValue<StringName, HashMap<StringName, Vector<StringName>>> &E : translation_map) {
count += E.value.size();
} }
return count; return count;
} }

File diff suppressed because it is too large Load Diff

View File

@ -31,14 +31,22 @@
#ifndef HASHFUNCS_H #ifndef HASHFUNCS_H
#define HASHFUNCS_H #define HASHFUNCS_H
#include "core/math/aabb.h"
#include "core/math/math_defs.h" #include "core/math/math_defs.h"
#include "core/math/math_funcs.h" #include "core/math/math_funcs.h"
#include "core/math/rect2.h"
#include "core/math/rect2i.h"
#include "core/math/vector2.h"
#include "core/math/vector2i.h"
#include "core/math/vector3.h"
#include "core/math/vector3i.h"
#include "core/object/object_id.h" #include "core/object/object_id.h"
#include "core/string/node_path.h" #include "core/string/node_path.h"
#include "core/string/string_name.h" #include "core/string/string_name.h"
#include "core/string/ustring.h" #include "core/string/ustring.h"
#include "core/templates/rid.h" #include "core/templates/rid.h"
#include "core/typedefs.h" #include "core/typedefs.h"
/** /**
* Hashing functions * Hashing functions
*/ */
@ -178,6 +186,49 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); } static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); } static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
static _FORCE_INLINE_ uint32_t hash(const Vector2i &p_vec) {
uint32_t h = hash_djb2_one_32(p_vec.x);
return hash_djb2_one_32(p_vec.y, h);
}
static _FORCE_INLINE_ uint32_t hash(const Vector3i &p_vec) {
uint32_t h = hash_djb2_one_32(p_vec.x);
h = hash_djb2_one_32(p_vec.y, h);
return hash_djb2_one_32(p_vec.z, h);
}
static _FORCE_INLINE_ uint32_t hash(const Vector2 &p_vec) {
uint32_t h = hash_djb2_one_float(p_vec.x);
return hash_djb2_one_float(p_vec.y, h);
}
static _FORCE_INLINE_ uint32_t hash(const Vector3 &p_vec) {
uint32_t h = hash_djb2_one_float(p_vec.x);
h = hash_djb2_one_float(p_vec.y, h);
return hash_djb2_one_float(p_vec.z, h);
}
static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) {
uint32_t h = hash_djb2_one_32(p_rect.position.x);
h = hash_djb2_one_32(p_rect.position.y, h);
h = hash_djb2_one_32(p_rect.size.x, h);
return hash_djb2_one_32(p_rect.size.y, h);
}
static _FORCE_INLINE_ uint32_t hash(const Rect2 &p_rect) {
uint32_t h = hash_djb2_one_float(p_rect.position.x);
h = hash_djb2_one_float(p_rect.position.y, h);
h = hash_djb2_one_float(p_rect.size.x, h);
return hash_djb2_one_float(p_rect.size.y, h);
}
static _FORCE_INLINE_ uint32_t hash(const AABB &p_aabb) {
uint32_t h = hash_djb2_one_float(p_aabb.position.x);
h = hash_djb2_one_float(p_aabb.position.y, h);
h = hash_djb2_one_float(p_aabb.position.z, h);
h = hash_djb2_one_float(p_aabb.size.x, h);
h = hash_djb2_one_float(p_aabb.size.y, h);
return hash_djb2_one_float(p_aabb.size.z, h);
}
//static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); } //static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
}; };
@ -196,4 +247,38 @@ struct HashMapComparatorDefault {
} }
}; };
constexpr uint32_t HASH_TABLE_SIZE_MAX = 29;
const uint32_t hash_table_size_primes[HASH_TABLE_SIZE_MAX] = {
5,
13,
23,
47,
97,
193,
389,
769,
1543,
3079,
6151,
12289,
24593,
49157,
98317,
196613,
393241,
786433,
1572869,
3145739,
6291469,
12582917,
25165843,
50331653,
100663319,
201326611,
402653189,
805306457,
1610612741,
};
#endif // HASHFUNCS_H #endif // HASHFUNCS_H

View File

@ -1,301 +0,0 @@
/*************************************************************************/
/* ordered_hash_map.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 ORDERED_HASH_MAP_H
#define ORDERED_HASH_MAP_H
#include "core/templates/hash_map.h"
#include "core/templates/list.h"
#include "core/templates/pair.h"
/**
* A hash map which allows to iterate elements in insertion order.
* Insertion, lookup, deletion have O(1) complexity.
* The API aims to be consistent with Map rather than HashMap, because the
* former is more frequently used and is more coherent with the rest of the
* codebase.
* Deletion during iteration is safe and will preserve the order.
*/
template <class K, class V, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<K>, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8>
class OrderedHashMap {
typedef List<Pair<const K *, V>> InternalList;
typedef HashMap<K, typename InternalList::Element *, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP> InternalMap;
InternalList list;
InternalMap map;
public:
class Element {
friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
typename InternalList::Element *list_element = nullptr;
typename InternalList::Element *prev_element = nullptr;
typename InternalList::Element *next_element = nullptr;
Element(typename InternalList::Element *p_element) {
list_element = p_element;
if (list_element) {
next_element = list_element->next();
prev_element = list_element->prev();
}
}
public:
_FORCE_INLINE_ Element() {}
Element next() const {
return Element(next_element);
}
Element prev() const {
return Element(prev_element);
}
Element(const Element &other) :
list_element(other.list_element),
prev_element(other.prev_element),
next_element(other.next_element) {
}
void operator=(const Element &other) {
list_element = other.list_element;
next_element = other.next_element;
prev_element = other.prev_element;
}
_FORCE_INLINE_ bool operator==(const Element &p_other) const {
return this->list_element == p_other.list_element;
}
_FORCE_INLINE_ bool operator!=(const Element &p_other) const {
return this->list_element != p_other.list_element;
}
operator bool() const {
return (list_element != nullptr);
}
const K &key() const {
CRASH_COND(!list_element);
return *(list_element->get().first);
}
V &value() {
CRASH_COND(!list_element);
return list_element->get().second;
}
const V &value() const {
CRASH_COND(!list_element);
return list_element->get().second;
}
V &get() {
CRASH_COND(!list_element);
return list_element->get().second;
}
const V &get() const {
CRASH_COND(!list_element);
return list_element->get().second;
}
};
class ConstElement {
friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
const typename InternalList::Element *list_element = nullptr;
ConstElement(const typename InternalList::Element *p_element) :
list_element(p_element) {
}
public:
_FORCE_INLINE_ ConstElement() {}
ConstElement(const ConstElement &other) :
list_element(other.list_element) {
}
void operator=(const ConstElement &other) {
list_element = other.list_element;
}
ConstElement next() const {
return ConstElement(list_element ? list_element->next() : nullptr);
}
ConstElement prev() const {
return ConstElement(list_element ? list_element->prev() : nullptr);
}
_FORCE_INLINE_ bool operator==(const ConstElement &p_other) const {
return this->list_element == p_other.list_element;
}
_FORCE_INLINE_ bool operator!=(const ConstElement &p_other) const {
return this->list_element != p_other.list_element;
}
operator bool() const {
return (list_element != nullptr);
}
const K &key() const {
CRASH_COND(!list_element);
return *(list_element->get().first);
}
const V &value() const {
CRASH_COND(!list_element);
return list_element->get().second;
}
const V &get() const {
CRASH_COND(!list_element);
return list_element->get().second;
}
};
ConstElement find(const K &p_key) const {
typename InternalList::Element *const *list_element = map.getptr(p_key);
if (list_element) {
return ConstElement(*list_element);
}
return ConstElement(nullptr);
}
Element find(const K &p_key) {
typename InternalList::Element **list_element = map.getptr(p_key);
if (list_element) {
return Element(*list_element);
}
return Element(nullptr);
}
Element insert(const K &p_key, const V &p_value) {
typename InternalList::Element **list_element = map.getptr(p_key);
if (list_element) {
(*list_element)->get().second = p_value;
return Element(*list_element);
}
// Incorrectly set the first value of the pair with a value that will
// be invalid as soon as we leave this function...
typename InternalList::Element *new_element = list.push_back(Pair<const K *, V>(&p_key, p_value));
// ...this is needed here in case the hashmap recursively reference itself...
typename InternalMap::Element *e = map.set(p_key, new_element);
// ...now we can set the right value !
new_element->get().first = &e->key();
return Element(new_element);
}
void erase(Element &p_element) {
map.erase(p_element.key());
list.erase(p_element.list_element);
p_element.list_element = nullptr;
}
bool erase(const K &p_key) {
typename InternalList::Element **list_element = map.getptr(p_key);
if (list_element) {
list.erase(*list_element);
map.erase(p_key);
return true;
}
return false;
}
inline bool has(const K &p_key) const {
return map.has(p_key);
}
const V &operator[](const K &p_key) const {
ConstElement e = find(p_key);
CRASH_COND(!e);
return e.value();
}
V &operator[](const K &p_key) {
Element e = find(p_key);
if (!e) {
// consistent with Map behaviour
e = insert(p_key, V());
}
return e.value();
}
inline Element front() {
return Element(list.front());
}
inline Element back() {
return Element(list.back());
}
inline ConstElement front() const {
return ConstElement(list.front());
}
inline ConstElement back() const {
return ConstElement(list.back());
}
inline bool is_empty() const { return list.is_empty(); }
inline int size() const { return list.size(); }
const void *id() const {
return list.id();
}
void clear() {
map.clear();
list.clear();
}
private:
void _copy_from(const OrderedHashMap &p_map) {
for (ConstElement E = p_map.front(); E; E = E.next()) {
insert(E.key(), E.value());
}
}
public:
void operator=(const OrderedHashMap &p_map) {
_copy_from(p_map);
}
OrderedHashMap(const OrderedHashMap &p_map) {
_copy_from(p_map);
}
_FORCE_INLINE_ OrderedHashMap() {}
};
#endif // ORDERED_HASH_MAP_H

View File

@ -50,6 +50,10 @@ class PagedAllocator {
SpinLock spin_lock; SpinLock spin_lock;
public: public:
enum {
DEFAULT_PAGE_SIZE = 4096
};
template <class... Args> template <class... Args>
T *alloc(const Args &&...p_args) { T *alloc(const Args &&...p_args) {
if (thread_safe) { if (thread_safe) {
@ -121,7 +125,9 @@ public:
page_shift = get_shift_from_power_of_2(page_size); page_shift = get_shift_from_power_of_2(page_size);
} }
PagedAllocator(uint32_t p_page_size = 4096) { // power of 2 recommended because of alignment with OS page sizes. Even if element is bigger, its still a multiple and get rounded amount of pages // Power of 2 recommended because of alignment with OS page sizes.
// Even if element is bigger, it's still a multiple and gets rounded to amount of pages.
PagedAllocator(uint32_t p_page_size = DEFAULT_PAGE_SIZE) {
configure(p_page_size); configure(p_page_size);
} }

View File

@ -30,7 +30,7 @@
#include "dictionary.h" #include "dictionary.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
#include "core/templates/safe_refcount.h" #include "core/templates/safe_refcount.h"
#include "core/variant/variant.h" #include "core/variant/variant.h"
// required in this order by VariantInternal, do not remove this comment. // required in this order by VariantInternal, do not remove this comment.
@ -41,7 +41,7 @@
struct DictionaryPrivate { struct DictionaryPrivate {
SafeRefCount refcount; SafeRefCount refcount;
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> variant_map; HashMap<Variant, Variant, VariantHasher, VariantComparator> variant_map;
}; };
void Dictionary::get_key_list(List<Variant> *p_keys) const { void Dictionary::get_key_list(List<Variant> *p_keys) const {
@ -49,16 +49,16 @@ void Dictionary::get_key_list(List<Variant> *p_keys) const {
return; return;
} }
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
p_keys->push_back(E.key()); p_keys->push_back(E.key);
} }
} }
Variant Dictionary::get_key_at_index(int p_index) const { Variant Dictionary::get_key_at_index(int p_index) const {
int index = 0; int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
if (index == p_index) { if (index == p_index) {
return E.key(); return E.key;
} }
index++; index++;
} }
@ -68,9 +68,9 @@ Variant Dictionary::get_key_at_index(int p_index) const {
Variant Dictionary::get_value_at_index(int p_index) const { Variant Dictionary::get_value_at_index(int p_index) const {
int index = 0; int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
if (index == p_index) { if (index == p_index) {
return E.value(); return E.value;
} }
index++; index++;
} }
@ -97,50 +97,50 @@ const Variant &Dictionary::operator[](const Variant &p_key) const {
} }
const Variant *Dictionary::getptr(const Variant &p_key) const { const Variant *Dictionary::getptr(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E; HashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstIterator E;
if (p_key.get_type() == Variant::STRING_NAME) { if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key); const StringName *sn = VariantInternal::get_string_name(&p_key);
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
} else { } else {
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
} }
if (!E) { if (!E) {
return nullptr; return nullptr;
} }
return &E.get(); return &E->value;
} }
Variant *Dictionary::getptr(const Variant &p_key) { Variant *Dictionary::getptr(const Variant &p_key) {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E; HashMap<Variant, Variant, VariantHasher, VariantComparator>::Iterator E;
if (p_key.get_type() == Variant::STRING_NAME) { if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key); const StringName *sn = VariantInternal::get_string_name(&p_key);
E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); E = ((HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
} else { } else {
E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); E = ((HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
} }
if (!E) { if (!E) {
return nullptr; return nullptr;
} }
return &E.get(); return &E->value;
} }
Variant Dictionary::get_valid(const Variant &p_key) const { Variant Dictionary::get_valid(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E; HashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstIterator E;
if (p_key.get_type() == Variant::STRING_NAME) { if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key); const StringName *sn = VariantInternal::get_string_name(&p_key);
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
} else { } else {
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
} }
if (!E) { if (!E) {
return Variant(); return Variant();
} }
return E.get(); return E->value;
} }
Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const { Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
@ -210,9 +210,9 @@ bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_c
return true; return true;
} }
recursion_count++; recursion_count++;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement this_E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->front(); this_E; this_E = this_E.next()) { for (const KeyValue<Variant, Variant> &this_E : _p->variant_map) {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement other_E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&p_dictionary._p->variant_map)->find(this_E.key()); HashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstIterator other_E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&p_dictionary._p->variant_map)->find(this_E.key);
if (!other_E || !this_E.value().hash_compare(other_E.value(), recursion_count)) { if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count)) {
return false; return false;
} }
} }
@ -261,9 +261,9 @@ uint32_t Dictionary::recursive_hash(int recursion_count) const {
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY); uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
recursion_count++; recursion_count++;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
h = hash_djb2_one_32(E.key().recursive_hash(recursion_count), h); h = hash_djb2_one_32(E.key.recursive_hash(recursion_count), h);
h = hash_djb2_one_32(E.value().recursive_hash(recursion_count), h); h = hash_djb2_one_32(E.value.recursive_hash(recursion_count), h);
} }
return h; return h;
@ -278,8 +278,8 @@ Array Dictionary::keys() const {
varr.resize(size()); varr.resize(size());
int i = 0; int i = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
varr[i] = E.key(); varr[i] = E.key;
i++; i++;
} }
@ -295,8 +295,8 @@ Array Dictionary::values() const {
varr.resize(size()); varr.resize(size());
int i = 0; int i = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
varr[i] = E.get(); varr[i] = E.value;
i++; i++;
} }
@ -306,16 +306,23 @@ Array Dictionary::values() const {
const Variant *Dictionary::next(const Variant *p_key) const { const Variant *Dictionary::next(const Variant *p_key) const {
if (p_key == nullptr) { if (p_key == nullptr) {
// caller wants to get the first element // caller wants to get the first element
if (_p->variant_map.front()) { if (_p->variant_map.begin()) {
return &_p->variant_map.front().key(); return &_p->variant_map.begin()->key;
} }
return nullptr; return nullptr;
} }
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(*p_key); HashMap<Variant, Variant, VariantHasher, VariantComparator>::Iterator E = _p->variant_map.find(*p_key);
if (E && E.next()) { if (!E) {
return &E.next().key(); return nullptr;
} }
++E;
if (E) {
return &E->key;
}
return nullptr; return nullptr;
} }
@ -333,12 +340,12 @@ Dictionary Dictionary::recursive_duplicate(bool p_deep, int recursion_count) con
if (p_deep) { if (p_deep) {
recursion_count++; recursion_count++;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
n[E.key().recursive_duplicate(true, recursion_count)] = E.value().recursive_duplicate(true, recursion_count); n[E.key.recursive_duplicate(true, recursion_count)] = E.value.recursive_duplicate(true, recursion_count);
} }
} else { } else {
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
n[E.key()] = E.value(); n[E.key] = E.value;
} }
} }

View File

@ -34,7 +34,6 @@
<member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5"> <member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5">
The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]. The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS].
</member> </member>
<member name="shadow_bias" type="float" setter="set_param" getter="get_param" overrides="Light3D" default="0.1" />
<member name="sky_mode" type="int" setter="set_sky_mode" getter="get_sky_mode" enum="DirectionalLight3D.SkyMode" default="0"> <member name="sky_mode" type="int" setter="set_sky_mode" getter="get_sky_mode" enum="DirectionalLight3D.SkyMode" default="0">
Set whether this [DirectionalLight3D] is visible in the sky, in the scene, or both in the sky and in the scene. See [enum SkyMode] for options. Set whether this [DirectionalLight3D] is visible in the sky, in the scene, or both in the sky and in the scene. See [enum SkyMode] for options.
</member> </member>

View File

@ -80,7 +80,7 @@
<member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5"> <member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5">
The intensity of the specular blob in objects affected by the light. At [code]0[/code], the light becomes a pure diffuse light. When not baking emission, this can be used to avoid unrealistic reflections when placing lights above an emissive surface. The intensity of the specular blob in objects affected by the light. At [code]0[/code], the light becomes a pure diffuse light. When not baking emission, this can be used to avoid unrealistic reflections when placing lights above an emissive surface.
</member> </member>
<member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.2"> <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.1">
Used to adjust shadow appearance. Too small a value results in self-shadowing ("shadow acne"), while too large a value causes shadows to separate from casters ("peter-panning"). Adjust as needed. Used to adjust shadow appearance. Too small a value results in self-shadowing ("shadow acne"), while too large a value causes shadows to separate from casters ("peter-panning"). Adjust as needed.
</member> </member>
<member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0"> <member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0">

View File

@ -19,6 +19,7 @@
<member name="omni_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" enum="OmniLight3D.ShadowMode" default="1"> <member name="omni_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" enum="OmniLight3D.ShadowMode" default="1">
See [enum ShadowMode]. See [enum ShadowMode].
</member> </member>
<member name="shadow_bias" type="float" setter="set_param" getter="get_param" overrides="Light3D" default="0.2" />
</members> </members>
<constants> <constants>
<constant name="SHADOW_DUAL_PARABOLOID" value="0" enum="ShadowMode"> <constant name="SHADOW_DUAL_PARABOLOID" value="0" enum="ShadowMode">

View File

@ -2077,10 +2077,9 @@ Vector<StringName> MaterialStorage::global_variable_get_list() const {
ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance.");
} }
const StringName *K = nullptr;
Vector<StringName> names; Vector<StringName> names;
while ((K = global_variables.variables.next(K))) { for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) {
names.push_back(*K); names.push_back(E.key);
} }
names.sort_custom<StringName::AlphCompare>(); names.sort_custom<StringName::AlphCompare>();
return names; return names;

View File

@ -97,9 +97,9 @@ void EditorPerformanceProfiler::_monitor_select() {
void EditorPerformanceProfiler::_monitor_draw() { void EditorPerformanceProfiler::_monitor_draw() {
Vector<StringName> active; Vector<StringName> active;
for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { for (const KeyValue<StringName, Monitor> &E : monitors) {
if (i.value().item->is_checked(0)) { if (E.value.item->is_checked(0)) {
active.push_back(i.key()); active.push_back(E.key);
} }
} }
@ -204,22 +204,22 @@ void EditorPerformanceProfiler::_monitor_draw() {
void EditorPerformanceProfiler::_build_monitor_tree() { void EditorPerformanceProfiler::_build_monitor_tree() {
Set<StringName> monitor_checked; Set<StringName> monitor_checked;
for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { for (KeyValue<StringName, Monitor> &E : monitors) {
if (i.value().item && i.value().item->is_checked(0)) { if (E.value.item && E.value.item->is_checked(0)) {
monitor_checked.insert(i.key()); monitor_checked.insert(E.key);
} }
} }
base_map.clear(); base_map.clear();
monitor_tree->get_root()->clear_children(); monitor_tree->get_root()->clear_children();
for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { for (KeyValue<StringName, Monitor> &E : monitors) {
TreeItem *base = _get_monitor_base(i.value().base); TreeItem *base = _get_monitor_base(E.value.base);
TreeItem *item = _create_monitor_item(i.value().name, base); TreeItem *item = _create_monitor_item(E.value.name, base);
item->set_checked(0, monitor_checked.has(i.key())); item->set_checked(0, monitor_checked.has(E.key));
i.value().item = item; E.value.item = item;
if (!i.value().history.is_empty()) { if (!E.value.history.is_empty()) {
i.value().update_value(i.value().history.front()->get()); E.value.update_value(E.value.history.front()->get());
} }
} }
} }
@ -252,9 +252,9 @@ void EditorPerformanceProfiler::_marker_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event; Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
Vector<StringName> active; Vector<StringName> active;
for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { for (KeyValue<StringName, Monitor> &E : monitors) {
if (i.value().item->is_checked(0)) { if (E.value.item->is_checked(0)) {
active.push_back(i.key()); active.push_back(E.key);
} }
} }
if (active.size() > 0) { if (active.size() > 0) {
@ -293,12 +293,16 @@ void EditorPerformanceProfiler::_marker_input(const Ref<InputEvent> &p_event) {
} }
void EditorPerformanceProfiler::reset() { void EditorPerformanceProfiler::reset() {
for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { HashMap<StringName, Monitor>::Iterator E = monitors.begin();
if (String(i.key()).begins_with("custom:")) { while (E != monitors.end()) {
monitors.erase(i); HashMap<StringName, Monitor>::Iterator N = E;
++N;
if (String(E->key).begins_with("custom:")) {
monitors.remove(E);
} else { } else {
i.value().reset(); E->value.reset();
} }
E = N;
} }
_build_monitor_tree(); _build_monitor_tree();
@ -308,43 +312,49 @@ void EditorPerformanceProfiler::reset() {
} }
void EditorPerformanceProfiler::update_monitors(const Vector<StringName> &p_names) { void EditorPerformanceProfiler::update_monitors(const Vector<StringName> &p_names) {
OrderedHashMap<StringName, int> names; HashMap<StringName, int> names;
for (int i = 0; i < p_names.size(); i++) { for (int i = 0; i < p_names.size(); i++) {
names.insert("custom:" + p_names[i], Performance::MONITOR_MAX + i); names.insert("custom:" + p_names[i], Performance::MONITOR_MAX + i);
} }
for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { {
if (String(i.key()).begins_with("custom:")) { HashMap<StringName, Monitor>::Iterator E = monitors.begin();
if (!names.has(i.key())) { while (E != monitors.end()) {
monitors.erase(i); HashMap<StringName, Monitor>::Iterator N = E;
++N;
if (String(E->key).begins_with("custom:")) {
if (!names.has(E->key)) {
monitors.remove(E);
} else { } else {
i.value().frame_index = names[i.key()]; E->value.frame_index = names[E->key];
names.erase(i.key()); names.erase(E->key);
} }
} }
E = N;
}
} }
for (OrderedHashMap<StringName, int>::Element i = names.front(); i; i = i.next()) { for (const KeyValue<StringName, int> &E : names) {
String name = String(i.key()).replace_first("custom:", ""); String name = String(E.key).replace_first("custom:", "");
String base = "Custom"; String base = "Custom";
if (name.get_slice_count("/") == 2) { if (name.get_slice_count("/") == 2) {
base = name.get_slicec('/', 0); base = name.get_slicec('/', 0);
name = name.get_slicec('/', 1); name = name.get_slicec('/', 1);
} }
monitors.insert(i.key(), Monitor(name, base, i.value(), Performance::MONITOR_TYPE_QUANTITY, nullptr)); monitors.insert(E.key, Monitor(name, base, E.value, Performance::MONITOR_TYPE_QUANTITY, nullptr));
} }
_build_monitor_tree(); _build_monitor_tree();
} }
void EditorPerformanceProfiler::add_profile_frame(const Vector<float> &p_values) { void EditorPerformanceProfiler::add_profile_frame(const Vector<float> &p_values) {
for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { for (KeyValue<StringName, Monitor> &E : monitors) {
float data = 0.0f; float data = 0.0f;
if (i.value().frame_index >= 0 && i.value().frame_index < p_values.size()) { if (E.value.frame_index >= 0 && E.value.frame_index < p_values.size()) {
data = p_values[i.value().frame_index]; data = p_values[E.value.frame_index];
} }
i.value().history.push_front(data); E.value.history.push_front(data);
i.value().update_value(data); E.value.update_value(data);
} }
marker_frame++; marker_frame++;
monitor_draw->update(); monitor_draw->update();

View File

@ -31,8 +31,8 @@
#ifndef EDITOR_PERFORMANCE_PROFILER_H #ifndef EDITOR_PERFORMANCE_PROFILER_H
#define EDITOR_PERFORMANCE_PROFILER_H #define EDITOR_PERFORMANCE_PROFILER_H
#include "core/templates/hash_map.h"
#include "core/templates/map.h" #include "core/templates/map.h"
#include "core/templates/ordered_hash_map.h"
#include "main/performance.h" #include "main/performance.h"
#include "scene/gui/control.h" #include "scene/gui/control.h"
#include "scene/gui/label.h" #include "scene/gui/label.h"
@ -59,7 +59,7 @@ private:
void reset(); void reset();
}; };
OrderedHashMap<StringName, Monitor> monitors; HashMap<StringName, Monitor> monitors;
Map<StringName, TreeItem *> base_map; Map<StringName, TreeItem *> base_map;
Tree *monitor_tree = nullptr; Tree *monitor_tree = nullptr;

View File

@ -57,20 +57,19 @@ float EditorCommandPalette::_score_path(const String &p_search, const String &p_
} }
void EditorCommandPalette::_update_command_search(const String &search_text) { void EditorCommandPalette::_update_command_search(const String &search_text) {
commands.get_key_list(&command_keys); ERR_FAIL_COND(commands.size() == 0);
ERR_FAIL_COND(command_keys.is_empty());
Map<String, TreeItem *> sections; Map<String, TreeItem *> sections;
TreeItem *first_section = nullptr; TreeItem *first_section = nullptr;
// Filter possible candidates. // Filter possible candidates.
Vector<CommandEntry> entries; Vector<CommandEntry> entries;
for (int i = 0; i < command_keys.size(); i++) { for (const KeyValue<String, Command> &E : commands) {
CommandEntry r; CommandEntry r;
r.key_name = command_keys[i]; r.key_name = E.key;
r.display_name = commands[r.key_name].name; r.display_name = E.value.name;
r.shortcut_text = commands[r.key_name].shortcut; r.shortcut_text = E.value.shortcut;
r.last_used = commands[r.key_name].last_used; r.last_used = E.value.last_used;
if (search_text.is_subsequence_ofn(r.display_name)) { if (search_text.is_subsequence_ofn(r.display_name)) {
if (!search_text.is_empty()) { if (!search_text.is_empty()) {
@ -180,7 +179,9 @@ void EditorCommandPalette::open_popup() {
} }
void EditorCommandPalette::get_actions_list(List<String> *p_list) const { void EditorCommandPalette::get_actions_list(List<String> *p_list) const {
commands.get_key_list(p_list); for (const KeyValue<String, Command> &E : commands) {
p_list->push_back(E.key);
}
} }
void EditorCommandPalette::remove_command(String p_key_name) { void EditorCommandPalette::remove_command(String p_key_name) {
@ -229,17 +230,14 @@ void EditorCommandPalette::execute_command(String &p_command_key) {
} }
void EditorCommandPalette::register_shortcuts_as_command() { void EditorCommandPalette::register_shortcuts_as_command() {
const String *key = nullptr; for (const KeyValue<String, Pair<String, Ref<Shortcut>>> &E : unregistered_shortcuts) {
key = unregistered_shortcuts.next(key); String command_name = E.value.first;
while (key != nullptr) { Ref<Shortcut> shortcut = E.value.second;
String command_name = unregistered_shortcuts[*key].first;
Ref<Shortcut> shortcut = unregistered_shortcuts[*key].second;
Ref<InputEventShortcut> ev; Ref<InputEventShortcut> ev;
ev.instantiate(); ev.instantiate();
ev->set_shortcut(shortcut); ev->set_shortcut(shortcut);
String shortcut_text = String(shortcut->get_as_text()); String shortcut_text = String(shortcut->get_as_text());
add_command(command_name, *key, callable_mp(EditorNode::get_singleton()->get_viewport(), &Viewport::push_unhandled_input), varray(ev, false), shortcut_text); add_command(command_name, E.key, callable_mp(EditorNode::get_singleton()->get_viewport(), &Viewport::push_unhandled_input), varray(ev, false), shortcut_text);
key = unregistered_shortcuts.next(key);
} }
unregistered_shortcuts.clear(); unregistered_shortcuts.clear();
@ -276,12 +274,10 @@ void EditorCommandPalette::_theme_changed() {
void EditorCommandPalette::_save_history() const { void EditorCommandPalette::_save_history() const {
Dictionary command_history; Dictionary command_history;
List<String> command_keys;
commands.get_key_list(&command_keys);
for (const String &key : command_keys) { for (const KeyValue<String, Command> &E : commands) {
if (commands[key].last_used > 0) { if (E.value.last_used > 0) {
command_history[key] = commands[key].last_used; command_history[E.key] = E.value.last_used;
} }
} }
EditorSettings::get_singleton()->set_project_metadata("command_palette", "command_history", command_history); EditorSettings::get_singleton()->set_project_metadata("command_palette", "command_history", command_history);

View File

@ -945,13 +945,10 @@ void EditorData::script_class_set_name(const String &p_path, const StringName &p
} }
void EditorData::script_class_save_icon_paths() { void EditorData::script_class_save_icon_paths() {
List<StringName> keys;
_script_class_icon_paths.get_key_list(&keys);
Dictionary d; Dictionary d;
for (const StringName &E : keys) { for (const KeyValue<StringName, String> &E : _script_class_icon_paths) {
if (ScriptServer::is_global_class(E)) { if (ScriptServer::is_global_class(E.key)) {
d[E] = _script_class_icon_paths[E]; d[E.key] = E.value;
} }
} }

View File

@ -31,7 +31,7 @@
#ifndef EDITOR_HELP_SEARCH_H #ifndef EDITOR_HELP_SEARCH_H
#define EDITOR_HELP_SEARCH_H #define EDITOR_HELP_SEARCH_H
#include "core/templates/ordered_hash_map.h" #include "core/templates/map.h"
#include "editor/code_editor.h" #include "editor/code_editor.h"
#include "editor/editor_help.h" #include "editor/editor_help.h"
#include "editor/editor_plugin.h" #include "editor/editor_plugin.h"

View File

@ -141,7 +141,7 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "shortcuts") { if (p_name == "shortcuts") {
Array save_array; Array save_array;
const OrderedHashMap<String, List<Ref<InputEvent>>> &builtin_list = InputMap::get_singleton()->get_builtins(); const HashMap<String, List<Ref<InputEvent>>> &builtin_list = InputMap::get_singleton()->get_builtins();
for (const KeyValue<String, Ref<Shortcut>> &shortcut_definition : shortcuts) { for (const KeyValue<String, Ref<Shortcut>> &shortcut_definition : shortcuts) {
Ref<Shortcut> sc = shortcut_definition.value; Ref<Shortcut> sc = shortcut_definition.value;
@ -244,18 +244,17 @@ struct _EVCSort {
void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const { void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
const String *k = nullptr;
Set<_EVCSort> vclist; Set<_EVCSort> vclist;
while ((k = props.next(k))) { for (const KeyValue<String, VariantContainer> &E : props) {
const VariantContainer *v = props.getptr(*k); const VariantContainer *v = &E.value;
if (v->hide_from_editor) { if (v->hide_from_editor) {
continue; continue;
} }
_EVCSort vc; _EVCSort vc;
vc.name = *k; vc.name = E.key;
vc.order = v->order; vc.order = v->order;
vc.type = v->variant.get_type(); vc.type = v->variant.get_type();
vc.save = v->save; vc.save = v->save;
@ -789,7 +788,11 @@ bool EditorSettings::_save_text_editor_theme(String p_file) {
Ref<ConfigFile> cf = memnew(ConfigFile); // hex is better? Ref<ConfigFile> cf = memnew(ConfigFile); // hex is better?
List<String> keys; List<String> keys;
props.get_key_list(&keys);
for (const KeyValue<String, VariantContainer> &E : props) {
keys.push_back(E.key);
}
keys.sort(); keys.sort();
for (const String &key : keys) { for (const String &key : keys) {
@ -1421,10 +1424,10 @@ Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const {
// If there was no override, check the default builtins to see if it has an InputEvent for the provided name. // If there was no override, check the default builtins to see if it has an InputEvent for the provided name.
if (sc.is_null()) { if (sc.is_null()) {
const OrderedHashMap<String, List<Ref<InputEvent>>>::ConstElement builtin_default = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(p_name); const HashMap<String, List<Ref<InputEvent>>>::ConstIterator builtin_default = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(p_name);
if (builtin_default) { if (builtin_default) {
sc.instantiate(); sc.instantiate();
sc->set_events_list(&builtin_default.get()); sc->set_events_list(&builtin_default->value);
sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name)); sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name));
} }
} }
@ -1562,9 +1565,9 @@ void EditorSettings::set_builtin_action_override(const String &p_name, const Arr
// Check if the provided event array is same as built-in. If it is, it does not need to be added to the overrides. // Check if the provided event array is same as built-in. If it is, it does not need to be added to the overrides.
// Note that event order must also be the same. // Note that event order must also be the same.
bool same_as_builtin = true; bool same_as_builtin = true;
OrderedHashMap<String, List<Ref<InputEvent>>>::ConstElement builtin_default = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(p_name); HashMap<String, List<Ref<InputEvent>>>::ConstIterator builtin_default = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(p_name);
if (builtin_default) { if (builtin_default) {
List<Ref<InputEvent>> builtin_events = builtin_default.get(); const List<Ref<InputEvent>> &builtin_events = builtin_default->value;
// In the editor we only care about key events. // In the editor we only care about key events.
List<Ref<InputEventKey>> builtin_key_events; List<Ref<InputEventKey>> builtin_key_events;

View File

@ -248,11 +248,11 @@ void EditorSettingsDialog::_update_shortcut_events(const String &p_path, const A
undo_redo->commit_action(); undo_redo->commit_action();
} }
Array EditorSettingsDialog::_event_list_to_array_helper(List<Ref<InputEvent>> &p_events) { Array EditorSettingsDialog::_event_list_to_array_helper(const List<Ref<InputEvent>> &p_events) {
Array events; Array events;
// Convert the list to an array, and only keep key events as this is for the editor. // Convert the list to an array, and only keep key events as this is for the editor.
for (List<Ref<InputEvent>>::Element *E = p_events.front(); E; E = E->next()) { for (const List<Ref<InputEvent>>::Element *E = p_events.front(); E; E = E->next()) {
Ref<InputEventKey> k = E->get(); Ref<InputEventKey> k = E->get();
if (k.is_valid()) { if (k.is_valid()) {
events.append(E->get()); events.append(E->get());
@ -374,10 +374,9 @@ void EditorSettingsDialog::_update_shortcuts() {
common_section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); common_section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
// Get the action map for the editor, and add each item to the "Common" section. // Get the action map for the editor, and add each item to the "Common" section.
OrderedHashMap<StringName, InputMap::Action> action_map = InputMap::get_singleton()->get_action_map(); for (const KeyValue<StringName, InputMap::Action> &E : InputMap::get_singleton()->get_action_map()) {
for (OrderedHashMap<StringName, InputMap::Action>::Element E = action_map.front(); E; E = E.next()) { const String &action_name = E.key;
String action_name = E.key(); const InputMap::Action &action = E.value;
InputMap::Action action = E.get();
Array events; // Need to get the list of events into an array so it can be set as metadata on the item. Array events; // Need to get the list of events into an array so it can be set as metadata on the item.
Vector<String> event_strings; Vector<String> event_strings;
@ -387,10 +386,10 @@ void EditorSettingsDialog::_update_shortcuts() {
continue; continue;
} }
List<Ref<InputEvent>> all_default_events = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(action_name).value(); const List<Ref<InputEvent>> &all_default_events = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(action_name)->value;
List<Ref<InputEventKey>> key_default_events; List<Ref<InputEventKey>> key_default_events;
// Remove all non-key events from the defaults. Only check keys, since we are in the editor. // Remove all non-key events from the defaults. Only check keys, since we are in the editor.
for (List<Ref<InputEvent>>::Element *I = all_default_events.front(); I; I = I->next()) { for (const List<Ref<InputEvent>>::Element *I = all_default_events.front(); I; I = I->next()) {
Ref<InputEventKey> k = I->get(); Ref<InputEventKey> k = I->get();
if (k.is_valid()) { if (k.is_valid()) {
key_default_events.push_back(k); key_default_events.push_back(k);

View File

@ -89,7 +89,7 @@ class EditorSettingsDialog : public AcceptDialog {
void _event_config_confirmed(); void _event_config_confirmed();
void _create_shortcut_treeitem(TreeItem *p_parent, const String &p_shortcut_identifier, const String &p_display, Array &p_events, bool p_allow_revert, bool p_is_common, bool p_is_collapsed); void _create_shortcut_treeitem(TreeItem *p_parent, const String &p_shortcut_identifier, const String &p_display, Array &p_events, bool p_allow_revert, bool p_is_common, bool p_is_collapsed);
Array _event_list_to_array_helper(List<Ref<InputEvent>> &p_events); Array _event_list_to_array_helper(const List<Ref<InputEvent>> &p_events);
void _update_builtin_action(const String &p_name, const Array &p_events); void _update_builtin_action(const String &p_name, const Array &p_events);
void _update_shortcut_events(const String &p_path, const Array &p_events); void _update_shortcut_events(const String &p_path, const Array &p_events);

View File

@ -1737,7 +1737,7 @@ void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, Ani
p_player->get_animation_list(&anims); p_player->get_animation_list(&anims);
Node *parent = p_player->get_parent(); Node *parent = p_player->get_parent();
ERR_FAIL_COND(parent == nullptr); ERR_FAIL_COND(parent == nullptr);
OrderedHashMap<NodePath, uint32_t> used_tracks[TRACK_CHANNEL_MAX]; HashMap<NodePath, uint32_t> used_tracks[TRACK_CHANNEL_MAX];
bool tracks_to_add = false; bool tracks_to_add = false;
static const Animation::TrackType track_types[TRACK_CHANNEL_MAX] = { Animation::TYPE_POSITION_3D, Animation::TYPE_ROTATION_3D, Animation::TYPE_SCALE_3D, Animation::TYPE_BLEND_SHAPE }; static const Animation::TrackType track_types[TRACK_CHANNEL_MAX] = { Animation::TYPE_POSITION_3D, Animation::TYPE_ROTATION_3D, Animation::TYPE_SCALE_3D, Animation::TYPE_BLEND_SHAPE };
for (const StringName &I : anims) { for (const StringName &I : anims) {
@ -1790,12 +1790,12 @@ void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, Ani
used_tracks[j][path] = pass; used_tracks[j][path] = pass;
} }
for (OrderedHashMap<NodePath, uint32_t>::Element J = used_tracks[j].front(); J; J = J.next()) { for (const KeyValue<NodePath, uint32_t> &J : used_tracks[j]) {
if (J.get() == pass) { if (J.value == pass) {
continue; continue;
} }
NodePath path = J.key(); NodePath path = J.key;
Node *n = parent->get_node(path); Node *n = parent->get_node(path);
if (j == TRACK_CHANNEL_BLEND_SHAPE) { if (j == TRACK_CHANNEL_BLEND_SHAPE) {

View File

@ -31,8 +31,8 @@
#ifndef NODE_3D_EDITOR_GIZMOS_H #ifndef NODE_3D_EDITOR_GIZMOS_H
#define NODE_3D_EDITOR_GIZMOS_H #define NODE_3D_EDITOR_GIZMOS_H
#include "core/templates/hash_map.h"
#include "core/templates/local_vector.h" #include "core/templates/local_vector.h"
#include "core/templates/ordered_hash_map.h"
#include "scene/3d/camera_3d.h" #include "scene/3d/camera_3d.h"
#include "scene/3d/node_3d.h" #include "scene/3d/node_3d.h"
#include "scene/3d/skeleton_3d.h" #include "scene/3d/skeleton_3d.h"

View File

@ -119,9 +119,9 @@ void EditorStandardSyntaxHighlighter::_update_cache() {
} }
/* Autoloads. */ /* Autoloads. */
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
const ProjectSettings::AutoloadInfo &info = E.value(); const ProjectSettings::AutoloadInfo &info = E.value;
if (info.is_singleton) { if (info.is_singleton) {
highlighter->add_keyword_color(info.name, usertype_color); highlighter->add_keyword_color(info.name, usertype_color);
} }

View File

@ -2339,8 +2339,8 @@ void ThemeTypeEditor::_update_type_list_debounced() {
update_debounce_timer->start(); update_debounce_timer->start();
} }
OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default) { HashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default) {
OrderedHashMap<StringName, bool> items; HashMap<StringName, bool> items;
List<StringName> names; List<StringName> names;
if (include_default) { if (include_default) {
@ -2367,12 +2367,12 @@ OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_
} }
List<StringName> keys; List<StringName> keys;
for (OrderedHashMap<StringName, bool>::Element E = items.front(); E; E = E.next()) { for (const KeyValue<StringName, bool> &E : items) {
keys.push_back(E.key()); keys.push_back(E.key);
} }
keys.sort_custom<StringName::AlphCompare>(); keys.sort_custom<StringName::AlphCompare>();
OrderedHashMap<StringName, bool> ordered_items; HashMap<StringName, bool> ordered_items;
for (const StringName &E : keys) { for (const StringName &E : keys) {
ordered_items[E] = items[E]; ordered_items[E] = items[E];
} }
@ -2464,18 +2464,18 @@ void ThemeTypeEditor::_update_type_items() {
color_items_list->remove_child(node); color_items_list->remove_child(node);
} }
OrderedHashMap<StringName, bool> color_items = _get_type_items(edited_type, &Theme::get_color_list, show_default); HashMap<StringName, bool> color_items = _get_type_items(edited_type, &Theme::get_color_list, show_default);
for (OrderedHashMap<StringName, bool>::Element E = color_items.front(); E; E = E.next()) { for (const KeyValue<StringName, bool> &E : color_items) {
HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_COLOR, E.key(), E.get()); HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_COLOR, E.key, E.value);
ColorPickerButton *item_editor = memnew(ColorPickerButton); ColorPickerButton *item_editor = memnew(ColorPickerButton);
item_editor->set_h_size_flags(SIZE_EXPAND_FILL); item_editor->set_h_size_flags(SIZE_EXPAND_FILL);
item_control->add_child(item_editor); item_control->add_child(item_editor);
if (E.get()) { if (E.value) {
item_editor->set_pick_color(edited_theme->get_color(E.key(), edited_type)); item_editor->set_pick_color(edited_theme->get_color(E.key, edited_type));
item_editor->connect("color_changed", callable_mp(this, &ThemeTypeEditor::_color_item_changed), varray(E.key())); item_editor->connect("color_changed", callable_mp(this, &ThemeTypeEditor::_color_item_changed), varray(E.key));
} else { } else {
item_editor->set_pick_color(Theme::get_default()->get_color(E.key(), edited_type)); item_editor->set_pick_color(Theme::get_default()->get_color(E.key, edited_type));
item_editor->set_disabled(true); item_editor->set_disabled(true);
} }
@ -2492,9 +2492,9 @@ void ThemeTypeEditor::_update_type_items() {
constant_items_list->remove_child(node); constant_items_list->remove_child(node);
} }
OrderedHashMap<StringName, bool> constant_items = _get_type_items(edited_type, &Theme::get_constant_list, show_default); HashMap<StringName, bool> constant_items = _get_type_items(edited_type, &Theme::get_constant_list, show_default);
for (OrderedHashMap<StringName, bool>::Element E = constant_items.front(); E; E = E.next()) { for (const KeyValue<StringName, bool> &E : constant_items) {
HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_CONSTANT, E.key(), E.get()); HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_CONSTANT, E.key, E.value);
SpinBox *item_editor = memnew(SpinBox); SpinBox *item_editor = memnew(SpinBox);
item_editor->set_h_size_flags(SIZE_EXPAND_FILL); item_editor->set_h_size_flags(SIZE_EXPAND_FILL);
item_editor->set_min(-100000); item_editor->set_min(-100000);
@ -2504,11 +2504,11 @@ void ThemeTypeEditor::_update_type_items() {
item_editor->set_allow_greater(true); item_editor->set_allow_greater(true);
item_control->add_child(item_editor); item_control->add_child(item_editor);
if (E.get()) { if (E.value) {
item_editor->set_value(edited_theme->get_constant(E.key(), edited_type)); item_editor->set_value(edited_theme->get_constant(E.key, edited_type));
item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_constant_item_changed), varray(E.key())); item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_constant_item_changed), varray(E.key));
} else { } else {
item_editor->set_value(Theme::get_default()->get_constant(E.key(), edited_type)); item_editor->set_value(Theme::get_default()->get_constant(E.key, edited_type));
item_editor->set_editable(false); item_editor->set_editable(false);
} }
@ -2525,25 +2525,25 @@ void ThemeTypeEditor::_update_type_items() {
font_items_list->remove_child(node); font_items_list->remove_child(node);
} }
OrderedHashMap<StringName, bool> font_items = _get_type_items(edited_type, &Theme::get_font_list, show_default); HashMap<StringName, bool> font_items = _get_type_items(edited_type, &Theme::get_font_list, show_default);
for (OrderedHashMap<StringName, bool>::Element E = font_items.front(); E; E = E.next()) { for (const KeyValue<StringName, bool> &E : font_items) {
HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_FONT, E.key(), E.get()); HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_FONT, E.key, E.value);
EditorResourcePicker *item_editor = memnew(EditorResourcePicker); EditorResourcePicker *item_editor = memnew(EditorResourcePicker);
item_editor->set_h_size_flags(SIZE_EXPAND_FILL); item_editor->set_h_size_flags(SIZE_EXPAND_FILL);
item_editor->set_base_type("Font"); item_editor->set_base_type("Font");
item_control->add_child(item_editor); item_control->add_child(item_editor);
if (E.get()) { if (E.value) {
if (edited_theme->has_font(E.key(), edited_type)) { if (edited_theme->has_font(E.key, edited_type)) {
item_editor->set_edited_resource(edited_theme->get_font(E.key(), edited_type)); item_editor->set_edited_resource(edited_theme->get_font(E.key, edited_type));
} else { } else {
item_editor->set_edited_resource(Ref<Resource>()); item_editor->set_edited_resource(Ref<Resource>());
} }
item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item));
item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_font_item_changed), varray(E.key())); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_font_item_changed), varray(E.key));
} else { } else {
if (Theme::get_default()->has_font(E.key(), edited_type)) { if (Theme::get_default()->has_font(E.key, edited_type)) {
item_editor->set_edited_resource(Theme::get_default()->get_font(E.key(), edited_type)); item_editor->set_edited_resource(Theme::get_default()->get_font(E.key, edited_type));
} else { } else {
item_editor->set_edited_resource(Ref<Resource>()); item_editor->set_edited_resource(Ref<Resource>());
} }
@ -2563,9 +2563,9 @@ void ThemeTypeEditor::_update_type_items() {
font_size_items_list->remove_child(node); font_size_items_list->remove_child(node);
} }
OrderedHashMap<StringName, bool> font_size_items = _get_type_items(edited_type, &Theme::get_font_size_list, show_default); HashMap<StringName, bool> font_size_items = _get_type_items(edited_type, &Theme::get_font_size_list, show_default);
for (OrderedHashMap<StringName, bool>::Element E = font_size_items.front(); E; E = E.next()) { for (const KeyValue<StringName, bool> &E : font_size_items) {
HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_FONT_SIZE, E.key(), E.get()); HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_FONT_SIZE, E.key, E.value);
SpinBox *item_editor = memnew(SpinBox); SpinBox *item_editor = memnew(SpinBox);
item_editor->set_h_size_flags(SIZE_EXPAND_FILL); item_editor->set_h_size_flags(SIZE_EXPAND_FILL);
item_editor->set_min(-100000); item_editor->set_min(-100000);
@ -2575,11 +2575,11 @@ void ThemeTypeEditor::_update_type_items() {
item_editor->set_allow_greater(true); item_editor->set_allow_greater(true);
item_control->add_child(item_editor); item_control->add_child(item_editor);
if (E.get()) { if (E.value) {
item_editor->set_value(edited_theme->get_font_size(E.key(), edited_type)); item_editor->set_value(edited_theme->get_font_size(E.key, edited_type));
item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_font_size_item_changed), varray(E.key())); item_editor->connect("value_changed", callable_mp(this, &ThemeTypeEditor::_font_size_item_changed), varray(E.key));
} else { } else {
item_editor->set_value(Theme::get_default()->get_font_size(E.key(), edited_type)); item_editor->set_value(Theme::get_default()->get_font_size(E.key, edited_type));
item_editor->set_editable(false); item_editor->set_editable(false);
} }
@ -2596,25 +2596,25 @@ void ThemeTypeEditor::_update_type_items() {
icon_items_list->remove_child(node); icon_items_list->remove_child(node);
} }
OrderedHashMap<StringName, bool> icon_items = _get_type_items(edited_type, &Theme::get_icon_list, show_default); HashMap<StringName, bool> icon_items = _get_type_items(edited_type, &Theme::get_icon_list, show_default);
for (OrderedHashMap<StringName, bool>::Element E = icon_items.front(); E; E = E.next()) { for (const KeyValue<StringName, bool> &E : icon_items) {
HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_ICON, E.key(), E.get()); HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_ICON, E.key, E.value);
EditorResourcePicker *item_editor = memnew(EditorResourcePicker); EditorResourcePicker *item_editor = memnew(EditorResourcePicker);
item_editor->set_h_size_flags(SIZE_EXPAND_FILL); item_editor->set_h_size_flags(SIZE_EXPAND_FILL);
item_editor->set_base_type("Texture2D"); item_editor->set_base_type("Texture2D");
item_control->add_child(item_editor); item_control->add_child(item_editor);
if (E.get()) { if (E.value) {
if (edited_theme->has_icon(E.key(), edited_type)) { if (edited_theme->has_icon(E.key, edited_type)) {
item_editor->set_edited_resource(edited_theme->get_icon(E.key(), edited_type)); item_editor->set_edited_resource(edited_theme->get_icon(E.key, edited_type));
} else { } else {
item_editor->set_edited_resource(Ref<Resource>()); item_editor->set_edited_resource(Ref<Resource>());
} }
item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item));
item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_icon_item_changed), varray(E.key())); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_icon_item_changed), varray(E.key));
} else { } else {
if (Theme::get_default()->has_icon(E.key(), edited_type)) { if (Theme::get_default()->has_icon(E.key, edited_type)) {
item_editor->set_edited_resource(Theme::get_default()->get_icon(E.key(), edited_type)); item_editor->set_edited_resource(Theme::get_default()->get_icon(E.key, edited_type));
} else { } else {
item_editor->set_edited_resource(Ref<Resource>()); item_editor->set_edited_resource(Ref<Resource>());
} }
@ -2664,26 +2664,26 @@ void ThemeTypeEditor::_update_type_items() {
stylebox_items_list->add_child(memnew(HSeparator)); stylebox_items_list->add_child(memnew(HSeparator));
} }
OrderedHashMap<StringName, bool> stylebox_items = _get_type_items(edited_type, &Theme::get_stylebox_list, show_default); HashMap<StringName, bool> stylebox_items = _get_type_items(edited_type, &Theme::get_stylebox_list, show_default);
for (OrderedHashMap<StringName, bool>::Element E = stylebox_items.front(); E; E = E.next()) { for (const KeyValue<StringName, bool> &E : stylebox_items) {
if (leading_stylebox.pinned && leading_stylebox.item_name == E.key()) { if (leading_stylebox.pinned && leading_stylebox.item_name == E.key) {
continue; continue;
} }
HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_STYLEBOX, E.key(), E.get()); HBoxContainer *item_control = _create_property_control(Theme::DATA_TYPE_STYLEBOX, E.key, E.value);
EditorResourcePicker *item_editor = memnew(EditorResourcePicker); EditorResourcePicker *item_editor = memnew(EditorResourcePicker);
item_editor->set_h_size_flags(SIZE_EXPAND_FILL); item_editor->set_h_size_flags(SIZE_EXPAND_FILL);
item_editor->set_stretch_ratio(1.5); item_editor->set_stretch_ratio(1.5);
item_editor->set_base_type("StyleBox"); item_editor->set_base_type("StyleBox");
if (E.get()) { if (E.value) {
if (edited_theme->has_stylebox(E.key(), edited_type)) { if (edited_theme->has_stylebox(E.key, edited_type)) {
item_editor->set_edited_resource(edited_theme->get_stylebox(E.key(), edited_type)); item_editor->set_edited_resource(edited_theme->get_stylebox(E.key, edited_type));
} else { } else {
item_editor->set_edited_resource(Ref<Resource>()); item_editor->set_edited_resource(Ref<Resource>());
} }
item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item));
item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(E.key())); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(E.key));
Button *pin_leader_button = memnew(Button); Button *pin_leader_button = memnew(Button);
pin_leader_button->set_flat(true); pin_leader_button->set_flat(true);
@ -2691,10 +2691,10 @@ void ThemeTypeEditor::_update_type_items() {
pin_leader_button->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"))); pin_leader_button->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")));
pin_leader_button->set_tooltip(TTR("Pin this StyleBox as a main style. Editing its properties will update the same properties in all other StyleBoxes of this type.")); pin_leader_button->set_tooltip(TTR("Pin this StyleBox as a main style. Editing its properties will update the same properties in all other StyleBoxes of this type."));
item_control->add_child(pin_leader_button); item_control->add_child(pin_leader_button);
pin_leader_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_on_pin_leader_button_pressed), varray(item_editor, E.key())); pin_leader_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_on_pin_leader_button_pressed), varray(item_editor, E.key));
} else { } else {
if (Theme::get_default()->has_stylebox(E.key(), edited_type)) { if (Theme::get_default()->has_stylebox(E.key, edited_type)) {
item_editor->set_edited_resource(Theme::get_default()->get_stylebox(E.key(), edited_type)); item_editor->set_edited_resource(Theme::get_default()->get_stylebox(E.key, edited_type));
} else { } else {
item_editor->set_edited_resource(Ref<Resource>()); item_editor->set_edited_resource(Ref<Resource>());
} }

View File

@ -363,7 +363,7 @@ class ThemeTypeEditor : public MarginContainer {
VBoxContainer *_create_item_list(Theme::DataType p_data_type); VBoxContainer *_create_item_list(Theme::DataType p_data_type);
void _update_type_list(); void _update_type_list();
void _update_type_list_debounced(); void _update_type_list_debounced();
OrderedHashMap<StringName, bool> _get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default); HashMap<StringName, bool> _get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default);
HBoxContainer *_create_property_control(Theme::DataType p_data_type, String p_item_name, bool p_editable); HBoxContainer *_create_property_control(Theme::DataType p_data_type, String p_item_name, bool p_editable);
void _add_focusable(Control *p_control); void _add_focusable(Control *p_control);
void _update_type_items(); void _update_type_items();

View File

@ -39,7 +39,7 @@ POTGenerator *POTGenerator::singleton = nullptr;
#ifdef DEBUG_POT #ifdef DEBUG_POT
void POTGenerator::_print_all_translation_strings() { void POTGenerator::_print_all_translation_strings() {
for (OrderedHashMap<String, Vector<POTGenerator::MsgidData>>::Element E = all_translation_strings.front(); E; E = E.next()) { for (HashMap<String, Vector<POTGenerator::MsgidData>>::Element E = all_translation_strings.front(); E; E = E.next()) {
Vector<MsgidData> v_md = all_translation_strings[E.key()]; Vector<MsgidData> v_md = all_translation_strings[E.key()];
for (int i = 0; i < v_md.size(); i++) { for (int i = 0; i < v_md.size(); i++) {
print_line("++++++"); print_line("++++++");
@ -121,9 +121,9 @@ void POTGenerator::_write_to_pot(const String &p_file) {
file->store_string(header); file->store_string(header);
for (OrderedHashMap<String, Vector<MsgidData>>::Element E_pair = all_translation_strings.front(); E_pair; E_pair = E_pair.next()) { for (const KeyValue<String, Vector<MsgidData>> &E_pair : all_translation_strings) {
String msgid = E_pair.key(); String msgid = E_pair.key;
Vector<MsgidData> v_msgid_data = E_pair.value(); const Vector<MsgidData> &v_msgid_data = E_pair.value;
for (int i = 0; i < v_msgid_data.size(); i++) { for (int i = 0; i < v_msgid_data.size(); i++) {
String context = v_msgid_data[i].ctx; String context = v_msgid_data[i].ctx;
String plural = v_msgid_data[i].plural; String plural = v_msgid_data[i].plural;

View File

@ -32,7 +32,7 @@
#define POT_GENERATOR_H #define POT_GENERATOR_H
#include "core/io/file_access.h" #include "core/io/file_access.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
#include "core/templates/set.h" #include "core/templates/set.h"
//#define DEBUG_POT //#define DEBUG_POT
@ -46,7 +46,7 @@ class POTGenerator {
Set<String> locations; Set<String> locations;
}; };
// Store msgid as key and the additional data around the msgid - if it's under a context, has plurals and its file locations. // Store msgid as key and the additional data around the msgid - if it's under a context, has plurals and its file locations.
OrderedHashMap<String, Vector<MsgidData>> all_translation_strings; HashMap<String, Vector<MsgidData>> all_translation_strings;
void _write_to_pot(const String &p_file); void _write_to_pot(const String &p_file);
void _write_msgid(Ref<FileAccess> r_file, const String &p_id, bool p_plural); void _write_msgid(Ref<FileAccess> r_file, const String &p_id, bool p_plural);

View File

@ -420,7 +420,7 @@ void ProjectSettingsEditor::_action_reordered(const String &p_action_name, const
Variant target_value = ps->get(target_name); Variant target_value = ps->get(target_name);
List<PropertyInfo> props; List<PropertyInfo> props;
OrderedHashMap<String, Variant> action_values; HashMap<String, Variant> action_values;
ProjectSettings::get_singleton()->get_property_list(&props); ProjectSettings::get_singleton()->get_property_list(&props);
undo_redo->create_action(TTR("Update Input Action Order")); undo_redo->create_action(TTR("Update Input Action Order"));
@ -437,9 +437,9 @@ void ProjectSettingsEditor::_action_reordered(const String &p_action_name, const
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", prop.name); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", prop.name);
} }
for (OrderedHashMap<String, Variant>::Element E = action_values.front(); E; E = E.next()) { for (const KeyValue<String, Variant> &E : action_values) {
String name = E.key(); String name = E.key;
Variant value = E.get(); const Variant &value = E.value;
if (name == target_name) { if (name == target_name) {
if (p_before) { if (p_before) {

View File

@ -2329,11 +2329,11 @@ bool Main::start() {
if (!project_manager && !editor) { // game if (!project_manager && !editor) { // game
if (!game_path.is_empty() || !script.is_empty()) { if (!game_path.is_empty() || !script.is_empty()) {
//autoload //autoload
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
//first pass, add the constants so they exist before any script is loaded //first pass, add the constants so they exist before any script is loaded
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
const ProjectSettings::AutoloadInfo &info = E.get(); const ProjectSettings::AutoloadInfo &info = E.value;
if (info.is_singleton) { if (info.is_singleton) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) { for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@ -2344,8 +2344,8 @@ bool Main::start() {
//second pass, load into global constants //second pass, load into global constants
List<Node *> to_add; List<Node *> to_add;
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
const ProjectSettings::AutoloadInfo &info = E.get(); const ProjectSettings::AutoloadInfo &info = E.value;
Ref<Resource> res = ResourceLoader::load(info.path); Ref<Resource> res = ResourceLoader::load(info.path);
ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path); ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path);

View File

@ -247,8 +247,8 @@ Array Performance::get_custom_monitor_names() {
Array return_array; Array return_array;
return_array.resize(_monitor_map.size()); return_array.resize(_monitor_map.size());
int index = 0; int index = 0;
for (OrderedHashMap<StringName, MonitorCall>::Element i = _monitor_map.front(); i; i = i.next()) { for (KeyValue<StringName, MonitorCall> i : _monitor_map) {
return_array.set(index, i.key()); return_array.set(index, i.key);
index++; index++;
} }
return return_array; return return_array;

View File

@ -32,7 +32,7 @@
#define PERFORMANCE_H #define PERFORMANCE_H
#include "core/object/class_db.h" #include "core/object/class_db.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
#define PERF_WARN_OFFLINE_FUNCTION #define PERF_WARN_OFFLINE_FUNCTION
#define PERF_WARN_PROCESS_SYNC #define PERF_WARN_PROCESS_SYNC
@ -58,7 +58,7 @@ class Performance : public Object {
Variant call(bool &r_error, String &r_error_message); Variant call(bool &r_error, String &r_error_message);
}; };
OrderedHashMap<StringName, MonitorCall> _monitor_map; HashMap<StringName, MonitorCall> _monitor_map;
uint64_t _monitor_modification_time; uint64_t _monitor_modification_time;
public: public:

View File

@ -510,9 +510,8 @@ void GDScriptSyntaxHighlighter::_update_cache() {
} }
/* Autoloads. */ /* Autoloads. */
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { const ProjectSettings::AutoloadInfo &info = E.value;
const ProjectSettings::AutoloadInfo &info = E.value();
if (info.is_singleton) { if (info.is_singleton) {
keywords[info.name] = usertype_color; keywords[info.name] = usertype_color;
} }

View File

@ -4218,13 +4218,11 @@ Error GDScriptAnalyzer::resolve_program() {
resolve_class_interface(parser->head); resolve_class_interface(parser->head);
resolve_class_body(parser->head); resolve_class_body(parser->head);
List<String> parser_keys; for (KeyValue<String, Ref<GDScriptParserRef>> &K : depended_parsers) {
depended_parsers.get_key_list(&parser_keys); if (K.value.is_null()) {
for (const String &E : parser_keys) {
if (depended_parsers[E].is_null()) {
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
depended_parsers[E]->raise_status(GDScriptParserRef::FULLY_SOLVED); K.value->raise_status(GDScriptParserRef::FULLY_SOLVED);
} }
return parser->errors.is_empty() ? OK : ERR_PARSE_ERROR; return parser->errors.is_empty() ? OK : ERR_PARSE_ERROR;
} }

View File

@ -196,10 +196,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() {
function->_constant_count = constant_map.size(); function->_constant_count = constant_map.size();
function->constants.resize(constant_map.size()); function->constants.resize(constant_map.size());
function->_constants_ptr = function->constants.ptrw(); function->_constants_ptr = function->constants.ptrw();
const Variant *K = nullptr; for (const KeyValue<Variant, int> &K : constant_map) {
while ((K = constant_map.next(K))) { function->constants.write[K.value] = K.key;
int idx = constant_map[*K];
function->constants.write[idx] = *K;
} }
} else { } else {
function->_constants_ptr = nullptr; function->_constants_ptr = nullptr;

View File

@ -336,7 +336,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) { if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
// If it's an autoload singleton, we postpone to load it at runtime. // If it's an autoload singleton, we postpone to load it at runtime.
// This is so one autoload doesn't try to load another before it's compiled. // This is so one autoload doesn't try to load another before it's compiled.
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
if (autoloads.has(identifier) && autoloads[identifier].is_singleton) { if (autoloads.has(identifier) && autoloads[identifier].is_singleton) {
GDScriptCodeGenerator::Address global = codegen.add_temporary(_gdtype_from_datatype(in->get_datatype())); GDScriptCodeGenerator::Address global = codegen.add_temporary(_gdtype_from_datatype(in->get_datatype()));
int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier]; int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier];

View File

@ -851,9 +851,10 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio
} }
// Autoload singletons // Autoload singletons
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) {
const ProjectSettings::AutoloadInfo &info = E.get(); for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
const ProjectSettings::AutoloadInfo &info = E.value;
if (!info.is_singleton || info.path.get_extension().to_lower() != "gd") { if (!info.is_singleton || info.path.get_extension().to_lower() != "gd") {
continue; continue;
} }
@ -1219,12 +1220,11 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context
r_result.insert(option.display, option); r_result.insert(option.display, option);
} }
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { if (!E.value.is_singleton) {
if (!E.value().is_singleton) {
continue; continue;
} }
ScriptLanguage::CodeCompletionOption option(E.key(), ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT); ScriptLanguage::CodeCompletionOption option(E.key, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT);
r_result.insert(option.display, option); r_result.insert(option.display, option);
} }
@ -1517,12 +1517,10 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[which]); r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[which]);
found = true; found = true;
} else { } else {
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
String name = E.key;
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) {
String name = E.key();
if (name == which) { if (name == which) {
String script = E.value().path; String script = E.value.path;
if (!script.begins_with("res://")) { if (!script.begins_with("res://")) {
script = "res://" + script; script = "res://" + script;
@ -2882,10 +2880,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
} }
// Get autoloads. // Get autoloads.
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
String path = "/root/" + E.key;
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) {
String path = "/root/" + E.key();
ScriptLanguage::CodeCompletionOption option(path.quote(quote_style), ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH); ScriptLanguage::CodeCompletionOption option(path.quote(quote_style), ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH);
options.insert(option.display, option); options.insert(option.display, option);
} }

View File

@ -100,10 +100,8 @@ void GDScriptParser::cleanup() {
} }
void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const { void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const {
List<StringName> keys; for (const KeyValue<StringName, AnnotationInfo> &E : valid_annotations) {
valid_annotations.get_key_list(&keys); r_annotations->push_back(E.value.info);
for (const StringName &E : keys) {
r_annotations->push_back(valid_annotations[E].info);
} }
} }
@ -1894,11 +1892,8 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
SuiteNode *suite = alloc_node<SuiteNode>(); SuiteNode *suite = alloc_node<SuiteNode>();
if (branch->patterns.size() > 0) { if (branch->patterns.size() > 0) {
List<StringName> binds; for (const KeyValue<StringName, IdentifierNode *> &E : branch->patterns[0]->binds) {
branch->patterns[0]->binds.get_key_list(&binds); SuiteNode::Local local(E.value, current_function);
for (const StringName &E : binds) {
SuiteNode::Local local(branch->patterns[0]->binds[E], current_function);
local.type = SuiteNode::Local::PATTERN_BIND; local.type = SuiteNode::Local::PATTERN_BIND;
suite->add_local(local); suite->add_local(local);
} }
@ -3566,14 +3561,15 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
variable->export_info.hint = PROPERTY_HINT_ENUM; variable->export_info.hint = PROPERTY_HINT_ENUM;
String enum_hint_string; String enum_hint_string;
for (OrderedHashMap<StringName, int>::Element E = export_type.enum_values.front(); E; E = E.next()) { bool first = true;
enum_hint_string += E.key().operator String().capitalize().xml_escape(); for (const KeyValue<StringName, int> &E : export_type.enum_values) {
enum_hint_string += ":"; if (!first) {
enum_hint_string += String::num_int64(E.value()).xml_escape();
if (E.next()) {
enum_hint_string += ","; enum_hint_string += ",";
first = false;
} }
enum_hint_string += E.key.operator String().capitalize().xml_escape();
enum_hint_string += ":";
enum_hint_string += String::num_int64(E.value).xml_escape();
} }
variable->export_info.hint_string = enum_hint_string; variable->export_info.hint_string = enum_hint_string;

View File

@ -132,7 +132,7 @@ public:
ClassNode *class_type = nullptr; ClassNode *class_type = nullptr;
MethodInfo method_info; // For callable/signals. MethodInfo method_info; // For callable/signals.
OrderedHashMap<StringName, int> enum_values; // For enums. HashMap<StringName, int> enum_values; // For enums.
_FORCE_INLINE_ bool is_set() const { return kind != UNRESOLVED; } _FORCE_INLINE_ bool is_set() const { return kind != UNRESOLVED; }
_FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; } _FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; }

View File

@ -89,16 +89,16 @@ void ExtendGDScriptParser::update_symbols() {
for (int i = 0; i < class_symbol.children.size(); i++) { for (int i = 0; i < class_symbol.children.size(); i++) {
const lsp::DocumentSymbol &symbol = class_symbol.children[i]; const lsp::DocumentSymbol &symbol = class_symbol.children[i];
members.set(symbol.name, &symbol); members.insert(symbol.name, &symbol);
// cache level one inner classes // cache level one inner classes
if (symbol.kind == lsp::SymbolKind::Class) { if (symbol.kind == lsp::SymbolKind::Class) {
ClassMembers inner_class; ClassMembers inner_class;
for (int j = 0; j < symbol.children.size(); j++) { for (int j = 0; j < symbol.children.size(); j++) {
const lsp::DocumentSymbol &s = symbol.children[j]; const lsp::DocumentSymbol &s = symbol.children[j];
inner_class.set(s.name, &s); inner_class.insert(s.name, &s);
} }
inner_classes.set(symbol.name, inner_class); inner_classes.insert(symbol.name, inner_class);
} }
} }
} }
@ -661,30 +661,22 @@ const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const
const Array &ExtendGDScriptParser::get_member_completions() { const Array &ExtendGDScriptParser::get_member_completions() {
if (member_completions.is_empty()) { if (member_completions.is_empty()) {
const String *name = members.next(nullptr); for (const KeyValue<String, const lsp::DocumentSymbol *> &E : members) {
while (name) { const lsp::DocumentSymbol *symbol = E.value;
const lsp::DocumentSymbol *symbol = members.get(*name);
lsp::CompletionItem item = symbol->make_completion_item(); lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(path, *name); item.data = JOIN_SYMBOLS(path, E.key);
member_completions.push_back(item.to_json()); member_completions.push_back(item.to_json());
name = members.next(name);
} }
const String *_class = inner_classes.next(nullptr); for (const KeyValue<String, ClassMembers> &E : inner_classes) {
while (_class) { const ClassMembers *inner_class = &E.value;
const ClassMembers *inner_class = inner_classes.getptr(*_class);
const String *member_name = inner_class->next(nullptr); for (const KeyValue<String, const lsp::DocumentSymbol *> &F : *inner_class) {
while (member_name) { const lsp::DocumentSymbol *symbol = F.value;
const lsp::DocumentSymbol *symbol = inner_class->get(*member_name);
lsp::CompletionItem item = symbol->make_completion_item(); lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(path, JOIN_SYMBOLS(*_class, *member_name)); item.data = JOIN_SYMBOLS(path, JOIN_SYMBOLS(E.key, F.key));
member_completions.push_back(item.to_json()); member_completions.push_back(item.to_json());
member_name = inner_class->next(member_name);
} }
_class = inner_classes.next(_class);
} }
} }

View File

@ -126,7 +126,7 @@ Error GDScriptLanguageProtocol::on_client_connected() {
ERR_FAIL_COND_V_MSG(clients.size() >= LSP_MAX_CLIENTS, FAILED, "Max client limits reached"); ERR_FAIL_COND_V_MSG(clients.size() >= LSP_MAX_CLIENTS, FAILED, "Max client limits reached");
Ref<LSPeer> peer = memnew(LSPeer); Ref<LSPeer> peer = memnew(LSPeer);
peer->connection = tcp_peer; peer->connection = tcp_peer;
clients.set(next_client_id, peer); clients.insert(next_client_id, peer);
next_client_id++; next_client_id++;
EditorNode::get_log()->add_message("[LSP] Connection Taken", EditorLog::MSG_TYPE_EDITOR); EditorNode::get_log()->add_message("[LSP] Connection Taken", EditorLog::MSG_TYPE_EDITOR);
return OK; return OK;
@ -229,28 +229,33 @@ void GDScriptLanguageProtocol::poll() {
if (server->is_connection_available()) { if (server->is_connection_available()) {
on_client_connected(); on_client_connected();
} }
const int *id = nullptr;
while ((id = clients.next(id))) { HashMap<int, Ref<LSPeer>>::Iterator E = clients.begin();
Ref<LSPeer> peer = clients.get(*id); while (E != clients.end()) {
Ref<LSPeer> peer = E->value;
StreamPeerTCP::Status status = peer->connection->get_status(); StreamPeerTCP::Status status = peer->connection->get_status();
if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) { if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) {
on_client_disconnected(*id); on_client_disconnected(E->key);
id = nullptr; E = clients.begin();
continue;
} else { } else {
if (peer->connection->get_available_bytes() > 0) { if (peer->connection->get_available_bytes() > 0) {
latest_client_id = *id; latest_client_id = E->key;
Error err = peer->handle_data(); Error err = peer->handle_data();
if (err != OK && err != ERR_BUSY) { if (err != OK && err != ERR_BUSY) {
on_client_disconnected(*id); on_client_disconnected(E->key);
id = nullptr; E = clients.begin();
continue;
} }
} }
Error err = peer->send_data(); Error err = peer->send_data();
if (err != OK && err != ERR_BUSY) { if (err != OK && err != ERR_BUSY) {
on_client_disconnected(*id); on_client_disconnected(E->key);
id = nullptr; E = clients.begin();
continue;
} }
} }
++E;
} }
} }
@ -259,9 +264,8 @@ Error GDScriptLanguageProtocol::start(int p_port, const IPAddress &p_bind_ip) {
} }
void GDScriptLanguageProtocol::stop() { void GDScriptLanguageProtocol::stop() {
const int *id = nullptr; for (const KeyValue<int, Ref<LSPeer>> &E : clients) {
while ((id = clients.next(id))) { Ref<LSPeer> peer = clients.get(E.key);
Ref<LSPeer> peer = clients.get(*id);
peer->connection->disconnect_from_host(); peer->connection->disconnect_from_host();
} }

View File

@ -109,23 +109,15 @@ void GDScriptTextDocument::notify_client_show_symbol(const lsp::DocumentSymbol *
void GDScriptTextDocument::initialize() { void GDScriptTextDocument::initialize() {
if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
const HashMap<StringName, ClassMembers> &native_members = GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members; for (const KeyValue<StringName, ClassMembers> &E : GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members) {
const ClassMembers &members = E.value;
const StringName *class_ptr = native_members.next(nullptr); for (const KeyValue<String, const lsp::DocumentSymbol *> &F : members) {
while (class_ptr) { const lsp::DocumentSymbol *symbol = members.get(F.key);
const ClassMembers &members = native_members.get(*class_ptr);
const String *name = members.next(nullptr);
while (name) {
const lsp::DocumentSymbol *symbol = members.get(*name);
lsp::CompletionItem item = symbol->make_completion_item(); lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(String(*class_ptr), *name); item.data = JOIN_SYMBOLS(String(E.key), F.key);
native_member_completions.push_back(item.to_json()); native_member_completions.push_back(item.to_json());
name = members.next(name);
} }
class_ptr = native_members.next(class_ptr);
} }
} }
} }

View File

@ -404,9 +404,9 @@ Error GDScriptWorkspace::initialize() {
const lsp::DocumentSymbol &class_symbol = E.value; const lsp::DocumentSymbol &class_symbol = E.value;
for (int i = 0; i < class_symbol.children.size(); i++) { for (int i = 0; i < class_symbol.children.size(); i++) {
const lsp::DocumentSymbol &symbol = class_symbol.children[i]; const lsp::DocumentSymbol &symbol = class_symbol.children[i];
members.set(symbol.name, &symbol); members.insert(symbol.name, &symbol);
} }
native_members.set(E.key, members); native_members.insert(E.key, members);
} }
// cache member completions // cache member completions
@ -682,13 +682,11 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
Vector2i offset; Vector2i offset;
symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset); symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset);
const StringName *class_ptr = native_members.next(nullptr); for (const KeyValue<StringName, ClassMembers> &E : native_members) {
while (class_ptr) { const ClassMembers &members = native_members.get(E.key);
const ClassMembers &members = native_members.get(*class_ptr);
if (const lsp::DocumentSymbol *const *symbol = members.getptr(symbol_identifier)) { if (const lsp::DocumentSymbol *const *symbol = members.getptr(symbol_identifier)) {
r_list.push_back(*symbol); r_list.push_back(*symbol);
} }
class_ptr = native_members.next(class_ptr);
} }
for (const KeyValue<String, ExtendGDScriptParser *> &E : scripts) { for (const KeyValue<String, ExtendGDScriptParser *> &E : scripts) {
@ -698,15 +696,11 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
r_list.push_back(*symbol); r_list.push_back(*symbol);
} }
const HashMap<String, ClassMembers> &inner_classes = script->get_inner_classes(); for (const KeyValue<String, ClassMembers> &F : script->get_inner_classes()) {
const String *_class = inner_classes.next(nullptr); const ClassMembers *inner_class = &F.value;
while (_class) {
const ClassMembers *inner_class = inner_classes.getptr(*_class);
if (const lsp::DocumentSymbol *const *symbol = inner_class->getptr(symbol_identifier)) { if (const lsp::DocumentSymbol *const *symbol = inner_class->getptr(symbol_identifier)) {
r_list.push_back(*symbol); r_list.push_back(*symbol);
} }
_class = inner_classes.next(_class);
} }
} }
} }

View File

@ -48,11 +48,11 @@
namespace GDScriptTests { namespace GDScriptTests {
void init_autoloads() { void init_autoloads() {
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
// First pass, add the constants so they exist before any script is loaded. // First pass, add the constants so they exist before any script is loaded.
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
const ProjectSettings::AutoloadInfo &info = E.get(); const ProjectSettings::AutoloadInfo &info = E.value;
if (info.is_singleton) { if (info.is_singleton) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) { for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@ -62,8 +62,8 @@ void init_autoloads() {
} }
// Second pass, load into global constants. // Second pass, load into global constants.
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
const ProjectSettings::AutoloadInfo &info = E.get(); const ProjectSettings::AutoloadInfo &info = E.value;
if (!info.is_singleton) { if (!info.is_singleton) {
// Skip non-singletons since we don't have a scene tree here anyway. // Skip non-singletons since we don't have a scene tree here anyway.

View File

@ -40,17 +40,12 @@
void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
Dictionary classes_dict; Dictionary classes_dict;
List<StringName> names; List<StringName> class_list;
ClassDB::get_class_list(&class_list);
// Must be alphabetically sorted for hash to compute.
class_list.sort_custom<StringName::AlphCompare>();
const StringName *k = nullptr; for (const StringName &E : class_list) {
while ((k = ClassDB::classes.next(k))) {
names.push_back(*k);
}
//must be alphabetically sorted for hash to compute
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
ClassDB::ClassInfo *t = ClassDB::classes.getptr(E); ClassDB::ClassInfo *t = ClassDB::classes.getptr(E);
ERR_FAIL_COND(!t); ERR_FAIL_COND(!t);
if (t->api != p_api || !t->exposed) { if (t->api != p_api || !t->exposed) {
@ -66,10 +61,8 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, MethodBind *> &F : t->method_map) {
String name = F.key.operator String();
while ((k = t->method_map.next(k))) {
String name = k->operator String();
ERR_CONTINUE(name.is_empty()); ERR_CONTINUE(name.is_empty());
@ -77,7 +70,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
continue; // Ignore non-virtual methods that start with an underscore continue; // Ignore non-virtual methods that start with an underscore
} }
snames.push_back(*k); snames.push_back(F.key);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();
@ -131,10 +124,8 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, int> &F : t->constant_map) {
snames.push_back(F.key);
while ((k = t->constant_map.next(k))) {
snames.push_back(*k);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();
@ -158,10 +149,8 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, MethodInfo> &F : t->signal_map) {
snames.push_back(F.key);
while ((k = t->signal_map.next(k))) {
snames.push_back(*k);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();
@ -193,10 +182,8 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames; List<StringName> snames;
k = nullptr; for (const KeyValue<StringName, ClassDB::PropertySetGet> &F : t->property_setget) {
snames.push_back(F.key);
while ((k = t->property_setget.next(k))) {
snames.push_back(*k);
} }
snames.sort_custom<StringName::AlphCompare>(); snames.sort_custom<StringName::AlphCompare>();

View File

@ -1798,8 +1798,8 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName,
void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
List<PropertyInfo> props; List<PropertyInfo> props;
for (OrderedHashMap<StringName, PropertyInfo>::ConstElement E = script->member_info.front(); E; E = E.next()) { for (const KeyValue<StringName, PropertyInfo> &E : script->member_info) {
props.push_front(E.value()); props.push_front(E.value);
} }
// Call _get_property_list // Call _get_property_list
@ -3491,8 +3491,8 @@ Ref<Script> CSharpScript::get_base_script() const {
void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const { void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const {
List<PropertyInfo> props; List<PropertyInfo> props;
for (OrderedHashMap<StringName, PropertyInfo>::ConstElement E = member_info.front(); E; E = E.next()) { for (const KeyValue<StringName, PropertyInfo> &E : member_info) {
props.push_front(E.value()); props.push_front(E.value);
} }
for (const PropertyInfo &prop : props) { for (const PropertyInfo &prop : props) {

View File

@ -154,7 +154,7 @@ private:
Set<StringName> exported_members_names; Set<StringName> exported_members_names;
#endif #endif
OrderedHashMap<StringName, PropertyInfo> member_info; HashMap<StringName, PropertyInfo> member_info;
void _clear(); void _clear();

View File

@ -1078,8 +1078,8 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
compile_items.push_back(output_file); compile_items.push_back(output_file);
} }
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { for (const KeyValue<StringName, TypeInterface> &E : obj_types) {
const TypeInterface &itype = E.get(); const TypeInterface &itype = E.value;
if (itype.api_type == ClassDB::API_EDITOR) { if (itype.api_type == ClassDB::API_EDITOR) {
continue; continue;
@ -1187,8 +1187,8 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
Vector<String> compile_items; Vector<String> compile_items;
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { for (const KeyValue<StringName, TypeInterface> &E : obj_types) {
const TypeInterface &itype = E.get(); const TypeInterface &itype = E.value;
if (itype.api_type != ClassDB::API_EDITOR) { if (itype.api_type != ClassDB::API_EDITOR) {
continue; continue;
@ -1573,9 +1573,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
// Search it in base types too // Search it in base types too
const TypeInterface *current_type = &p_itype; const TypeInterface *current_type = &p_itype;
while (!setter && current_type->base_name != StringName()) { while (!setter && current_type->base_name != StringName()) {
OrderedHashMap<StringName, TypeInterface>::Element base_match = obj_types.find(current_type->base_name); HashMap<StringName, TypeInterface>::Iterator base_match = obj_types.find(current_type->base_name);
ERR_FAIL_COND_V_MSG(!base_match, ERR_BUG, "Type not found '" + current_type->base_name + "'. Inherited by '" + current_type->name + "'."); ERR_FAIL_COND_V_MSG(!base_match, ERR_BUG, "Type not found '" + current_type->base_name + "'. Inherited by '" + current_type->name + "'.");
current_type = &base_match.get(); current_type = &base_match->value;
setter = current_type->find_method_by_name(p_iprop.setter); setter = current_type->find_method_by_name(p_iprop.setter);
} }
@ -1584,9 +1584,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
// Search it in base types too // Search it in base types too
current_type = &p_itype; current_type = &p_itype;
while (!getter && current_type->base_name != StringName()) { while (!getter && current_type->base_name != StringName()) {
OrderedHashMap<StringName, TypeInterface>::Element base_match = obj_types.find(current_type->base_name); HashMap<StringName, TypeInterface>::Iterator base_match = obj_types.find(current_type->base_name);
ERR_FAIL_COND_V_MSG(!base_match, ERR_BUG, "Type not found '" + current_type->base_name + "'. Inherited by '" + current_type->name + "'."); ERR_FAIL_COND_V_MSG(!base_match, ERR_BUG, "Type not found '" + current_type->base_name + "'. Inherited by '" + current_type->name + "'.");
current_type = &base_match.get(); current_type = &base_match->value;
getter = current_type->find_method_by_name(p_iprop.getter); getter = current_type->find_method_by_name(p_iprop.getter);
} }
@ -2096,8 +2096,8 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
generated_icall_funcs.clear(); generated_icall_funcs.clear();
for (OrderedHashMap<StringName, TypeInterface>::Element type_elem = obj_types.front(); type_elem; type_elem = type_elem.next()) { for (const KeyValue<StringName, TypeInterface> &type_elem : obj_types) {
const TypeInterface &itype = type_elem.get(); const TypeInterface &itype = type_elem.value;
bool is_derived_type = itype.base_name != StringName(); bool is_derived_type = itype.base_name != StringName();
@ -2474,10 +2474,10 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_null(con
return &builtin_type_match->get(); return &builtin_type_match->get();
} }
const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_typeref.cname); const HashMap<StringName, TypeInterface>::Iterator obj_type_match = obj_types.find(p_typeref.cname);
if (obj_type_match) { if (obj_type_match) {
return &obj_type_match.get(); return &obj_type_match->value;
} }
if (p_typeref.is_enum) { if (p_typeref.is_enum) {
@ -2942,12 +2942,11 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
// Populate signals // Populate signals
const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map; const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map;
const StringName *k = nullptr;
while ((k = signal_map.next(k))) { for (const KeyValue<StringName, MethodInfo> &E : signal_map) {
SignalInterface isignal; SignalInterface isignal;
const MethodInfo &method_info = signal_map.get(*k); const MethodInfo &method_info = E.value;
isignal.name = method_info.name; isignal.name = method_info.name;
isignal.cname = method_info.name; isignal.cname = method_info.name;
@ -3024,10 +3023,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
ClassDB::get_integer_constant_list(type_cname, &constants, true); ClassDB::get_integer_constant_list(type_cname, &constants, true);
const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map; const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
k = nullptr;
while ((k = enum_map.next(k))) { for (const KeyValue<StringName, List<StringName>> &E : enum_map) {
StringName enum_proxy_cname = *k; StringName enum_proxy_cname = E.key;
String enum_proxy_name = enum_proxy_cname.operator String(); String enum_proxy_name = enum_proxy_cname.operator String();
if (itype.find_property_by_proxy_name(enum_proxy_cname)) { if (itype.find_property_by_proxy_name(enum_proxy_cname)) {
// We have several conflicts between enums and PascalCase properties, // We have several conflicts between enums and PascalCase properties,
@ -3036,7 +3034,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
enum_proxy_cname = StringName(enum_proxy_name); enum_proxy_cname = StringName(enum_proxy_name);
} }
EnumInterface ienum(enum_proxy_cname); EnumInterface ienum(enum_proxy_cname);
const List<StringName> &enum_constants = enum_map.get(*k); const List<StringName> &enum_constants = E.value;
for (const StringName &constant_cname : enum_constants) { for (const StringName &constant_cname : enum_constants) {
String constant_name = constant_cname.operator String(); String constant_name = constant_cname.operator String();
int *value = class_info->constant_map.getptr(constant_cname); int *value = class_info->constant_map.getptr(constant_cname);
@ -3066,7 +3064,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
TypeInterface enum_itype; TypeInterface enum_itype;
enum_itype.is_enum = true; enum_itype.is_enum = true;
enum_itype.name = itype.name + "." + String(*k); enum_itype.name = itype.name + "." + String(E.key);
enum_itype.cname = StringName(enum_itype.name); enum_itype.cname = StringName(enum_itype.name);
enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name; enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name;
TypeInterface::postsetup_enum_type(enum_itype); TypeInterface::postsetup_enum_type(enum_itype);
@ -3715,8 +3713,8 @@ void BindingsGenerator::_initialize() {
core_custom_icalls.clear(); core_custom_icalls.clear();
editor_custom_icalls.clear(); editor_custom_icalls.clear();
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { for (const KeyValue<StringName, TypeInterface> &E : obj_types) {
_generate_method_icalls(E.get()); _generate_method_icalls(E.value);
} }
initialized = true; initialized = true;

View File

@ -533,7 +533,7 @@ class BindingsGenerator {
bool log_print_enabled = true; bool log_print_enabled = true;
bool initialized = false; bool initialized = false;
OrderedHashMap<StringName, TypeInterface> obj_types; HashMap<StringName, TypeInterface> obj_types;
Map<StringName, TypeInterface> placeholder_types; Map<StringName, TypeInterface> placeholder_types;
Map<StringName, TypeInterface> builtin_types; Map<StringName, TypeInterface> builtin_types;

View File

@ -121,10 +121,10 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
case CompletionKind::NODE_PATHS: { case CompletionKind::NODE_PATHS: {
{ {
// Autoloads. // Autoloads.
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
const ProjectSettings::AutoloadInfo &info = E.value(); const ProjectSettings::AutoloadInfo &info = E.value;
suggestions.push_back(quoted("/root/" + String(info.name))); suggestions.push_back(quoted("/root/" + String(info.name)));
} }
} }

View File

@ -1167,9 +1167,8 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
int32_t domain_id = mono_domain_get_id(mono_domain_get()); int32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
const String *k = nullptr; for (const KeyValue<String, GDMonoAssembly *> &E : domain_assemblies) {
while ((k = domain_assemblies.next(k))) { GDMonoAssembly *assembly = E.value;
GDMonoAssembly *assembly = domain_assemblies.get(*k);
if (assembly->get_image() == image) { if (assembly->get_image() == image) {
GDMonoClass *klass = assembly->get_class(p_raw_class); GDMonoClass *klass = assembly->get_class(p_raw_class);
if (klass) { if (klass) {
@ -1190,9 +1189,8 @@ GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &
int32_t domain_id = mono_domain_get_id(mono_domain_get()); int32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
const String *k = nullptr; for (const KeyValue<String, GDMonoAssembly *> &E : domain_assemblies) {
while ((k = domain_assemblies.next(k))) { GDMonoAssembly *assembly = E.value;
GDMonoAssembly *assembly = domain_assemblies.get(*k);
klass = assembly->get_class(p_namespace, p_name); klass = assembly->get_class(p_namespace, p_name);
if (klass) { if (klass) {
return klass; return klass;
@ -1205,9 +1203,8 @@ GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &
void GDMono::_domain_assemblies_cleanup(int32_t p_domain_id) { void GDMono::_domain_assemblies_cleanup(int32_t p_domain_id) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id]; HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id];
const String *k = nullptr; for (const KeyValue<String, GDMonoAssembly *> &E : domain_assemblies) {
while ((k = domain_assemblies.next(k))) { memdelete(E.value);
memdelete(domain_assemblies.get(*k));
} }
assemblies.erase(p_domain_id); assemblies.erase(p_domain_id);
@ -1298,13 +1295,11 @@ GDMono::~GDMono() {
// Leave the rest to 'mono_jit_cleanup' // Leave the rest to 'mono_jit_cleanup'
#endif #endif
const int32_t *k = nullptr; for (const KeyValue<int32_t, HashMap<String, GDMonoAssembly *>> &E : assemblies) {
while ((k = assemblies.next(k))) { const HashMap<String, GDMonoAssembly *> &domain_assemblies = E.value;
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies.get(*k);
const String *kk = nullptr; for (const KeyValue<String, GDMonoAssembly *> &F : domain_assemblies) {
while ((kk = domain_assemblies.next(kk))) { memdelete(F.value);
memdelete(domain_assemblies.get(*kk));
} }
} }
assemblies.clear(); assemblies.clear();

View File

@ -247,7 +247,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
if (existing_method) { if (existing_method) {
memdelete(*existing_method); // Must delete old one memdelete(*existing_method); // Must delete old one
} }
methods.set(key, method); methods.insert(key, method);
break; break;
} }
@ -266,11 +266,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p_name) { GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p_name) {
ERR_FAIL_COND_V(!methods_fetched, nullptr); ERR_FAIL_COND_V(!methods_fetched, nullptr);
const MethodKey *k = nullptr; for (const KeyValue<MethodKey, GDMonoMethod *> &E : methods) {
if (E.key.name == p_name) {
while ((k = methods.next(k))) { return E.value;
if (k->name == p_name) {
return methods.get(*k);
} }
} }
@ -307,7 +305,7 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, uint16_t p_param
if (raw_method) { if (raw_method) {
GDMonoMethod *method = memnew(GDMonoMethod(p_name, raw_method)); GDMonoMethod *method = memnew(GDMonoMethod(p_name, raw_method));
methods.set(key, method); methods.insert(key, method);
return method; return method;
} }
@ -342,7 +340,7 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName
} }
GDMonoMethod *method = memnew(GDMonoMethod(p_name, p_raw_method)); GDMonoMethod *method = memnew(GDMonoMethod(p_name, p_raw_method));
methods.set(key, method); methods.insert(key, method);
return method; return method;
} }
@ -549,9 +547,8 @@ GDMonoClass::~GDMonoClass() {
Vector<GDMonoMethod *> deleted_methods; Vector<GDMonoMethod *> deleted_methods;
deleted_methods.resize(methods.size()); deleted_methods.resize(methods.size());
const MethodKey *k = nullptr; for (const KeyValue<MethodKey, GDMonoMethod *> &E : methods) {
while ((k = methods.next(k))) { GDMonoMethod *method = E.value;
GDMonoMethod *method = methods.get(*k);
if (method) { if (method) {
for (int i = 0; i < offset; i++) { for (int i = 0; i < offset; i++) {

View File

@ -454,10 +454,9 @@ bool RaycastOcclusionCull::Scenario::update(ThreadWorkPool &p_thread_pool) {
next_scene = rtcNewScene(raycast_singleton->ebr_device); next_scene = rtcNewScene(raycast_singleton->ebr_device);
rtcSetSceneBuildQuality(next_scene, RTCBuildQuality(raycast_singleton->build_quality)); rtcSetSceneBuildQuality(next_scene, RTCBuildQuality(raycast_singleton->build_quality));
const RID *inst_rid = nullptr; for (const KeyValue<RID, OccluderInstance> &E : instances) {
while ((inst_rid = instances.next(inst_rid))) { const OccluderInstance *occ_inst = &E.value;
OccluderInstance *occ_inst = instances.getptr(*inst_rid); const Occluder *occ = raycast_singleton->occluder_owner.get_or_null(occ_inst->occluder);
Occluder *occ = raycast_singleton->occluder_owner.get_or_null(occ_inst->occluder);
if (!occ || !occ_inst->enabled) { if (!occ || !occ_inst->enabled) {
continue; continue;
@ -573,9 +572,8 @@ void RaycastOcclusionCull::set_build_quality(RS::ViewportOcclusionCullingBuildQu
build_quality = p_quality; build_quality = p_quality;
const RID *scenario_rid = nullptr; for (KeyValue<RID, Scenario> &K : scenarios) {
while ((scenario_rid = scenarios.next(scenario_rid))) { K.value.dirty = true;
scenarios[*scenario_rid].dirty = true;
} }
} }
@ -596,9 +594,8 @@ RaycastOcclusionCull::RaycastOcclusionCull() {
} }
RaycastOcclusionCull::~RaycastOcclusionCull() { RaycastOcclusionCull::~RaycastOcclusionCull() {
const RID *scenario_rid = nullptr; for (KeyValue<RID, Scenario> &K : scenarios) {
while ((scenario_rid = scenarios.next(scenario_rid))) { Scenario &scenario = K.value;
Scenario &scenario = scenarios[*scenario_rid];
if (scenario.commit_thread) { if (scenario.commit_thread) {
scenario.commit_thread->wait_to_finish(); scenario.commit_thread->wait_to_finish();
memdelete(scenario.commit_thread); memdelete(scenario.commit_thread);

View File

@ -2371,9 +2371,8 @@ Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid, const Vecto
Array ret; Array ret;
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
const int32_t *E = nullptr; for (const KeyValue<int32_t, FontGlyph> &E : gl) {
while ((E = gl.next(E))) { ret.push_back(E.key);
ret.push_back(*E);
} }
return ret; return ret;
} }
@ -2864,9 +2863,8 @@ String TextServerAdvanced::font_get_supported_chars(const RID &p_font_rid) const
#endif #endif
if (at_size) { if (at_size) {
const HashMap<int32_t, FontGlyph> &gl = at_size->glyph_map; const HashMap<int32_t, FontGlyph> &gl = at_size->glyph_map;
const int32_t *E = nullptr; for (const KeyValue<int32_t, FontGlyph> &E : gl) {
while ((E = gl.next(E))) { chars = chars + String::chr(E.key);
chars = chars + String::chr(*E);
} }
} }
return chars; return chars;

View File

@ -1533,9 +1533,8 @@ Array TextServerFallback::font_get_glyph_list(const RID &p_font_rid, const Vecto
Array ret; Array ret;
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
const int32_t *E = nullptr; for (const KeyValue<int32_t, FontGlyph> &E : gl) {
while ((E = gl.next(E))) { ret.push_back(E.key);
ret.push_back(*E);
} }
return ret; return ret;
} }
@ -1994,9 +1993,8 @@ String TextServerFallback::font_get_supported_chars(const RID &p_font_rid) const
#endif #endif
if (at_size) { if (at_size) {
const HashMap<int32_t, FontGlyph> &gl = at_size->glyph_map; const HashMap<int32_t, FontGlyph> &gl = at_size->glyph_map;
const int32_t *E = nullptr; for (const KeyValue<int32_t, FontGlyph> &E : gl) {
while ((E = gl.next(E))) { chars = chars + String::chr(E.key);
chars = chars + String::chr(*E);
} }
} }
return chars; return chars;

View File

@ -1608,7 +1608,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
if (E.from_node == p_id && E.from_port == p_port) { if (E.from_node == p_id && E.from_port == p_port) {
// Push into the connections map. // Push into the connections map.
if (!conn_map.has(E.to_node)) { if (!conn_map.has(E.to_node)) {
conn_map.set(E.to_node, Set<int>()); conn_map.insert(E.to_node, Set<int>());
} }
conn_map[E.to_node].insert(E.to_port); conn_map[E.to_node].insert(E.to_port);
} }
@ -1617,11 +1617,9 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
undo_redo->add_do_method(vsn.ptr(), "remove_output_data_port", p_port); undo_redo->add_do_method(vsn.ptr(), "remove_output_data_port", p_port);
undo_redo->add_do_method(this, "_update_graph", p_id); undo_redo->add_do_method(this, "_update_graph", p_id);
List<int> keys; for (const KeyValue<int, Set<int>> &E : conn_map) {
conn_map.get_key_list(&keys); for (const Set<int>::Element *F = E.value.front(); F; F = F->next()) {
for (const int &E : keys) { undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E.key, F->get());
for (const Set<int>::Element *F = conn_map[E].front(); F; F = F->next()) {
undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E, F->get());
} }
} }
@ -1912,7 +1910,7 @@ void VisualScriptEditor::_on_nodes_duplicate() {
Ref<VisualScriptNode> dupe = node->duplicate(true); Ref<VisualScriptNode> dupe = node->duplicate(true);
int new_id = idc++; int new_id = idc++;
remap.set(F->get(), new_id); remap.insert(F->get(), new_id);
to_select.insert(new_id); to_select.insert(new_id);
undo_redo->add_do_method(script.ptr(), "add_node", new_id, dupe, script->get_node_position(F->get()) + Vector2(20, 20)); undo_redo->add_do_method(script.ptr(), "add_node", new_id, dupe, script->get_node_position(F->get()) + Vector2(20, 20));

View File

@ -209,8 +209,9 @@ Vector2 VisualScript::get_scroll() const {
} }
void VisualScript::get_function_list(List<StringName> *r_functions) const { void VisualScript::get_function_list(List<StringName> *r_functions) const {
functions.get_key_list(r_functions); for (const KeyValue<StringName, Function> &E : functions) {
// r_functions->sort_custom<StringName::AlphCompare>(); // Don't force sorting. r_functions->push_back(E.key);
}
} }
int VisualScript::get_function_node_id(const StringName &p_name) const { int VisualScript::get_function_node_id(const StringName &p_name) const {
@ -346,7 +347,9 @@ Point2 VisualScript::get_node_position(int p_id) const {
} }
void VisualScript::get_node_list(List<int> *r_nodes) const { void VisualScript::get_node_list(List<int> *r_nodes) const {
nodes.get_key_list(r_nodes); for (const KeyValue<int, NodeData> &E : nodes) {
r_nodes->push_back(E.key);
}
} }
void VisualScript::sequence_connect(int p_from_node, int p_from_output, int p_to_node) { void VisualScript::sequence_connect(int p_from_node, int p_from_output, int p_to_node) {
@ -563,8 +566,9 @@ Dictionary VisualScript::_get_variable_info(const StringName &p_name) const {
} }
void VisualScript::get_variable_list(List<StringName> *r_variables) const { void VisualScript::get_variable_list(List<StringName> *r_variables) const {
variables.get_key_list(r_variables); for (const KeyValue<StringName, Variable> &E : variables) {
// r_variables->sort_custom<StringName::AlphCompare>(); // Don't force it. r_variables->push_back(E.key);
}
} }
void VisualScript::set_instance_base_type(const StringName &p_type) { void VisualScript::set_instance_base_type(const StringName &p_type) {
@ -713,12 +717,11 @@ int VisualScript::get_available_id() const {
// This is infinitely increasing, // This is infinitely increasing,
// so one might want to implement a better solution, // so one might want to implement a better solution,
// if the there is a case for huge number of nodes to be added to visual script. // if the there is a case for huge number of nodes to be added to visual script.
List<int> nds;
nodes.get_key_list(&nds);
int max = -1; int max = -1;
for (const int &E : nds) { for (const KeyValue<int, NodeData> &E : nodes) {
if (E > max) { if (E.key > max) {
max = E; max = E.key;
} }
} }
return (max + 1); return (max + 1);
@ -750,18 +753,15 @@ void VisualScript::_update_placeholders() {
List<PropertyInfo> pinfo; List<PropertyInfo> pinfo;
Map<StringName, Variant> values; Map<StringName, Variant> values;
List<StringName> keys; for (const KeyValue<StringName, Variable> &E : variables) {
variables.get_key_list(&keys); if (!variables[E.key]._export) {
for (const StringName &E : keys) {
if (!variables[E]._export) {
continue; continue;
} }
PropertyInfo p = variables[E].info; PropertyInfo p = variables[E.key].info;
p.name = String(E); p.name = String(E.key);
pinfo.push_back(p); pinfo.push_back(p);
values[p.name] = variables[E].default_value; values[p.name] = variables[E.key].default_value;
} }
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) { for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
@ -781,18 +781,15 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
List<PropertyInfo> pinfo; List<PropertyInfo> pinfo;
Map<StringName, Variant> values; Map<StringName, Variant> values;
List<StringName> keys; for (const KeyValue<StringName, Variable> &E : variables) {
variables.get_key_list(&keys); if (!variables[E.key]._export) {
for (const StringName &E : keys) {
if (!variables[E]._export) {
continue; continue;
} }
PropertyInfo p = variables[E].info; PropertyInfo p = variables[E.key].info;
p.name = String(E); p.name = String(E.key);
pinfo.push_back(p); pinfo.push_back(p);
values[p.name] = variables[E].default_value; values[p.name] = variables[E.key].default_value;
} }
sins->update(pinfo, values); sins->update(pinfo, values);
@ -872,14 +869,11 @@ bool VisualScript::get_property_default_value(const StringName &p_property, Vari
} }
void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const { void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const {
List<StringName> funcs; for (const KeyValue<StringName, Function> &E : functions) {
functions.get_key_list(&funcs);
for (const StringName &E : funcs) {
MethodInfo mi; MethodInfo mi;
mi.name = E; mi.name = E.key;
if (functions[E].func_id >= 0) { if (functions[E.key].func_id >= 0) {
Ref<VisualScriptFunction> func = nodes[functions[E].func_id].node; Ref<VisualScriptFunction> func = nodes[functions[E.key].func_id].node;
if (func.is_valid()) { if (func.is_valid()) {
for (int i = 0; i < func->get_argument_count(); i++) { for (int i = 0; i < func->get_argument_count(); i++) {
PropertyInfo arg; PropertyInfo arg;
@ -945,10 +939,8 @@ int VisualScript::get_member_line(const StringName &p_member) const {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
bool VisualScript::are_subnodes_edited() const { bool VisualScript::are_subnodes_edited() const {
List<int> keys; for (const KeyValue<int, NodeData> &F : nodes) {
nodes.get_key_list(&keys); if (F.value.node->is_edited()) {
for (const int &F : keys) {
if (nodes[F].node->is_edited()) {
return true; return true;
} }
} }
@ -1017,15 +1009,13 @@ void VisualScript::_set_data(const Dictionary &p_data) {
// Takes all the rpc methods. // Takes all the rpc methods.
rpc_functions.clear(); rpc_functions.clear();
List<StringName> fns; for (const KeyValue<StringName, Function> &E : functions) {
functions.get_key_list(&fns); if (E.value.func_id >= 0 && nodes.has(E.value.func_id)) {
for (const StringName &E : fns) { Ref<VisualScriptFunction> vsf = nodes[E.value.func_id].node;
if (functions[E].func_id >= 0 && nodes.has(functions[E].func_id)) {
Ref<VisualScriptFunction> vsf = nodes[functions[E].func_id].node;
if (vsf.is_valid()) { if (vsf.is_valid()) {
if (vsf->get_rpc_mode() != Multiplayer::RPC_MODE_DISABLED) { if (vsf->get_rpc_mode() != Multiplayer::RPC_MODE_DISABLED) {
Multiplayer::RPCConfig nd; Multiplayer::RPCConfig nd;
nd.name = E; nd.name = E.key;
nd.rpc_mode = vsf->get_rpc_mode(); nd.rpc_mode = vsf->get_rpc_mode();
nd.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; // TODO nd.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; // TODO
if (rpc_functions.find(nd) == -1) { if (rpc_functions.find(nd) == -1) {
@ -1045,13 +1035,11 @@ Dictionary VisualScript::_get_data() const {
d["base_type"] = base_type; d["base_type"] = base_type;
Array vars; Array vars;
List<StringName> var_names; for (const KeyValue<StringName, Variable> &E : variables) {
variables.get_key_list(&var_names); Dictionary var = _get_variable_info(E.key);
for (const StringName &E : var_names) { var["name"] = E.key; // Make sure it's the right one.
Dictionary var = _get_variable_info(E); var["default_value"] = E.value.default_value;
var["name"] = E; // Make sure it's the right one. var["export"] = E.value._export;
var["default_value"] = variables[E].default_value;
var["export"] = variables[E]._export;
vars.push_back(var); vars.push_back(var);
} }
d["variables"] = vars; d["variables"] = vars;
@ -1073,23 +1061,19 @@ Dictionary VisualScript::_get_data() const {
d["signals"] = sigs; d["signals"] = sigs;
Array funcs; Array funcs;
List<StringName> func_names; for (const KeyValue<StringName, Function> &E : functions) {
functions.get_key_list(&func_names);
for (const StringName &E : func_names) {
Dictionary func; Dictionary func;
func["name"] = E; func["name"] = E.key;
func["function_id"] = functions[E].func_id; func["function_id"] = E.value.func_id;
funcs.push_back(func); funcs.push_back(func);
} }
d["functions"] = funcs; d["functions"] = funcs;
Array nds; Array nds;
List<int> node_ids; for (const KeyValue<int, NodeData> &F : nodes) {
nodes.get_key_list(&node_ids); nds.push_back(F.key);
for (const int &F : node_ids) { nds.push_back(F.value.pos);
nds.push_back(F); nds.push_back(F.value.node);
nds.push_back(nodes[F].pos);
nds.push_back(nodes[F].node);
} }
d["nodes"] = nds; d["nodes"] = nds;
@ -1199,10 +1183,8 @@ Set<int> VisualScript::get_output_sequence_ports_connected(int from_node) {
VisualScript::~VisualScript() { VisualScript::~VisualScript() {
// Remove all nodes and stuff that hold data refs. // Remove all nodes and stuff that hold data refs.
List<int> nds; for (const KeyValue<int, NodeData> &E : nodes) {
nodes.get_key_list(&nds); remove_node(E.key);
for (const int &E : nds) {
remove_node(E);
} }
} }
@ -1230,14 +1212,12 @@ bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
} }
void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
List<StringName> vars; for (const KeyValue<StringName, VisualScript::Variable> &E : script->variables) {
script->variables.get_key_list(&vars); if (!E.value._export) {
for (const StringName &E : vars) {
if (!script->variables[E]._export) {
continue; continue;
} }
PropertyInfo p = script->variables[E].info; PropertyInfo p = E.value.info;
p.name = String(E); p.name = String(E.key);
p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
p_properties->push_back(p); p_properties->push_back(p);
} }
@ -1259,13 +1239,11 @@ Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name,
} }
void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
List<StringName> fns; for (const KeyValue<StringName, VisualScript::Function> &E : script->functions) {
script->functions.get_key_list(&fns);
for (const StringName &E : fns) {
MethodInfo mi; MethodInfo mi;
mi.name = E; mi.name = E.key;
if (script->functions[E].func_id >= 0 && script->nodes.has(script->functions[E].func_id)) { if (E.value.func_id >= 0 && script->nodes.has(E.value.func_id)) {
Ref<VisualScriptFunction> vsf = script->nodes[script->functions[E].func_id].node; Ref<VisualScriptFunction> vsf = script->nodes[E.value.func_id].node;
if (vsf.is_valid()) { if (vsf.is_valid()) {
for (int i = 0; i < vsf->get_argument_count(); i++) { for (int i = 0; i < vsf->get_argument_count(); i++) {
PropertyInfo arg; PropertyInfo arg;
@ -1845,19 +1823,15 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
// Setup variables. // Setup variables.
{ {
List<StringName> keys; for (const KeyValue<StringName, VisualScript::Variable> &E : script->variables) {
script->variables.get_key_list(&keys); variables[E.key] = E.value.default_value;
for (const StringName &E : keys) {
variables[E] = script->variables[E].default_value;
} }
} }
// Setup functions from sequence trees. // Setup functions from sequence trees.
{ {
List<StringName> keys; for (const KeyValue<StringName, VisualScript::Function> &E : script->functions) {
script->functions.get_key_list(&keys); const VisualScript::Function &vsfn = E.value;
for (const StringName &E : keys) {
const VisualScript::Function vsfn = p_script->functions[E];
Function function; Function function;
function.node = vsfn.func_id; function.node = vsfn.func_id;
function.max_stack = 0; function.max_stack = 0;
@ -1868,7 +1842,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
Map<StringName, int> local_var_indices; Map<StringName, int> local_var_indices;
if (function.node < 0) { if (function.node < 0) {
VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E)); VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E.key));
ERR_CONTINUE(function.node < 0); ERR_CONTINUE(function.node < 0);
} }
@ -1876,7 +1850,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
Ref<VisualScriptFunction> func_node = script->get_node(vsfn.func_id); Ref<VisualScriptFunction> func_node = script->get_node(vsfn.func_id);
if (func_node.is_null()) { if (func_node.is_null()) {
VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E)); VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E.key));
} }
ERR_CONTINUE(!func_node.is_valid()); ERR_CONTINUE(!func_node.is_valid());
@ -1916,13 +1890,12 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
List<int> dc_keys; List<int> dc_keys;
while (!nd_queue.is_empty()) { while (!nd_queue.is_empty()) {
int ky = nd_queue.front()->get(); int ky = nd_queue.front()->get();
dc_lut[ky].get_key_list(&dc_keys); for (const KeyValue<int, Pair<int, int>> &F : dc_lut[ky]) {
for (const int &F : dc_keys) {
VisualScript::DataConnection dc; VisualScript::DataConnection dc;
dc.from_node = dc_lut[ky][F].first; dc.from_node = F.value.first;
dc.from_port = dc_lut[ky][F].second; dc.from_port = F.value.second;
dc.to_node = ky; dc.to_node = ky;
dc.to_port = F; dc.to_port = F.key;
dataconns.insert(dc); dataconns.insert(dc);
nd_queue.push_back(dc.from_node); nd_queue.push_back(dc.from_node);
node_ids.insert(dc.from_node); node_ids.insert(dc.from_node);
@ -2072,7 +2045,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
} }
} }
functions[E] = function; functions[E.key] = function;
} }
} }
} }

View File

@ -107,16 +107,13 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
for (int i = 0; i < found_plugins.size(); i++) { for (int i = 0; i < found_plugins.size(); i++) {
// Editable plugin plist values // Editable plugin plist values
PluginConfigIOS plugin = found_plugins[i]; PluginConfigIOS plugin = found_plugins[i];
const String *K = nullptr;
while ((K = plugin.plist.next(K))) { for (const KeyValue<String, PluginConfigIOS::PlistItem> &E : plugin.plist) {
String key = *K; switch (E.value.type) {
PluginConfigIOS::PlistItem item = plugin.plist[key];
switch (item.type) {
case PluginConfigIOS::PlistItemType::STRING_INPUT: { case PluginConfigIOS::PlistItemType::STRING_INPUT: {
String preset_name = "plugins_plist/" + key; String preset_name = "plugins_plist/" + E.key;
if (!plist_keys.has(preset_name)) { if (!plist_keys.has(preset_name)) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, preset_name), item.value)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, preset_name), E.value.value));
plist_keys.insert(preset_name); plist_keys.insert(preset_name);
} }
} break; } break;
@ -1258,11 +1255,10 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
// Plist // Plist
// Using hash map container to remove duplicates // Using hash map container to remove duplicates
const String *K = nullptr;
while ((K = plugin.plist.next(K))) { for (const KeyValue<String, PluginConfigIOS::PlistItem> &E : plugin.plist) {
String key = *K; String key = E.key;
PluginConfigIOS::PlistItem item = plugin.plist[key]; const PluginConfigIOS::PlistItem &item = E.value;
String value; String value;
@ -1301,10 +1297,9 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
// Updating `Info.plist` // Updating `Info.plist`
{ {
const String *K = nullptr; for (const KeyValue<String, String> &E : plist_values) {
while ((K = plist_values.next(K))) { String key = E.key;
String key = *K; String value = E.value;
String value = plist_values[key];
if (key.is_empty() || value.is_empty()) { if (key.is_empty() || value.is_empty()) {
continue; continue;

View File

@ -198,12 +198,11 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri
blendw[i] = 0.0; //all to zero by default blendw[i] = 0.0; //all to zero by default
} }
const NodePath *K = nullptr; for (const KeyValue<NodePath, bool> &E : filter) {
while ((K = filter.next(K))) { if (!state->track_map.has(E.key)) {
if (!state->track_map.has(*K)) {
continue; continue;
} }
int idx = state->track_map[*K]; int idx = state->track_map[E.key];
blendw[idx] = 1.0; //filtered goes to one blendw[idx] = 1.0; //filtered goes to one
} }
@ -374,9 +373,8 @@ bool AnimationNode::has_filter() const {
Array AnimationNode::_get_filters() const { Array AnimationNode::_get_filters() const {
Array paths; Array paths;
const NodePath *K = nullptr; for (const KeyValue<NodePath, bool> &E : filter) {
while ((K = filter.next(K))) { paths.push_back(String(E.key)); //use strings, so sorting is possible
paths.push_back(String(*K)); //use strings, so sorting is possible
} }
paths.sort(); //done so every time the scene is saved, it does not change paths.sort(); //done so every time the scene is saved, it does not change
@ -803,11 +801,10 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
List<NodePath> to_delete; List<NodePath> to_delete;
const NodePath *K = nullptr; for (const KeyValue<NodePath, TrackCache *> &K : track_cache) {
while ((K = track_cache.next(K))) { TrackCache *tc = track_cache[K.key];
TrackCache *tc = track_cache[*K];
if (tc->setup_pass != setup_pass) { if (tc->setup_pass != setup_pass) {
to_delete.push_back(*K); to_delete.push_back(K.key);
} }
} }
@ -820,10 +817,9 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
state.track_map.clear(); state.track_map.clear();
K = nullptr;
int idx = 0; int idx = 0;
while ((K = track_cache.next(K))) { for (const KeyValue<NodePath, TrackCache *> &K : track_cache) {
state.track_map[*K] = idx; state.track_map[K.key] = idx;
idx++; idx++;
} }
@ -835,9 +831,8 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} }
void AnimationTree::_clear_caches() { void AnimationTree::_clear_caches() {
const NodePath *K = nullptr; for (KeyValue<NodePath, TrackCache *> &K : track_cache) {
while ((K = track_cache.next(K))) { memdelete(K.value);
memdelete(track_cache[*K]);
} }
playing_caches.clear(); playing_caches.clear();
@ -1569,9 +1564,8 @@ void AnimationTree::_process_graph(double p_delta) {
{ {
// finally, set the tracks // finally, set the tracks
const NodePath *K = nullptr; for (const KeyValue<NodePath, TrackCache *> &K : track_cache) {
while ((K = track_cache.next(K))) { TrackCache *track = K.value;
TrackCache *track = track_cache[*K];
if (track->process_pass != process_pass) { if (track->process_pass != process_pass) {
continue; //not processed, ignore continue; //not processed, ignore
} }

View File

@ -3036,7 +3036,9 @@ void CodeEdit::_text_changed() {
lc = get_line_count(); lc = get_line_count();
List<int> breakpoints; List<int> breakpoints;
breakpointed_lines.get_key_list(&breakpoints); for (const KeyValue<int, bool> &E : breakpointed_lines) {
breakpoints.push_back(E.key);
}
for (const int &line : breakpoints) { for (const int &line : breakpoints) {
if (line < lines_edited_from || (line < lc && is_line_breakpointed(line))) { if (line < lines_edited_from || (line < lc && is_line_breakpointed(line))) {
continue; continue;

View File

@ -523,7 +523,7 @@ void GraphEdit::_update_comment_enclosed_nodes_list(GraphNode *p_node, HashMap<S
} }
} }
p_comment_enclosed_nodes.set(p_node->get_name(), enclosed_nodes); p_comment_enclosed_nodes.insert(p_node->get_name(), enclosed_nodes);
} }
void GraphEdit::_set_drag_comment_enclosed_nodes(GraphNode *p_node, HashMap<StringName, Vector<GraphNode *>> &p_comment_enclosed_nodes, bool p_drag) { void GraphEdit::_set_drag_comment_enclosed_nodes(GraphNode *p_node, HashMap<StringName, Vector<GraphNode *>> &p_comment_enclosed_nodes, bool p_drag) {
@ -1742,11 +1742,11 @@ HashMap<int, Vector<StringName>> GraphEdit::_layering(const Set<StringName> &r_s
Vector<StringName> t; Vector<StringName> t;
t.push_back(E->get()); t.push_back(E->get());
if (!l.has(current_layer)) { if (!l.has(current_layer)) {
l.set(current_layer, Vector<StringName>{}); l.insert(current_layer, Vector<StringName>{});
} }
selected = true; selected = true;
t.append_array(l[current_layer]); t.append_array(l[current_layer]);
l.set(current_layer, t); l.insert(current_layer, t);
Set<StringName> V; Set<StringName> V;
V.insert(E->get()); V.insert(E->get());
_set_operations(GraphEdit::UNION, u, V); _set_operations(GraphEdit::UNION, u, V);
@ -1860,10 +1860,10 @@ void GraphEdit::_crossing_minimisation(HashMap<int, Vector<StringName>> &r_layer
} }
d[q] = crossings; d[q] = crossings;
} }
c.set(p, d); c.insert(p, d);
} }
r_layers.set(i, _split(lower_layer, c)); r_layers.insert(i, _split(lower_layer, c));
} }
} }
@ -2026,7 +2026,7 @@ void GraphEdit::_place_block(StringName p_v, float p_delta, const HashMap<int, V
threshold = _calculate_threshold(p_v, w, r_node_name, r_layers, r_root, r_align, r_inner_shift, threshold, r_node_positions); threshold = _calculate_threshold(p_v, w, r_node_name, r_layers, r_root, r_align, r_inner_shift, threshold, r_node_positions);
w = r_align[w]; w = r_align[w];
} while (w != p_v); } while (w != p_v);
r_node_positions.set(p_v, pos); r_node_positions.insert(p_v, pos);
} }
#undef PRED #undef PRED
@ -2082,10 +2082,10 @@ void GraphEdit::arrange_nodes() {
ports = p_ports; ports = p_ports;
} }
} }
port_info.set(_connection, ports); port_info.insert(_connection, ports);
} }
} }
upper_neighbours.set(gn->get_name(), s); upper_neighbours.insert(gn->get_name(), s);
} }
} }
@ -2109,7 +2109,7 @@ void GraphEdit::arrange_nodes() {
inner_shift[E->get()] = 0.0f; inner_shift[E->get()] = 0.0f;
sink[E->get()] = E->get(); sink[E->get()] = E->get();
shift[E->get()] = FLT_MAX; shift[E->get()] = FLT_MAX;
new_positions.set(E->get(), default_position); new_positions.insert(E->get(), default_position);
if ((StringName)root[E->get()] == E->get()) { if ((StringName)root[E->get()] == E->get()) {
block_heads.insert(E->get()); block_heads.insert(E->get());
} }
@ -2129,7 +2129,7 @@ void GraphEdit::arrange_nodes() {
do { do {
Vector2 cal_pos; Vector2 cal_pos;
cal_pos.y = start_from + (real_t)inner_shift[u]; cal_pos.y = start_from + (real_t)inner_shift[u];
new_positions.set(u, cal_pos); new_positions.insert(u, cal_pos);
u = align[u]; u = align[u];
} while (u != E->get()); } while (u != E->get());
} }
@ -2161,7 +2161,7 @@ void GraphEdit::arrange_nodes() {
} }
cal_pos.x = current_node_start_pos; cal_pos.x = current_node_start_pos;
} }
new_positions.set(layer[j], cal_pos); new_positions.insert(layer[j], cal_pos);
} }
start_from += largest_node_size + gap_h; start_from += largest_node_size + gap_h;

View File

@ -53,8 +53,8 @@ bool MissingNode::_get(const StringName &p_name, Variant &r_ret) const {
} }
void MissingNode::_get_property_list(List<PropertyInfo> *p_list) const { void MissingNode::_get_property_list(List<PropertyInfo> *p_list) const {
for (OrderedHashMap<StringName, Variant>::ConstElement E = properties.front(); E; E = E.next()) { for (const KeyValue<StringName, Variant> &E : properties) {
p_list->push_back(PropertyInfo(E.value().get_type(), E.key())); p_list->push_back(PropertyInfo(E.value.get_type(), E.key));
} }
} }

View File

@ -36,7 +36,7 @@
class MissingNode : public Node { class MissingNode : public Node {
GDCLASS(MissingNode, Node) GDCLASS(MissingNode, Node)
OrderedHashMap<StringName, Variant> properties; HashMap<StringName, Variant> properties;
String original_class; String original_class;
bool recording_properties = false; bool recording_properties = false;

View File

@ -438,9 +438,8 @@ bool SceneTree::process(double p_time) {
if (multiplayer_poll) { if (multiplayer_poll) {
multiplayer->poll(); multiplayer->poll();
const NodePath *rpath = nullptr; for (KeyValue<NodePath, Ref<MultiplayerAPI>> &E : custom_multiplayers) {
while ((rpath = custom_multiplayers.next(rpath))) { E.value->poll();
custom_multiplayers[*rpath]->poll();
} }
} }
@ -1137,9 +1136,8 @@ Array SceneTree::get_processed_tweens() {
Ref<MultiplayerAPI> SceneTree::get_multiplayer(const NodePath &p_for_path) const { Ref<MultiplayerAPI> SceneTree::get_multiplayer(const NodePath &p_for_path) const {
Ref<MultiplayerAPI> out = multiplayer; Ref<MultiplayerAPI> out = multiplayer;
const NodePath *spath = nullptr; for (const KeyValue<NodePath, Ref<MultiplayerAPI>> &E : custom_multiplayers) {
while ((spath = custom_multiplayers.next(spath))) { const Vector<StringName> snames = E.key.get_names();
const Vector<StringName> snames = (*spath).get_names();
const Vector<StringName> tnames = p_for_path.get_names(); const Vector<StringName> tnames = p_for_path.get_names();
if (tnames.size() < snames.size()) { if (tnames.size() < snames.size()) {
continue; continue;
@ -1154,7 +1152,7 @@ Ref<MultiplayerAPI> SceneTree::get_multiplayer(const NodePath &p_for_path) const
} }
} }
if (valid) { if (valid) {
out = custom_multiplayers[*spath]; out = E.value;
break; break;
} }
} }

View File

@ -229,22 +229,21 @@ void ShaderGlobalsOverride::_activate() {
active = true; active = true;
add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active); add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active);
const StringName *K = nullptr; for (const KeyValue<StringName, Override> &E : overrides) {
while ((K = overrides.next(K))) { const Override *o = &E.value;
Override *o = overrides.getptr(*K);
if (o->in_use && o->override.get_type() != Variant::NIL) { if (o->in_use && o->override.get_type() != Variant::NIL) {
if (o->override.get_type() == Variant::OBJECT) { if (o->override.get_type() == Variant::OBJECT) {
RID tex_rid = o->override; RID tex_rid = o->override;
RS::get_singleton()->global_variable_set_override(*K, tex_rid); RS::get_singleton()->global_variable_set_override(E.key, tex_rid);
} else { } else {
RS::get_singleton()->global_variable_set_override(*K, o->override); RS::get_singleton()->global_variable_set_override(E.key, o->override);
}
} }
} }
update_configuration_warnings(); //may have activated update_configuration_warnings(); //may have activated
} }
} }
}
void ShaderGlobalsOverride::_notification(int p_what) { void ShaderGlobalsOverride::_notification(int p_what) {
switch (p_what) { switch (p_what) {
@ -256,11 +255,10 @@ void ShaderGlobalsOverride::_notification(int p_what) {
case Node3D::NOTIFICATION_EXIT_TREE: { case Node3D::NOTIFICATION_EXIT_TREE: {
if (active) { if (active) {
//remove overrides //remove overrides
const StringName *K = nullptr; for (const KeyValue<StringName, Override> &E : overrides) {
while ((K = overrides.next(K))) { const Override *o = &E.value;
Override *o = overrides.getptr(*K);
if (o->in_use) { if (o->in_use) {
RS::get_singleton()->global_variable_set_override(*K, Variant()); RS::get_singleton()->global_variable_set_override(E.key, Variant());
} }
} }
} }

View File

@ -91,9 +91,9 @@ void MultiplayerSpawner::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {
_update_spawn_node(); _update_spawn_node();
const ObjectID *oid = nullptr;
while ((oid = tracked_nodes.next(oid))) { for (const KeyValue<ObjectID, SpawnInfo> &E : tracked_nodes) {
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(*oid)); Node *node = Object::cast_to<Node>(ObjectDB::get_instance(E.key));
ERR_CONTINUE(!node); ERR_CONTINUE(!node);
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &MultiplayerSpawner::_node_exit)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &MultiplayerSpawner::_node_exit));
// This is unlikely, but might still crash the engine. // This is unlikely, but might still crash the engine.

View File

@ -50,10 +50,8 @@ void SceneCacheInterface::on_peer_change(int p_id, bool p_connected) {
path_get_cache.erase(p_id); path_get_cache.erase(p_id);
// Cleanup sent cache. // Cleanup sent cache.
// Some refactoring is needed to make this faster and do paths GC. // Some refactoring is needed to make this faster and do paths GC.
List<NodePath> keys; for (const KeyValue<NodePath, PathSentCache> &E : path_send_cache) {
path_send_cache.get_key_list(&keys); PathSentCache *psc = path_send_cache.getptr(E.key);
for (const NodePath &E : keys) {
PathSentCache *psc = path_send_cache.getptr(E);
psc->confirmed_peers.erase(p_id); psc->confirmed_peers.erase(p_id);
} }
} }

View File

@ -49,9 +49,8 @@ void SceneReplicationInterface::make_default() {
void SceneReplicationInterface::_free_remotes(int p_id) { void SceneReplicationInterface::_free_remotes(int p_id) {
const HashMap<uint32_t, ObjectID> remotes = rep_state->peer_get_remotes(p_id); const HashMap<uint32_t, ObjectID> remotes = rep_state->peer_get_remotes(p_id);
const uint32_t *k = nullptr; for (const KeyValue<uint32_t, ObjectID> &E : remotes) {
while ((k = remotes.next(k))) { Node *node = rep_state->get_node(E.value);
Node *node = rep_state->get_node(remotes.get(*k));
ERR_CONTINUE(!node); ERR_CONTINUE(!node);
node->queue_delete(); node->queue_delete();
} }

View File

@ -55,9 +55,8 @@ void SceneReplicationState::_untrack(const ObjectID &p_id) {
} }
// If we spawned or synced it, we need to remove it from any peer it was sent to. // If we spawned or synced it, we need to remove it from any peer it was sent to.
if (net_id || peer == 0) { if (net_id || peer == 0) {
const int *k = nullptr; for (KeyValue<int, PeerInfo> &E : peers_info) {
while ((k = peers_info.next(k))) { E.value.known_nodes.erase(p_id);
peers_info.get(*k).known_nodes.erase(p_id);
} }
} }
} }
@ -134,9 +133,8 @@ void SceneReplicationState::reset() {
peers_info.clear(); peers_info.clear();
known_peers.clear(); known_peers.clear();
// Tracked nodes are cleared on deletion, here we only reset the ids so they can be later re-assigned. // Tracked nodes are cleared on deletion, here we only reset the ids so they can be later re-assigned.
const ObjectID *oid = nullptr; for (KeyValue<ObjectID, TrackedNode> &E : tracked_nodes) {
while ((oid = tracked_nodes.next(oid))) { TrackedNode &tobj = E.value;
TrackedNode &tobj = tracked_nodes[*oid];
tobj.net_id = 0; tobj.net_id = 0;
tobj.remote_peer = 0; tobj.remote_peer = 0;
tobj.last_sync = 0; tobj.last_sync = 0;
@ -195,9 +193,8 @@ Error SceneReplicationState::peer_add_node(int p_peer, const ObjectID &p_id) {
ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
peers_info[p_peer].known_nodes.insert(p_id); peers_info[p_peer].known_nodes.insert(p_id);
} else { } else {
const int *pid = nullptr; for (KeyValue<int, PeerInfo> &E : peers_info) {
while ((pid = peers_info.next(pid))) { E.value.known_nodes.insert(p_id);
peers_info.get(*pid).known_nodes.insert(p_id);
} }
} }
return OK; return OK;
@ -208,9 +205,8 @@ Error SceneReplicationState::peer_del_node(int p_peer, const ObjectID &p_id) {
ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
peers_info[p_peer].known_nodes.erase(p_id); peers_info[p_peer].known_nodes.erase(p_id);
} else { } else {
const int *pid = nullptr; for (KeyValue<int, PeerInfo> &E : peers_info) {
while ((pid = peers_info.next(pid))) { E.value.known_nodes.erase(p_id);
peers_info.get(*pid).known_nodes.erase(p_id);
} }
} }
return OK; return OK;

View File

@ -81,8 +81,8 @@ private:
public: public:
const Set<int> get_peers() const { return known_peers; } const Set<int> get_peers() const { return known_peers; }
const Set<ObjectID> get_spawned_nodes() const { return spawned_nodes; } const Set<ObjectID> &get_spawned_nodes() const { return spawned_nodes; }
const Set<ObjectID> get_path_only_nodes() const { return path_only_nodes; } const Set<ObjectID> &get_path_only_nodes() const { return path_only_nodes; }
MultiplayerSynchronizer *get_synchronizer(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_synchronizer() : nullptr; } MultiplayerSynchronizer *get_synchronizer(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_synchronizer() : nullptr; }
MultiplayerSpawner *get_spawner(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_spawner() : nullptr; } MultiplayerSpawner *get_spawner(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_spawner() : nullptr; }

View File

@ -913,10 +913,10 @@ Error SceneState::pack(Node *p_scene) {
} }
variants.resize(variant_map.size()); variants.resize(variant_map.size());
const Variant *K = nullptr;
while ((K = variant_map.next(K))) { for (const KeyValue<Variant, int> &E : variant_map) {
int idx = variant_map[*K]; int idx = E.value;
variants.write[idx] = *K; variants.write[idx] = E.key;
} }
node_paths.resize(nodepath_map.size()); node_paths.resize(nodepath_map.size());

View File

@ -1165,7 +1165,7 @@ void SurfaceTool::generate_normals(bool p_flip) {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
Vector3 *lv = vertex_hash.getptr(v[i]); Vector3 *lv = vertex_hash.getptr(v[i]);
if (!lv) { if (!lv) {
vertex_hash.set(v[i], normal); vertex_hash.insert(v[i], normal);
} else { } else {
(*lv) += normal; (*lv) += normal;
} }

View File

@ -123,76 +123,50 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
void Theme::_get_property_list(List<PropertyInfo> *p_list) const { void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
List<PropertyInfo> list; List<PropertyInfo> list;
const StringName *key = nullptr;
// Type variations. // Type variations.
while ((key = variation_map.next(key))) { for (const KeyValue<StringName, StringName> &E : variation_map) {
list.push_back(PropertyInfo(Variant::STRING_NAME, String() + *key + "/base_type")); list.push_back(PropertyInfo(Variant::STRING_NAME, String() + E.key + "/base_type"));
} }
key = nullptr;
// Icons. // Icons.
while ((key = icon_map.next(key))) { for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : icon_map) {
const StringName *key2 = nullptr; for (const KeyValue<StringName, Ref<Texture2D>> &F : E.value) {
list.push_back(PropertyInfo(Variant::OBJECT, String() + E.key + "/icons/" + F.key, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
while ((key2 = icon_map[*key].next(key2))) {
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
} }
} }
key = nullptr;
// Styles. // Styles.
while ((key = style_map.next(key))) { for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : style_map) {
const StringName *key2 = nullptr; for (const KeyValue<StringName, Ref<StyleBox>> &F : E.value) {
list.push_back(PropertyInfo(Variant::OBJECT, String() + E.key + "/styles/" + F.key, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
while ((key2 = style_map[*key].next(key2))) {
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/styles/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
} }
} }
key = nullptr;
// Fonts. // Fonts.
while ((key = font_map.next(key))) { for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : font_map) {
const StringName *key2 = nullptr; for (const KeyValue<StringName, Ref<Font>> &F : E.value) {
list.push_back(PropertyInfo(Variant::OBJECT, String() + E.key + "/fonts/" + F.key, PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
while ((key2 = font_map[*key].next(key2))) {
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/fonts/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
} }
} }
key = nullptr;
// Font sizes. // Font sizes.
while ((key = font_size_map.next(key))) { for (const KeyValue<StringName, HashMap<StringName, int>> &E : font_size_map) {
const StringName *key2 = nullptr; for (const KeyValue<StringName, int> &F : E.value) {
list.push_back(PropertyInfo(Variant::INT, String() + E.key + "/font_sizes/" + F.key, PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
while ((key2 = font_size_map[*key].next(key2))) {
list.push_back(PropertyInfo(Variant::INT, String() + *key + "/font_sizes/" + *key2, PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
} }
} }
key = nullptr;
// Colors. // Colors.
while ((key = color_map.next(key))) { for (const KeyValue<StringName, HashMap<StringName, Color>> &E : color_map) {
const StringName *key2 = nullptr; for (const KeyValue<StringName, Color> &F : E.value) {
list.push_back(PropertyInfo(Variant::INT, String() + E.key + "/colors/" + F.key));
while ((key2 = color_map[*key].next(key2))) {
list.push_back(PropertyInfo(Variant::COLOR, String() + *key + "/colors/" + *key2));
} }
} }
key = nullptr;
// Constants. // Constants.
while ((key = constant_map.next(key))) { for (const KeyValue<StringName, HashMap<StringName, int>> &E : constant_map) {
const StringName *key2 = nullptr; for (const KeyValue<StringName, int> &F : E.value) {
list.push_back(PropertyInfo(Variant::INT, String() + E.key + "/constants/" + F.key));
while ((key2 = constant_map[*key].next(key2))) {
list.push_back(PropertyInfo(Variant::INT, String() + *key + "/constants/" + *key2));
} }
} }
@ -414,10 +388,8 @@ void Theme::get_icon_list(StringName p_theme_type, List<StringName> *p_list) con
return; return;
} }
const StringName *key = nullptr; for (const KeyValue<StringName, Ref<Texture2D>> &E : icon_map[p_theme_type]) {
p_list->push_back(E.key);
while ((key = icon_map[p_theme_type].next(key))) {
p_list->push_back(*key);
} }
} }
@ -437,9 +409,8 @@ void Theme::remove_icon_type(const StringName &p_theme_type) {
_freeze_change_propagation(); _freeze_change_propagation();
const StringName *L = nullptr; for (const KeyValue<StringName, Ref<Texture2D>> &E : icon_map[p_theme_type]) {
while ((L = icon_map[p_theme_type].next(L))) { Ref<Texture2D> icon = E.value;
Ref<Texture2D> icon = icon_map[p_theme_type][*L];
if (icon.is_valid()) { if (icon.is_valid()) {
icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
} }
@ -453,9 +424,8 @@ void Theme::remove_icon_type(const StringName &p_theme_type) {
void Theme::get_icon_type_list(List<StringName> *p_list) const { void Theme::get_icon_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list); ERR_FAIL_NULL(p_list);
const StringName *key = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : icon_map) {
while ((key = icon_map.next(key))) { p_list->push_back(E.key);
p_list->push_back(*key);
} }
} }
@ -528,10 +498,8 @@ void Theme::get_stylebox_list(StringName p_theme_type, List<StringName> *p_list)
return; return;
} }
const StringName *key = nullptr; for (const KeyValue<StringName, Ref<StyleBox>> &E : style_map[p_theme_type]) {
p_list->push_back(E.key);
while ((key = style_map[p_theme_type].next(key))) {
p_list->push_back(*key);
} }
} }
@ -551,9 +519,8 @@ void Theme::remove_stylebox_type(const StringName &p_theme_type) {
_freeze_change_propagation(); _freeze_change_propagation();
const StringName *L = nullptr; for (const KeyValue<StringName, Ref<StyleBox>> &E : style_map[p_theme_type]) {
while ((L = style_map[p_theme_type].next(L))) { Ref<StyleBox> style = E.value;
Ref<StyleBox> style = style_map[p_theme_type][*L];
if (style.is_valid()) { if (style.is_valid()) {
style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
} }
@ -567,9 +534,8 @@ void Theme::remove_stylebox_type(const StringName &p_theme_type) {
void Theme::get_stylebox_type_list(List<StringName> *p_list) const { void Theme::get_stylebox_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list); ERR_FAIL_NULL(p_list);
const StringName *key = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : style_map) {
while ((key = style_map.next(key))) { p_list->push_back(E.key);
p_list->push_back(*key);
} }
} }
@ -644,10 +610,8 @@ void Theme::get_font_list(StringName p_theme_type, List<StringName> *p_list) con
return; return;
} }
const StringName *key = nullptr; for (const KeyValue<StringName, Ref<Font>> &E : font_map[p_theme_type]) {
p_list->push_back(E.key);
while ((key = font_map[p_theme_type].next(key))) {
p_list->push_back(*key);
} }
} }
@ -667,9 +631,8 @@ void Theme::remove_font_type(const StringName &p_theme_type) {
_freeze_change_propagation(); _freeze_change_propagation();
const StringName *L = nullptr; for (const KeyValue<StringName, Ref<Font>> &E : font_map[p_theme_type]) {
while ((L = font_map[p_theme_type].next(L))) { Ref<Font> font = E.value;
Ref<Font> font = font_map[p_theme_type][*L];
if (font.is_valid()) { if (font.is_valid()) {
font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
} }
@ -683,9 +646,8 @@ void Theme::remove_font_type(const StringName &p_theme_type) {
void Theme::get_font_type_list(List<StringName> *p_list) const { void Theme::get_font_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list); ERR_FAIL_NULL(p_list);
const StringName *key = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : font_map) {
while ((key = font_map.next(key))) { p_list->push_back(E.key);
p_list->push_back(*key);
} }
} }
@ -747,10 +709,8 @@ void Theme::get_font_size_list(StringName p_theme_type, List<StringName> *p_list
return; return;
} }
const StringName *key = nullptr; for (const KeyValue<StringName, int> &E : font_size_map[p_theme_type]) {
p_list->push_back(E.key);
while ((key = font_size_map[p_theme_type].next(key))) {
p_list->push_back(*key);
} }
} }
@ -774,9 +734,8 @@ void Theme::remove_font_size_type(const StringName &p_theme_type) {
void Theme::get_font_size_type_list(List<StringName> *p_list) const { void Theme::get_font_size_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list); ERR_FAIL_NULL(p_list);
const StringName *key = nullptr; for (const KeyValue<StringName, HashMap<StringName, int>> &E : font_size_map) {
while ((key = font_size_map.next(key))) { p_list->push_back(E.key);
p_list->push_back(*key);
} }
} }
@ -836,10 +795,8 @@ void Theme::get_color_list(StringName p_theme_type, List<StringName> *p_list) co
return; return;
} }
const StringName *key = nullptr; for (const KeyValue<StringName, Color> &E : color_map[p_theme_type]) {
p_list->push_back(E.key);
while ((key = color_map[p_theme_type].next(key))) {
p_list->push_back(*key);
} }
} }
@ -863,9 +820,8 @@ void Theme::remove_color_type(const StringName &p_theme_type) {
void Theme::get_color_type_list(List<StringName> *p_list) const { void Theme::get_color_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list); ERR_FAIL_NULL(p_list);
const StringName *key = nullptr; for (const KeyValue<StringName, HashMap<StringName, Color>> &E : color_map) {
while ((key = color_map.next(key))) { p_list->push_back(E.key);
p_list->push_back(*key);
} }
} }
@ -925,10 +881,8 @@ void Theme::get_constant_list(StringName p_theme_type, List<StringName> *p_list)
return; return;
} }
const StringName *key = nullptr; for (const KeyValue<StringName, int> &E : constant_map[p_theme_type]) {
p_list->push_back(E.key);
while ((key = constant_map[p_theme_type].next(key))) {
p_list->push_back(*key);
} }
} }
@ -952,9 +906,8 @@ void Theme::remove_constant_type(const StringName &p_theme_type) {
void Theme::get_constant_type_list(List<StringName> *p_list) const { void Theme::get_constant_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list); ERR_FAIL_NULL(p_list);
const StringName *key = nullptr; for (const KeyValue<StringName, HashMap<StringName, int>> &E : constant_map) {
while ((key = constant_map.next(key))) { p_list->push_back(E.key);
p_list->push_back(*key);
} }
} }
@ -1311,52 +1264,12 @@ void Theme::remove_type(const StringName &p_theme_type) {
void Theme::get_type_list(List<StringName> *p_list) const { void Theme::get_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list); ERR_FAIL_NULL(p_list);
Set<StringName> types; get_icon_type_list(p_list);
const StringName *key = nullptr; get_stylebox_type_list(p_list);
get_font_type_list(p_list);
// Icons. get_font_size_type_list(p_list);
while ((key = icon_map.next(key))) { get_color_type_list(p_list);
types.insert(*key); get_constant_type_list(p_list);
}
key = nullptr;
// StyleBoxes.
while ((key = style_map.next(key))) {
types.insert(*key);
}
key = nullptr;
// Fonts.
while ((key = font_map.next(key))) {
types.insert(*key);
}
key = nullptr;
// Font sizes.
while ((key = font_size_map.next(key))) {
types.insert(*key);
}
key = nullptr;
// Colors.
while ((key = color_map.next(key))) {
types.insert(*key);
}
key = nullptr;
// Constants.
while ((key = constant_map.next(key))) {
types.insert(*key);
}
for (Set<StringName>::Element *E = types.front(); E; E = E->next()) {
p_list->push_back(E->get());
}
} }
void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, List<StringName> *p_list) { void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, List<StringName> *p_list) {
@ -1667,75 +1580,62 @@ void Theme::merge_with(const Ref<Theme> &p_other) {
// Colors. // Colors.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, Color>> &E : p_other->color_map) {
while ((K = p_other->color_map.next(K))) { for (const KeyValue<StringName, Color> &F : E.value) {
const StringName *L = nullptr; set_color(F.key, E.key, F.value);
while ((L = p_other->color_map[*K].next(L))) {
set_color(*L, *K, p_other->color_map[*K][*L]);
} }
} }
} }
// Constants. // Constants.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, int>> &E : p_other->constant_map) {
while ((K = p_other->constant_map.next(K))) { for (const KeyValue<StringName, int> &F : E.value) {
const StringName *L = nullptr; set_constant(F.key, E.key, F.value);
while ((L = p_other->constant_map[*K].next(L))) {
set_constant(*L, *K, p_other->constant_map[*K][*L]);
} }
} }
} }
// Fonts. // Fonts.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : p_other->font_map) {
while ((K = p_other->font_map.next(K))) { for (const KeyValue<StringName, Ref<Font>> &F : E.value) {
const StringName *L = nullptr; set_font(F.key, E.key, F.value);
while ((L = p_other->font_map[*K].next(L))) {
set_font(*L, *K, p_other->font_map[*K][*L]);
} }
} }
} }
// Font sizes. // Font sizes.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, int>> &E : p_other->font_size_map) {
while ((K = p_other->font_size_map.next(K))) { for (const KeyValue<StringName, int> &F : E.value) {
const StringName *L = nullptr; set_font_size(F.key, E.key, F.value);
while ((L = p_other->font_size_map[*K].next(L))) {
set_font_size(*L, *K, p_other->font_size_map[*K][*L]);
} }
} }
} }
// Icons. // Icons.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : p_other->icon_map) {
while ((K = p_other->icon_map.next(K))) { for (const KeyValue<StringName, Ref<Texture2D>> &F : E.value) {
const StringName *L = nullptr; set_icon(F.key, E.key, F.value);
while ((L = p_other->icon_map[*K].next(L))) {
set_icon(*L, *K, p_other->icon_map[*K][*L]);
} }
} }
} }
// Styleboxes. // Styleboxes.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : p_other->style_map) {
while ((K = p_other->style_map.next(K))) { for (const KeyValue<StringName, Ref<StyleBox>> &F : E.value) {
const StringName *L = nullptr; set_stylebox(F.key, E.key, F.value);
while ((L = p_other->style_map[*K].next(L))) {
set_stylebox(*L, *K, p_other->style_map[*K][*L]);
} }
} }
} }
// Type variations. // Type variations.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, StringName> &E : p_other->variation_map) {
while ((K = p_other->variation_map.next(K))) { set_type_variation(E.key, E.value);
set_type_variation(*K, p_other->variation_map[*K]);
} }
} }
@ -1745,12 +1645,10 @@ void Theme::merge_with(const Ref<Theme> &p_other) {
void Theme::clear() { void Theme::clear() {
// These items need disconnecting. // These items need disconnecting.
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : icon_map) {
while ((K = icon_map.next(K))) { for (const KeyValue<StringName, Ref<Texture2D>> &F : E.value) {
const StringName *L = nullptr; if (F.value.is_valid()) {
while ((L = icon_map[*K].next(L))) { Ref<Texture2D> icon = F.value;
Ref<Texture2D> icon = icon_map[*K][*L];
if (icon.is_valid()) {
icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
} }
} }
@ -1758,12 +1656,10 @@ void Theme::clear() {
} }
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : style_map) {
while ((K = style_map.next(K))) { for (const KeyValue<StringName, Ref<StyleBox>> &F : E.value) {
const StringName *L = nullptr; if (F.value.is_valid()) {
while ((L = style_map[*K].next(L))) { Ref<StyleBox> style = F.value;
Ref<StyleBox> style = style_map[*K][*L];
if (style.is_valid()) {
style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
} }
} }
@ -1771,12 +1667,10 @@ void Theme::clear() {
} }
{ {
const StringName *K = nullptr; for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : font_map) {
while ((K = font_map.next(K))) { for (const KeyValue<StringName, Ref<Font>> &F : E.value) {
const StringName *L = nullptr; if (F.value.is_valid()) {
while ((L = font_map[*K].next(L))) { Ref<Font> font = F.value;
Ref<Font> font = font_map[*K][*L];
if (font.is_valid()) {
font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
} }
} }

View File

@ -1959,10 +1959,9 @@ Vector<StringName> MaterialStorage::global_variable_get_list() const {
ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance.");
} }
const StringName *K = nullptr;
Vector<StringName> names; Vector<StringName> names;
while ((K = global_variables.variables.next(K))) { for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) {
names.push_back(*K); names.push_back(E.key);
} }
names.sort_custom<StringName::AlphCompare>(); names.sort_custom<StringName::AlphCompare>();
return names; return names;

View File

@ -1831,13 +1831,13 @@ void TextureStorage::update_decal_atlas() {
Vector<DecalAtlas::SortItem> itemsv; Vector<DecalAtlas::SortItem> itemsv;
itemsv.resize(decal_atlas.textures.size()); itemsv.resize(decal_atlas.textures.size());
int base_size = 8; int base_size = 8;
const RID *K = nullptr;
int idx = 0; int idx = 0;
while ((K = decal_atlas.textures.next(K))) {
for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) {
DecalAtlas::SortItem &si = itemsv.write[idx]; DecalAtlas::SortItem &si = itemsv.write[idx];
Texture *src_tex = get_texture(*K); Texture *src_tex = get_texture(E.key);
si.size.width = (src_tex->width / border) + 1; si.size.width = (src_tex->width / border) + 1;
si.size.height = (src_tex->height / border) + 1; si.size.height = (src_tex->height / border) + 1;
@ -1847,7 +1847,7 @@ void TextureStorage::update_decal_atlas() {
base_size = nearest_power_of_2_templated(si.size.width); base_size = nearest_power_of_2_templated(si.size.width);
} }
si.texture = *K; si.texture = E.key;
idx++; idx++;
} }
@ -1983,10 +1983,9 @@ void TextureStorage::update_decal_atlas() {
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
const RID *K = nullptr; for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) {
while ((K = decal_atlas.textures.next(K))) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(E.key);
DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); Texture *src_tex = get_texture(E.key);
Texture *src_tex = get_texture(*K);
copy_effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); copy_effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
} }

View File

@ -179,10 +179,10 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
print_line("GPU PROFILE (total " + rtos(total_time) + "ms): "); print_line("GPU PROFILE (total " + rtos(total_time) + "ms): ");
float print_threshold = 0.01; float print_threshold = 0.01;
for (OrderedHashMap<String, float>::Element E = print_gpu_profile_task_time.front(); E; E = E.next()) { for (const KeyValue<String, float> &E : print_gpu_profile_task_time) {
double time = E.value() / double(print_frame_profile_frame_count); double time = E.value / double(print_frame_profile_frame_count);
if (time > print_threshold) { if (time > print_threshold) {
print_line("\t-" + E.key() + ": " + rtos(time) + "ms"); print_line("\t-" + E.key + ": " + rtos(time) + "ms");
} }
} }
print_gpu_profile_task_time.clear(); print_gpu_profile_task_time.clear();

View File

@ -33,7 +33,7 @@
#include "core/math/octree.h" #include "core/math/octree.h"
#include "core/templates/command_queue_mt.h" #include "core/templates/command_queue_mt.h"
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
#include "renderer_canvas_cull.h" #include "renderer_canvas_cull.h"
#include "renderer_scene_cull.h" #include "renderer_scene_cull.h"
#include "renderer_viewport.h" #include "renderer_viewport.h"
@ -69,7 +69,7 @@ class RenderingServerDefault : public RenderingServer {
//for printing //for printing
bool print_gpu_profile = false; bool print_gpu_profile = false;
OrderedHashMap<String, float> print_gpu_profile_task_time; HashMap<String, float> print_gpu_profile_task_time;
uint64_t print_frame_profile_ticks_from = 0; uint64_t print_frame_profile_ticks_from = 0;
uint32_t print_frame_profile_frame_count = 0; uint32_t print_frame_profile_frame_count = 0;

View File

@ -31,7 +31,7 @@
#ifndef SHADERTYPES_H #ifndef SHADERTYPES_H
#define SHADERTYPES_H #define SHADERTYPES_H
#include "core/templates/ordered_hash_map.h" #include "core/templates/map.h"
#include "servers/rendering_server.h" #include "servers/rendering_server.h"
#include "shader_language.h" #include "shader_language.h"

View File

@ -173,7 +173,7 @@ struct NamesCache {
} }
}; };
typedef OrderedHashMap<StringName, ExposedClass> ExposedClasses; typedef HashMap<StringName, ExposedClass> ExposedClasses;
struct Context { struct Context {
Vector<StringName> enum_types; Vector<StringName> enum_types;
@ -183,13 +183,13 @@ struct Context {
NamesCache names_cache; NamesCache names_cache;
const ExposedClass *find_exposed_class(const StringName &p_name) const { const ExposedClass *find_exposed_class(const StringName &p_name) const {
ExposedClasses::ConstElement elem = exposed_classes.find(p_name); ExposedClasses::ConstIterator elem = exposed_classes.find(p_name);
return elem ? &elem.value() : nullptr; return elem ? &elem->value : nullptr;
} }
const ExposedClass *find_exposed_class(const TypeReference &p_type_ref) const { const ExposedClass *find_exposed_class(const TypeReference &p_type_ref) const {
ExposedClasses::ConstElement elem = exposed_classes.find(p_type_ref.name); ExposedClasses::ConstIterator elem = exposed_classes.find(p_type_ref.name);
return elem ? &elem.value() : nullptr; return elem ? &elem->value : nullptr;
} }
bool has_type(const TypeReference &p_type_ref) const { bool has_type(const TypeReference &p_type_ref) const {
@ -676,12 +676,11 @@ void add_exposed_classes(Context &r_context) {
// Add signals // Add signals
const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map; const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map;
const StringName *k = nullptr;
while ((k = signal_map.next(k))) { for (const KeyValue<StringName, MethodInfo> &K : signal_map) {
SignalData signal; SignalData signal;
const MethodInfo &method_info = signal_map.get(*k); const MethodInfo &method_info = signal_map.get(K.key);
signal.name = method_info.name; signal.name = method_info.name;
@ -734,14 +733,12 @@ void add_exposed_classes(Context &r_context) {
ClassDB::get_integer_constant_list(class_name, &constants, true); ClassDB::get_integer_constant_list(class_name, &constants, true);
const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map; const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
k = nullptr;
while ((k = enum_map.next(k))) { for (const KeyValue<StringName, List<StringName>> &K : enum_map) {
EnumData enum_; EnumData enum_;
enum_.name = *k; enum_.name = K.key;
const List<StringName> &enum_constants = enum_map.get(*k); for (const StringName &E : K.value) {
for (const StringName &E : enum_constants) {
const StringName &constant_name = E; const StringName &constant_name = E;
TEST_FAIL_COND(String(constant_name).find("::") != -1, TEST_FAIL_COND(String(constant_name).find("::") != -1,
"Enum constant contains '::', check bindings to remove the scope: '", "Enum constant contains '::', check bindings to remove the scope: '",
@ -760,7 +757,7 @@ void add_exposed_classes(Context &r_context) {
exposed_class.enums.push_back(enum_); exposed_class.enums.push_back(enum_);
r_context.enum_types.push_back(String(class_name) + "." + String(*k)); r_context.enum_types.push_back(String(class_name) + "." + String(K.key));
} }
for (const String &E : constants) { for (const String &E : constants) {
@ -850,8 +847,8 @@ TEST_SUITE("[ClassDB]") {
TEST_FAIL_COND(object_class->base != StringName(), TEST_FAIL_COND(object_class->base != StringName(),
"Object class derives from another class: '", object_class->base, "'."); "Object class derives from another class: '", object_class->base, "'.");
for (ExposedClasses::Element E = context.exposed_classes.front(); E; E = E.next()) { for (const KeyValue<StringName, ExposedClass> &E : context.exposed_classes) {
validate_class(context, E.value()); validate_class(context, E.value);
} }
} }
} }

View File

@ -1,5 +1,5 @@
/*************************************************************************/ /*************************************************************************/
/* test_ordered_hash_map.h */ /* test_hash_map.h */
/*************************************************************************/ /*************************************************************************/
/* This file is part of: */ /* This file is part of: */
/* GODOT ENGINE */ /* GODOT ENGINE */
@ -28,56 +28,53 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#ifndef TEST_ORDERED_HASH_MAP_H #ifndef TEST_HASH_MAP_H
#define TEST_ORDERED_HASH_MAP_H #define TEST_HASH_MAP_H
#include "core/templates/ordered_hash_map.h" #include "core/templates/hash_map.h"
#include "tests/test_macros.h" #include "tests/test_macros.h"
namespace TestOrderedHashMap { namespace TestHashMap {
TEST_CASE("[OrderedHashMap] Insert element") { TEST_CASE("[HashMap] Insert element") {
OrderedHashMap<int, int> map; HashMap<int, int> map;
OrderedHashMap<int, int>::Element e = map.insert(42, 84); HashMap<int, int>::Iterator e = map.insert(42, 84);
CHECK(e); CHECK(e);
CHECK(e.key() == 42); CHECK(e->key == 42);
CHECK(e.get() == 84); CHECK(e->value == 84);
CHECK(e.value() == 84);
CHECK(map[42] == 84); CHECK(map[42] == 84);
CHECK(map.has(42)); CHECK(map.has(42));
CHECK(map.find(42)); CHECK(map.find(42));
} }
TEST_CASE("[OrderedHashMap] Overwrite element") { TEST_CASE("[HashMap] Overwrite element") {
OrderedHashMap<int, int> map; HashMap<int, int> map;
map.insert(42, 84); map.insert(42, 84);
map.insert(42, 1234); map.insert(42, 1234);
CHECK(map[42] == 1234); CHECK(map[42] == 1234);
} }
TEST_CASE("[OrderedHashMap] Erase via element") { TEST_CASE("[HashMap] Erase via element") {
OrderedHashMap<int, int> map; HashMap<int, int> map;
OrderedHashMap<int, int>::Element e = map.insert(42, 84); HashMap<int, int>::Iterator e = map.insert(42, 84);
map.remove(e);
map.erase(e);
CHECK(!e);
CHECK(!map.has(42)); CHECK(!map.has(42));
CHECK(!map.find(42)); CHECK(!map.find(42));
} }
TEST_CASE("[OrderedHashMap] Erase via key") { TEST_CASE("[HashMap] Erase via key") {
OrderedHashMap<int, int> map; HashMap<int, int> map;
map.insert(42, 84); map.insert(42, 84);
map.erase(42); map.erase(42);
CHECK(!map.has(42)); CHECK(!map.has(42));
CHECK(!map.find(42)); CHECK(!map.find(42));
} }
TEST_CASE("[OrderedHashMap] Size") { TEST_CASE("[HashMap] Size") {
OrderedHashMap<int, int> map; HashMap<int, int> map;
map.insert(42, 84); map.insert(42, 84);
map.insert(123, 84); map.insert(123, 84);
map.insert(123, 84); map.insert(123, 84);
@ -87,8 +84,8 @@ TEST_CASE("[OrderedHashMap] Size") {
CHECK(map.size() == 4); CHECK(map.size() == 4);
} }
TEST_CASE("[OrderedHashMap] Iteration") { TEST_CASE("[HashMap] Iteration") {
OrderedHashMap<int, int> map; HashMap<int, int> map;
map.insert(42, 84); map.insert(42, 84);
map.insert(123, 12385); map.insert(123, 12385);
map.insert(0, 12934); map.insert(0, 12934);
@ -102,34 +99,35 @@ TEST_CASE("[OrderedHashMap] Iteration") {
expected.push_back(Pair<int, int>(123485, 1238888)); expected.push_back(Pair<int, int>(123485, 1238888));
int idx = 0; int idx = 0;
for (OrderedHashMap<int, int>::Element E = map.front(); E; E = E.next()) { for (const KeyValue<int, int> &E : map) {
CHECK(expected[idx] == Pair<int, int>(E.key(), E.value())); CHECK(expected[idx] == Pair<int, int>(E.key, E.value));
++idx; ++idx;
} }
} }
TEST_CASE("[OrderedHashMap] Const iteration") { TEST_CASE("[HashMap] Const iteration") {
OrderedHashMap<int, int> map; HashMap<int, int> map;
map.insert(42, 84); map.insert(42, 84);
map.insert(123, 12385); map.insert(123, 12385);
map.insert(0, 12934); map.insert(0, 12934);
map.insert(123485, 1238888); map.insert(123485, 1238888);
map.insert(123, 111111); map.insert(123, 111111);
const OrderedHashMap<int, int> const_map = map; const HashMap<int, int> const_map = map;
Vector<Pair<int, int>> expected; Vector<Pair<int, int>> expected;
expected.push_back(Pair<int, int>(42, 84)); expected.push_back(Pair<int, int>(42, 84));
expected.push_back(Pair<int, int>(123, 111111)); expected.push_back(Pair<int, int>(123, 111111));
expected.push_back(Pair<int, int>(0, 12934)); expected.push_back(Pair<int, int>(0, 12934));
expected.push_back(Pair<int, int>(123485, 1238888)); expected.push_back(Pair<int, int>(123485, 1238888));
expected.push_back(Pair<int, int>(123, 111111));
int idx = 0; int idx = 0;
for (OrderedHashMap<int, int>::ConstElement E = const_map.front(); E; E = E.next()) { for (const KeyValue<int, int> &E : const_map) {
CHECK(expected[idx] == Pair<int, int>(E.key(), E.value())); CHECK(expected[idx] == Pair<int, int>(E.key, E.value));
++idx; ++idx;
} }
} }
} // namespace TestOrderedHashMap } // namespace TestHashMap
#endif // TEST_ORDERED_HASH_MAP_H #endif // TEST_HASH_MAP_H

View File

@ -59,10 +59,10 @@
#include "tests/core/string/test_string.h" #include "tests/core/string/test_string.h"
#include "tests/core/string/test_translation.h" #include "tests/core/string/test_translation.h"
#include "tests/core/templates/test_command_queue.h" #include "tests/core/templates/test_command_queue.h"
#include "tests/core/templates/test_hash_map.h"
#include "tests/core/templates/test_list.h" #include "tests/core/templates/test_list.h"
#include "tests/core/templates/test_local_vector.h" #include "tests/core/templates/test_local_vector.h"
#include "tests/core/templates/test_lru.h" #include "tests/core/templates/test_lru.h"
#include "tests/core/templates/test_ordered_hash_map.h"
#include "tests/core/templates/test_paged_array.h" #include "tests/core/templates/test_paged_array.h"
#include "tests/core/templates/test_vector.h" #include "tests/core/templates/test_vector.h"
#include "tests/core/test_crypto.h" #include "tests/core/test_crypto.h"