WWW-www.enlightenment.org pushed a commit to branch master.

http://git.enlightenment.org/website/www-content.git/commit/?id=67539c96933e81d298e25ecdc4bc60c83a39ed16

commit 67539c96933e81d298e25ecdc4bc60c83a39ed16
Author: Xavi Artigas <xavierarti...@yahoo.es>
Date:   Fri May 25 10:23:59 2018 -0700

    Wiki page eo-intro.md changed with summary [Updated to efl_new] by Xavi 
Artigas
---
 pages/develop/tutorials/c/eo-intro.md.txt | 76 +++++++++++++++++--------------
 1 file changed, 42 insertions(+), 34 deletions(-)

diff --git a/pages/develop/tutorials/c/eo-intro.md.txt 
b/pages/develop/tutorials/c/eo-intro.md.txt
index 0d3767676..9df289b75 100644
--- a/pages/develop/tutorials/c/eo-intro.md.txt
+++ b/pages/develop/tutorials/c/eo-intro.md.txt
@@ -4,11 +4,12 @@
  
 # Introduction to Eo: Creating and Destroying Objects #
  
-The Eo generic object system was designed to provide *Object-Oriented 
capabilities* to EFL. Eo objects are at the core of almost every EFL entity 
(like Windows, Buttons or Timers) providing lifecycle management and 
inheritance abilities amongst other features.
+EFL is written in C and therefore lacks language support for [Object-oriented 
programming](https://en.wikipedia.org/wiki/Object-oriented_programming). 
+The Eo generic object system was designed to provide such capabilities to EFL. 
Eo objects are at the core of almost every EFL entity (like Windows, Buttons or 
Timers) providing lifecycle management and inheritance abilities amongst other 
features.
 
 This tutorial shows you the basics of creating and destroying Eo objects as 
well as *Reference Counting*, the technique at the heart of the Eo object 
lifecycle management.
 
-This tutorial is more theoretical than practical however the concepts being 
explained are crucial, so it's highly advisable to go through it. If you're 
familiar with Reference Counting, you should have no trouble.
+This tutorial is more theoretical than practical however the concepts being 
explained are crucial, so it's highly advisable to go through it. If you're 
familiar with Reference Counting, you should have no trouble at all.
  
 ## Prerequisites ##
  
@@ -70,26 +71,26 @@ static void
 _obj_create()
 {
    // First create a root element
-   _root = efl_add(EFL_MODEL_ITEM_CLASS, NULL,
+   _root = efl_new(EFL_MODEL_ITEM_CLASS,
                    efl_name_set(efl_added, "Root"));
 }
 ```
 
-``efl_add()`` is one of the most commonly-used methods in EFL so it requires 
careful inspection. It mainly does **three** separate things:
+``efl_new()`` is the most basic of the object creation methods. It does three 
things:
 
-* Creates a new object of the type (**class**) specified in the first 
parameter.
-* Sets the new object as a child of the already existing object specified in 
the second parameter.
+* Creates a new object of the type (**class**) specified in the first 
parameter and returns a pointer to it.
+* Calls any constructor method defined for the object's class.
 * Calls a list of methods to further initialize or configure the new object.
 
-In the code snippet above an object of type ``EFL_MODEL_ITEM_CLASS`` is 
created, as a child of nothing (the ``NULL`` parameter) and ``efl_name_set()`` 
is then used to configure the object (as explained below).
+In the code snippet above an object of type ``EFL_MODEL_ITEM_CLASS`` is 
created, and ``efl_name_set()`` is then used to configure the object (as 
explained below).
 
 Note that the specific type of object being created in this tutorial 
(``EFL_MODEL_ITEM_CLASS``) is not important. It was chosen because it does not 
need configuration and is therefore easier to use.
 
-You can use as many configuration calls inside ``efl_add()`` as you need, 
since it accepts an infinite number of parameters. Also, configuration calls 
can use the special symbol ``efl_added`` which refers to the object being 
created. Together these two powerful features make object creation code much 
more compact. You can create an object, configure it and add it to a scene 
without even requiring a variable to store it.
+You can use as many configuration calls inside ``efl_new()`` as you need, 
since it accepts an infinite number of parameters. Also, configuration calls 
can use the special symbol ``efl_added`` which refers to the object being 
created. Together these two powerful features make object creation code much 
more compact.
 
 In this example, ``efl_name_set()`` is used to name the new object "Root" 
(note the ``efl_added`` parameter being used).
 
-The return value of ``efl_add()`` is the new object with type ``Eo *``, which 
you can safely assign to a pointer of the specific type you requested or keep 
as the generic ``Eo *``. In this case the pointer is stored in the ``_root`` 
variable for later use.
+The return value of ``efl_new()`` is the new object with type ``Eo *``, which 
you can safely assign to a pointer of the specific type you requested or keep 
it as the generic ``Eo *``. In this case the pointer is stored in the ``_root`` 
variable for later use.
 
 At this point you have created your first Eo object. It is now time to decide 
who will be responsible for destroying it later. If the object is not destroyed 
system resources will eventually be exhausted. This is known as a *memory leak*.
 
@@ -97,24 +98,15 @@ At this point you have created your first Eo object. It is 
now time to decide wh
 
 In the simplest case when only one piece of code is interacting with an 
object, you can create the object, use it and then destroy it. In more complex 
scenarios where different parts of code use the same object, it's not easy to 
know when an object isn't in use anymore and can therefore be safely destroyed.
 
-A common approach to this problem is to use the **Reference Counting** 
technique whereby every object keeps track of how many people (pieces of code) 
are using it, using an internal *reference counter*:
+A common approach to this problem is to use the **Reference Counting** 
technique whereby every object keeps track of how many people (pieces of code) 
are using it, using an internal *reference counter* (*refcount* for short):
 
-* When somebody wants to work with a particular object it first needs to 
*obtain a reference* by using a call like ``efl_ref()`` on the object. This 
increments the internal reference counter.
+* ``efl_new()`` returns a new object with a reference counter of 1, meaning 
that the object is currently in use by one person: you, the caller of 
``efl_new()``.
+* If somebody else wants to work with that object it first needs to *obtain a 
reference* by using a call like ``efl_ref()`` on the object. This increments 
the internal reference counter.
 * When that piece of code is done working with the object it *returns the 
reference* by calling ``efl_unref()`` on the object in question. This 
decrements the internal reference counter.
 
 The advantage of this technique is that objects can automatically be destroyed 
when their internal reference counter reaches 0 as no one else is using them. 
 
-### Reference Counting and efl_add() ###
-
-Eo objects created through ``efl_add()`` have a starting reference count of 1, 
meaning that only one piece of code is using them. **You must know which code 
this is** as it will be responsible for returning the reference. This is very 
easy to do.
-
-* **If you assigned the object a parent** then said parent is the owner of the 
reference. There's nothing else that you need to do with the object. You cannot 
actually work with the object because you do not hold any reference to it (more 
about this later).
-* **If you gave no parent to the object**: If you passed ``NULL`` as the 
parent, then **you** are the owner of the reference and you are responsible for 
returning it with ``efl_unref()``. Forgetting to do so is the most common cause 
of memory leaks.
-
-> **NOTE:**
-> Parenthood does need to be permanent in EFL: you can always remove a child 
object from its parent using ``efl_unparent()``. Be careful, though, because 
this returns to you the reference the parent was holding. **You are now 
responsible for returning this reference**, and failing to do so will leak the 
object. If you want to remove the object from its parent **and** return the 
reference at the same time, you can use the convenience method ``efl_del()``.
-
-Back to the tutorial code, no parent was given to the object created in 
``_obj_create()``, therefore you need to return that reference at some point. 
It is time to fill-in the ``_obj_destroy()`` method:
+Back to the tutorial code, you obtained an object using ``efl_new()`` with a 
refcount of 1, therefore you need to return that reference at some point. It is 
time to fill-in the ``_obj_destroy()`` method:
 
 ```c
 static void
@@ -128,7 +120,7 @@ _obj_destroy()
 
 The reference you were holding to the ``_root`` object has now returned. Since 
it was the only existing reference to this object, the internal reference 
counter will reach 0 and the object will be destroyed. This isn't immediately 
obvious but you will explore this process further in the next tutorial. 
 
-The first step of the tutorial is now complete. You may not have seen much on 
screen but now understand the fundamental concept of **Object Lifecycle 
Management**: when objects are created and destroyed.
+The first step of the tutorial is now complete. You may not have seen much on 
screen but you now understand the fundamental concept of **Object Lifecycle 
Management**: when objects are created and destroyed.
 
 See below the complete listing, which you can build and run yourself:
 
@@ -148,7 +140,7 @@ static void
 _obj_create()
 {
    // First create a root element
-   _root = efl_add(EFL_MODEL_ITEM_CLASS, NULL,
+   _root = efl_new(EFL_MODEL_ITEM_CLASS,
                    efl_name_set(efl_added, "Root"));
 }
 
@@ -178,7 +170,7 @@ EFL_MAIN()
 
 ## Step Two: A More Complex Hierarchy ##
 
-In this second section more objects will be added, forming a hierarchy. This 
will give you more hands-on training with the concepts you acquired in the 
previous stection.
+In this second section more objects will be created as children of other 
objects, forming a hierarchy. This will give you more hands-on training with 
the concepts you acquired in the previous section.
 
 Start by adding two more global object pointers to keep track of the new 
objects. Just below the ``#includes``, replace the ``Eo *_root;`` line with:
 
@@ -186,7 +178,7 @@ Start by adding two more global object pointers to keep 
track of the new objects
 Eo *_root, *_child1, *_child2;
 ```
 
-Next, in the ``_obj_create()`` method add a new ``efl_add()`` line below the 
previous one:
+Next, in the ``_obj_create()`` method add these lines below the call to 
``efl_new()``:
 
 ```c
    // Create the first child element
@@ -194,7 +186,17 @@ Next, in the ``_obj_create()`` method add a new 
``efl_add()`` line below the pre
                      efl_name_set(efl_added, "Child1"));
 ```
 
-Here you are creating a new object (of type ``EFL_MODEL_ITEM_CLASS``, again) 
and setting its parent to ``_root``. As you learned in the previous section, 
since you are assigning the object a parent, its only reference now belongs to 
said parent. This means you don't need to worry about returning it. It also 
means that you won't be able to work with this object later on. In fact, you 
don't event need to keep the ``_child1`` pointer. It exists because you will be 
using it in the following  [...]
+``efl_add()`` is one of the most commonly-used methods in EFL so it requires 
careful inspection. It works the same way ``efl_new()`` does (it creates and 
initializes a new object), and it then gives the new object a **parent**. This 
means that the only reference to the new object **belongs to the parent**, so 
you don't need to worry about returning it. It also means that you won't be 
able to work with this object later on unless you obtain an extra reference. In 
fact, you don't event nee [...]
+
+As you can see, ``efl_add()`` is very convenient since it allows you to create 
an object, configure it and add it to a hierarchy without even requiring a 
variable to store it.
+
+> **NOTE:**
+>
+> Parenthood does not need to be permanent in EFL: you can always remove a 
child object from its parent using ``efl_parent_set(obj, NULL)``. Be careful, 
though, because this returns to you the reference the parent was holding. **You 
are now responsible for returning this reference**, and failing to do so will 
leak the object. If you want to remove the object from its parent **and** 
return the reference at the same time, you can use the convenience method 
``efl_del()``.
+>
+> Likewise, you can assign an object to a parent using ``efl_parent_set(obj, 
parent)``. This steals the reference from you and gives it to the new parent.
+
+In the above code snippet, you are creating a new object (of type 
``EFL_MODEL_ITEM_CLASS``, again) and setting its parent to ``_root``, so from 
this point onwards you can forget about this object: its parent will take care 
of it.
 
 Now add a second object immediately below the previous one:
 
@@ -204,7 +206,13 @@ Now add a second object immediately below the previous one:
                          efl_name_set(efl_added, "Child2"));
 ```
 
-This time you didn't use ``efl_add()`` but ``efl_add_ref()``. This method 
creates objects with an initial reference count of 2, one reference for the 
parent and one for you. This is handy when you want the object to have a parent 
but also want to work with it. Obviously, you will need to return the extra 
reference later on.
+This time you didn't use ``efl_add()`` but ``efl_add_ref()``. This method 
creates objects with an initial reference count of 2, one reference for the 
parent and one for you. This is handy when you want the object to have a parent 
but also want to work with it. You will need to return your extra reference 
later on, and the parent will return its own reference.
+
+> **NOTE:**
+>
+> ``efl_add_ref()`` accepts ``NULL`` as parent. In this case, it behaves 
exactly like ``efl_new()`` and returns an object with a single reference.
+>
+> ``efl_add()`` does **not** accept ``NULL`` as parent and will show an error 
message at runtime if you try.
 
 In this simple tutorial you will not be doing anything special with 
``_child2``: It has been created with an extra reference for example purposes 
only.
 
@@ -216,7 +224,7 @@ Next, move on to the ``_obj_destroy()`` method. You need to 
return the extra ref
    efl_unref(_child2);
 ```
 
-Note how you are **not** returning the reference to ``_child1``. This is 
because that reference belongs to its parent, ``_root``, which handles it. In 
this example when ``_root`` is destroyed it will also return the references for 
all its children. This in turn destroys ``_child1`` because there was only one 
reference to it but **not** ``_child2`` because there is an extra reference to 
it. You will manually return this with an explicit call to ``efl_unref()``).
+Note how you are **not** returning the reference to ``_child1``. This is 
because that reference belongs to its parent, ``_root``, which handles it. In 
this example when ``_root`` is destroyed it will also return the references for 
all its children. This in turn destroys ``_child1`` because there was only one 
reference to it but **not** ``_child2`` because there is an extra reference to 
it. You will manually return this with an explicit call to ``efl_unref()``.
 
 If you compile and run the complete code below you will only see messages 
about objects being deleted but in so doing you've learned about the very 
important topic of object creation and destruction, as well as how to avoid 
memory leaks.
 
@@ -236,7 +244,7 @@ static void
 _obj_create()
 {
    // First create a root element
-   _root = efl_add(EFL_MODEL_ITEM_CLASS, NULL,
+   _root = efl_new(EFL_MODEL_ITEM_CLASS,
                    efl_name_set(efl_added, "Root"));
 
    // Create the first child element
@@ -280,10 +288,10 @@ EFL_MAIN()
 
 At the end of this tutorial you have learned:
 
-* Objects are **created** with ``efl_add()``.
-* ``efl_add()`` creates objects with **one reference**, which belongs to their 
parent. You don't have to do anything to destroy the objects.
-* If you do not provide a parent to ``efl_add()`` then the reference belongs 
to **you**, and you have to return it when you are done working with the object 
using ``efl_unref()``.
-* Objects can be created with an **extra reference**  with ``efl_add_ref()``, 
which is useful if you want to give the object a parent and also start working 
with it right away.
+* **Standalone** (parent-less) objects are created with ``efl_new()``. You 
must manually destroy these objects using ``efl_unref()``.
+* ``efl_add()`` creates objects which **belong to their parent**. You don't 
have to do anything to destroy the objects.
+* Objects can be created with an **extra reference**  with ``efl_add_ref()``, 
which is useful if you want to give the object a parent and also start working 
with it right away. You must return the extra reference using ``efl_unref()``.
+* The parent of an object can be **changed** at any time using 
``efl_parent_set()``. Be careful with object ownership if you do so.
 
 The following tutorial builds on top of this one, adding instrumentation calls 
to display the actual values of the different reference counters.
 

-- 


Reply via email to