summaryrefslogtreecommitdiff
path: root/pages
diff options
context:
space:
mode:
authorBoris Faure <billiob+e@gmail.com>2018-05-14 13:38:49 -0700
committerapache <apache@e5-web1.enlightenment.org>2018-05-14 13:38:49 -0700
commit6119bfad9d98dc8b1d75511ebeecbb0db79b6272 (patch)
tree64429db699a2bfc7055af4e2e3f96839aaa08767 /pages
parentedb5ab0e1d5238f17942d73ac5ac79f05dc560e4 (diff)
Wiki page 2018-05-14-terminology-1.2.1 changed with summary [created] by Boris Faure
Diffstat (limited to 'pages')
-rw-r--r--pages/news/2018-05-14-terminology-1.2.1.txt18
-rw-r--r--pages/sandbox/eo-intro-new.md.txt306
2 files changed, 18 insertions, 306 deletions
diff --git a/pages/news/2018-05-14-terminology-1.2.1.txt b/pages/news/2018-05-14-terminology-1.2.1.txt
new file mode 100644
index 000000000..12119450a
--- /dev/null
+++ b/pages/news/2018-05-14-terminology-1.2.1.txt
@@ -0,0 +1,18 @@
1=== Terminology 1.2.1 Release ===
2 * //2018-05-14 - by Boris Faure//
3
4I am pleased to release Terminology 1.2.1 today!
5
6== Fixes ==
7 * Fix focus issues when input was not registering
8 * User-defined tab titles stay even when terminal wants change it
9 * Themes no longer have glow when unfocused
10
11
12== Download ==
13
14^ ** LINK ** ^ ** SHA256 ** ^
15| [[ https://download.enlightenment.org/rel/apps/terminology/terminology-1.2.1.tar.xz | Terminology 1.2.1 XZ]] | ''ac8673a129ed78ef669a8c04e7a136f5ca95226ce5ef375a451421bac41828c6'' |
16{{:blank.png?nolink&100|}}
17~~DISCUSSIONS~~
18
diff --git a/pages/sandbox/eo-intro-new.md.txt b/pages/sandbox/eo-intro-new.md.txt
deleted file mode 100644
index 9df289b75..000000000
--- a/pages/sandbox/eo-intro-new.md.txt
+++ /dev/null
@@ -1,306 +0,0 @@
1---
2~~Title: Introduction to Eo~~
3---
4
5# Introduction to Eo: Creating and Destroying Objects #
6
7EFL is written in C and therefore lacks language support for [Object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming).
8The 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.
9
10This 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.
11
12This 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.
13
14## Prerequisites ##
15
16* Read the [Setting up the Development Environment](/develop/setup/c/) guide so you are able to build and run EFL applications.
17* Read the [Hello World tutorial](hello-world.md) so you know the basics of building an EFL application.
18
19## Step One: Object Creation and Destruction ##
20
21Start with the basic EFL application skeleton from the [Hello World tutorial](hello-world.md) and add some placeholder methods that will be filled later on:
22
23```c
24#define EFL_EO_API_SUPPORT 1
25#define EFL_BETA_API_SUPPORT 1
26
27#include <Eina.h>
28#include <Efl_Core.h>
29
30// Create our test hierarchy
31static void
32_obj_create()
33{
34}
35
36// Destroy the test hierarchy
37static void
38_obj_destroy()
39{
40}
41
42EAPI_MAIN void
43efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
44{
45 // Create all objects
46 _obj_create();
47
48 // Destroy all objects
49 _obj_destroy();
50
51 // Exit
52 efl_exit(0);
53}
54EFL_MAIN()
55```
56
57Sensibly enough the objects are created in ``_obj_create()`` and destroyed in ``_obj_destroy()``.
58
59Also define some global pointers to keep track of the created objects. In a real application you won't be using global variables but do so in this tutorial for the sake of simplicity. Place this line after the includes:
60
61```c
62Eo *_root;
63```
64
65This tutorial will use generic ``Eo *`` pointers to store objects. Your programs can use these too or use more specific types like ``Efl_Ui_Win *`` or ``Efl_Ui_Button *``. EFL methods will accept both types (generic and specific) and perform runtime checks to ensure that you provide objects of the type expected by a method.
66
67Next fill-in the object creation method:
68
69```c
70static void
71_obj_create()
72{
73 // First create a root element
74 _root = efl_new(EFL_MODEL_ITEM_CLASS,
75 efl_name_set(efl_added, "Root"));
76}
77```
78
79``efl_new()`` is the most basic of the object creation methods. It does three things:
80
81* Creates a new object of the type (**class**) specified in the first parameter and returns a pointer to it.
82* Calls any constructor method defined for the object's class.
83* Calls a list of methods to further initialize or configure the new object.
84
85In 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).
86
87Note 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.
88
89You 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.
90
91In this example, ``efl_name_set()`` is used to name the new object "Root" (note the ``efl_added`` parameter being used).
92
93The 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.
94
95At 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*.
96
97### Reference Counting ###
98
99In 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.
100
101A 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):
102
103* ``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()``.
104* 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.
105* 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.
106
107The 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.
108
109Back 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:
110
111```c
112static void
113_obj_destroy()
114{
115 // Destroy the root element
116 printf ("Deleting root...\n");
117 efl_unref(_root);
118}
119```
120
121The 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.
122
123The 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.
124
125See below the complete listing, which you can build and run yourself:
126
127```c
128#define EFL_EO_API_SUPPORT 1
129#define EFL_BETA_API_SUPPORT 1
130
131#include <Eina.h>
132#include <Efl_Core.h>
133
134#include <stdlib.h>
135
136Eo *_root;
137
138// Create our test hierarchy
139static void
140_obj_create()
141{
142 // First create a root element
143 _root = efl_new(EFL_MODEL_ITEM_CLASS,
144 efl_name_set(efl_added, "Root"));
145}
146
147// Destroy the test hierarchy
148static void
149_obj_destroy()
150{
151 // Destroy the root element
152 printf ("Deleting root...\n");
153 efl_unref(_root);
154}
155
156EAPI_MAIN void
157efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
158{
159 // Create all objects
160 _obj_create();
161
162 // Destroy all objects
163 _obj_destroy();
164
165 // Exit
166 efl_exit(0);
167}
168EFL_MAIN()
169```
170
171## Step Two: A More Complex Hierarchy ##
172
173In 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.
174
175Start by adding two more global object pointers to keep track of the new objects. Just below the ``#includes``, replace the ``Eo *_root;`` line with:
176
177```c
178Eo *_root, *_child1, *_child2;
179```
180
181Next, in the ``_obj_create()`` method add these lines below the call to ``efl_new()``:
182
183```c
184 // Create the first child element
185 _child1 = efl_add(EFL_MODEL_ITEM_CLASS, _root,
186 efl_name_set(efl_added, "Child1"));
187```
188
189``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 need to keep the ``_child1`` pointer. It exists because you will be using it in the following tutorial.
190
191As 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.
192
193> **NOTE:**
194>
195> 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()``.
196>
197> 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.
198
199In 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.
200
201Now add a second object immediately below the previous one:
202
203```c
204 // Create the second child element, this time, with an extra reference
205 _child2 = efl_add_ref(EFL_MODEL_ITEM_CLASS, _root,
206 efl_name_set(efl_added, "Child2"));
207```
208
209This 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.
210
211> **NOTE:**
212>
213> ``efl_add_ref()`` accepts ``NULL`` as parent. In this case, it behaves exactly like ``efl_new()`` and returns an object with a single reference.
214>
215> ``efl_add()`` does **not** accept ``NULL`` as parent and will show an error message at runtime if you try.
216
217In this simple tutorial you will not be doing anything special with ``_child2``: It has been created with an extra reference for example purposes only.
218
219Next, move on to the ``_obj_destroy()`` method. You need to return the extra reference to ``_child2``, immediately below the previous call to ``efl_unref()``:
220
221```c
222 // Destroy the child2 element, for which we were keeping an extra reference
223 printf ("Deleting Child2...\n");
224 efl_unref(_child2);
225```
226
227Note 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()``.
228
229If 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.
230
231```c
232#define EFL_EO_API_SUPPORT 1
233#define EFL_BETA_API_SUPPORT 1
234
235#include <Eina.h>
236#include <Efl_Core.h>
237
238#include <stdlib.h>
239
240Eo *_root, *_child1, *_child2;
241
242// Create our test hierarchy
243static void
244_obj_create()
245{
246 // First create a root element
247 _root = efl_new(EFL_MODEL_ITEM_CLASS,
248 efl_name_set(efl_added, "Root"));
249
250 // Create the first child element
251 _child1 = efl_add(EFL_MODEL_ITEM_CLASS, _root,
252 efl_name_set(efl_added, "Child1"));
253
254 // Create the second child element, this time, with an extra reference
255 _child2 = efl_add_ref(EFL_MODEL_ITEM_CLASS, _root,
256 efl_name_set(efl_added, "Child2"));
257}
258
259// Destroy the test hierarchy
260static void
261_obj_destroy()
262{
263 // Destroy the root element
264 printf ("Deleting root...\n");
265 efl_unref(_root);
266
267 // Destroy the child2 element, for which we were keeping an extra reference
268 printf ("Deleting Child2...\n");
269 efl_unref(_child2);
270}
271
272EAPI_MAIN void
273efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
274{
275 // Create all objects
276 _obj_create();
277
278 // Destroy all objects
279 _obj_destroy();
280
281 // Exit
282 efl_exit(0);
283}
284EFL_MAIN()
285```
286
287## Summary ##
288
289At the end of this tutorial you have learned:
290
291* **Standalone** (parent-less) objects are created with ``efl_new()``. You must manually destroy these objects using ``efl_unref()``.
292* ``efl_add()`` creates objects which **belong to their parent**. You don't have to do anything to destroy the objects.
293* 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()``.
294* The parent of an object can be **changed** at any time using ``efl_parent_set()``. Be careful with object ownership if you do so.
295
296The following tutorial builds on top of this one, adding instrumentation calls to display the actual values of the different reference counters.
297
298## Further Reading ##
299[Reference Counting in Eo](eo-refcount.md)
300: Next tutorial in this series
301
302[Setting up the Development Environment](/develop/setup/c/)
303: Read this before trying to develop with the EFL
304
305[Hello World tutorial](hello-world.md)
306: Teaches the basic EFL application skeleton