ajwillia-ms pushed a commit to branch master.

http://git.enlightenment.org/tools/examples.git/commit/?id=54070a9226abd6be16884f3bf3b9286b254483b3

commit 54070a9226abd6be16884f3bf3b9286b254483b3
Author: Andy Williams <[email protected]>
Date:   Tue Dec 12 19:37:56 2017 +0000

    eina: Add a first pass futures example (from eina examples)
---
 reference/c/eina/src/eina_future.c | 244 +++++++++++++++++++++++++++++++++++++
 reference/c/eina/src/meson.build   |   7 ++
 2 files changed, 251 insertions(+)

diff --git a/reference/c/eina/src/eina_future.c 
b/reference/c/eina/src/eina_future.c
new file mode 100644
index 0000000..006e063
--- /dev/null
+++ b/reference/c/eina/src/eina_future.c
@@ -0,0 +1,244 @@
+#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()
diff --git a/reference/c/eina/src/meson.build b/reference/c/eina/src/meson.build
index 04d998b..740bbb3 100644
--- a/reference/c/eina/src/meson.build
+++ b/reference/c/eina/src/meson.build
@@ -49,6 +49,13 @@ executable('efl_reference_eina_value_custom',
   install : true
 )
 
+executable('efl_reference_eina_future',
+  files(['eina_future.c']),
+  dependencies : deps,
+  include_directories : inc,
+  install : true
+)
+
 executable('efl_reference_eina_log',
   files(['eina_log.c']),
   dependencies : deps,

-- 


Reply via email to