eo: add abstract efl.future.

This commit is contained in:
Cedric BAIL 2016-06-29 14:09:40 -07:00
parent 6023143b78
commit 9a2ada6d87
6 changed files with 179 additions and 5 deletions

View File

@ -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@

View File

@ -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"
/**
* @}

56
src/lib/eo/efl_future.c Normal file
View File

@ -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;
}

107
src/lib/eo/efl_future.h Normal file
View File

@ -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

View File

@ -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)

View File

@ -369,4 +369,7 @@ _efl_unref(_Eo_Object *obj)
}
}
Eina_Bool efl_future_init(void);
Eina_Bool efl_future_shutdown(void);
#endif