#define EFL_EO_API_SUPPORT 1 #define EFL_BETA_API_SUPPORT 1 #include #include #include #include #include /* * Eina Future examples. * * TODO */ /* * This will be called if a promise is cancelled */ static void _promise_cancel(void *data EINA_UNUSED, const Eina_Promise *dead EINA_UNUSED) { printf("Promise cancelled\n"); } /* * This simple method prints the content of a value and passes it on */ static Eina_Value _value_print(void *data EINA_UNUSED, const Eina_Value value) { printf("Found value %s\n", eina_value_to_string(&value)); return value; } /* * This method will resolve the passed promise with a string value */ static Eina_Value _delayed_value_resolve(void *data, const Eina_Value value EINA_UNUSED) { Eina_Promise *promise; promise = (Eina_Promise *)data; eina_promise_resolve(promise, eina_value_string_init("Delayed Value :)")); return EINA_VALUE_EMPTY; } /* * A simple future demo, set up a promised future * and resolve it from a timer future. */ static void _simple_future() { Efl_Loop *loop; Eina_Promise *promise; // Create a demo promise for the sake of a trivial demo loop = efl_loop_main_get(EFL_LOOP_CLASS); promise = eina_promise_new(efl_loop_future_scheduler_get(loop), _promise_cancel, NULL); // Tis future will trigger a _value_print once resolved eina_future_then_easy(eina_future_new(promise), .success = _value_print); // This future is basically a timer - wait 100ms and then resolve the promise above eina_future_then_easy(efl_loop_timeout(efl_loop_main_get(EFL_LOOP_CLASS), 0.1), .success = _delayed_value_resolve, .data = promise); } /* * This method prints the message of the error encountered and returns no value. */ static Eina_Value _error_print(void *data EINA_UNUSED, const Eina_Error error) { printf("Encountered error %s\n", eina_error_msg_get(error)); return EINA_VALUE_EMPTY; } /* * This method will reject the passed promise with a "magic" error. */ static Eina_Value _delayed_value_reject(void *data, const Eina_Value value EINA_UNUSED) { Eina_Promise *promise; promise = (Eina_Promise *)data; eina_promise_reject(promise, EINA_ERROR_NOT_IMPLEMENTED); return EINA_VALUE_EMPTY; } /* * A simple future failed demo, set up a promised future * and reject it from a timer future. */ static void _failed_future() { Efl_Loop *loop; Eina_Promise *promise; // Create a demo promise for the sake of a trivial demo loop = efl_loop_main_get(EFL_LOOP_CLASS); promise = eina_promise_new(efl_loop_future_scheduler_get(loop), _promise_cancel, NULL); // Tis future will trigger a _value_print once resolved eina_future_then_easy(eina_future_new(promise), .error = _error_print); // This future is basically a timer - wait 100ms and then resolve the promise above eina_future_then_easy(efl_loop_timeout(efl_loop_main_get(EFL_LOOP_CLASS), 0.2), .success = _delayed_value_reject, .data = promise); } /* * A simple future failed demo, set up a promised future * and reject it from a timer future. */ static void _cancel_future() { Efl_Loop *loop; Eina_Promise *promise; Eina_Future *future; // Create a demo promise for the sake of a trivial demo loop = efl_loop_main_get(EFL_LOOP_CLASS); promise = eina_promise_new(efl_loop_future_scheduler_get(loop), _promise_cancel, NULL); future = eina_future_new(promise); // Tis future will trigger a _value_print once resolved eina_future_then_easy(future, .success = _value_print); // Then we cancel the future before it has a chance to resolve eina_future_cancel(future); } /* * When our timeout is triggered we will resolve the promise passed. * Set an int value to initialise the chain. */ static void _timeout(void *data, const Efl_Event *event) { Eina_Promise *promise; promise = data; eina_promise_resolve(promise, eina_value_int_init(1)); efl_del(event->object); } /* * Create a new int future that will resolve after a specified timer delay. */ static Eina_Future * _delayed_int_future_get(double delay) { Efl_Loop *loop; Eina_Promise *promise; // Create a demo promise for the sake of a trivial demo loop = efl_loop_main_get(EFL_LOOP_CLASS); promise = eina_promise_new(efl_loop_future_scheduler_get(loop), _promise_cancel, NULL); efl_add(EFL_LOOP_TIMER_CLASS, loop, efl_loop_timer_interval_set(efl_added, delay), efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _timeout, promise)); return eina_future_new(promise); } /* * A value callback to chain, taking in an int value and returning to chain * the int multiplied by two. */ static Eina_Value _chain_multiply_cb(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED) { int val; if (v.type != EINA_VALUE_TYPE_INT) { fprintf(stderr, "Incorrect type was returned"); return v; } eina_value_get(&v, &val); return *eina_value_util_int_new(val * 2); } /* * This chained callback exits our example. */ static Eina_Value _exit_cb(void *data EINA_UNUSED, const Eina_Value v EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED) { efl_exit(0); return EINA_VALUE_EMPTY; } /* * Run a future chain where the initial future returns a single value. * Each item in the chain then processes this value and passes on another. * The _chain_multiply_cb returns twice the value it gets and the * eina_future_cb_console prints a message including the value before passing * it on. */ static void _chained_future(void) { eina_future_chain(_delayed_int_future_get(0.5), eina_future_cb_console("Starting chain with: ", NULL), {.cb = _chain_multiply_cb, .data = NULL}, eina_future_cb_console(" Multiplied by 2: ", NULL), {.cb = _chain_multiply_cb, .data = NULL}, eina_future_cb_console(" Multiplied by 2: ", NULL), {.cb = _chain_multiply_cb, .data = NULL}, eina_future_cb_console(" Multiplied by 2: ", NULL), {.cb = _chain_multiply_cb, .data = NULL}, eina_future_cb_console(" Multiplied by 2: ", NULL), {.cb = _exit_cb, .data = NULL}); } /* * Run some futures examples. */ EAPI_MAIN void efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) { _simple_future(); _failed_future(); _cancel_future(); _chained_future(); } EFL_MAIN()