forked from enlightenment/efl
Add a custom Ecore Aniamtor source and tick ability to be able
to plug in external animator tick sources like vblank interrupts and so on. SVN revision: 59345
This commit is contained in:
parent
909e11f49f
commit
7fbe314439
|
@ -167,3 +167,8 @@
|
||||||
* Fixed null pointer dereference in selection notification
|
* Fixed null pointer dereference in selection notification
|
||||||
handling in Ecore_X.
|
handling in Ecore_X.
|
||||||
|
|
||||||
|
2011-05-12 Carsten Haitzler (The Rasterman)
|
||||||
|
|
||||||
|
* Add a custom Ecore Aniamtor source and tick ability to be able
|
||||||
|
to plug in external animator tick sources like vblank interrupts
|
||||||
|
and so on.
|
||||||
|
|
|
@ -162,6 +162,13 @@ extern "C" {
|
||||||
};
|
};
|
||||||
typedef enum _Ecore_Pos_Map Ecore_Pos_Map;
|
typedef enum _Ecore_Pos_Map Ecore_Pos_Map;
|
||||||
|
|
||||||
|
enum _Ecore_Animator_Source /* Timing sources for animators */
|
||||||
|
{
|
||||||
|
ECORE_ANIMATOR_SOURCE_TIMER, /**< The default system clock/timer based animator that ticks every "frametime" seconds */
|
||||||
|
ECORE_ANIMATOR_SOURCE_CUSTOM /**< A custom animator trigger that you need to call ecore_animator_trigger() to make it tick */
|
||||||
|
};
|
||||||
|
typedef enum _Ecore_Animator_Source Ecore_Animator_Source;
|
||||||
|
|
||||||
typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */
|
typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */
|
||||||
typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */
|
typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */
|
||||||
typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */
|
typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */
|
||||||
|
@ -582,6 +589,11 @@ extern "C" {
|
||||||
EAPI void ecore_animator_frametime_set(double frametime);
|
EAPI void ecore_animator_frametime_set(double frametime);
|
||||||
EAPI double ecore_animator_frametime_get(void);
|
EAPI double ecore_animator_frametime_get(void);
|
||||||
EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2);
|
EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2);
|
||||||
|
EAPI void ecore_animator_source_set(Ecore_Animator_Source source);
|
||||||
|
EAPI Ecore_Animator_Source ecore_animator_source_get(void);
|
||||||
|
EAPI void ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data);
|
||||||
|
EAPI void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data);
|
||||||
|
EAPI void ecore_animator_custom_tick(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
|
|
@ -29,10 +29,109 @@ struct _Ecore_Animator
|
||||||
static Eina_Bool _ecore_animator_run(void *data);
|
static Eina_Bool _ecore_animator_run(void *data);
|
||||||
static Eina_Bool _ecore_animator(void *data);
|
static Eina_Bool _ecore_animator(void *data);
|
||||||
|
|
||||||
static Ecore_Timer *timer = NULL;
|
static int animators_delete_me = 0;
|
||||||
static int animators_delete_me = 0;
|
static Ecore_Animator *animators = NULL;
|
||||||
static Ecore_Animator *animators = NULL;
|
static double animators_frametime = 1.0 / 30.0;
|
||||||
static double animators_frametime = 1.0 / 30.0;
|
|
||||||
|
static Ecore_Animator_Source src = ECORE_ANIMATOR_SOURCE_TIMER;
|
||||||
|
static Ecore_Timer *timer = NULL;
|
||||||
|
static int ticking = 0;
|
||||||
|
static Ecore_Cb begin_tick_cb = NULL;
|
||||||
|
static const void *begin_tick_data = NULL;
|
||||||
|
static Ecore_Cb end_tick_cb = NULL;
|
||||||
|
static const void *end_tick_data = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_begin_tick(void)
|
||||||
|
{
|
||||||
|
if (ticking) return;
|
||||||
|
ticking = 1;
|
||||||
|
switch (src)
|
||||||
|
{
|
||||||
|
case ECORE_ANIMATOR_SOURCE_TIMER:
|
||||||
|
if (!timer)
|
||||||
|
{
|
||||||
|
double t_loop = ecore_loop_time_get();
|
||||||
|
double sync_0 = 0.0;
|
||||||
|
double d = -fmod(t_loop - sync_0, animators_frametime);
|
||||||
|
|
||||||
|
timer = ecore_timer_loop_add(animators_frametime,
|
||||||
|
_ecore_animator, NULL);
|
||||||
|
ecore_timer_delay(timer, d);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ECORE_ANIMATOR_SOURCE_CUSTOM:
|
||||||
|
if (begin_tick_cb) begin_tick_cb((void *)begin_tick_data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_end_tick(void)
|
||||||
|
{
|
||||||
|
if (!ticking) return;
|
||||||
|
ticking = 0;
|
||||||
|
switch (src)
|
||||||
|
{
|
||||||
|
case ECORE_ANIMATOR_SOURCE_TIMER:
|
||||||
|
if (timer)
|
||||||
|
{
|
||||||
|
ecore_timer_del(timer);
|
||||||
|
timer = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ECORE_ANIMATOR_SOURCE_CUSTOM:
|
||||||
|
if (end_tick_cb) end_tick_cb((void *)end_tick_data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_do_tick(void)
|
||||||
|
{
|
||||||
|
Ecore_Animator *animator;
|
||||||
|
|
||||||
|
EINA_INLIST_FOREACH(animators, animator)
|
||||||
|
{
|
||||||
|
if (!animator->delete_me && !animator->suspended)
|
||||||
|
{
|
||||||
|
if (!animator->func(animator->data))
|
||||||
|
{
|
||||||
|
animator->delete_me = EINA_TRUE;
|
||||||
|
animators_delete_me++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (animators_delete_me)
|
||||||
|
{
|
||||||
|
Ecore_Animator *l;
|
||||||
|
for (l = animators; l;)
|
||||||
|
{
|
||||||
|
animator = l;
|
||||||
|
l = (Ecore_Animator *) EINA_INLIST_GET(l)->next;
|
||||||
|
if (animator->delete_me)
|
||||||
|
{
|
||||||
|
animators = (Ecore_Animator *)
|
||||||
|
eina_inlist_remove(EINA_INLIST_GET(animators),
|
||||||
|
EINA_INLIST_GET(animator));
|
||||||
|
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
|
||||||
|
free(animator);
|
||||||
|
animators_delete_me--;
|
||||||
|
if (animators_delete_me == 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!animators)
|
||||||
|
{
|
||||||
|
_end_tick();
|
||||||
|
return ECORE_CALLBACK_CANCEL;
|
||||||
|
}
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup Ecore_Group Ecore - Main Loop and Job Functions.
|
* @addtogroup Ecore_Group Ecore - Main Loop and Job Functions.
|
||||||
|
@ -74,15 +173,7 @@ ecore_animator_add(Ecore_Task_Cb func, const void *data)
|
||||||
animator->func = func;
|
animator->func = func;
|
||||||
animator->data = (void *)data;
|
animator->data = (void *)data;
|
||||||
animators = (Ecore_Animator *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
|
animators = (Ecore_Animator *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
|
||||||
if (!timer)
|
_begin_tick();
|
||||||
{
|
|
||||||
double t_loop = ecore_loop_time_get();
|
|
||||||
double sync_0 = 0.0;
|
|
||||||
double d = -fmod(t_loop - sync_0, animators_frametime);
|
|
||||||
|
|
||||||
timer = ecore_timer_loop_add(animators_frametime, _ecore_animator, NULL);
|
|
||||||
ecore_timer_delay(timer, d);
|
|
||||||
}
|
|
||||||
return animator;
|
return animator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,13 +371,8 @@ ecore_animator_frametime_set(double frametime)
|
||||||
if (frametime < 0.0) frametime = 0.0;
|
if (frametime < 0.0) frametime = 0.0;
|
||||||
if (animators_frametime == frametime) return;
|
if (animators_frametime == frametime) return;
|
||||||
animators_frametime = frametime;
|
animators_frametime = frametime;
|
||||||
if (timer)
|
_end_tick();
|
||||||
{
|
if (animators) _begin_tick();
|
||||||
ecore_timer_del(timer);
|
|
||||||
timer = NULL;
|
|
||||||
}
|
|
||||||
if (animators)
|
|
||||||
timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -341,14 +427,111 @@ ecore_animator_thaw(Ecore_Animator *animator)
|
||||||
animator->suspended = EINA_FALSE;
|
animator->suspended = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the source of animator ticks for the mainloop
|
||||||
|
*
|
||||||
|
* @param source The source of animator ticks to use
|
||||||
|
*
|
||||||
|
* This sets the source of animator ticks. When an animator is active the
|
||||||
|
* mainloop will "tick" over frame by frame calling all animators that are
|
||||||
|
* registered until none are. The mainloop will tick at a given rate based
|
||||||
|
* on the animator source. The default source is the system clock timer
|
||||||
|
* source - ECORE_ANIMATOR_SOURCE_TIMER. This source uses the system clock
|
||||||
|
* to tick over every N seconds (specified by ecore_animator_frametime_set(),
|
||||||
|
* with the default being 1/30th of a second unless set otherwise). You can
|
||||||
|
* set a custom tick source by setting the source to
|
||||||
|
* ECORE_ANIMATOR_SOURCE_CUSTOM and then drive it yourself based on some input
|
||||||
|
* tick source (like another application via ipc, some vertical blanking
|
||||||
|
* interrupt etc.) using ecore_animator_custom_source_tick_begin_callback_set()
|
||||||
|
* and ecore_animator_custom_source_tick_end_callback_set() to set the
|
||||||
|
* functions that will be called to start and stop the ticking source, which
|
||||||
|
* when it gets a "tick" should call ecore_animator_custom_tick() to make
|
||||||
|
* the animator "tick" over 1 frame.
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
ecore_animator_source_set(Ecore_Animator_Source source)
|
||||||
|
{
|
||||||
|
src = source;
|
||||||
|
_end_tick();
|
||||||
|
if (animators) _begin_tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the animator source currently set
|
||||||
|
* @return The current animator source
|
||||||
|
*
|
||||||
|
* This gets the current animator source. See ecore_animator_source_set() for
|
||||||
|
* more information.
|
||||||
|
*/
|
||||||
|
EAPI Ecore_Animator_Source
|
||||||
|
ecore_animator_source_get(void)
|
||||||
|
{
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the function that begins a custom animator tick source
|
||||||
|
*
|
||||||
|
* @param func The function to call when ticking is to begin
|
||||||
|
* @param data The data passed to the tick begin function as its parameter
|
||||||
|
*
|
||||||
|
* The Ecore Animator infrastructure handles tracking if animators are needed
|
||||||
|
* or not and which ones need to be called and when, but when the tick source
|
||||||
|
* is custom, you have to provide a tick source by calling
|
||||||
|
* ecore_animator_custom_tick() to indicate a frame tick happened. In order
|
||||||
|
* to allow the source of ticks to be dynamically enabled or disabled as
|
||||||
|
* needed, the @p func when set is called to enable the tick source to
|
||||||
|
* produce tick events that call ecore_animator_custom_tick(). If @p func
|
||||||
|
* is NULL then no function is called to begin custom ticking.
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data)
|
||||||
|
{
|
||||||
|
begin_tick_cb = func;
|
||||||
|
begin_tick_data = data;
|
||||||
|
_end_tick();
|
||||||
|
if (animators) _begin_tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the function that ends a custom animator tick source
|
||||||
|
* @param func The function to call when ticking is to end
|
||||||
|
* @param data The data passed to the tick end function as its parameter
|
||||||
|
*
|
||||||
|
* This function is a matching pair to the function set by
|
||||||
|
* ecore_animator_custom_source_tick_begin_callback_set() and is called
|
||||||
|
* when ticking is to stop. If @p func is NULL then no function will be
|
||||||
|
* called to stop ticking. For more information please see
|
||||||
|
* ecore_animator_custom_source_tick_begin_callback_set().
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data)
|
||||||
|
{
|
||||||
|
end_tick_cb = func;
|
||||||
|
end_tick_data = data;
|
||||||
|
_end_tick();
|
||||||
|
if (animators) _begin_tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger a custom animator tick
|
||||||
|
*
|
||||||
|
* When animator source is set to ECORE_ANIMATOR_SOURCE_CUSTOM, then calling
|
||||||
|
* this function triggers a run of all animators currently registered with
|
||||||
|
* Ecore as this indicates a "frame tick" happened. This will do nothing
|
||||||
|
* if the animator source (set by ecore_animator_source_set() ) is not set
|
||||||
|
* to ECORE_ANIMATOR_SOURCE_CUSTOM.
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
ecore_animator_custom_tick(void)
|
||||||
|
{
|
||||||
|
if (src == ECORE_ANIMATOR_SOURCE_CUSTOM) _do_tick();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_ecore_animator_shutdown(void)
|
_ecore_animator_shutdown(void)
|
||||||
{
|
{
|
||||||
if (timer)
|
_end_tick();
|
||||||
{
|
|
||||||
ecore_timer_del(timer);
|
|
||||||
timer = NULL;
|
|
||||||
}
|
|
||||||
while (animators)
|
while (animators)
|
||||||
{
|
{
|
||||||
Ecore_Animator *animator;
|
Ecore_Animator *animator;
|
||||||
|
@ -382,42 +565,7 @@ _ecore_animator_run(void *data)
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_ecore_animator(void *data __UNUSED__)
|
_ecore_animator(void *data __UNUSED__)
|
||||||
{
|
{
|
||||||
Ecore_Animator *animator;
|
return _do_tick();
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(animators, animator)
|
|
||||||
{
|
|
||||||
if (!animator->delete_me && !animator->suspended)
|
|
||||||
{
|
|
||||||
if (!animator->func(animator->data))
|
|
||||||
{
|
|
||||||
animator->delete_me = EINA_TRUE;
|
|
||||||
animators_delete_me++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (animators_delete_me)
|
|
||||||
{
|
|
||||||
Ecore_Animator *l;
|
|
||||||
for(l = animators; l;)
|
|
||||||
{
|
|
||||||
animator = l;
|
|
||||||
l = (Ecore_Animator *) EINA_INLIST_GET(l)->next;
|
|
||||||
if (animator->delete_me)
|
|
||||||
{
|
|
||||||
animators = (Ecore_Animator *) eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
|
|
||||||
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
|
|
||||||
free(animator);
|
|
||||||
animators_delete_me--;
|
|
||||||
if (animators_delete_me == 0) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!animators)
|
|
||||||
{
|
|
||||||
timer = NULL;
|
|
||||||
return ECORE_CALLBACK_CANCEL;
|
|
||||||
}
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue