summaryrefslogtreecommitdiff
path: root/src/lib/ecore/ecore_idle_enterer.c
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2016-04-21 14:07:16 -0700
committerCedric BAIL <cedric@osg.samsung.com>2016-04-21 14:07:49 -0700
commit5c87f2762fca7b4adc8940e1d77a4fdc6a214562 (patch)
tree3a0f18a7ce92bedd82d4f53bd2ec004b92d9829f /src/lib/ecore/ecore_idle_enterer.c
parent7c62154d52d7522b401ef0c362a75bbdad529d13 (diff)
ecore: use new refactorized idle infrastructure to make idle enterer rely on mainloop events
Diffstat (limited to 'src/lib/ecore/ecore_idle_enterer.c')
-rw-r--r--src/lib/ecore/ecore_idle_enterer.c200
1 files changed, 13 insertions, 187 deletions
diff --git a/src/lib/ecore/ecore_idle_enterer.c b/src/lib/ecore/ecore_idle_enterer.c
index 2acf290..5bcbab8 100644
--- a/src/lib/ecore/ecore_idle_enterer.c
+++ b/src/lib/ecore/ecore_idle_enterer.c
@@ -9,68 +9,16 @@
9#include "Ecore.h" 9#include "Ecore.h"
10#include "ecore_private.h" 10#include "ecore_private.h"
11 11
12#define MY_CLASS ECORE_IDLE_ENTERER_CLASS 12EO_CALLBACKS_ARRAY_DEFINE(ecore_idle_enterer_callbacks,
13 { ECORE_MAINLOOP_EVENT_IDLE_ENTER, _ecore_factorized_idle_process },
14 { EO_BASE_EVENT_DEL, _ecore_factorized_idle_event_del });
13 15
14#define MY_CLASS_NAME "Ecore_Idle_Enterer"
15
16struct _Ecore_Idle_Enterer_Data
17{
18 EINA_INLIST;
19 Ecore_Idle_Enterer *obj;
20 Ecore_Task_Cb func;
21 void *data;
22 int references;
23 Eina_Bool delete_me : 1;
24};
25typedef struct _Ecore_Idle_Enterer_Data Ecore_Idle_Enterer_Data;
26
27static Ecore_Idle_Enterer_Data *idle_enterers = NULL;
28static Ecore_Idle_Enterer_Data *idle_enterer_current = NULL;
29static int idle_enterers_delete_me = 0;
30
31static void *
32_ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
33
34static Eina_Bool
35_ecore_idle_enterer_add(Ecore_Idle_Enterer *obj,
36 Ecore_Idle_Enterer_Data *ie,
37 Ecore_Task_Cb func,
38 const void *data)
39{
40 if (EINA_UNLIKELY(!eina_main_loop_is()))
41 {
42 EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
43 }
44
45 ie->obj = obj;
46 eo_manual_free_set(obj, EINA_TRUE);
47
48 if (!func)
49 {
50 ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME);
51 return EINA_FALSE;
52 }
53
54 ie->func = func;
55 ie->data = (void *)data;
56 return EINA_TRUE;
57}
58 16
59EAPI Ecore_Idle_Enterer * 17EAPI Ecore_Idle_Enterer *
60ecore_idle_enterer_add(Ecore_Task_Cb func, 18ecore_idle_enterer_add(Ecore_Task_Cb func,
61 const void *data) 19 const void *data)
62{ 20{
63 Ecore_Idle_Enterer *ie = NULL; 21 return _ecore_factorized_idle_add(ecore_idle_enterer_callbacks(), func, data);
64 ie = eo_add(MY_CLASS, _ecore_parent, ecore_idle_enterer_after_constructor(eo_self, func, data));
65 return ie;
66}
67
68EOLIAN static void
69_ecore_idle_enterer_after_constructor(Eo *obj, Ecore_Idle_Enterer_Data *ie, Ecore_Task_Cb func, const void *data)
70{
71 if (!_ecore_idle_enterer_add(obj, ie, func, data)) return;
72
73 idle_enterers = (Ecore_Idle_Enterer_Data *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
74} 22}
75 23
76EAPI Ecore_Idle_Enterer * 24EAPI Ecore_Idle_Enterer *
@@ -78,146 +26,24 @@ ecore_idle_enterer_before_add(Ecore_Task_Cb func,
78 const void *data) 26 const void *data)
79{ 27{
80 Ecore_Idle_Enterer *ie = NULL; 28 Ecore_Idle_Enterer *ie = NULL;
81 ie = eo_add(MY_CLASS, _ecore_parent, ecore_idle_enterer_before_constructor(eo_self, func, data)); 29 ie = _ecore_factorized_idle_add(ecore_idle_enterer_callbacks(), func, data);
82 return ie;
83}
84 30
85EOLIAN static void 31 // This avoid us duplicating code and should only be slightly slower
86_ecore_idle_enterer_before_constructor(Eo *obj, Ecore_Idle_Enterer_Data *ie, Ecore_Task_Cb func, const void *data) 32 // due to a useless cycle of callback registration
87{ 33 eo_event_callback_array_del(_mainloop_singleton, ecore_idle_enterer_callbacks(), ie);
88 if (!_ecore_idle_enterer_add(obj, ie, func, data)) return; 34 eo_event_callback_array_priority_add(_mainloop_singleton, ecore_idle_enterer_callbacks(), EO_CALLBACK_PRIORITY_BEFORE, ie);
89 35
90 idle_enterers = (Ecore_Idle_Enterer_Data *)eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); 36 return ie;
91} 37}
92 38
93EAPI void * 39EAPI void *
94ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer) 40ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
95{ 41{
96 if (!idle_enterer) return NULL; 42 return _ecore_factorized_idle_del(idle_enterer);
97 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
98
99 return _ecore_idle_enterer_del(idle_enterer);
100}
101
102static void *
103_ecore_idle_enterer_del(Ecore_Idle_Enterer *obj)
104{
105 Ecore_Idle_Enterer_Data *idle_enterer = eo_data_scope_get(obj, MY_CLASS);
106
107 if (!idle_enterer) return NULL;
108 EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL);
109 idle_enterer->delete_me = 1;
110 idle_enterers_delete_me = 1;
111 return idle_enterer->data;
112}
113
114EOLIAN static void
115_ecore_idle_enterer_eo_base_destructor(Eo *obj, Ecore_Idle_Enterer_Data *idle_enterer)
116{
117 idle_enterer->delete_me = 1;
118 idle_enterers_delete_me = 1;
119
120 eo_destructor(eo_super(obj, MY_CLASS));
121}
122
123EOLIAN static Eo *
124_ecore_idle_enterer_eo_base_finalize(Eo *obj, Ecore_Idle_Enterer_Data *idle_enterer)
125{
126 if (!idle_enterer->func)
127 {
128 return NULL;
129 }
130
131 return eo_finalize(eo_super(obj, MY_CLASS));
132} 43}
133 44
134void 45void
135_ecore_idle_enterer_shutdown(void) 46_ecore_idle_enterer_call(Eo *loop)
136{ 47{
137 Ecore_Idle_Enterer_Data *ie; 48 eo_event_callback_call(loop, ECORE_MAINLOOP_EVENT_IDLE_ENTER, NULL);
138 while ((ie = idle_enterers))
139 {
140 idle_enterers = (Ecore_Idle_Enterer_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
141
142 eo_parent_set(ie->obj, NULL);
143 if (eo_destructed_is(ie->obj))
144 eo_manual_free(ie->obj);
145 else
146 eo_manual_free_set(ie->obj, EINA_FALSE);
147 }
148 idle_enterers_delete_me = 0;
149 idle_enterer_current = NULL;
150} 49}
151
152void
153_ecore_idle_enterer_call(void)
154{
155 if (!idle_enterer_current)
156 {
157 /* regular main loop, start from head */
158 idle_enterer_current = idle_enterers;
159 }
160 else
161 {
162 /* recursive main loop, continue from where we were */
163 idle_enterer_current =
164 (Ecore_Idle_Enterer_Data *)EINA_INLIST_GET(idle_enterer_current)->next;
165 }
166
167 while (idle_enterer_current)
168 {
169 Ecore_Idle_Enterer_Data *ie = (Ecore_Idle_Enterer_Data *)idle_enterer_current;
170 if (!ie->delete_me)
171 {
172 ie->references++;
173 eina_evlog("+idle_enterer", ie, 0.0, NULL);
174 if (!_ecore_call_task_cb(ie->func, ie->data))
175 {
176 if (!ie->delete_me) _ecore_idle_enterer_del(ie->obj);
177 }
178 eina_evlog("-idle_enterer", ie, 0.0, NULL);
179 ie->references--;
180 }
181 if (idle_enterer_current) /* may have changed in recursive main loops */
182 idle_enterer_current =
183 (Ecore_Idle_Enterer_Data *)EINA_INLIST_GET(idle_enterer_current)->next;
184 }
185 if (idle_enterers_delete_me)
186 {
187 Ecore_Idle_Enterer_Data *l;
188 int deleted_idler_enterers_in_use = 0;
189
190 for (l = idle_enterers; l; )
191 {
192 Ecore_Idle_Enterer_Data *ie = l;
193 l = (Ecore_Idle_Enterer_Data *)EINA_INLIST_GET(l)->next;
194 if (ie->delete_me)
195 {
196 if (ie->references)
197 {
198 deleted_idler_enterers_in_use++;
199 continue;
200 }
201
202 idle_enterers = (Ecore_Idle_Enterer_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
203
204 eo_parent_set(ie->obj, NULL);
205 if (eo_destructed_is(ie->obj))
206 eo_manual_free(ie->obj);
207 else
208 eo_manual_free_set(ie->obj, EINA_FALSE);
209 }
210 }
211 if (!deleted_idler_enterers_in_use)
212 idle_enterers_delete_me = 0;
213 }
214}
215
216int
217_ecore_idle_enterer_exist(void)
218{
219 if (idle_enterers) return 1;
220 return 0;
221}
222
223#include "ecore_idle_enterer.eo.c"