Force String as Dictionary key instead of StringName

* Lua table syntax uses named indexing: `{ mykey = myvalue }`
* Python style syntax uses string indexing: `{ "mykey" : myvalue }`
* Both are incompatible since a StringName key wont fetch a String key, hence confusing.
* This PR proposes always using String for indexing at a very minimal performance cost. Always indexing with StringNames will be faster, but they are considerably more expensive to create.
This commit is contained in:
reduz 2021-07-01 16:03:37 -03:00
parent 382ddd497a
commit 379b90fd33

View file

@ -33,6 +33,11 @@
#include "core/templates/ordered_hash_map.h"
#include "core/templates/safe_refcount.h"
#include "core/variant/variant.h"
// required in this order by VariantInternal, do not remove this comment.
#include "core/object/class_db.h"
#include "core/object/object.h"
#include "core/variant/type_info.h"
#include "core/variant/variant_internal.h"
struct DictionaryPrivate {
SafeRefCount refcount;
@ -74,15 +79,32 @@ Variant Dictionary::get_value_at_index(int p_index) const {
}
Variant &Dictionary::operator[](const Variant &p_key) {
return _p->variant_map[p_key];
if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key);
return _p->variant_map[sn->operator String()];
} else {
return _p->variant_map[p_key];
}
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
return _p->variant_map[p_key];
if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key);
return _p->variant_map[sn->operator String()];
} else {
return _p->variant_map[p_key];
}
}
const Variant *Dictionary::getptr(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E;
if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key);
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
} else {
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
}
if (!E) {
return nullptr;
@ -91,8 +113,14 @@ const Variant *Dictionary::getptr(const Variant &p_key) const {
}
Variant *Dictionary::getptr(const Variant &p_key) {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key);
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E;
if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key);
E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
} else {
E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
}
if (!E) {
return nullptr;
}
@ -100,7 +128,14 @@ Variant *Dictionary::getptr(const Variant &p_key) {
}
Variant Dictionary::get_valid(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E;
if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key);
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
} else {
E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
}
if (!E) {
return Variant();
@ -126,7 +161,12 @@ bool Dictionary::is_empty() const {
}
bool Dictionary::has(const Variant &p_key) const {
return _p->variant_map.has(p_key);
if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key);
return _p->variant_map.has(sn->operator String());
} else {
return _p->variant_map.has(p_key);
}
}
bool Dictionary::has_all(const Array &p_keys) const {
@ -139,7 +179,12 @@ bool Dictionary::has_all(const Array &p_keys) const {
}
bool Dictionary::erase(const Variant &p_key) {
return _p->variant_map.erase(p_key);
if (p_key.get_type() == Variant::STRING_NAME) {
const StringName *sn = VariantInternal::get_string_name(&p_key);
return _p->variant_map.erase(sn->operator String());
} else {
return _p->variant_map.erase(p_key);
}
}
bool Dictionary::operator==(const Dictionary &p_dictionary) const {