summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2016-06-29 14:09:40 -0700
committerCedric BAIL <cedric@osg.samsung.com>2016-09-08 14:51:55 -0700
commit94c2915c627204c94bf14368a6ec458308932623 (patch)
treef059ba7974f4a984cae1259102256b7ea860637e
parent6023143b781e764a356e5d21326f9d41e3f2f7bc (diff)
downloadefl-94c2915c627204c94bf14368a6ec458308932623.tar.gz
eo: add abstract efl.future.
-rw-r--r--src/Makefile_Eo.am5
-rw-r--r--src/lib/eo/Eo.h10
-rw-r--r--src/lib/eo/efl_future.c56
-rw-r--r--src/lib/eo/efl_future.h107
-rw-r--r--src/lib/eo/eo.c3
-rw-r--r--src/lib/eo/eo_private.h3
6 files changed, 179 insertions, 5 deletions
diff --git a/src/Makefile_Eo.am b/src/Makefile_Eo.am
index bd5dcba9d4..80460ef791 100644
--- a/src/Makefile_Eo.am
+++ b/src/Makefile_Eo.am
@@ -17,7 +17,7 @@ BUILT_SOURCES += \
lib_LTLIBRARIES += lib/eo/libeo.la
installed_eomainheadersdir = $(includedir)/eo-@VMAJ@
-dist_installed_eomainheaders_DATA = lib/eo/Eo.h
+dist_installed_eomainheaders_DATA = lib/eo/Eo.h lib/eo/efl_future.h
nodist_installed_eomainheaders_DATA = \
$(eo_eolian_h)
@@ -30,7 +30,8 @@ lib/eo/eo_base_class.c \
lib/eo/eo_class_class.c \
lib/eo/eo_add_fallback.c \
lib/eo/eo_add_fallback.h \
-lib/eo/eo_private.h
+lib/eo/eo_private.h \
+lib/eo/efl_future.c
lib_eo_libeo_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EO_CFLAGS@
lib_eo_libeo_la_LIBADD = @EO_LIBS@
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 8fd5ca7c93..f1ce4c150d 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -167,6 +167,12 @@ typedef enum _Efl_Object_Op_Type Efl_Object_Op_Type;
*/
typedef void (*Efl_Del_Intercept) (Eo *obj_id);
+/**
+ * @typedef Efl_Future
+ * The type of Efl Future used in asynchronous operation, the read side of a promise.
+ */
+typedef Eo Efl_Future;
+
#include "efl_object_override.eo.h"
#include "efl_object.eo.h"
#include "efl_interface.eo.h"
@@ -1321,9 +1327,7 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_
* @}
*/
-/**
- * @}
- */
+#include "efl_future.h"
/**
* @}
diff --git a/src/lib/eo/efl_future.c b/src/lib/eo/efl_future.c
new file mode 100644
index 0000000000..5f37f7afd9
--- /dev/null
+++ b/src/lib/eo/efl_future.c
@@ -0,0 +1,56 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Eina.h>
+#include "Eo.h"
+
+// Efl.Future implementation is an opaque type in Ecore.
+EOAPI const Efl_Event_Description _EFL_FUTURE_EVENT_FAILURE =
+ EFL_EVENT_DESCRIPTION("future,failure");
+EOAPI const Efl_Event_Description _EFL_FUTURE_EVENT_SUCCESS =
+ EFL_EVENT_DESCRIPTION("future,success");
+EOAPI const Efl_Event_Description _EFL_FUTURE_EVENT_PROGRESS =
+ EFL_EVENT_DESCRIPTION("future,progress");
+
+EOAPI EFL_FUNC_BODYV(efl_future_then, Efl_Future *, 0, EFL_FUNC_CALL(success, failure, progress, data), Efl_Event_Cb success, Efl_Event_Cb failure, Efl_Event_Cb progress, const void *data);
+EOAPI EFL_VOID_FUNC_BODY(efl_future_cancel);
+
+static Eina_Bool
+_efl_future_class_initializer(Efl_Class *klass)
+{
+ EFL_OPS_DEFINE(ops,
+ EFL_OBJECT_OP_FUNC(efl_future_then, NULL),
+ EFL_OBJECT_OP_FUNC(efl_future_cancel, NULL));
+
+ return efl_class_functions_set(klass, &ops);
+}
+
+static const Efl_Class_Description _efl_future_class_desc = {
+ EO_VERSION,
+ "Efl_Future",
+ EFL_CLASS_TYPE_REGULAR_NO_INSTANT,
+ 0,
+ _efl_future_class_initializer,
+ NULL,
+ NULL
+};
+
+EFL_DEFINE_CLASS(efl_future_class_get, &_efl_future_class_desc, EFL_OBJECT_CLASS, NULL);
+
+static const char EINA_ERROR_FUTURE_CANCEL_STR[] = "Future cancelled";
+EAPI Eina_Error EINA_ERROR_FUTURE_CANCEL;
+
+Eina_Bool
+efl_future_init(void)
+{
+ EINA_ERROR_FUTURE_CANCEL = eina_error_msg_static_register(EINA_ERROR_FUTURE_CANCEL_STR);
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+efl_future_shutdown(void)
+{
+ return EINA_TRUE;
+}
diff --git a/src/lib/eo/efl_future.h b/src/lib/eo/efl_future.h
new file mode 100644
index 0000000000..243d660979
--- /dev/null
+++ b/src/lib/eo/efl_future.h
@@ -0,0 +1,107 @@
+#ifndef EFL_FUTURE_H_
+# define EFL_FUTURE_H_
+
+/**
+ * @addtogroup Efl_Future Efl future and promise.
+ * @{
+ */
+
+/**
+ * @typedef Efl_Promise
+ * The type of Efl Promise used in asynchronous operation, the write side of a promise.
+ */
+typedef Eo Efl_Promise;
+
+#define EFL_FUTURE_CLASS efl_future_class_get()
+EWAPI const Efl_Class *efl_future_class_get(void);
+
+EAPI extern Eina_Error EINA_ERROR_FUTURE_CANCEL;
+
+typedef struct _Efl_Future_Event_Failure Efl_Future_Event_Failure;
+struct _Efl_Future_Event_Failure
+{
+ Efl_Promise *next;
+ Eina_Error error;
+};
+
+typedef struct _Efl_Future_Event_Success Efl_Future_Event_Success;
+struct _Efl_Future_Event_Success
+{
+ Efl_Promise *next;
+ void *value;
+};
+
+typedef struct _Efl_Future_Event_Progress Efl_Future_Event_Progress;
+struct _Efl_Future_Event_Progress
+{
+ Efl_Promise *next;
+ void *progress;
+};
+
+EOAPI extern const Efl_Event_Description _EFL_FUTURE_EVENT_FAILURE;
+EOAPI extern const Efl_Event_Description _EFL_FUTURE_EVENT_SUCCESS;
+EOAPI extern const Efl_Event_Description _EFL_FUTURE_EVENT_PROGRESS;
+
+ // FIXME: documentation
+#define EFL_FUTURE_EVENT_FAILURE (&(_EFL_FUTURE_EVENT_FAILURE))
+#define EFL_FUTURE_EVENT_SUCCESS (&(_EFL_FUTURE_EVENT_SUCCESS))
+#define EFL_FUTURE_EVENT_PROGRESS (&(_EFL_FUTURE_EVENT_PROGRESS))
+
+/**
+ * @brief Add sets of callbacks to handle the progress and the result of a future.
+ *
+ * callbacks are called depending on the outcome of the promise related to the future.
+ *
+ * @param[in] success the callback to call in case of a succesful computation from the promise
+ * @param[in] failure the callback to call in case of a failure to deliver from the promise
+ * @param[in] progress the callback to call during the progression of the the promise, this is optional
+ * @param[in] data additional data to pass to the callback
+ *
+ * @return Return a new future when the callback has been successfully added. This future can be ignored.
+ *
+ * @note except if you do reference count the Efl.Future object, you can only call once this function.
+ *
+ * @ingroup Efl_Future
+ */
+EOAPI Efl_Future *efl_future_then(Eo *obj, Efl_Event_Cb success, Efl_Event_Cb failure, Efl_Event_Cb progress, const void *data);
+
+/**
+ * @brief Cancel the need for that specific future.
+ *
+ * This will trigger the failure of the future and may result in the promise stopping its computation.
+ *
+ * @see efl_future_use
+ *
+ * @ingroup Efl_Future
+ */
+EOAPI void efl_future_cancel(Eo *obj);
+
+/**
+ * @brief To be used in conjunction with when you plan to use efl_future_cancel
+ *
+ * This function will store in *wref, obj and make sure that on failure or success of the future, it
+ * will be reset to NULL. This guarantee that the pointer you are using will always be correct and
+ * that you do not have to worry about passing a dead pointer to efl_future_cancel.
+ *
+ * @param[out] storage Will be set to obj and tracked during all the lifetime of the future.
+ * @param[in] future The future to remember about.
+ *
+ * @see efl_future_cancel
+ *
+ * @ingroup Efl_Future
+ */
+static inline void
+efl_future_use(Efl_Future **storage, Eo *future)
+{
+ efl_wref_add(future, storage);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index fa8a7f7d51..d90d417628 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -1862,6 +1862,7 @@ efl_object_init(void)
EO_FREED_EINA_MAGIC_STR);
eina_magic_string_static_set(EO_CLASS_EINA_MAGIC,
EO_CLASS_EINA_MAGIC_STR);
+ efl_future_init();
#ifndef _WIN32
_ops_storage = eina_hash_pointer_new(NULL);
@@ -1923,6 +1924,8 @@ efl_object_shutdown(void)
_efl_add_fallback_shutdown();
+ efl_future_shutdown();
+
for (i = 0 ; i < _eo_classes_last_id ; i++, cls_itr--)
{
if (*cls_itr)
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index 4fd2eeece9..1cbddf2ccf 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -369,4 +369,7 @@ _efl_unref(_Eo_Object *obj)
}
}
+Eina_Bool efl_future_init(void);
+Eina_Bool efl_future_shutdown(void);
+
#endif