8 #include "ecore_private.h"
10 struct _Ecore_Idle_Enterer
17 Eina_Bool delete_me : 1;
19 GENERIC_ALLOC_SIZE_DECLARE(Ecore_Idle_Enterer);
21 static Ecore_Idle_Enterer *idle_enterers = NULL;
22 static Ecore_Idle_Enterer *idle_enterer_current = NULL;
23 static int idle_enterers_delete_me = 0;
26 _ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
29 * @addtogroup Ecore_Idle_Group
35 * Add an idle enterer handler.
36 * @param func The function to call when entering an idle state.
37 * @param data The data to be passed to the @p func call
38 * @return A handle to the idle enterer callback if successful. Otherwise,
40 * @note The function func will be called every time the main loop is entering
41 * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0
42 * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer.
44 EAPI Ecore_Idle_Enterer *
45 ecore_idle_enterer_add(Ecore_Task_Cb func,
48 Ecore_Idle_Enterer *ie = NULL;
50 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
53 if (!func) goto unlock;
54 ie = ecore_idle_enterer_calloc(1);
56 ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
58 ie->data = (void *)data;
59 idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
66 * Add an idle enterer handler at the start of the list so it gets called earlier than others.
67 * @param func The function to call when entering an idle state.
68 * @param data The data to be passed to the @p func call
69 * @return A handle to the idle enterer callback if successful. Otherwise,
71 * @note The function func will be called every time the main loop is entering
72 * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0
73 * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer.
75 EAPI Ecore_Idle_Enterer *
76 ecore_idle_enterer_before_add(Ecore_Task_Cb func,
79 Ecore_Idle_Enterer *ie = NULL;
81 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
84 if (!func) goto unlock;
85 ie = ecore_idle_enterer_calloc(1);
87 ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
89 ie->data = (void *)data;
90 idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
97 * Delete an idle enterer callback.
98 * @param idle_enterer The idle enterer to delete
99 * @return The data pointer passed to the idler enterer callback on success.
103 ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
107 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
108 if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER))
110 ECORE_MAGIC_FAIL(idle_enterer, ECORE_MAGIC_IDLE_ENTERER,
111 "ecore_idle_enterer_del");
115 data = _ecore_idle_enterer_del(idle_enterer);
125 _ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
127 EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL);
128 idle_enterer->delete_me = 1;
129 idle_enterers_delete_me = 1;
130 return idle_enterer->data;
134 _ecore_idle_enterer_shutdown(void)
136 Ecore_Idle_Enterer *ie;
137 while ((ie = idle_enterers))
139 idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
140 ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
141 ecore_idle_enterer_mp_free(ie);
143 idle_enterers_delete_me = 0;
144 idle_enterer_current = NULL;
148 _ecore_idle_enterer_call(void)
150 if (!idle_enterer_current)
152 /* regular main loop, start from head */
153 idle_enterer_current = idle_enterers;
157 /* recursive main loop, continue from where we were */
158 idle_enterer_current =
159 (Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
162 while (idle_enterer_current)
164 Ecore_Idle_Enterer *ie = (Ecore_Idle_Enterer *)idle_enterer_current;
168 if (!_ecore_call_task_cb(ie->func, ie->data))
170 if (!ie->delete_me) _ecore_idle_enterer_del(ie);
174 if (idle_enterer_current) /* may have changed in recursive main loops */
175 idle_enterer_current =
176 (Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
178 if (idle_enterers_delete_me)
180 Ecore_Idle_Enterer *l;
181 int deleted_idler_enterers_in_use = 0;
183 for (l = idle_enterers; l; )
185 Ecore_Idle_Enterer *ie = l;
186 l = (Ecore_Idle_Enterer *)EINA_INLIST_GET(l)->next;
191 deleted_idler_enterers_in_use++;
195 idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
196 ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
197 ecore_idle_enterer_mp_free(ie);
200 if (!deleted_idler_enterers_in_use)
201 idle_enterers_delete_me = 0;
206 _ecore_idle_enterer_exist(void)
208 if (idle_enterers) return 1;