summaryrefslogtreecommitdiffstats
path: root/core/variant/dictionary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant/dictionary.cpp')
-rw-r--r--core/variant/dictionary.cpp59
1 files changed, 49 insertions, 10 deletions
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index 0754814d35..2db754438f 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -83,35 +83,64 @@ Variant Dictionary::get_value_at_index(int p_index) const {
return Variant();
}
+// WARNING: This operator does not validate the value type. For scripting/extensions this is
+// done in `variant_setget.cpp`. Consider using `set()` if the data might be invalid.
Variant &Dictionary::operator[](const Variant &p_key) {
- if (unlikely(_p->read_only)) {
- if (likely(_p->variant_map.has(p_key))) {
- *_p->read_only = _p->variant_map[p_key];
+ Variant key = p_key;
+ if (unlikely(!_p->typed_key.validate(key, "use `operator[]`"))) {
+ if (unlikely(!_p->typed_fallback)) {
+ _p->typed_fallback = memnew(Variant);
+ }
+ VariantInternal::initialize(_p->typed_fallback, _p->typed_value.type);
+ return *_p->typed_fallback;
+ } else if (unlikely(_p->read_only)) {
+ if (likely(_p->variant_map.has(key))) {
+ *_p->read_only = _p->variant_map[key];
} else {
- *_p->read_only = Variant();
+ VariantInternal::initialize(_p->read_only, _p->typed_value.type);
}
-
return *_p->read_only;
} else {
- return _p->variant_map[p_key];
+ if (unlikely(!_p->variant_map.has(key))) {
+ VariantInternal::initialize(&_p->variant_map[key], _p->typed_value.type);
+ }
+ return _p->variant_map[key];
}
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
- // Will not insert key, so no conversion is necessary.
- return _p->variant_map[p_key];
+ Variant key = p_key;
+ if (unlikely(!_p->typed_key.validate(key, "use `operator[]`"))) {
+ if (unlikely(!_p->typed_fallback)) {
+ _p->typed_fallback = memnew(Variant);
+ }
+ VariantInternal::initialize(_p->typed_fallback, _p->typed_value.type);
+ return *_p->typed_fallback;
+ } else {
+ // Will not insert key, so no initialization is necessary.
+ return _p->variant_map[key];
+ }
}
const Variant *Dictionary::getptr(const Variant &p_key) const {
- HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(p_key));
+ Variant key = p_key;
+ if (unlikely(!_p->typed_key.validate(key, "getptr"))) {
+ return nullptr;
+ }
+ HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(key));
if (!E) {
return nullptr;
}
return &E->value;
}
+// WARNING: This method does not validate the value type.
Variant *Dictionary::getptr(const Variant &p_key) {
- HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::Iterator E(_p->variant_map.find(p_key));
+ Variant key = p_key;
+ if (unlikely(!_p->typed_key.validate(key, "getptr"))) {
+ return nullptr;
+ }
+ HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::Iterator E(_p->variant_map.find(key));
if (!E) {
return nullptr;
}
@@ -158,6 +187,16 @@ Variant Dictionary::get_or_add(const Variant &p_key, const Variant &p_default) {
return *result;
}
+bool Dictionary::set(const Variant &p_key, const Variant &p_value) {
+ ERR_FAIL_COND_V_MSG(_p->read_only, false, "Dictionary is in read-only state.");
+ Variant key = p_key;
+ ERR_FAIL_COND_V(!_p->typed_key.validate(key, "set"), false);
+ Variant value = p_value;
+ ERR_FAIL_COND_V(!_p->typed_value.validate(value, "set"), false);
+ _p->variant_map[key] = value;
+ return true;
+}
+
int Dictionary::size() const {
return _p->variant_map.size();
}