mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
Merge pull request #59452 from reduz/refactor-metadata
This commit is contained in:
commit
283246a9fe
9 changed files with 175 additions and 33 deletions
|
|
@ -416,12 +416,22 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
|
|||
}
|
||||
return;
|
||||
|
||||
} else if (p_name == CoreStringNames::get_singleton()->_meta) {
|
||||
metadata = p_value.duplicate();
|
||||
if (r_valid) {
|
||||
*r_valid = true;
|
||||
} else {
|
||||
OrderedHashMap<StringName, Variant>::Element *E = metadata_properties.getptr(p_name);
|
||||
if (E) {
|
||||
E->get() = p_value;
|
||||
if (r_valid) {
|
||||
*r_valid = true;
|
||||
}
|
||||
return;
|
||||
} else if (p_name.operator String().begins_with("metadata/")) {
|
||||
// Must exist, otherwise duplicate() will not work.
|
||||
set_meta(p_name.operator String().replace_first("metadata/", ""), p_value);
|
||||
if (r_valid) {
|
||||
*r_valid = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Something inside the object... :|
|
||||
|
|
@ -496,9 +506,12 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
|
|||
*r_valid = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} else if (p_name == CoreStringNames::get_singleton()->_meta) {
|
||||
ret = metadata;
|
||||
const OrderedHashMap<StringName, Variant>::Element *E = metadata_properties.getptr(p_name);
|
||||
|
||||
if (E) {
|
||||
ret = E->get();
|
||||
if (r_valid) {
|
||||
*r_valid = true;
|
||||
}
|
||||
|
|
@ -648,13 +661,20 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
|
|||
if (!is_class("Script")) { // can still be set, but this is for user-friendliness
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT));
|
||||
}
|
||||
if (!metadata.is_empty()) {
|
||||
p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||
}
|
||||
|
||||
if (script_instance && !p_reversed) {
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
|
||||
script_instance->get_property_list(p_list);
|
||||
}
|
||||
|
||||
for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) {
|
||||
PropertyInfo pi = PropertyInfo(K.value().get_type(), "metadata/" + K.key().operator String());
|
||||
if (K.value().get_type() == Variant::OBJECT) {
|
||||
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
||||
pi.hint_string = "Resource";
|
||||
}
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::_validate_property(PropertyInfo &property) const {
|
||||
|
|
@ -915,11 +935,23 @@ bool Object::has_meta(const StringName &p_name) const {
|
|||
|
||||
void Object::set_meta(const StringName &p_name, const Variant &p_value) {
|
||||
if (p_value.get_type() == Variant::NIL) {
|
||||
metadata.erase(p_name);
|
||||
if (metadata.has(p_name)) {
|
||||
metadata.erase(p_name);
|
||||
metadata_properties.erase("metadata/" + p_name.operator String());
|
||||
notify_property_list_changed();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
metadata[p_name] = p_value;
|
||||
OrderedHashMap<StringName, Variant>::Element E = metadata.find(p_name);
|
||||
if (E) {
|
||||
E.value() = p_value;
|
||||
} else {
|
||||
ERR_FAIL_COND(!p_name.operator String().is_valid_identifier());
|
||||
E = metadata.insert(p_name, p_value);
|
||||
metadata_properties["metadata/" + p_name.operator String()] = E;
|
||||
notify_property_list_changed();
|
||||
}
|
||||
}
|
||||
|
||||
Variant Object::get_meta(const StringName &p_name) const {
|
||||
|
|
@ -928,7 +960,7 @@ Variant Object::get_meta(const StringName &p_name) const {
|
|||
}
|
||||
|
||||
void Object::remove_meta(const StringName &p_name) {
|
||||
metadata.erase(p_name);
|
||||
set_meta(p_name, Variant());
|
||||
}
|
||||
|
||||
Array Object::_get_property_list_bind() const {
|
||||
|
|
@ -954,20 +986,16 @@ Array Object::_get_method_list_bind() const {
|
|||
Vector<StringName> Object::_get_meta_list_bind() const {
|
||||
Vector<StringName> _metaret;
|
||||
|
||||
List<Variant> keys;
|
||||
metadata.get_key_list(&keys);
|
||||
for (const Variant &E : keys) {
|
||||
_metaret.push_back(E);
|
||||
for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) {
|
||||
_metaret.push_back(K.key());
|
||||
}
|
||||
|
||||
return _metaret;
|
||||
}
|
||||
|
||||
void Object::get_meta_list(List<StringName> *p_list) const {
|
||||
List<Variant> keys;
|
||||
metadata.get_key_list(&keys);
|
||||
for (const Variant &E : keys) {
|
||||
p_list->push_back(E);
|
||||
for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) {
|
||||
p_list->push_back(K.key());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "core/templates/hash_map.h"
|
||||
#include "core/templates/list.h"
|
||||
#include "core/templates/map.h"
|
||||
#include "core/templates/ordered_hash_map.h"
|
||||
#include "core/templates/safe_refcount.h"
|
||||
#include "core/templates/set.h"
|
||||
#include "core/templates/vmap.h"
|
||||
|
|
@ -530,7 +531,8 @@ private:
|
|||
#endif
|
||||
ScriptInstance *script_instance = nullptr;
|
||||
Variant script; // Reference does not exist yet, store it in a Variant.
|
||||
Dictionary metadata;
|
||||
OrderedHashMap<StringName, Variant> metadata;
|
||||
HashMap<StringName, OrderedHashMap<StringName, Variant>::Element> metadata_properties;
|
||||
mutable StringName _class_name;
|
||||
mutable const StringName *_class_ptr = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -543,14 +543,12 @@ public:
|
|||
class VariantConstructNoArgsObject {
|
||||
public:
|
||||
static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
|
||||
VariantInternal::clear(&r_ret);
|
||||
VariantInternal::object_assign_null(&r_ret);
|
||||
r_ret = (Object *)nullptr; // Must construct a TYPE_OBJECT containing nullptr.
|
||||
r_error.error = Callable::CallError::CALL_OK;
|
||||
}
|
||||
|
||||
static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
|
||||
VariantInternal::clear(r_ret);
|
||||
VariantInternal::object_assign_null(r_ret);
|
||||
*r_ret = (Object *)nullptr; // Must construct a TYPE_OBJECT containing nullptr.
|
||||
}
|
||||
static void ptr_construct(void *base, const void **p_args) {
|
||||
PtrConstruct<Object *>::construct(nullptr, base);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue