Object: Make deleted object access raise errors, not warnings

Clarify doc about not decaying to `null` for `free` and `queue_free`.

Part of #45639.
This commit is contained in:
Rémi Verschelde 2021-04-20 11:33:26 +02:00
parent bb10729c6e
commit 1c9203ad68
No known key found for this signature in database
GPG key ID: C3336907360768E1
5 changed files with 15 additions and 13 deletions

View file

@ -1769,7 +1769,7 @@ Variant::operator RID() const {
Object *obj = likely(_get_obj().rc) ? _get_obj().rc->get_ptr() : NULL;
if (unlikely(!obj)) {
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted get RID on a deleted object.");
ERR_PRINT("Attempted get RID on a deleted object.");
}
return RID();
}

View file

@ -1139,7 +1139,7 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
if (!obj) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted call on a deleted object.");
ERR_PRINT("Attempted method call on a deleted object.");
}
#endif
r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
@ -1318,7 +1318,7 @@ bool Variant::has_method(const StringName &p_method) const {
if (!obj) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted method check on a deleted object.");
ERR_PRINT("Attempted method check on a deleted object.");
}
#endif
return false;

View file

@ -1517,7 +1517,7 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
#ifdef DEBUG_ENABLED
if (unlikely(!obj)) {
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted set on a deleted object.");
ERR_PRINT("Attempted set on a deleted object.");
}
break;
}
@ -1685,7 +1685,7 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
if (r_valid)
*r_valid = false;
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted get on a deleted object.");
ERR_PRINT("Attempted get on a deleted object.");
}
return Variant();
}
@ -2170,7 +2170,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
#ifdef DEBUG_ENABLED
valid = false;
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted set on a deleted object.");
ERR_PRINT("Attempted set on a deleted object.");
}
#endif
return;
@ -2540,7 +2540,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
#ifdef DEBUG_ENABLED
valid = false;
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted get on a deleted object.");
ERR_PRINT("Attempted get on a deleted object.");
}
#endif
return Variant();
@ -2603,7 +2603,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
*r_valid = false;
}
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted 'in' on a deleted object.");
ERR_PRINT("Attempted 'in' on a deleted object.");
}
#endif
return false;
@ -2866,7 +2866,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
if (unlikely(!obj)) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted get property list on a deleted object.");
ERR_PRINT("Attempted get property list on a deleted object.");
}
#endif
return;
@ -2944,7 +2944,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
if (unlikely(!obj)) {
valid = false;
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted iteration start on a deleted object.");
ERR_PRINT("Attempted iteration start on a deleted object.");
}
return false;
}
@ -3111,7 +3111,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
if (unlikely(!obj)) {
valid = false;
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted iteration check next on a deleted object.");
ERR_PRINT("Attempted iteration check next on a deleted object.");
}
return false;
}
@ -3269,7 +3269,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
if (unlikely(!obj)) {
r_valid = false;
if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
WARN_PRINT("Attempted iteration get next on a deleted object.");
ERR_PRINT("Attempted iteration get next on a deleted object.");
}
return Variant();
}

View file

@ -564,6 +564,7 @@
</return>
<description>
Queues a node for deletion at the end of the current frame. When deleted, all of its child nodes will be deleted as well. This method ensures it's safe to delete the node, contrary to [method Object.free]. Use [method Object.is_queued_for_deletion] to check whether a node will be deleted at the end of the frame.
[b]Important:[/b] If you have a variable pointing to a node, it will [i]not[/i] be assigned to [code]null[/code] once the node is freed. Instead, it will point to a [i]previously freed instance[/i] and you should validate it with [method @GDScript.is_instance_valid] before attempting to call its methods or access its properties.
</description>
</method>
<method name="raise">

View file

@ -201,7 +201,8 @@
<return type="void">
</return>
<description>
Deletes the object from memory. Any pre-existing reference to the freed object will become invalid, e.g. [code]is_instance_valid(object)[/code] will return [code]false[/code].
Deletes the object from memory immediately. For [Node]s, you may want to use [method Node.queue_free] to queue the node for safe deletion at the end of the current frame.
[b]Important:[/b] If you have a variable pointing to an object, it will [i]not[/i] be assigned to [code]null[/code] once the object is freed. Instead, it will point to a [i]previously freed instance[/i] and you should validate it with [method @GDScript.is_instance_valid] before attempting to call its methods or access its properties.
</description>
</method>
<method name="get" qualifiers="const">