Porting to Eo: Job, Animator, Idler, Idle_Enterer, Idle_Exiter, Timer, Ecore_Poll

Signed-off-by: Yakov Goldberg <yakov.g@samsung.com>

SVN revision: 77722
This commit is contained in:
Yakov Goldberg 2012-10-10 08:19:58 +00:00 committed by Daniel Zaoui
parent fa1dd2b86f
commit dbda81582a
16 changed files with 1437 additions and 460 deletions

View File

@ -1,3 +1,6 @@
2012-10-10 Daniel Zaoui and Yaakov Goldberg
* Porting of Ecore to Eo
2011-01-29 Carsten Haitzler (The Rasterman)
1.0.0 release

View File

@ -4,6 +4,8 @@ Changes since Ecore 1.7.0:
--------------------------
Additions:
* ecore:
- porting to Eo
* ecore_con:
- Add Ecore_Con_Eet API to help using Eet_Data with Ecore_Con.
* ecore_x:

View File

@ -565,6 +565,13 @@ requirements_ecore_win32="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_wi
requirements_ecore_wince="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_wince}"
requirements_ecore_x="ecore >= 1.6.99 eina >= 1.6.99 ${requirements_ecore_x}"
# Eo
PKG_CHECK_MODULES([EO], [eo])
requirements_ecore="eo ${requirements_ecore}"
EINA_CFLAGS="$EINA_CFLAGS $EO_CFLAGS"
EINA_LIBS="$EINA_LIBS $EO_LIBS"
# glib support (main loop integration)
AC_ARG_ENABLE([glib],

View File

@ -56,7 +56,8 @@ _event_handler_cb(void *data, int type, void *event) // event callback
{
ecore_idle_enterer_del(ctxt->enterer);
ecore_idle_exiter_del(ctxt->exiter);
ecore_idler_del(ctxt->idler);
// ecore_idler_del(ctxt->idler);
eo_unref(ctxt->idler);
ctxt->enterer = NULL;
ctxt->exiter = NULL;
@ -101,7 +102,8 @@ main(int argc, char **argv)
ctxt.enterer = ecore_idle_enterer_add(_enterer_cb, &ctxt);
ctxt.exiter = ecore_idle_exiter_add(_exiter_cb, &ctxt);
ctxt.idler = ecore_idler_add(_idler_cb, &ctxt);
// ctxt.idler = ecore_idler_add(_idler_cb, &ctxt);
ctxt.idler = eo_add_custom(ECORE_IDLER_CLASS, NULL, ecore_idler_constructor(_idler_cb, &ctxt));
ctxt.handler = ecore_event_handler_add(_event_type,
_event_handler_cb,
&ctxt);

View File

@ -13,13 +13,22 @@ _poller_print_cb(void *data)
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_poller_quit_cb(void *data)
{
ecore_main_loop_quit();
return EINA_TRUE;
}
int
main(int argc, char **argv)
{
double interval = 0.3; // tick each 0.3 seconds
Ecore_Poller *poller1, *poller2;
Ecore_Poller *poller1, *poller2, *poller3;
char *str1 = "poller1";
char *str2 = "poller2";
char *str3 = "poller3";
if (!ecore_init())
{
@ -31,18 +40,32 @@ main(int argc, char **argv)
ecore_poller_poll_interval_set(ECORE_POLLER_CORE, interval);
poller1 = ecore_poller_add(ECORE_POLLER_CORE, 4, _poller_print_cb, str1);
poller2 = ecore_poller_add(ECORE_POLLER_CORE, 8, _poller_print_cb, str2);
// poller1 = ecore_poller_add(ECORE_POLLER_CORE, 4, _poller_print_cb, str1);
// poller2 = ecore_poller_add(ECORE_POLLER_CORE, 8, _poller_print_cb, str2);
// poller3 = ecore_poller_add(ECORE_POLLER_CORE, 30, _poller_quit_cb, str3);
poller1 = eo_add_custom(ECORE_POLLER_CLASS, NULL,
ecore_poller_constructor(ECORE_POLLER_CORE, 4, _poller_print_cb, str1));
poller2 = eo_add_custom(ECORE_POLLER_CLASS, NULL,
ecore_poller_constructor(ECORE_POLLER_CORE, 8, _poller_print_cb, str2));
poller3 = eo_add_custom(ECORE_POLLER_CLASS, NULL,
ecore_poller_constructor(ECORE_POLLER_CORE, 20, _poller_quit_cb, str3));
ecore_main_loop_begin();
printf("changing poller2 interval to 16\n");
ecore_poller_poller_interval_set(poller2, 16);
// ecore_poller_poller_interval_set(poller2, 16);
eo_do(poller2, ecore_poller_interval_set(16, NULL));
ecore_main_loop_begin();
ecore_poller_del(poller1);
ecore_poller_del(poller2);
eo_unref(poller1);
eo_unref(poller2);
eo_unref(poller3);
// ecore_poller_del(poller1);
// ecore_poller_del(poller2);
// ecore_poller_del(poller3);
ecore_shutdown();
}

View File

@ -328,6 +328,9 @@ sudo make install
#include <Eina.h>
/* This include has been added to support Eo in Ecore */
#include <Eo.h>
#ifdef EAPI
# undef EAPI
#endif
@ -1253,7 +1256,31 @@ enum _Ecore_Poller_Type /* Poller types */
};
typedef enum _Ecore_Poller_Type Ecore_Poller_Type;
typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */
/*
* @since 1.8
*/
typedef Eo Ecore_Poller; /**< A handle for pollers */
#define ECORE_POLLER_CLASS ecore_poller_class_get()
const Eo_Class *ecore_poller_class_get(void) EINA_CONST;
extern EAPI Eo_Op ECORE_POLLER_BASE_ID;
enum
{
ECORE_POLLER_SUB_ID_CONSTRUCTOR,
ECORE_POLLER_SUB_ID_INTERVAL_SET,
ECORE_POLLER_SUB_ID_INTERVAL_GET,
ECORE_POLLER_SUB_ID_LAST,
};
#define ECORE_POLLER_ID(sub_id) (ECORE_POLLER_BASE_ID + sub_id)
#define ecore_poller_constructor(type, interval, func, data) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Poller_Type, type), EO_TYPECHECK(int, interval), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
#define ecore_poller_interval_set(interval, ret) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_SET), EO_TYPECHECK(int, interval), EO_TYPECHECK(Eina_Bool *, ret)
#define ecore_poller_interval_get(ret) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_GET), EO_TYPECHECK(int *, ret)
/**
* @brief Sets the time(in seconds) between ticks for the given poller type.
@ -1368,7 +1395,27 @@ EAPI void *ecore_poller_del(Ecore_Poller *poller);
* @{
*/
typedef struct _Ecore_Animator Ecore_Animator; /**< A handle for animators */
/*
* @since 1.8
*/
typedef Eo Ecore_Animator; /**< A handle for animators */
#define ECORE_ANIMATOR_CLASS ecore_animator_class_get()
const Eo_Class *ecore_animator_class_get(void) EINA_CONST;
extern EAPI Eo_Op ECORE_ANIMATOR_BASE_ID;
enum
{
ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR,
ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR,
ECORE_ANIMATOR_SUB_ID_LAST
};
#define ECORE_ANIMATOR_ID(sub_id) (ECORE_ANIMATOR_BASE_ID + sub_id)
#define ecore_animator_constructor(func, data) ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
#define ecore_animator_timeline_constructor(runtime, func, data) ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR), EO_TYPECHECK(double, runtime), EO_TYPECHECK(Ecore_Timeline_Cb, func), EO_TYPECHECK(const void *, data)
/**
* @enum _Ecore_Pos_Map
@ -1711,7 +1758,37 @@ EAPI double ecore_loop_time_get(void);
* @{
*/
typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */
/*
* @since 1.8
*/
typedef Eo Ecore_Timer; /**< A handle for timers */
#define ECORE_TIMER_CLASS ecore_timer_class_get()
const Eo_Class *ecore_timer_class_get(void) EINA_CONST;
extern EAPI Eo_Op ECORE_TIMER_BASE_ID;
enum
{
ECORE_TIMER_SUB_ID_CONSTRUCTOR,
ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR,
ECORE_TIMER_SUB_ID_INTERVAL_SET,
ECORE_TIMER_SUB_ID_INTERVAL_GET,
ECORE_TIMER_SUB_ID_DELAY,
ECORE_TIMER_SUB_ID_RESET,
ECORE_TIMER_SUB_ID_PENDING_GET,
ECORE_TIMER_SUB_ID_LAST,
};
#define ECORE_TIMER_ID(sub_id) (ECORE_TIMER_BASE_ID + sub_id)
#define ecore_timer_constructor(in, func, data) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(double, in), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
#define ecore_timer_loop_constructor(in, func, data) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR), EO_TYPECHECK(double, in), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
#define ecore_obj_timer_interval_set(in) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_SET), EO_TYPECHECK(double, in)
#define ecore_obj_timer_interval_get(ret) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_GET), EO_TYPECHECK(double *, ret)
#define ecore_obj_timer_delay(add) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_DELAY), EO_TYPECHECK(double, add)
#define ecore_obj_timer_reset() ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_RESET)
#define ecore_obj_timer_pending_get(ret) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_PENDING_GET), EO_TYPECHECK(double *, ret)
EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data);
EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data);
@ -1776,9 +1853,66 @@ EAPI char *ecore_timer_dump(void);
* @{
*/
typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */
typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; /**< A handle for idle enterers */
typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; /**< A handle for idle exiters */
/*
* @since 1.8
*/
typedef Eo Ecore_Idler; /**< A handle for idlers */
#define ECORE_IDLER_CLASS ecore_idler_class_get()
const Eo_Class *ecore_idler_class_get(void) EINA_CONST;
extern EAPI Eo_Op ECORE_IDLER_BASE_ID;
enum
{
ECORE_IDLER_SUB_ID_CONSTRUCTOR,
ECORE_IDLER_SUB_ID_LAST
};
#define ECORE_IDLER_ID(sub_id) (ECORE_IDLER_BASE_ID + sub_id)
#define ecore_idler_constructor(func, data) ECORE_IDLER_ID(ECORE_IDLER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
/**
*
*/
typedef Eo Ecore_Idle_Enterer; /**< A handle for idle enterers */
#define ECORE_IDLE_ENTERER_CLASS ecore_idle_enterer_class_get()
const Eo_Class *ecore_idle_enterer_class_get(void) EINA_CONST;
extern EAPI Eo_Op ECORE_IDLE_ENTERER_BASE_ID;
enum
{
ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR,
ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR,
ECORE_IDLE_ENTERER_SUB_ID_LAST
};
#define ECORE_IDLE_ENTERER_ID(sub_id) (ECORE_IDLE_ENTERER_BASE_ID + sub_id)
#define ecore_idle_enterer_after_constructor(func, data) ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
#define ecore_idle_enterer_before_constructor(func, data) ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
/**
*
*/
/*
* @since 1.8
*/
typedef Eo Ecore_Idle_Exiter; /**< A handle for idle exiters */
#define ECORE_IDLE_EXITER_CLASS ecore_idle_exiter_class_get()
const Eo_Class *ecore_idle_exiter_class_get(void) EINA_CONST;
extern EAPI Eo_Op ECORE_IDLE_EXITER_BASE_ID;
enum
{
ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR,
ECORE_IDLE_EXITER_SUB_ID_LAST
};
#define ECORE_IDLE_EXITER_ID(sub_id) (ECORE_IDLE_EXITER_BASE_ID + sub_id)
#define ecore_idle_exiter_constructor(func, data) ECORE_IDLE_EXITER_ID(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data)
/**
* Add an idler handler.
@ -2575,7 +2709,23 @@ EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait);
* @{
*/
typedef struct _Ecore_Job Ecore_Job; /**< A job handle */
/*
* @since 1.8
*/
typedef Eo Ecore_Job; /**< A job handle */
#define ECORE_JOB_CLASS ecore_job_class_get()
const Eo_Class *ecore_job_class_get(void) EINA_CONST;
extern EAPI Eo_Op ECORE_JOB_BASE_ID;
enum
{
ECORE_JOB_SUB_ID_CONSTRUCTOR,
ECORE_JOB_SUB_ID_LAST
};
#define ECORE_JOB_ID(sub_id) (ECORE_JOB_BASE_ID + sub_id)
#define ecore_job_constructor(func, data) ECORE_JOB_ID(ECORE_JOB_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Cb, func), EO_TYPECHECK(const void *, data)
EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data);
EAPI void *ecore_job_del(Ecore_Job *job);

View File

@ -36,6 +36,9 @@
#if HAVE_MALLINFO
#include <malloc.h>
EAPI Eo *_ecore_parent = NULL;
static Ecore_Version _version = { VERS_MAJ, VERS_MIN, VERS_MIC, VERS_REV };
EAPI Ecore_Version *ecore_version = &_version;
@ -138,6 +141,8 @@ ecore_init(void)
if (++_ecore_init_count != 1)
return _ecore_init_count;
eo_init();
#ifdef HAVE_LOCALE_H
setlocale(LC_CTYPE, "");
#endif
@ -194,6 +199,7 @@ ecore_init(void)
#if defined(GLIB_INTEGRATION_ALWAYS)
if (_ecore_glib_always_integrate) ecore_main_loop_glib_integrate();
#endif
_ecore_parent = eo_add(ECORE_PARENT_CLASS, NULL);
return _ecore_init_count;
@ -205,6 +211,9 @@ shutdown_evil:
#ifdef HAVE_EVIL
evil_shutdown();
#endif
eo_shutdown();
return --_ecore_init_count;
}
@ -299,6 +308,9 @@ ecore_shutdown(void)
#ifdef HAVE_EVIL
evil_shutdown();
#endif
eo_unref(_ecore_parent);
eo_shutdown();
unlock:
_ecore_unlock();
@ -852,3 +864,15 @@ _thread_callback(void *data __UNUSED__,
_ecore_main_call_flush();
}
static const Eo_Class_Description parent_class_desc = {
EO_VERSION,
"ecore_parent",
EO_CLASS_TYPE_REGULAR,
EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
NULL,
0,
NULL,
NULL
};
EO_DEFINE_CLASS(ecore_parent_class_get, &parent_class_desc, EO_BASE_CLASS, NULL);

View File

@ -32,16 +32,16 @@ struct _Ecore_Mempool
eina_mempool_free(Type##_mp.mp, e); \
}
GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator);
//GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator);
GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler);
GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter);
GENERIC_ALLOC_FREE(Ecore_Event, ecore_event);
GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter);
GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer);
GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler);
GENERIC_ALLOC_FREE(Ecore_Job, ecore_job);
GENERIC_ALLOC_FREE(Ecore_Timer, ecore_timer);
GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller);
//GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter);
//GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer);
//GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler);
//GENERIC_ALLOC_FREE(Ecore_Job, ecore_job);
//GENERIC_ALLOC_FREE(Ecore_Timer, ecore_timer);
//GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller);
GENERIC_ALLOC_FREE(Ecore_Pipe, ecore_pipe);
GENERIC_ALLOC_FREE(Ecore_Fd_Handler, ecore_fd_handler);
#ifdef _WIN32
@ -49,16 +49,16 @@ GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler);
#endif
static Ecore_Mempool *mempool_array[] = {
&ecore_animator_mp,
// &ecore_animator_mp,
&ecore_event_handler_mp,
&ecore_event_filter_mp,
&ecore_event_mp,
&ecore_idle_exiter_mp,
&ecore_idle_enterer_mp,
&ecore_idler_mp,
&ecore_job_mp,
&ecore_timer_mp,
&ecore_poller_mp,
// &ecore_idle_exiter_mp,
// &ecore_idle_enterer_mp,
// &ecore_idler_mp,
// &ecore_job_mp,
// &ecore_timer_mp,
// &ecore_poller_mp,
&ecore_pipe_mp,
&ecore_fd_handler_mp,
#ifdef _WIN32
@ -75,16 +75,16 @@ ecore_mempool_init(void)
#define MP_SIZE_INIT(TYPE, Type) \
Type##_mp.size = _ecore_sizeof_##TYPE
MP_SIZE_INIT(Ecore_Animator, ecore_animator);
// MP_SIZE_INIT(Ecore_Animator, ecore_animator);
MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler);
MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter);
MP_SIZE_INIT(Ecore_Event, ecore_event);
MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter);
MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer);
MP_SIZE_INIT(Ecore_Idler, ecore_idler);
MP_SIZE_INIT(Ecore_Job, ecore_job);
MP_SIZE_INIT(Ecore_Timer, ecore_timer);
MP_SIZE_INIT(Ecore_Poller, ecore_poller);
// MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter);
// MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer);
// MP_SIZE_INIT(Ecore_Idler, ecore_idler);
// MP_SIZE_INIT(Ecore_Job, ecore_job);
// MP_SIZE_INIT(Ecore_Timer, ecore_timer);
// MP_SIZE_INIT(Ecore_Poller, ecore_poller);
MP_SIZE_INIT(Ecore_Pipe, ecore_pipe);
MP_SIZE_INIT(Ecore_Fd_Handler, ecore_fd_handler);
#ifdef _WIN32

View File

@ -8,10 +8,22 @@
#include "Ecore.h"
#include "ecore_private.h"
struct _Ecore_Animator
#include "Eo.h"
#define MY_CLASS ECORE_ANIMATOR_CLASS
#define MY_CLASS_NAME "ecore_animator"
#define ECORE_ANIMATOR_CHECK(obj) \
if (!eo_isa((obj), ECORE_ANIMATOR_CLASS)) \
return
EAPI Eo_Op ECORE_ANIMATOR_BASE_ID = EO_NOOP;
struct _Ecore_Animator_Private_Data
{
EINA_INLIST;
ECORE_MAGIC;
Ecore_Animator *obj;
Ecore_Task_Cb func;
void *data;
@ -25,13 +37,13 @@ struct _Ecore_Animator
Eina_Bool just_added : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Animator);
typedef struct _Ecore_Animator_Private_Data Ecore_Animator_Private_Data;
static Eina_Bool _ecore_animator_run(void *data);
static Eina_Bool _ecore_animator(void *data);
static int animators_delete_me = 0;
static Ecore_Animator *animators = NULL;
static Ecore_Animator_Private_Data *animators = NULL;
static double animators_frametime = 1.0 / 30.0;
static Ecore_Animator_Source src = ECORE_ANIMATOR_SOURCE_TIMER;
@ -98,7 +110,7 @@ _end_tick(void)
static Eina_Bool
_do_tick(void)
{
Ecore_Animator *animator;
Ecore_Animator_Private_Data *animator;
EINA_INLIST_FOREACH(animators, animator)
{
@ -120,18 +132,23 @@ _do_tick(void)
}
if (animators_delete_me)
{
Ecore_Animator *l;
Ecore_Animator_Private_Data *l;
for (l = animators; l; )
{
animator = l;
l = (Ecore_Animator *)EINA_INLIST_GET(l)->next;
l = (Ecore_Animator_Private_Data *)EINA_INLIST_GET(l)->next;
if (animator->delete_me)
{
animators = (Ecore_Animator *)
animators = (Ecore_Animator_Private_Data *)
eina_inlist_remove(EINA_INLIST_GET(animators),
EINA_INLIST_GET(animator));
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
ecore_animator_mp_free(animator);
eo_parent_set(animator->obj, NULL);
if (eo_destructed_is(animator->obj))
eo_manual_free(animator->obj);
else
eo_manual_free_set(animator->obj, EINA_FALSE);
animators_delete_me--;
if (animators_delete_me == 0) break;
}
@ -145,56 +162,100 @@ _do_tick(void)
return ECORE_CALLBACK_RENEW;
}
static Ecore_Animator *
_ecore_animator_add(Ecore_Task_Cb func,
static Eina_Bool
_ecore_animator_add(Ecore_Animator *obj,
Ecore_Animator_Private_Data *animator,
Ecore_Task_Cb func,
const void *data)
{
Ecore_Animator *animator = NULL;
if (EINA_UNLIKELY(!eina_main_loop_is()))
{
eo_error_set(obj);
EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
}
animator->obj = obj;
eo_do_super(obj, eo_constructor());
eo_manual_free_set(obj, EINA_TRUE);
if (!func)
{
eo_error_set(obj);
ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME);
return EINA_FALSE;
}
if (!func) return animator;
animator = ecore_animator_calloc(1);
if (!animator) return animator;
ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR);
animator->func = func;
animator->data = (void *)data;
animator->just_added = EINA_TRUE;
animators = (Ecore_Animator *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
animators = (Ecore_Animator_Private_Data *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
_begin_tick();
return animator;
return EINA_TRUE;
}
static void
_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
{
eo_error_set(obj);
ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME);
}
EAPI Ecore_Animator *
ecore_animator_add(Ecore_Task_Cb func,
const void *data)
{
Ecore_Animator *animator;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
_ecore_lock();
animator = _ecore_animator_add(func, data);
_ecore_unlock();
Ecore_Animator *animator = NULL;
animator = eo_add_custom(MY_CLASS, _ecore_parent,
ecore_animator_constructor(func, data));
eo_unref(animator);
return animator;
}
static void
_animator_constructor(Eo *obj, void *_pd, va_list *list)
{
Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb);
const void *data = va_arg(*list, const void *);
_ecore_lock();
Ecore_Animator_Private_Data *animator = _pd;
_ecore_animator_add(obj, animator, func, data);
_ecore_unlock();
}
EAPI Ecore_Animator *
ecore_animator_timeline_add(double runtime,
Ecore_Timeline_Cb func,
const void *data)
{
Ecore_Animator *animator;
animator = eo_add_custom(MY_CLASS, _ecore_parent,
ecore_animator_timeline_constructor(runtime, func, data));
eo_unref(animator);
return animator;
}
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
static void
_animator_timeline_constructor(Eo *obj, void *_pd, va_list *list)
{
_ecore_lock();
double runtime = va_arg(*list, double);
if (runtime <= 0.0) runtime = 0.0;
animator = _ecore_animator_add(_ecore_animator_run, NULL);
animator->data = animator;
Ecore_Timeline_Cb func = va_arg(*list, Ecore_Timeline_Cb);
const void *data = va_arg(*list, const void *);
Ecore_Animator_Private_Data *animator = _pd;
if (!_ecore_animator_add(obj, animator, _ecore_animator_run, NULL)) goto unlock;
animator->data = obj;
animator->run_func = func;
animator->run_data = (void *)data;
animator->start = ecore_loop_time_get();
animator->run = runtime;
unlock:
_ecore_unlock();
return animator;
}
static double
@ -333,18 +394,14 @@ ecore_animator_pos_map(double pos,
}
EAPI void *
ecore_animator_del(Ecore_Animator *animator)
ecore_animator_del(Ecore_Animator *obj)
{
void *data = NULL;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Animator_Private_Data *animator = eo_data_get(obj, MY_CLASS);
_ecore_lock();
if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
{
ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
"ecore_animator_del");
goto unlock;
}
if (animator->delete_me)
{
data = animator->data;
@ -361,6 +418,17 @@ unlock:
return data;
}
static void
_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
{
Ecore_Animator_Private_Data *pd = _pd;
pd->delete_me = EINA_TRUE;
animators_delete_me++;
eo_do_super(obj, eo_destructor());
}
EAPI void
ecore_animator_frametime_set(double frametime)
{
@ -384,15 +452,19 @@ ecore_animator_frametime_get(void)
EAPI void
ecore_animator_freeze(Ecore_Animator *animator)
{
ECORE_ANIMATOR_CHECK(animator);
eo_do(animator, eo_event_freeze());
}
static void
_ecore_animator_freeze(Eo *obj EINA_UNUSED, void *_pd,
va_list *list EINA_UNUSED)
{
EINA_MAIN_LOOP_CHECK_RETURN;
_ecore_lock();
if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
{
ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
"ecore_animator_del");
goto unlock;
}
Ecore_Animator_Private_Data *animator = _pd;
if (animator->delete_me) goto unlock;
animator->suspended = EINA_TRUE;
unlock:
@ -401,15 +473,19 @@ unlock:
EAPI void
ecore_animator_thaw(Ecore_Animator *animator)
{
ECORE_ANIMATOR_CHECK(animator);
eo_do(animator, eo_event_thaw());
}
static void
_ecore_animator_thaw(Eo *obj EINA_UNUSED, void *_pd,
va_list *list EINA_UNUSED)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Animator_Private_Data *animator = _pd;
_ecore_lock();
if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
{
ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
"ecore_animator_del");
goto unlock;
}
if (animator->delete_me) goto unlock;
animator->suspended = EINA_FALSE;
unlock:
@ -475,19 +551,25 @@ _ecore_animator_shutdown(void)
_end_tick();
while (animators)
{
Ecore_Animator *animator;
Ecore_Animator_Private_Data *animator;
animator = animators;
animators = (Ecore_Animator *)eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators));
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
ecore_animator_mp_free(animator);
animators = (Ecore_Animator_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators));
eo_parent_set(animator->obj, NULL);
if (eo_destructed_is(animator->obj))
eo_manual_free(animator->obj);
else
eo_manual_free_set(animator->obj, EINA_FALSE);
}
}
static Eina_Bool
_ecore_animator_run(void *data)
{
Ecore_Animator *animator = data;
Ecore_Animator *obj = data;
Ecore_Animator_Private_Data *animator = eo_data_get(obj, MY_CLASS);
double pos = 0.0, t;
Eina_Bool run_ret;
@ -514,3 +596,38 @@ _ecore_animator(void *data __UNUSED__)
return r;
}
static void
_class_constructor(Eo_Class *klass)
{
const Eo_Op_Func_Description func_desc[] = {
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _ecore_animator_freeze),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _ecore_animator_thaw),
EO_OP_FUNC(ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR), _animator_constructor),
EO_OP_FUNC(ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR), _animator_timeline_constructor),
EO_OP_FUNC_SENTINEL
};
eo_class_funcs_set(klass, func_desc);
}
static const Eo_Op_Description op_desc[] = {
EO_OP_DESCRIPTION(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR, "Add an animator to call func at every animation tick during main loop execution."),
EO_OP_DESCRIPTION(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR, "Add an animator that runs for a limited time"),
EO_OP_DESCRIPTION_SENTINEL
};
static const Eo_Class_Description class_desc = {
EO_VERSION,
MY_CLASS_NAME,
EO_CLASS_TYPE_REGULAR,
EO_CLASS_DESCRIPTION_OPS(&ECORE_ANIMATOR_BASE_ID, op_desc, ECORE_ANIMATOR_SUB_ID_LAST),
NULL,
sizeof(Ecore_Animator_Private_Data),
_class_constructor,
NULL
};
EO_DEFINE_CLASS(ecore_animator_class_get, &class_desc, EO_BASE_CLASS, NULL)

View File

@ -7,19 +7,27 @@
#include "Ecore.h"
#include "ecore_private.h"
struct _Ecore_Idle_Enterer
#include "Eo.h"
#define MY_CLASS ECORE_IDLE_ENTERER_CLASS
#define MY_CLASS_NAME "ecore_idle_enterer"
EAPI Eo_Op ECORE_IDLE_ENTERER_BASE_ID = EO_NOOP;
struct _Ecore_Idle_Enterer_Private_Data
{
EINA_INLIST;
ECORE_MAGIC;
Ecore_Task_Cb func;
void *data;
int references;
Eina_Bool delete_me : 1;
Ecore_Idle_Enterer *obj;
Ecore_Task_Cb func;
void *data;
int references;
Eina_Bool delete_me : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Idle_Enterer);
typedef struct _Ecore_Idle_Enterer_Private_Data Ecore_Idle_Enterer_Private_Data;
static Ecore_Idle_Enterer *idle_enterers = NULL;
static Ecore_Idle_Enterer *idle_enterer_current = NULL;
static Ecore_Idle_Enterer_Private_Data *idle_enterers = NULL;
static Ecore_Idle_Enterer_Private_Data *idle_enterer_current = NULL;
static int idle_enterers_delete_me = 0;
static void *
@ -31,6 +39,34 @@ _ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
* @{
*/
static Eina_Bool
_ecore_idle_enterer_add(Ecore_Idle_Enterer *obj,
Ecore_Idle_Enterer_Private_Data *ie,
Ecore_Task_Cb func,
const void *data)
{
if (EINA_UNLIKELY(!eina_main_loop_is()))
{
eo_error_set(obj);
EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FLASE);
}
ie->obj = obj;
eo_do_super(obj, eo_constructor());
eo_manual_free_set(obj, EINA_TRUE);
if (!func)
{
eo_error_set(obj);
ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME);
return EINA_FALSE;
}
ie->func = func;
ie->data = (void *)data;
return EINA_TRUE;
}
/**
* Add an idle enterer handler.
* @param func The function to call when entering an idle state.
@ -46,20 +82,25 @@ ecore_idle_enterer_add(Ecore_Task_Cb func,
const void *data)
{
Ecore_Idle_Enterer *ie = NULL;
ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_enterer_after_constructor(func, data));
eo_unref(ie);
return ie;
}
static void
_idle_enterer_after_constructor(Eo *obj, void *_pd, va_list *list)
{
Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb);
const void *data = va_arg(*list, const void *);
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
_ecore_lock();
Ecore_Idle_Enterer_Private_Data *ie = _pd;
if (!_ecore_idle_enterer_add(obj, ie, func, data)) goto unlock;
idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
if (!func) goto unlock;
ie = ecore_idle_enterer_calloc(1);
if (!ie) goto unlock;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
ie->func = func;
ie->data = (void *)data;
idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
unlock:
_ecore_unlock();
return ie;
}
/**
@ -77,20 +118,32 @@ ecore_idle_enterer_before_add(Ecore_Task_Cb func,
const void *data)
{
Ecore_Idle_Enterer *ie = NULL;
ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_enterer_before_constructor(func, data));
eo_unref(ie);
return ie;
}
static void
_idle_enterer_before_constructor(Eo *obj, void *_pd, va_list *list)
{
Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb);
const void *data = va_arg(*list, const void *);
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
_ecore_lock();
Ecore_Idle_Enterer_Private_Data *ie = _pd;
if (!_ecore_idle_enterer_add(obj, ie, func, data)) goto unlock;
idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
if (!func) goto unlock;
ie = ecore_idle_enterer_calloc(1);
if (!ie) goto unlock;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
ie->func = func;
ie->data = (void *)data;
idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
unlock:
_ecore_unlock();
return ie;
}
static void
_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
{
eo_error_set(obj);
ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME);
}
/**
@ -102,15 +155,10 @@ unlock:
EAPI void *
ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
{
void *data;
void *data = NULL;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER))
{
ECORE_MAGIC_FAIL(idle_enterer, ECORE_MAGIC_IDLE_ENTERER,
"ecore_idle_enterer_del");
return NULL;
}
_ecore_lock();
data = _ecore_idle_enterer_del(idle_enterer);
_ecore_unlock();
@ -121,24 +169,42 @@ ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
* @}
*/
static void *
_ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
_ecore_idle_enterer_del(Ecore_Idle_Enterer *obj)
{
Ecore_Idle_Enterer_Private_Data *idle_enterer = eo_data_get(obj, MY_CLASS);
EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL);
idle_enterer->delete_me = 1;
idle_enterers_delete_me = 1;
return idle_enterer->data;
}
static void
_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
{
Ecore_Idle_Enterer_Private_Data *idle_enterer = _pd;
idle_enterer->delete_me = 1;
idle_enterers_delete_me = 1;
eo_do_super(obj, eo_destructor());
}
void
_ecore_idle_enterer_shutdown(void)
{
Ecore_Idle_Enterer *ie;
Ecore_Idle_Enterer_Private_Data *ie;
while ((ie = idle_enterers))
{
idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
ecore_idle_enterer_mp_free(ie);
idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
eo_parent_set(ie->obj, NULL);
if (eo_destructed_is(ie->obj))
eo_manual_free(ie->obj);
else
eo_manual_free_set(ie->obj, EINA_FALSE);
}
idle_enterers_delete_me = 0;
idle_enterer_current = NULL;
@ -156,34 +222,34 @@ _ecore_idle_enterer_call(void)
{
/* recursive main loop, continue from where we were */
idle_enterer_current =
(Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
(Ecore_Idle_Enterer_Private_Data *)EINA_INLIST_GET(idle_enterer_current)->next;
}
while (idle_enterer_current)
{
Ecore_Idle_Enterer *ie = (Ecore_Idle_Enterer *)idle_enterer_current;
Ecore_Idle_Enterer_Private_Data *ie = (Ecore_Idle_Enterer_Private_Data *)idle_enterer_current;
if (!ie->delete_me)
{
ie->references++;
if (!_ecore_call_task_cb(ie->func, ie->data))
{
if (!ie->delete_me) _ecore_idle_enterer_del(ie);
if (!ie->delete_me) _ecore_idle_enterer_del(ie->obj);
}
ie->references--;
}
if (idle_enterer_current) /* may have changed in recursive main loops */
idle_enterer_current =
(Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
(Ecore_Idle_Enterer_Private_Data *)EINA_INLIST_GET(idle_enterer_current)->next;
}
if (idle_enterers_delete_me)
{
Ecore_Idle_Enterer *l;
Ecore_Idle_Enterer_Private_Data *l;
int deleted_idler_enterers_in_use = 0;
for (l = idle_enterers; l; )
{
Ecore_Idle_Enterer *ie = l;
l = (Ecore_Idle_Enterer *)EINA_INLIST_GET(l)->next;
Ecore_Idle_Enterer_Private_Data *ie = l;
l = (Ecore_Idle_Enterer_Private_Data *)EINA_INLIST_GET(l)->next;
if (ie->delete_me)
{
if (ie->references)
@ -192,9 +258,13 @@ _ecore_idle_enterer_call(void)
continue;
}
idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
ecore_idle_enterer_mp_free(ie);
idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
eo_parent_set(ie->obj, NULL);
if (eo_destructed_is(ie->obj))
eo_manual_free(ie->obj);
else
eo_manual_free_set(ie->obj, EINA_FALSE);
}
}
if (!deleted_idler_enterers_in_use)
@ -209,3 +279,35 @@ _ecore_idle_enterer_exist(void)
return 0;
}
static void
_class_constructor(Eo_Class *klass)
{
const Eo_Op_Func_Description func_desc[] = {
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
EO_OP_FUNC(ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR), _idle_enterer_after_constructor),
EO_OP_FUNC(ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR), _idle_enterer_before_constructor),
EO_OP_FUNC_SENTINEL
};
eo_class_funcs_set(klass, func_desc);
}
static const Eo_Op_Description op_desc[] = {
EO_OP_DESCRIPTION(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR, "Add an idle enterer handler."),
EO_OP_DESCRIPTION(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR, "Add an idle enterer handler at the start of the list so it gets called earlier than others."),
EO_OP_DESCRIPTION_SENTINEL
};
static const Eo_Class_Description class_desc = {
EO_VERSION,
MY_CLASS_NAME,
EO_CLASS_TYPE_REGULAR,
EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLE_ENTERER_BASE_ID, op_desc, ECORE_IDLE_ENTERER_SUB_ID_LAST),
NULL,
sizeof(Ecore_Idle_Enterer_Private_Data),
_class_constructor,
NULL
};
EO_DEFINE_CLASS(ecore_idle_enterer_class_get, &class_desc, EO_BASE_CLASS, NULL)

View File

@ -7,19 +7,28 @@
#include "Ecore.h"
#include "ecore_private.h"
struct _Ecore_Idle_Exiter
#include "Eo.h"
#define MY_CLASS ECORE_IDLE_EXITER_CLASS
#define MY_CLASS_NAME "ecore_idle_exitier"
EAPI Eo_Op ECORE_IDLE_EXITER_BASE_ID = EO_NOOP;
struct _Ecore_Idle_Exiter_Private_Data
{
EINA_INLIST;
ECORE_MAGIC;
Ecore_Task_Cb func;
void *data;
int references;
Eina_Bool delete_me : 1;
Ecore_Idle_Exiter *obj;
Ecore_Task_Cb func;
void *data;
int references;
Eina_Bool delete_me : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Idle_Exiter);
static Ecore_Idle_Exiter *idle_exiters = NULL;
static Ecore_Idle_Exiter *idle_exiter_current = NULL;
typedef struct _Ecore_Idle_Exiter_Private_Data Ecore_Idle_Exiter_Private_Data;
static Ecore_Idle_Exiter_Private_Data *idle_exiters = NULL;
static Ecore_Idle_Exiter_Private_Data *idle_exiter_current = NULL;
static int idle_exiters_delete_me = 0;
static void *
@ -45,19 +54,49 @@ ecore_idle_exiter_add(Ecore_Task_Cb func,
const void *data)
{
Ecore_Idle_Exiter *ie = NULL;
ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_exiter_constructor(func, data));
eo_unref(ie);
return ie;
}
static void
_idle_exiter_constructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
{
Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb);
const void *data = va_arg(*list, const void *);
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
_ecore_lock();
if (!func) goto unlock;
ie = ecore_idle_exiter_calloc(1);
if (!ie) goto unlock;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER);
if (EINA_UNLIKELY(!eina_main_loop_is()))
{
eo_error_set(obj);
EINA_MAIN_LOOP_CHECK_RETURN;
}
Ecore_Idle_Exiter_Private_Data *ie = _pd;
ie->obj = obj;
eo_do_super(obj, eo_constructor());
eo_manual_free_set(obj, EINA_TRUE);
if (!func)
{
eo_error_set(obj);
ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME);
return;
}
ie->func = func;
ie->data = (void *)data;
idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
unlock:
idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
_ecore_unlock();
return ie;
}
static void
_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
{
eo_error_set(obj);
ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME);
}
/**
@ -72,12 +111,7 @@ ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
void *data;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER))
{
ECORE_MAGIC_FAIL(idle_exiter, ECORE_MAGIC_IDLE_EXITER,
"ecore_idle_exiter_del");
return NULL;
}
_ecore_lock();
data = _ecore_idle_exiter_del(idle_exiter);
_ecore_unlock();
@ -87,25 +121,41 @@ ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
/**
* @}
*/
static void *
_ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
_ecore_idle_exiter_del(Ecore_Idle_Exiter *obj)
{
Ecore_Idle_Exiter_Private_Data *idle_exiter = eo_data_get(obj, MY_CLASS);
EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_exiter->delete_me, NULL);
idle_exiter->delete_me = 1;
idle_exiters_delete_me = 1;
return idle_exiter->data;
}
static void
_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
{
Ecore_Idle_Exiter_Private_Data *idle_exiter = _pd;
idle_exiter->delete_me = 1;
idle_exiters_delete_me = 1;
eo_do_super(obj, eo_destructor());
}
void
_ecore_idle_exiter_shutdown(void)
{
Ecore_Idle_Exiter *ie;
Ecore_Idle_Exiter_Private_Data *ie;
while ((ie = idle_exiters))
{
idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
ecore_idle_exiter_mp_free(ie);
idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters));
eo_parent_set(ie->obj, NULL);
if (eo_destructed_is(ie->obj))
eo_manual_free(ie->obj);
else
eo_manual_free_set(ie->obj, EINA_FALSE);
}
idle_exiters_delete_me = 0;
idle_exiter_current = NULL;
@ -123,35 +173,35 @@ _ecore_idle_exiter_call(void)
{
/* recursive main loop, continue from where we were */
idle_exiter_current =
(Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
(Ecore_Idle_Exiter_Private_Data *)EINA_INLIST_GET(idle_exiter_current)->next;
}
while (idle_exiter_current)
{
Ecore_Idle_Exiter *ie = (Ecore_Idle_Exiter *)idle_exiter_current;
Ecore_Idle_Exiter_Private_Data *ie = (Ecore_Idle_Exiter_Private_Data *)idle_exiter_current;
if (!ie->delete_me)
{
ie->references++;
if (!_ecore_call_task_cb(ie->func, ie->data))
{
if (!ie->delete_me) _ecore_idle_exiter_del(ie);
if (!ie->delete_me) _ecore_idle_exiter_del(ie->obj);
}
ie->references--;
}
if (idle_exiter_current) /* may have changed in recursive main loops */
idle_exiter_current =
(Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
(Ecore_Idle_Exiter_Private_Data *)EINA_INLIST_GET(idle_exiter_current)->next;
}
if (idle_exiters_delete_me)
{
Ecore_Idle_Exiter *l;
Ecore_Idle_Exiter_Private_Data *l;
int deleted_idler_exiters_in_use = 0;
for (l = idle_exiters; l; )
{
Ecore_Idle_Exiter *ie = l;
Ecore_Idle_Exiter_Private_Data *ie = l;
l = (Ecore_Idle_Exiter *)EINA_INLIST_GET(l)->next;
l = (Ecore_Idle_Exiter_Private_Data *)EINA_INLIST_GET(l)->next;
if (ie->delete_me)
{
if (ie->references)
@ -160,9 +210,13 @@ _ecore_idle_exiter_call(void)
continue;
}
idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
ecore_idle_exiter_mp_free(ie);
idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
eo_parent_set(ie->obj, NULL);
if (eo_destructed_is(ie->obj))
eo_manual_free(ie->obj);
else
eo_manual_free_set(ie->obj, EINA_FALSE);
}
}
if (!deleted_idler_exiters_in_use)
@ -177,3 +231,34 @@ _ecore_idle_exiter_exist(void)
return 0;
}
static void
_class_constructor(Eo_Class *klass)
{
const Eo_Op_Func_Description func_desc[] = {
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
EO_OP_FUNC(ECORE_IDLE_EXITER_ID(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR), _idle_exiter_constructor),
EO_OP_FUNC_SENTINEL
};
eo_class_funcs_set(klass, func_desc);
}
static const Eo_Op_Description op_desc[] = {
EO_OP_DESCRIPTION(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR, "Add an idle exiter handler."),
EO_OP_DESCRIPTION_SENTINEL
};
static const Eo_Class_Description class_desc = {
EO_VERSION,
MY_CLASS_NAME,
EO_CLASS_TYPE_REGULAR,
EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLE_EXITER_BASE_ID, op_desc, ECORE_IDLE_EXITER_SUB_ID_LAST),
NULL,
sizeof(Ecore_Idle_Exiter_Private_Data),
_class_constructor,
NULL
};
EO_DEFINE_CLASS(ecore_idle_exiter_class_get, &class_desc, EO_BASE_CLASS, NULL)

View File

@ -7,19 +7,27 @@
#include "Ecore.h"
#include "ecore_private.h"
struct _Ecore_Idler
#include "Eo.h"
#define MY_CLASS ECORE_IDLER_CLASS
#define MY_CLASS_NAME "ecore_idler"
EAPI Eo_Op ECORE_IDLER_BASE_ID = EO_NOOP;
struct _Ecore_Idler_Private_Data
{
EINA_INLIST;
ECORE_MAGIC;
Ecore_Idler *obj;
Ecore_Task_Cb func;
void *data;
int references;
Eina_Bool delete_me : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Idler);
static Ecore_Idler *idlers = NULL;