245 lines
6.4 KiB
C
245 lines
6.4 KiB
C
|
#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
|
||
|
*/
|
||
|
|
||
|
#define DEFAULT_MSG "the simple example is working!"
|
||
|
|
||
|
#define VALUE_TYPE_CHECK(_v, _type) \
|
||
|
if (_v.type != _type) \
|
||
|
{ \
|
||
|
fprintf(stderr, "Value type is not '%s' - received '%s'\n", \
|
||
|
_type->name, _v.type->name); \
|
||
|
return _v; \
|
||
|
}
|
||
|
|
||
|
typedef struct _Ctx {
|
||
|
Eina_Promise *p;
|
||
|
Eina_Bool should_fail;
|
||
|
Ecore_Timer *timer;
|
||
|
Eina_Value *value;
|
||
|
} Ctx;
|
||
|
|
||
|
static void
|
||
|
_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED)
|
||
|
{
|
||
|
Ctx *ctx = data;
|
||
|
if (ctx->timer) efl_del(ctx->timer);
|
||
|
eina_value_free(ctx->value);
|
||
|
free(ctx);
|
||
|
}
|
||
|
|
||
|
static Ctx *
|
||
|
_promise_ctx_new(Eina_Value *v)
|
||
|
{
|
||
|
Ctx *ctx;
|
||
|
Efl_Loop *loop;
|
||
|
ctx = calloc(1, sizeof(Ctx));
|
||
|
EINA_SAFETY_ON_NULL_GOTO(ctx, err_ctx);
|
||
|
|
||
|
loop = efl_loop_main_get(EFL_LOOP_CLASS);
|
||
|
ctx->p = eina_promise_new(efl_loop_future_scheduler_get(loop),
|
||
|
_promise_cancel, ctx);
|
||
|
EINA_SAFETY_ON_NULL_GOTO(ctx->p, err_timer);
|
||
|
ctx->value = v;
|
||
|
return ctx;
|
||
|
err_timer:
|
||
|
free(ctx);
|
||
|
err_ctx:
|
||
|
eina_value_free(v);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_timeout(void *data, const Efl_Event *event EINA_UNUSED)
|
||
|
{
|
||
|
Ctx *ctx = data;
|
||
|
|
||
|
if (ctx->should_fail)
|
||
|
{
|
||
|
eina_promise_reject(ctx->p, ENETDOWN);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Eina_Value v;
|
||
|
eina_value_copy(ctx->value, &v);
|
||
|
eina_promise_resolve(ctx->p, v);
|
||
|
eina_value_free(ctx->value);
|
||
|
}
|
||
|
|
||
|
efl_del(ctx->timer);
|
||
|
free(ctx);
|
||
|
}
|
||
|
|
||
|
static Eina_Future *
|
||
|
_future_get(Ctx *ctx)
|
||
|
{
|
||
|
Eina_Future *f;
|
||
|
|
||
|
f = eina_future_new(ctx->p);
|
||
|
EINA_SAFETY_ON_NULL_GOTO(f, err_future);
|
||
|
|
||
|
efl_add(EFL_LOOP_TIMER_CLASS, NULL,
|
||
|
ctx->timer = efl_added,
|
||
|
efl_loop_timer_interval_set(efl_added, 0.1),
|
||
|
efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _timeout, ctx));
|
||
|
|
||
|
EINA_SAFETY_ON_NULL_GOTO(ctx->timer, err_timer);
|
||
|
return f;
|
||
|
|
||
|
err_timer:
|
||
|
eina_future_cancel(f);
|
||
|
err_future:
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
static Eina_Future *
|
||
|
_fail_future_get(void)
|
||
|
{
|
||
|
Ctx *ctx = _promise_ctx_new(NULL);
|
||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||
|
ctx->should_fail = EINA_TRUE;
|
||
|
return _future_get(ctx);
|
||
|
}
|
||
|
|
||
|
static Eina_Future *
|
||
|
_str_future_get(void)
|
||
|
{
|
||
|
Eina_Value *v = eina_value_util_string_new(DEFAULT_MSG);
|
||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(v, NULL);
|
||
|
Ctx *ctx = _promise_ctx_new(v);
|
||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||
|
return _future_get(ctx);
|
||
|
}
|
||
|
|
||
|
static Eina_Value
|
||
|
_simple_ok(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
|
||
|
{
|
||
|
VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
static Eina_Value
|
||
|
_simple_err(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
|
||
|
{
|
||
|
VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_ERROR);
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_simple(void)
|
||
|
{
|
||
|
eina_future_chain(_str_future_get(),
|
||
|
eina_future_cb_console("Expecting the following message: "DEFAULT_MSG "\n Got: ", NULL),
|
||
|
{ .cb = _simple_ok, .data = NULL });
|
||
|
eina_future_chain(_fail_future_get(),
|
||
|
eina_future_cb_console("Expecting network down error\n Got: ", NULL),
|
||
|
{ .cb = _simple_err, .data = NULL });
|
||
|
}
|
||
|
|
||
|
static Eina_Future *
|
||
|
_int_future_get(void)
|
||
|
{
|
||
|
Eina_Value *v = eina_value_util_int_new(1);
|
||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(v, NULL);
|
||
|
Ctx *ctx = _promise_ctx_new(v);
|
||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||
|
return _future_get(ctx);
|
||
|
}
|
||
|
|
||
|
static Eina_Value
|
||
|
_chain_no_errors_cb(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
|
||
|
{
|
||
|
int val;
|
||
|
|
||
|
VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_INT);
|
||
|
eina_value_get(&v, &val);
|
||
|
|
||
|
return *eina_value_util_int_new(val * 2);
|
||
|
}
|
||
|
|
||
|
static Eina_Value
|
||
|
_exit_cb(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
|
||
|
{
|
||
|
efl_exit(0);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_chain_no_errors(void)
|
||
|
{
|
||
|
eina_future_chain(_int_future_get(),
|
||
|
eina_future_cb_console("Expecting number 1\n Got: ", NULL),
|
||
|
{.cb = _chain_no_errors_cb, .data = NULL},
|
||
|
eina_future_cb_console("Expecting number 2\n Got: ", NULL),
|
||
|
{.cb = _chain_no_errors_cb, .data = NULL},
|
||
|
eina_future_cb_console("Expecting number 4\n Got: ", NULL),
|
||
|
{.cb = _chain_no_errors_cb, .data = NULL},
|
||
|
eina_future_cb_console("Expecting number 8\n Got: ", NULL),
|
||
|
{.cb = _chain_no_errors_cb, .data = NULL},
|
||
|
eina_future_cb_console("Expecting number 16\n Got: ", NULL),
|
||
|
{.cb = _exit_cb, .data = NULL});
|
||
|
}
|
||
|
|
||
|
static Eina_Value
|
||
|
_chain_with_error_cb(void *data EINA_UNUSED, const Eina_Value v EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
|
||
|
{
|
||
|
Eina_Value err;
|
||
|
eina_value_setup(&err, EINA_VALUE_TYPE_ERROR);
|
||
|
eina_value_set(&err, E2BIG);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_chain_with_error(void)
|
||
|
{
|
||
|
eina_future_chain(_int_future_get(),
|
||
|
{ .cb=_chain_with_error_cb, .data=NULL },
|
||
|
eina_future_cb_console("Expecting argument list too long. Got: ", NULL),
|
||
|
{ .cb = _simple_err, .data = NULL });
|
||
|
}
|
||
|
|
||
|
static Eina_Value
|
||
|
_canceled_cb(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
|
||
|
{
|
||
|
VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_ERROR);
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_future_cancel(void)
|
||
|
{
|
||
|
Eina_Future *f;
|
||
|
|
||
|
f = eina_future_chain(_int_future_get(),
|
||
|
eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL),
|
||
|
{ .cb = _canceled_cb, .data = NULL },
|
||
|
eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL),
|
||
|
{ .cb = _canceled_cb, .data = NULL },
|
||
|
eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL));
|
||
|
eina_future_cancel(f);
|
||
|
}
|
||
|
|
||
|
EAPI_MAIN void
|
||
|
efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
|
||
|
{
|
||
|
_simple();
|
||
|
_chain_no_errors();
|
||
|
_chain_with_error();
|
||
|
_future_cancel();
|
||
|
}
|
||
|
|
||
|
EFL_MAIN()
|