forked from enlightenment/efl
eo: Add API to allow deletion by unref
This allows deleting an object by simply calling efl_unref() on it, even if there is a parent. Normally the parent is in charge, and you can request deletion by calling efl_del() or efl_parent_set(NULL). But in some rare cases, you want to give ownership of an object (@owned) and still give a parent to that object. efl_unref() should be used (and would be used by bindings when going out of scope or on garbage collection), which would then print an error message. This API allows the specific behaviour. @feature
This commit is contained in:
parent
662a172139
commit
d3436af616
|
@ -262,6 +262,25 @@ abstract Efl.Object ()
|
|||
]]
|
||||
return: bool; [[$true if it is. $false otherwise.]]
|
||||
}
|
||||
@property allow_parent_unref {
|
||||
[[Allow an object to be deleted by unref even if it has a parent.
|
||||
|
||||
This simply hides error messages warning that an object being
|
||||
destructed still has a parent. This property is false by default.
|
||||
|
||||
In a normal object use case, when ownership of an object is given
|
||||
to a caller, said ownership should be released with efl_unref(). But
|
||||
if the object has a parent, this will print error messages, as
|
||||
$efl_unref() is stealing the ref from the parent.
|
||||
|
||||
Warning: Use this function very carefully, if you are absolutely
|
||||
sure of what you are doing.
|
||||
]]
|
||||
values {
|
||||
allow: bool(false); [[Whether to allow $efl_unref() to zero
|
||||
even if @.parent is not $null.]]
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
class.constructor;
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef struct
|
|||
Eina_Bool callback_stopped : 1;
|
||||
Eina_Bool need_cleaning : 1;
|
||||
Eina_Bool parent_sunk : 1; // If parent ref has already been settled (parent has been set, or we are in add_ref mode
|
||||
Eina_Bool allow_parent_unref : 1; // Allows unref to zero even with a parent
|
||||
} Efl_Object_Data;
|
||||
|
||||
typedef enum
|
||||
|
@ -2088,11 +2089,24 @@ composite_obj:
|
|||
goto composite_obj_back;
|
||||
|
||||
err_parent:
|
||||
ERR("Object '%p' still has a parent at the time of destruction.", obj);
|
||||
if (EINA_LIKELY(!pd->allow_parent_unref))
|
||||
ERR("Object '%p' still has a parent at the time of destruction.", obj);
|
||||
efl_parent_set(obj, NULL);
|
||||
goto err_parent_back;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_object_allow_parent_unref_set(Eo *obj_id EINA_UNUSED, Efl_Object_Data *pd, Eina_Bool allow)
|
||||
{
|
||||
pd->allow_parent_unref = !!allow;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_object_allow_parent_unref_get(Eo *obj_id EINA_UNUSED, Efl_Object_Data *pd)
|
||||
{
|
||||
return pd->allow_parent_unref;
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_efl_object_finalize(Eo *obj, Efl_Object_Data *pd EINA_UNUSED)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue