summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2017-08-26 19:59:39 -0300
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2017-08-27 11:47:55 -0300
commit4d7661b1746dcb2ba5d146700de887ecbe2e462e (patch)
tree5ebc792a722e2a7796a993878595f1a7b2c7e7f1
parentf3d56425031b2f40e111d78e98129b6a2846a26d (diff)
Efl_Loop: add job, timeout and idle based on Eina_Future.devs/barbieri/future
Since some clash with old version, then add Eina_FutureXXX to their name, later we'll sed.
-rw-r--r--src/lib/ecore/ecore_alloc.c3
-rw-r--r--src/lib/ecore/ecore_main.c104
-rw-r--r--src/lib/ecore/ecore_private.h3
-rw-r--r--src/lib/ecore/efl_loop.eo25
-rw-r--r--src/tests/ecore/ecore_test_promise2.c64
5 files changed, 199 insertions, 0 deletions
diff --git a/src/lib/ecore/ecore_alloc.c b/src/lib/ecore/ecore_alloc.c
index bec66ef0d5..3196b82a2d 100644
--- a/src/lib/ecore/ecore_alloc.c
+++ b/src/lib/ecore/ecore_alloc.c
@@ -44,6 +44,7 @@ GENERIC_ALLOC_FREE(Ecore_Event, ecore_event);
44//GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller); 44//GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller);
45GENERIC_ALLOC_FREE(Ecore_Pipe, ecore_pipe); 45GENERIC_ALLOC_FREE(Ecore_Pipe, ecore_pipe);
46GENERIC_ALLOC_FREE(Ecore_Fd_Handler, ecore_fd_handler); 46GENERIC_ALLOC_FREE(Ecore_Fd_Handler, ecore_fd_handler);
47GENERIC_ALLOC_FREE(Efl_Loop_Promise_Simple_Data, efl_loop_promise_simple_data);
47#ifdef _WIN32 48#ifdef _WIN32
48GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler); 49GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler);
49#endif 50#endif
@@ -61,6 +62,7 @@ static Ecore_Mempool *mempool_array[] = {
61// &ecore_poller_mp, 62// &ecore_poller_mp,
62 &ecore_pipe_mp, 63 &ecore_pipe_mp,
63 &ecore_fd_handler_mp, 64 &ecore_fd_handler_mp,
65 &efl_loop_promise_simple_data_mp,
64#ifdef _WIN32 66#ifdef _WIN32
65 &ecore_win32_handler_mp 67 &ecore_win32_handler_mp
66#endif 68#endif
@@ -87,6 +89,7 @@ ecore_mempool_init(void)
87// MP_SIZE_INIT(Ecore_Poller, ecore_poller); 89// MP_SIZE_INIT(Ecore_Poller, ecore_poller);
88 MP_SIZE_INIT(Ecore_Pipe, ecore_pipe); 90 MP_SIZE_INIT(Ecore_Pipe, ecore_pipe);
89 MP_SIZE_INIT(Ecore_Fd_Handler, ecore_fd_handler); 91 MP_SIZE_INIT(Ecore_Fd_Handler, ecore_fd_handler);
92 MP_SIZE_INIT(Efl_Loop_Promise_Simple_Data, efl_loop_promise_simple_data);
90#ifdef _WIN32 93#ifdef _WIN32
91 MP_SIZE_INIT(Ecore_Win32_Handler, ecore_win32_handler); 94 MP_SIZE_INIT(Ecore_Win32_Handler, ecore_win32_handler);
92#endif 95#endif
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 0bb15e0c02..6819a05d7e 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -233,6 +233,15 @@ struct _Ecore_Fd_Handler
233}; 233};
234GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler); 234GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler);
235 235
236typedef struct _Efl_Loop_Promise_Simple_Data {
237 union {
238 Ecore_Timer *timer;
239 Ecore_Idler *idler;
240 };
241 Eina_Promise *promise;
242} Efl_Loop_Promise_Simple_Data;
243GENERIC_ALLOC_SIZE_DECLARE(Efl_Loop_Promise_Simple_Data);
244
236#ifdef _WIN32 245#ifdef _WIN32
237struct _Ecore_Win32_Handler 246struct _Ecore_Win32_Handler
238{ 247{
@@ -3112,6 +3121,101 @@ EFL_CALLBACKS_ARRAY_DEFINE(timeout,
3112 { EFL_LOOP_TIMER_EVENT_TICK, _efl_loop_timeout_cb }, 3121 { EFL_LOOP_TIMER_EVENT_TICK, _efl_loop_timeout_cb },
3113 { EFL_EVENT_DEL, _efl_loop_timeout_force_cancel_cb }); 3122 { EFL_EVENT_DEL, _efl_loop_timeout_force_cancel_cb });
3114 3123
3124static Eina_Future *
3125_efl_loop_Eina_FutureXXX_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
3126{
3127 // NOTE: Eolian should do efl_future_then() to bind future to object.
3128 return efl_future_Eina_FutureXXX_then(obj,
3129 eina_future_resolved(efl_loop_future_scheduler_get(obj),
3130 EINA_VALUE_EMPTY));
3131}
3132
3133static void
3134_efl_loop_Eina_FutureXXX_idle_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
3135{
3136 Efl_Loop_Promise_Simple_Data *d = data;
3137 ecore_idler_del(d->idler);
3138 efl_loop_promise_simple_data_mp_free(d);
3139}
3140
3141static Eina_Bool
3142_efl_loop_Eina_FutureXXX_idle_done(void *data)
3143{
3144 Efl_Loop_Promise_Simple_Data *d = data;
3145 eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
3146 efl_loop_promise_simple_data_mp_free(d);
3147 return EINA_FALSE;
3148}
3149
3150static Eina_Future *
3151_efl_loop_Eina_FutureXXX_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
3152{
3153 Efl_Loop_Promise_Simple_Data *d;
3154 Eina_Promise *p;
3155
3156 d = efl_loop_promise_simple_data_calloc(1);
3157 EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
3158
3159 d->idler = ecore_idler_add(_efl_loop_Eina_FutureXXX_idle_done, d);
3160 EINA_SAFETY_ON_NULL_GOTO(d->idler, idler_error);
3161
3162 p = eina_promise_new(efl_loop_future_scheduler_get(obj),
3163 _efl_loop_Eina_FutureXXX_idle_cancel, d);
3164 // d is dead if p is NULL
3165 EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
3166 d->promise = p;
3167
3168 // NOTE: Eolian should do efl_future_then() to bind future to object.
3169 return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
3170
3171 idler_error:
3172 efl_loop_promise_simple_data_mp_free(d);
3173 return NULL;
3174}
3175
3176static void
3177_efl_loop_Eina_FutureXXX_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
3178{
3179 Efl_Loop_Promise_Simple_Data *d = data;
3180 ecore_timer_del(d->timer);
3181 efl_loop_promise_simple_data_mp_free(d);
3182}
3183
3184static Eina_Bool
3185_efl_loop_Eina_FutureXXX_timeout_done(void *data)
3186{
3187 Efl_Loop_Promise_Simple_Data *d = data;
3188 eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
3189 efl_loop_promise_simple_data_mp_free(d);
3190 return EINA_FALSE;
3191}
3192
3193static Eina_Future *
3194_efl_loop_Eina_FutureXXX_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double time)
3195{
3196 Efl_Loop_Promise_Simple_Data *d;
3197 Eina_Promise *p;
3198
3199 d = efl_loop_promise_simple_data_calloc(1);
3200 EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
3201
3202 d->timer = ecore_timer_add(time, _efl_loop_Eina_FutureXXX_timeout_done, d);
3203 EINA_SAFETY_ON_NULL_GOTO(d->timer, timer_error);
3204
3205 p = eina_promise_new(efl_loop_future_scheduler_get(obj),
3206 _efl_loop_Eina_FutureXXX_timeout_cancel, d);
3207 // d is dead if p is NULL
3208 EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
3209 d->promise = p;
3210
3211 // NOTE: Eolian should do efl_future_then() to bind future to object.
3212 return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
3213
3214 timer_error:
3215 efl_loop_promise_simple_data_mp_free(d);
3216 return NULL;
3217}
3218
3115/* This event will be triggered when the main loop is destroyed and destroy its timers along */ 3219/* This event will be triggered when the main loop is destroyed and destroy its timers along */
3116static void _efl_loop_internal_cancel(Efl_Internal_Promise *p); 3220static void _efl_loop_internal_cancel(Efl_Internal_Promise *p);
3117 3221
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index 3494280aa7..8cf0c74915 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -81,6 +81,8 @@ extern int _ecore_log_dom;
81 81
82typedef struct _Ecore_Factorized_Idle Ecore_Factorized_Idle; 82typedef struct _Ecore_Factorized_Idle Ecore_Factorized_Idle;
83 83
84typedef struct _Efl_Loop_Promise_Simple_Data Efl_Loop_Promise_Simple_Data;
85
84typedef struct _Efl_Loop_Data Efl_Loop_Data; 86typedef struct _Efl_Loop_Data Efl_Loop_Data;
85struct _Efl_Loop_Data 87struct _Efl_Loop_Data
86{ 88{
@@ -371,6 +373,7 @@ GENERIC_ALLOC_FREE_HEADER(Ecore_Event, ecore_event);
371//GENERIC_ALLOC_FREE_HEADER(Ecore_Poller, ecore_poller); 373//GENERIC_ALLOC_FREE_HEADER(Ecore_Poller, ecore_poller);
372GENERIC_ALLOC_FREE_HEADER(Ecore_Pipe, ecore_pipe); 374GENERIC_ALLOC_FREE_HEADER(Ecore_Pipe, ecore_pipe);
373GENERIC_ALLOC_FREE_HEADER(Ecore_Fd_Handler, ecore_fd_handler); 375GENERIC_ALLOC_FREE_HEADER(Ecore_Fd_Handler, ecore_fd_handler);
376GENERIC_ALLOC_FREE_HEADER(Efl_Loop_Promise_Simple_Data, efl_loop_promise_simple_data);
374#ifdef _WIN32 377#ifdef _WIN32
375GENERIC_ALLOC_FREE_HEADER(Ecore_Win32_Handler, ecore_win32_handler); 378GENERIC_ALLOC_FREE_HEADER(Ecore_Win32_Handler, ecore_win32_handler);
376#endif 379#endif
diff --git a/src/lib/ecore/efl_loop.eo b/src/lib/ecore/efl_loop.eo
index e34deb586f..a5610c20e2 100644
--- a/src/lib/ecore/efl_loop.eo
+++ b/src/lib/ecore/efl_loop.eo
@@ -82,6 +82,31 @@ class Efl.Loop (Efl.Object)
82 scheduler: ptr(Eina.Future.Scheduler); [[The scheduler.]] 82 scheduler: ptr(Eina.Future.Scheduler); [[The scheduler.]]
83 } 83 }
84 } 84 }
85 Eina_FutureXXX_job {
86 [[A future promise that will be resolved from a clean main
87 loop context as soon as possible.
88
89 This has higher priority, for low priority use
90 @.Eina_FutureXXX_idle
91 ]]
92 return: own(ptr(Eina.Future)) /* TODO: future<void> */; [[The future handle.]]
93 }
94 Eina_FutureXXX_idle {
95 [[A future promise that will be resolved from a clean main
96 loop context as soon as the main loop is idle.
97
98 This is a low priority version of @.Eina_FutureXXX_job
99 ]]
100 return: own(ptr(Eina.Future)) /* TODO: future<void> */; [[The future handle.]]
101 }
102 Eina_FutureXXX_timeout {
103 [[A future promise that will be resolved from a clean main
104 loop context after $time seconds.]]
105 params {
106 @in time: double; [[The time from now in second that the main loop will wait before triggering it.]]
107 }
108 return: own(ptr(Eina.Future)) /* future<void> */; [[The future handle.]]
109 }
85 job { 110 job {
86 [[Will execute that promise in the near future.]] 111 [[Will execute that promise in the near future.]]
87 params { 112 params {
diff --git a/src/tests/ecore/ecore_test_promise2.c b/src/tests/ecore/ecore_test_promise2.c
index f71fa07c0e..315e67d4ce 100644
--- a/src/tests/ecore/ecore_test_promise2.c
+++ b/src/tests/ecore/ecore_test_promise2.c
@@ -411,6 +411,67 @@ _race_end_cb(void *data, const Eina_Value v, const Eina_Future *dead EINA_UNUSED
411 return v; 411 return v;
412} 412}
413 413
414static Eina_Value
415_promise_empty_done(void *data, const Eina_Value value, const Eina_Future *dead_future EINA_UNUSED)
416{
417 Eina_Bool *pdone = data;
418
419 if (!value.type) *pdone = EINA_TRUE;
420
421 ecore_main_loop_quit();
422
423 return value;
424}
425
426START_TEST(efl_test_timeout)
427{
428 Eina_Future *f;
429 Eina_Bool done = EINA_FALSE;
430
431 fail_if(!ecore_init());
432 f = eina_future_then(efl_loop_Eina_FutureXXX_timeout(ecore_main_loop_get(), 0.0001),
433 _promise_empty_done, &done);
434 fail_if(!f);
435 ecore_main_loop_begin();
436 ecore_shutdown();
437
438 fail_unless(done);
439}
440END_TEST
441
442START_TEST(efl_test_job)
443{
444 Eina_Future *f;
445 Eina_Bool done = EINA_FALSE;
446
447 fail_if(!ecore_init());
448 f = eina_future_then(efl_loop_Eina_FutureXXX_job(ecore_main_loop_get()),
449 _promise_empty_done, &done);
450 fail_if(!f);
451 ecore_main_loop_begin();
452 ecore_shutdown();
453
454 fail_unless(done);
455}
456END_TEST
457
458START_TEST(efl_test_idle)
459{
460 Eina_Future *f;
461 Eina_Bool done = EINA_FALSE;
462
463 fail_if(!ecore_init());
464 f = eina_future_then(efl_loop_Eina_FutureXXX_idle(ecore_main_loop_get()),
465 _promise_empty_done, &done);
466 fail_if(!f);
467 ecore_main_loop_begin();
468 ecore_shutdown();
469
470 fail_unless(done);
471}
472END_TEST
473
474
414START_TEST(efl_test_promise_future_success) 475START_TEST(efl_test_promise_future_success)
415{ 476{
416 Eina_Future *f; 477 Eina_Future *f;
@@ -834,6 +895,9 @@ END_TEST
834 895
835void ecore_test_ecore_promise2(TCase *tc) 896void ecore_test_ecore_promise2(TCase *tc)
836{ 897{
898 tcase_add_test(tc, efl_test_timeout);
899 tcase_add_test(tc, efl_test_job);
900 tcase_add_test(tc, efl_test_idle);
837 tcase_add_test(tc, efl_test_promise_future_success); 901 tcase_add_test(tc, efl_test_promise_future_success);
838 tcase_add_test(tc, efl_test_promise_future_failure); 902 tcase_add_test(tc, efl_test_promise_future_failure);
839 tcase_add_test(tc, efl_test_promise_future_chain_no_error); 903 tcase_add_test(tc, efl_test_promise_future_chain_no_error);