docs: Update efl_object lifecycle docs

Summary:
Explained the different phases, added method refs and removed outdated links.
Ref T7557

Reviewers: zmike, bu5hm4n

Reviewed By: bu5hm4n

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T7557

Differential Revision: https://phab.enlightenment.org/D7903
This commit is contained in:
Xavi Artigas 2019-02-11 14:00:04 +01:00
parent 1b568327c4
commit 8985222f47
1 changed files with 107 additions and 54 deletions

View File

@ -29,25 +29,54 @@ const Efl.Callback_Priority_After : Efl.Callback_Priority = 100;
abstract Efl.Object
{
[[Abstract Efl object class]]
[[Abstract EFL object class.
All EFL objects inherit from this class, which provides basic functionality
like naming, debugging, hierarchy traversal, event emission and life cycle
management.
Life Cycle
Objects are created with efl_add() and mostly disposed of with efl_del().
As an optimization, efl_add() accepts a list of initialization functions
which the programmer can use to further customize the object before it is
fully constructed.
Also, objects can have a parent which will keep them alive as long as the
parent is alive, so the programmer does not need to keep track of references.
(See the @.parent property for details).
Due to the above characteristics, EFL objects undergo the following phases
during their Life Cycle:
- Construction: The @.constructor method is called. Afterwards, any
user-supplied initialization methods are called.
- Finalization: The @.finalize method is called and @.finalized is set to
$true when it returns. Object is usable at this point.
- Invalidation: The object has lost its parent. The @.invalidate method is
called so all the object's relationships can be terminated. @.invalidated
is set to $true.
- Destruction: The object has no parent and it can be destroyed. The
@.destructor method is called, use it to return any resources the object
might have gathered during its life.
]]
eo_prefix: efl;
methods {
@property parent {
[[The parent of an object.
Parents keep references to their children. In order to
delete objects which have parents you need to set parent to
NULL or use efl_del(). This will both delete & unref
the object).
Parents keep references to their children and will release these
references when destroyed. In this way, objects can be assigned to
a parent upon creation, tying their life cycle so the programmer
does not need to worry about destroying the child object.
In order to destroy an object before its parent, set the parent to
$NULL and use efl_unref(), or use efl_del() directly.
The Eo parent is conceptually user set. That means that a parent
should not be changed behind the scenes in an unexpected way.
For example:
If you have a widget that has a box internally and
when you 'swallow' a widget and the swallowed object ends up in
the box, the parent should be the widget, not the box.
If you have a widget which can swallow objects into an internal
box, the parent of the swallowed objects should be the widget, not
the internal box. The user is not even aware of the existence of
the internal box.
]]
set {
@ -55,32 +84,31 @@ abstract Efl.Object
get {
}
values {
parent: Efl.Object @nullable; [[The new parent]]
parent: Efl.Object @nullable; [[The new parent.]]
}
}
@property name {
[[ The name of the object.
[[The name of the object.
Every object can have a string name. Names may not contain
the following characters:
/ ? * [ ] ! \ :
Using any of these in a name will result in undefined
behavior later on. An empty string is considered the same as a
NULL string or no string for the name.
Every EFL object can have a name. Names may not contain the
following characters: / ? * [ ] ! \ :
Using any of these in a name will result in undefined behavior
later on. An empty string is considered the same as a $NULL string
or no string for the name.
]]
set {
}
get {
}
values {
name: string @nullable; [[The name]]
name: string @nullable; [[The name.]]
}
}
@property comment {
[[ A human readable comment for the object
[[A human readable comment for the object.
Every object can have a string comment. This is intended for developers
and debugging. An empty string is considered the same as a NULL
Every EFL object can have a comment. This is intended for developers
and debugging. An empty string is considered the same as a $NULL
string or no string for the comment.
]]
set {
@ -88,11 +116,11 @@ abstract Efl.Object
get {
}
values {
comment: string @nullable; [[The comment]]
comment: string @nullable; [[The comment.]]
}
}
debug_name_override {
[[ Build a read-only name for this object used for debugging.
[[Build a read-only name for this object used for debugging.
Multiple calls using efl_super() can be chained in order to build
the entire debug name, from parent to child classes. In C the usual
@ -121,7 +149,7 @@ abstract Efl.Object
]]
}
values {
fcount: int; [[The global event freeze count]]
fcount: int; [[The global event freeze count.]]
}
}
@property event_freeze_count {
@ -135,34 +163,36 @@ abstract Efl.Object
]]
}
values {
fcount: int; [[The event freeze count of this object]]
fcount: int; [[The event freeze count of this object.]]
}
}
@property finalized {
[[True if the object is already finalized, otherwise false.]]
[[$true if the object has been finalized, i.e. construction has finished.
See the Life Cycle section in this class' description.]]
get {
}
values {
finalized: bool; [[$true if the object is finalized, $false otherwise]]
finalized: bool; [[$true if the object is finalized, $false otherwise.]]
}
}
@property invalidated {
[[True if the object is already invalidated, otherwise false.]]
[[$true if the object has been invalidated, i.e. it has no parent.
See the Life Cycle section in this class' description.]]
get {
}
values {
finalized: bool; [[$true if the object is invalidated, $false otherwise]]
finalized: bool; [[$true if the object is invalidated, $false otherwise.]]
}
}
@property invalidating {
[[True if the object is about to be invalidated, and the invalidation of the children is already happening.
Note this is true before the invalidate call on the object.
]]
[[$true if the object has started the invalidation phase, but has not
finished it yet.
Note: This might become $true before @.invalidate is called.
See the Life Cycle section in this class' description.]]
get {
}
values {
invalidating: bool; [[$true if the object is invalidating, $false otherwise]]
invalidating: bool; [[$true if the object is invalidating, $false otherwise.]]
}
}
provider_find @const {
@ -176,30 +206,53 @@ abstract Efl.Object
If this is not done the class cannot be found up in the object tree.
]]
params {
klass : const(Efl.Class); [[The class identifier to search for]]
klass : const(Efl.Class); [[The class identifier to search for.]]
}
return : Efl.Object; [[Object from the provider list]]
return : Efl.Object; [[Object from the provider list.]]
}
constructor {
[[Call the object's constructor.
[[Implement this method to provide optional initialization code for your object.
Should not be used with #eo_do. Only use it with #eo_do_super.
]]
return: Efl.Object; [[The new object created, can be NULL if aborting]]
See the Life Cycle section in this class' description.]]
return: Efl.Object; [[The new object, can be $NULL if aborted.]]
}
destructor {
[[Call the object's destructor.
[[Implement this method to provide deinitialization code for your object if you need it.
Should not be used with #efl_do. Only use it with #efl_do_super.
Will be triggered once #invalidate and #noref have been triggered.
]]
Will be called once @.invalidate has returned.
See the Life Cycle section in this class' description.]]
}
finalize {
[[Called at the end of efl_add. Should not be called, just overridden.]]
return: Efl.Object; [[The new object created, can be NULL if aborting]]
[[Implement this method to finish the initialization of your object
after all (if any) user-provided configuration methods have been
executed.
Use this method to delay expensive operations until user configuration
has finished, to avoid building the object in a "default" state in the
constructor, just to have to throw it all away because a user
configuration (a property being set, for example) requires a diferent
state.
This is the last call inside efl_add() and will set @.finalized to $true
once it returns.
This is an optimization and implementing this method is optional if you
already perform all your initialization in the @.constructor method.
See the Life Cycle section in this class' description.]]
return: Efl.Object; [[The new object. Return $NULL to abort object creation.]]
}
invalidate {
[[Called when parent reference is lost/set to $NULL and switch the state of the object to invalidate.]]
[[Implement this method to perform special actions when your object loses
its parent, if you need to.
It is called when the parent reference is lost or set to $NULL. After this
call returns, @.invalidated is set to $true.
This allows a simpler tear down of complex hierarchies, by performing
object destruction in two steps, first all object relationships are
broken and then the isolated objects are destroyed. Performing everything
in the @.destructor can sometimes lead to deadlocks, but implementing
this method is optional if this is not your case.
When an object with a parent is destroyed, it first receives a call to
@.invalidate and then to @.destructor.
See the Life Cycle section in this class' description.]]
}
name_find @const {
[[Find a child object with the given name and return it.
@ -211,9 +264,9 @@ abstract Efl.Object
the search will match any object of that class.
]]
params {
@in search: string; [[The name search string]]
@in search: string; [[The name search string.]]
}
return: Efl.Object; [[The first object found]]
return: Efl.Object; [[The first object found.]]
}
event_thaw {
[[Thaw events of object.
@ -334,13 +387,13 @@ abstract Efl.Object
In a normal object use case, when ownership of an object is given
to a caller, said ownership should be released with efl_unref().
If the object has a parent, this will print error messages, as
$efl_unref() is stealing the ref from the parent.
efl_unref() is stealing the ref from the parent.
Warning: Use this function very carefully, unless you're absolutely
sure of what you are doing.
]]
values {
allow: bool(false); [[Whether to allow $efl_unref() to zero
allow: bool(false); [[Whether to allow efl_unref() to zero
even if @.parent is not $null.]]
}
}
@ -350,12 +403,12 @@ abstract Efl.Object
class.destructor;
}
events {
del @hot: void; [[Object is being deleted.]]
invalidate @hot: void; [[Object is being invalidated and loosing its parent.]]
noref @hot: void; [[Object has lost its last reference, only parent relationship is keeping it alive.]]
del @hot: void; [[Object is being deleted. See @.destructor.]]
invalidate @hot: void; [[Object is being invalidated and losing its parent. See @.invalidate.]]
noref @hot: void; [[Object has lost its last reference, only parent relationship is keeping it alive. Advanced usage.]]
destruct @hot: void; [[Object has been fully destroyed. It can not be used
beyond this point. This event should only serve to clean up any
dangling pointer.]]
reference you keep to the object.]]
}
}