summaryrefslogtreecommitdiff
path: root/core/variant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant.cpp')
-rw-r--r--core/variant.cpp140
1 files changed, 108 insertions, 32 deletions
diff --git a/core/variant.cpp b/core/variant.cpp
index f4e4cd5341..c2ffe3721f 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -908,6 +908,14 @@ bool Variant::is_one() const {
return false;
}
+bool Variant::is_null() const {
+ if (type == OBJECT && _get_obj().obj) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
void Variant::reference(const Variant &p_variant) {
switch (type) {
@@ -999,7 +1007,20 @@ void Variant::reference(const Variant &p_variant) {
} break;
case OBJECT: {
- memnew_placement(_data._mem, ObjData(p_variant._get_obj()));
+ memnew_placement(_data._mem, ObjData);
+
+ if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) {
+ Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj);
+ if (!reference->reference()) {
+ _get_obj().obj = nullptr;
+ _get_obj().id = ObjectID();
+ break;
+ }
+ }
+
+ _get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj);
+ _get_obj().id = p_variant._get_obj().id;
+
} break;
case NODE_PATH: {
@@ -1114,8 +1135,15 @@ void Variant::clear() {
} break;
case OBJECT: {
+ if (_get_obj().id.is_reference()) {
+ //we are safe that there is a reference here
+ Reference *reference = static_cast<Reference *>(_get_obj().obj);
+ if (reference->unreference()) {
+ memdelete(reference);
+ }
+ }
_get_obj().obj = NULL;
- _get_obj().ref.unref();
+ _get_obj().id = ObjectID();
} break;
case _RID: {
// not much need probably
@@ -1248,6 +1276,14 @@ Variant::operator uint64_t() const {
}
}
+Variant::operator ObjectID() const {
+ if (type == INT) {
+ return ObjectID(_data._int);
+ } else {
+ return ObjectID();
+ }
+}
+
#ifdef NEED_LONG_INT
Variant::operator signed long() const {
@@ -1581,14 +1617,11 @@ String Variant::stringify(List<const void *> &stack) const {
case OBJECT: {
if (_get_obj().obj) {
-#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
- //only if debugging!
- if (!ObjectDB::instance_validate(_get_obj().obj)) {
- return "[Deleted Object]";
- };
+
+ if (!_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ return "[Freed Object]";
};
-#endif
+
return _get_obj().obj->to_string();
} else
return "[Object:null]";
@@ -1731,24 +1764,16 @@ Variant::operator NodePath() const {
return NodePath();
}
-Variant::operator RefPtr() const {
-
- if (type == OBJECT)
- return _get_obj().ref;
- else
- return RefPtr();
-}
-
Variant::operator RID() const {
if (type == _RID)
return *reinterpret_cast<const RID *>(_data._mem);
- else if (type == OBJECT && !_get_obj().ref.is_null()) {
- return _get_obj().ref.get_rid();
+ else if (type == OBJECT && _get_obj().obj == nullptr) {
+ return RID();
} else if (type == OBJECT && _get_obj().obj) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton()) {
- ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(_get_obj().obj), RID(), "Invalid pointer (object was deleted).");
+ ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, RID(), "Invalid pointer (object was freed).");
};
#endif
Variant::CallError ce;
@@ -1769,6 +1794,25 @@ Variant::operator Object *() const {
else
return NULL;
}
+
+Object *Variant::get_validated_object_with_check(bool &r_previously_freed) const {
+ if (type == OBJECT) {
+ Object *instance = ObjectDB::get_instance(_get_obj().id);
+ r_previously_freed = !instance && _get_obj().id != ObjectID();
+ return instance;
+ } else {
+ r_previously_freed = false;
+ return NULL;
+ }
+}
+
+Object *Variant::get_validated_object() const {
+ if (type == OBJECT)
+ return ObjectDB::get_instance(_get_obj().id);
+ else
+ return NULL;
+}
+
Variant::operator Node *() const {
if (type == OBJECT)
@@ -2193,6 +2237,11 @@ Variant::Variant(double p_double) {
_data._real = p_double;
}
+Variant::Variant(const ObjectID &p_id) {
+ type = INT;
+ _data._int = p_id;
+}
+
Variant::Variant(const StringName &p_string) {
type = STRING;
@@ -2276,15 +2325,6 @@ Variant::Variant(const NodePath &p_node_path) {
memnew_placement(_data._mem, NodePath(p_node_path));
}
-Variant::Variant(const RefPtr &p_resource) {
-
- type = OBJECT;
- memnew_placement(_data._mem, ObjData);
- REF *ref = reinterpret_cast<REF *>(p_resource.get_data());
- _get_obj().obj = ref->ptr();
- _get_obj().ref = p_resource;
-}
-
Variant::Variant(const RID &p_rid) {
type = _RID;
@@ -2296,7 +2336,24 @@ Variant::Variant(const Object *p_object) {
type = OBJECT;
memnew_placement(_data._mem, ObjData);
- _get_obj().obj = const_cast<Object *>(p_object);
+
+ if (p_object) {
+
+ if (p_object->is_reference()) {
+ Reference *reference = const_cast<Reference *>(static_cast<const Reference *>(p_object));
+ if (!reference->init_ref()) {
+ _get_obj().obj = nullptr;
+ _get_obj().id = ObjectID();
+ return;
+ }
+ }
+
+ _get_obj().obj = const_cast<Object *>(p_object);
+ _get_obj().id = p_object->get_instance_id();
+ } else {
+ _get_obj().obj = nullptr;
+ _get_obj().id = ObjectID();
+ }
}
Variant::Variant(const Dictionary &p_dictionary) {
@@ -2607,7 +2664,26 @@ void Variant::operator=(const Variant &p_variant) {
} break;
case OBJECT: {
- *reinterpret_cast<ObjData *>(_data._mem) = p_variant._get_obj();
+ if (_get_obj().id.is_reference()) {
+ //we are safe that there is a reference here
+ Reference *reference = static_cast<Reference *>(_get_obj().obj);
+ if (reference->unreference()) {
+ memdelete(reference);
+ }
+ }
+
+ if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) {
+ Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj);
+ if (!reference->reference()) {
+ _get_obj().obj = nullptr;
+ _get_obj().id = ObjectID();
+ break;
+ }
+ }
+
+ _get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj);
+ _get_obj().id = p_variant._get_obj().id;
+
} break;
case NODE_PATH: {
@@ -3118,7 +3194,7 @@ bool Variant::hash_compare(const Variant &p_variant) const {
bool Variant::is_ref() const {
- return type == OBJECT && !_get_obj().ref.is_null();
+ return type == OBJECT && _get_obj().id.is_reference();
}
Vector<Variant> varray() {