examples/reference/c/eina/src/eina_future.c

248 lines
6.6 KiB
C
Raw Normal View History

#define EFL_EO_API_SUPPORT 1
#define EFL_BETA_API_SUPPORT 1
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <Eina.h>
#include <Efl_Core.h>
/*
* 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;
2017-12-21 08:00:29 -08:00
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
2017-12-21 08:00:29 -08:00
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);
2017-12-21 08:00:29 -08:00
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)
{
2017-12-21 08:00:29 -08:00
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()