diff --git a/src/lib/eo/efl_object.eo b/src/lib/eo/efl_object.eo index 5aa1c846d8..a9ac302eee 100644 --- a/src/lib/eo/efl_object.eo +++ b/src/lib/eo/efl_object.eo @@ -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.]] } }