2009-01-31 10:33:39 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2010-01-26 19:51:46 -08:00
|
|
|
#include <math.h>
|
2009-01-31 10:33:39 -08:00
|
|
|
|
2012-11-18 22:26:48 -08:00
|
|
|
#include <Eo.h>
|
|
|
|
|
2004-09-05 01:00:10 -07:00
|
|
|
#include "Ecore.h"
|
2009-12-22 13:15:12 -08:00
|
|
|
#include "ecore_private.h"
|
2004-09-05 01:00:10 -07:00
|
|
|
|
2012-10-10 01:19:58 -07:00
|
|
|
#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
|
2011-12-11 00:29:35 -08:00
|
|
|
{
|
|
|
|
EINA_INLIST;
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator *obj;
|
2011-12-11 00:29:35 -08:00
|
|
|
|
|
|
|
Ecore_Task_Cb func;
|
|
|
|
void *data;
|
|
|
|
|
|
|
|
double start, run;
|
|
|
|
Ecore_Timeline_Cb run_func;
|
|
|
|
void *run_data;
|
|
|
|
|
|
|
|
Eina_Bool delete_me : 1;
|
|
|
|
Eina_Bool suspended : 1;
|
2011-12-11 23:41:27 -08:00
|
|
|
Eina_Bool just_added : 1;
|
2011-12-11 00:29:35 -08:00
|
|
|
};
|
|
|
|
|
2012-10-10 01:19:58 -07:00
|
|
|
typedef struct _Ecore_Animator_Private_Data Ecore_Animator_Private_Data;
|
2011-12-11 00:29:35 -08:00
|
|
|
|
2011-04-19 23:51:39 -07:00
|
|
|
static Eina_Bool _ecore_animator_run(void *data);
|
2010-06-24 09:15:56 -07:00
|
|
|
static Eina_Bool _ecore_animator(void *data);
|
2004-09-05 01:00:10 -07:00
|
|
|
|
2011-10-20 22:40:39 -07:00
|
|
|
static int animators_delete_me = 0;
|
2012-10-10 01:19:58 -07:00
|
|
|
static Ecore_Animator_Private_Data *animators = NULL;
|
2011-10-20 22:40:39 -07:00
|
|
|
static double animators_frametime = 1.0 / 30.0;
|
2011-05-12 02:11:36 -07:00
|
|
|
|
2011-10-20 22:40:39 -07:00
|
|
|
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;
|
2011-05-12 02:11:36 -07:00
|
|
|
|
|
|
|
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);
|
2011-07-28 05:01:16 -07:00
|
|
|
|
|
|
|
timer = _ecore_timer_loop_add(animators_frametime,
|
2011-10-20 22:40:39 -07:00
|
|
|
_ecore_animator, NULL);
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_timer_delay(timer, d);
|
2011-05-12 02:11:36 -07:00
|
|
|
}
|
|
|
|
break;
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2011-05-12 02:11:36 -07:00
|
|
|
case ECORE_ANIMATOR_SOURCE_CUSTOM:
|
|
|
|
if (begin_tick_cb) begin_tick_cb((void *)begin_tick_data);
|
|
|
|
break;
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2011-05-12 02:11:36 -07:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_end_tick(void)
|
|
|
|
{
|
|
|
|
if (!ticking) return;
|
|
|
|
ticking = 0;
|
|
|
|
switch (src)
|
|
|
|
{
|
|
|
|
case ECORE_ANIMATOR_SOURCE_TIMER:
|
|
|
|
if (timer)
|
|
|
|
{
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_timer_del(timer);
|
2011-05-12 02:11:36 -07:00
|
|
|
timer = NULL;
|
|
|
|
}
|
|
|
|
break;
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2011-05-12 02:11:36 -07:00
|
|
|
case ECORE_ANIMATOR_SOURCE_CUSTOM:
|
|
|
|
if (end_tick_cb) end_tick_cb((void *)end_tick_data);
|
|
|
|
break;
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2011-05-12 02:11:36 -07:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_do_tick(void)
|
|
|
|
{
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator_Private_Data *animator;
|
2011-05-12 02:11:36 -07:00
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(animators, animator)
|
|
|
|
{
|
2011-12-11 23:41:27 -08:00
|
|
|
animator->just_added = EINA_FALSE;
|
|
|
|
}
|
|
|
|
EINA_INLIST_FOREACH(animators, animator)
|
|
|
|
{
|
|
|
|
if ((!animator->delete_me) &&
|
|
|
|
(!animator->suspended) &&
|
|
|
|
(!animator->just_added))
|
2011-05-12 02:11:36 -07:00
|
|
|
{
|
2011-08-11 03:59:48 -07:00
|
|
|
if (!_ecore_call_task_cb(animator->func, animator->data))
|
2011-05-12 02:11:36 -07:00
|
|
|
{
|
|
|
|
animator->delete_me = EINA_TRUE;
|
|
|
|
animators_delete_me++;
|
|
|
|
}
|
|
|
|
}
|
2011-12-11 23:41:27 -08:00
|
|
|
else animator->just_added = EINA_FALSE;
|
2011-05-12 02:11:36 -07:00
|
|
|
}
|
|
|
|
if (animators_delete_me)
|
|
|
|
{
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator_Private_Data *l;
|
2011-10-20 22:40:39 -07:00
|
|
|
for (l = animators; l; )
|
2011-05-12 02:11:36 -07:00
|
|
|
{
|
|
|
|
animator = l;
|
2012-10-10 01:19:58 -07:00
|
|
|
l = (Ecore_Animator_Private_Data *)EINA_INLIST_GET(l)->next;
|
2011-05-12 02:11:36 -07:00
|
|
|
if (animator->delete_me)
|
|
|
|
{
|
2012-10-10 01:19:58 -07:00
|
|
|
animators = (Ecore_Animator_Private_Data *)
|
2011-10-20 22:40:39 -07:00
|
|
|
eina_inlist_remove(EINA_INLIST_GET(animators),
|
|
|
|
EINA_INLIST_GET(animator));
|
2012-10-10 01:19:58 -07:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2011-05-12 02:11:36 -07:00
|
|
|
animators_delete_me--;
|
|
|
|
if (animators_delete_me == 0) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!animators)
|
|
|
|
{
|
|
|
|
_end_tick();
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
2004-09-05 01:00:10 -07:00
|
|
|
|
2012-10-10 01:19:58 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_ecore_animator_add(Ecore_Animator *obj,
|
|
|
|
Ecore_Animator_Private_Data *animator,
|
|
|
|
Ecore_Task_Cb func,
|
2011-10-20 22:40:39 -07:00
|
|
|
const void *data)
|
2004-09-05 01:00:10 -07:00
|
|
|
{
|
2012-10-10 01:19:58 -07:00
|
|
|
if (EINA_UNLIKELY(!eina_main_loop_is()))
|
|
|
|
{
|
|
|
|
eo_error_set(obj);
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
animator->obj = obj;
|
2013-03-18 08:33:54 -07:00
|
|
|
eo_do_super(obj, MY_CLASS, eo_constructor());
|
2012-10-10 01:19:58 -07:00
|
|
|
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;
|
|
|
|
}
|
2008-11-29 03:23:17 -08:00
|
|
|
|
2004-09-05 01:00:10 -07:00
|
|
|
animator->func = func;
|
|
|
|
animator->data = (void *)data;
|
2011-12-11 23:41:27 -08:00
|
|
|
animator->just_added = EINA_TRUE;
|
2012-10-10 01:19:58 -07:00
|
|
|
animators = (Ecore_Animator_Private_Data *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
|
2011-05-12 02:11:36 -07:00
|
|
|
_begin_tick();
|
2012-10-10 01:19:58 -07:00
|
|
|
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);
|
2011-08-11 22:21:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Ecore_Animator *
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_animator_add(Ecore_Task_Cb func,
|
|
|
|
const void *data)
|
2011-08-11 22:21:58 -07:00
|
|
|
{
|
2012-10-10 01:19:58 -07:00
|
|
|
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 *);
|
2011-08-11 22:21:58 -07:00
|
|
|
|
|
|
|
_ecore_lock();
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator_Private_Data *animator = _pd;
|
|
|
|
_ecore_animator_add(obj, animator, func, data);
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_unlock();
|
2004-09-05 01:00:10 -07:00
|
|
|
}
|
|
|
|
|
2011-04-19 23:51:39 -07:00
|
|
|
EAPI Ecore_Animator *
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_animator_timeline_add(double runtime,
|
|
|
|
Ecore_Timeline_Cb func,
|
|
|
|
const void *data)
|
2011-04-19 23:51:39 -07:00
|
|
|
{
|
|
|
|
Ecore_Animator *animator;
|
2012-10-10 01:19:58 -07:00
|
|
|
animator = eo_add_custom(MY_CLASS, _ecore_parent,
|
|
|
|
ecore_animator_timeline_constructor(runtime, func, data));
|
|
|
|
eo_unref(animator);
|
|
|
|
return animator;
|
|
|
|
}
|
2011-04-19 23:51:39 -07:00
|
|
|
|
2012-10-10 01:19:58 -07:00
|
|
|
static void
|
|
|
|
_animator_timeline_constructor(Eo *obj, void *_pd, va_list *list)
|
|
|
|
{
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2012-10-10 01:19:58 -07:00
|
|
|
double runtime = va_arg(*list, double);
|
2011-04-19 23:51:39 -07:00
|
|
|
if (runtime <= 0.0) runtime = 0.0;
|
2012-10-10 01:19:58 -07:00
|
|
|
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;
|
2011-04-19 23:51:39 -07:00
|
|
|
animator->run_func = func;
|
|
|
|
animator->run_data = (void *)data;
|
|
|
|
animator->start = ecore_loop_time_get();
|
|
|
|
animator->run = runtime;
|
2012-10-10 01:19:58 -07:00
|
|
|
|
|
|
|
unlock:
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_unlock();
|
2011-04-19 23:51:39 -07:00
|
|
|
}
|
|
|
|
|
2011-05-16 03:51:02 -07:00
|
|
|
static double
|
|
|
|
_pos_map_sin(double in)
|
|
|
|
{
|
|
|
|
return eina_f32p32_double_to(eina_f32p32_sin(eina_f32p32_double_from(in)));
|
|
|
|
}
|
|
|
|
|
2012-05-10 01:41:50 -07:00
|
|
|
#if 0
|
2011-05-16 03:51:02 -07:00
|
|
|
static double
|
|
|
|
_pos_map_cos(double in)
|
|
|
|
{
|
|
|
|
return eina_f32p32_double_to(eina_f32p32_cos(eina_f32p32_double_from(in)));
|
|
|
|
}
|
2012-05-10 01:41:50 -07:00
|
|
|
#endif
|
2011-05-16 03:51:02 -07:00
|
|
|
|
2011-04-19 23:51:39 -07:00
|
|
|
static double
|
2011-10-20 22:40:39 -07:00
|
|
|
_pos_map_accel_factor(double pos,
|
|
|
|
double v1)
|
2011-04-19 23:51:39 -07:00
|
|
|
{
|
|
|
|
int i, fact = (int)v1;
|
2012-06-15 07:11:38 -07:00
|
|
|
double p, o1 = pos, o2, v;
|
2011-05-16 03:51:02 -07:00
|
|
|
p = 1.0 - _pos_map_sin((M_PI / 2.0) + ((pos * M_PI) / 2.0));
|
2011-04-19 23:51:39 -07:00
|
|
|
o2 = p;
|
|
|
|
for (i = 0; i < fact; i++)
|
|
|
|
{
|
|
|
|
o1 = o2;
|
|
|
|
o2 = o2 * p;
|
|
|
|
}
|
|
|
|
v = v1 - (double)fact;
|
|
|
|
pos = (v * o2) + ((1.0 - v) * o1);
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
static double
|
2011-10-20 22:40:39 -07:00
|
|
|
_pos_map_pow(double pos,
|
|
|
|
double divis,
|
|
|
|
int p)
|
2011-04-19 23:51:39 -07:00
|
|
|
{
|
|
|
|
double v = 1.0;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < p; i++) v *= pos;
|
|
|
|
return ((pos * divis) * (1.0 - v)) + (pos * v);
|
|
|
|
}
|
|
|
|
|
|
|
|
static double
|
2011-10-20 22:40:39 -07:00
|
|
|
_pos_map_spring(double pos,
|
|
|
|
int bounces,
|
|
|
|
double decfac)
|
2011-04-19 23:51:39 -07:00
|
|
|
{
|
|
|
|
int segnum, segpos, b1, b2;
|
|
|
|
double len, decay, decpos, p2;
|
|
|
|
if (bounces < 0) bounces = 0;
|
|
|
|
p2 = _pos_map_pow(pos, 0.5, 3);
|
|
|
|
len = (M_PI / 2.0) + ((double)bounces * M_PI);
|
|
|
|
segnum = (bounces * 2) + 1;
|
|
|
|
segpos = 2 * (((int)(p2 * segnum) + 1) / 2);
|
|
|
|
b1 = segpos;
|
|
|
|
b2 = segnum + 1;
|
|
|
|
if (b1 < 0) b1 = 0;
|
|
|
|
decpos = (double)b1 / (double)b2;
|
|
|
|
decay = _pos_map_accel_factor(1.0 - decpos, decfac);
|
2011-05-16 03:51:02 -07:00
|
|
|
return _pos_map_sin((M_PI / 2.0) + (p2 * len)) * decay;
|
2011-04-19 23:51:39 -07:00
|
|
|
}
|
|
|
|
|
2012-05-10 01:41:50 -07:00
|
|
|
#define DBL_TO(Fp) eina_f32p32_double_to(Fp)
|
|
|
|
#define DBL_FROM(D) eina_f32p32_double_from(D)
|
|
|
|
#define INT_FROM(I) eina_f32p32_int_from(I)
|
|
|
|
#define SIN(Fp) eina_f32p32_sin(Fp)
|
|
|
|
#define COS(Fp) eina_f32p32_cos(Fp)
|
|
|
|
#define ADD(A, B) eina_f32p32_add(A, B)
|
|
|
|
#define SUB(A, B) eina_f32p32_sub(A, B)
|
|
|
|
#define MUL(A, B) eina_f32p32_mul(A, B)
|
|
|
|
|
2011-04-19 23:51:39 -07:00
|
|
|
EAPI double
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_animator_pos_map(double pos,
|
|
|
|
Ecore_Pos_Map map,
|
|
|
|
double v1,
|
|
|
|
double v2)
|
2011-04-19 23:51:39 -07:00
|
|
|
{
|
2011-07-28 05:01:16 -07:00
|
|
|
/* purely functional - locking not required */
|
2013-05-16 10:09:14 -07:00
|
|
|
if (pos >= 1.0) return 1.0;
|
|
|
|
else if (pos <= 0.0)
|
|
|
|
return 0.0;
|
2011-10-20 22:40:39 -07:00
|
|
|
switch (map)
|
|
|
|
{
|
|
|
|
case ECORE_POS_MAP_LINEAR:
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_ACCELERATE:
|
2012-05-10 01:41:50 -07:00
|
|
|
/* pos = 1 - sin(Pi / 2 + pos * Pi / 2); */
|
|
|
|
pos = DBL_TO(SUB(INT_FROM(1), SIN(ADD((EINA_F32P32_PI >> 1), MUL(DBL_FROM(pos), (EINA_F32P32_PI >> 1))))));
|
2011-10-20 22:40:39 -07:00
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_DECELERATE:
|
2012-05-10 01:41:50 -07:00
|
|
|
/* pos = sin(pos * Pi / 2); */
|
|
|
|
pos = DBL_TO(SIN(MUL(DBL_FROM(pos), (EINA_F32P32_PI >> 1))));
|
2011-10-20 22:40:39 -07:00
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_SINUSOIDAL:
|
2012-05-10 01:41:50 -07:00
|
|
|
/* pos = (1 - cos(pos * Pi)) / 2 */
|
|
|
|
pos = DBL_TO((SUB(INT_FROM(1), COS(MUL(DBL_FROM(pos), EINA_F32P32_PI)))) >> 1);
|
2011-10-20 22:40:39 -07:00
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_ACCELERATE_FACTOR:
|
|
|
|
pos = _pos_map_accel_factor(pos, v1);
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_DECELERATE_FACTOR:
|
|
|
|
pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v1);
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_SINUSOIDAL_FACTOR:
|
|
|
|
if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v1) / 2.0;
|
|
|
|
else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v1) / 2.0);
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_DIVISOR_INTERP:
|
|
|
|
pos = _pos_map_pow(pos, v1, (int)v2);
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_BOUNCE:
|
|
|
|
pos = _pos_map_spring(pos, (int)v2, v1);
|
|
|
|
if (pos < 0.0) pos = -pos;
|
|
|
|
pos = 1.0 - pos;
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
case ECORE_POS_MAP_SPRING:
|
|
|
|
pos = 1.0 - _pos_map_spring(pos, (int)v2, v1);
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return pos;
|
|
|
|
}
|
2013-05-16 10:09:14 -07:00
|
|
|
|
2011-10-20 22:40:39 -07:00
|
|
|
return pos;
|
2011-04-19 23:51:39 -07:00
|
|
|
}
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void *
|
2012-10-10 01:19:58 -07:00
|
|
|
ecore_animator_del(Ecore_Animator *obj)
|
2004-09-05 01:00:10 -07:00
|
|
|
{
|
2011-07-28 05:01:16 -07:00
|
|
|
void *data = NULL;
|
2011-07-05 04:13:29 -07:00
|
|
|
|
2012-12-24 01:35:56 -08:00
|
|
|
if (!obj) return NULL;
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
2013-05-02 00:47:16 -07:00
|
|
|
Ecore_Animator_Private_Data *animator = eo_data_scope_get(obj, MY_CLASS);
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2012-10-10 01:19:58 -07:00
|
|
|
|
2012-12-03 02:22:19 -08:00
|
|
|
if (!animator) goto unlock;
|
2011-07-28 05:01:16 -07:00
|
|
|
if (animator->delete_me)
|
|
|
|
{
|
|
|
|
data = animator->data;
|
|
|
|
goto unlock;
|
2004-09-05 01:00:10 -07:00
|
|
|
}
|
2010-05-03 09:21:39 -07:00
|
|
|
animator->delete_me = EINA_TRUE;
|
2004-09-05 01:00:10 -07:00
|
|
|
animators_delete_me++;
|
2011-07-28 05:01:16 -07:00
|
|
|
if (animator->run_func)
|
|
|
|
data = animator->run_data;
|
|
|
|
else
|
|
|
|
data = animator->data;
|
|
|
|
unlock:
|
|
|
|
_ecore_unlock();
|
|
|
|
return data;
|
2004-09-05 01:00:10 -07:00
|
|
|
}
|
|
|
|
|
2012-10-10 01:19:58 -07:00
|
|
|
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++;
|
|
|
|
|
2013-03-18 08:33:54 -07:00
|
|
|
eo_do_super(obj, MY_CLASS, eo_destructor());
|
2012-10-10 01:19:58 -07:00
|
|
|
}
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void
|
2004-09-05 01:00:10 -07:00
|
|
|
ecore_animator_frametime_set(double frametime)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2004-09-05 01:00:10 -07:00
|
|
|
if (frametime < 0.0) frametime = 0.0;
|
2011-07-28 05:01:16 -07:00
|
|
|
if (animators_frametime == frametime) goto unlock;
|
2004-09-05 01:00:10 -07:00
|
|
|
animators_frametime = frametime;
|
2011-05-12 02:11:36 -07:00
|
|
|
_end_tick();
|
|
|
|
if (animators) _begin_tick();
|
2011-07-28 05:01:16 -07:00
|
|
|
unlock:
|
|
|
|
_ecore_unlock();
|
2004-09-05 01:00:10 -07:00
|
|
|
}
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI double
|
2004-09-05 01:00:10 -07:00
|
|
|
ecore_animator_frametime_get(void)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0);
|
2004-09-05 01:00:10 -07:00
|
|
|
return animators_frametime;
|
|
|
|
}
|
|
|
|
|
2010-05-03 09:21:39 -07:00
|
|
|
EAPI void
|
|
|
|
ecore_animator_freeze(Ecore_Animator *animator)
|
2012-10-10 01:19:58 -07:00
|
|
|
{
|
|
|
|
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)
|
2010-05-03 09:21:39 -07:00
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator_Private_Data *animator = _pd;
|
|
|
|
|
2011-07-28 05:01:16 -07:00
|
|
|
if (animator->delete_me) goto unlock;
|
2010-05-03 09:21:39 -07:00
|
|
|
animator->suspended = EINA_TRUE;
|
2011-07-28 05:01:16 -07:00
|
|
|
unlock:
|
|
|
|
_ecore_unlock();
|
2010-05-03 09:21:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
ecore_animator_thaw(Ecore_Animator *animator)
|
2012-10-10 01:19:58 -07:00
|
|
|
{
|
|
|
|
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)
|
2010-05-03 09:21:39 -07:00
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator_Private_Data *animator = _pd;
|
|
|
|
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
|
|
|
if (animator->delete_me) goto unlock;
|
2010-05-03 09:21:39 -07:00
|
|
|
animator->suspended = EINA_FALSE;
|
2011-07-28 05:01:16 -07:00
|
|
|
unlock:
|
|
|
|
_ecore_unlock();
|
2010-05-03 09:21:39 -07:00
|
|
|
}
|
|
|
|
|
2011-05-12 02:11:36 -07:00
|
|
|
EAPI void
|
|
|
|
ecore_animator_source_set(Ecore_Animator_Source source)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2011-05-12 02:11:36 -07:00
|
|
|
src = source;
|
|
|
|
_end_tick();
|
|
|
|
if (animators) _begin_tick();
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_unlock();
|
2011-05-12 02:11:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Ecore_Animator_Source
|
|
|
|
ecore_animator_source_get(void)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
|
2011-05-12 02:11:36 -07:00
|
|
|
return src;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func,
|
|
|
|
const void *data)
|
2011-05-12 02:11:36 -07:00
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2011-05-12 02:11:36 -07:00
|
|
|
begin_tick_cb = func;
|
|
|
|
begin_tick_data = data;
|
|
|
|
_end_tick();
|
|
|
|
if (animators) _begin_tick();
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_unlock();
|
2011-05-12 02:11:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func,
|
|
|
|
const void *data)
|
2011-05-12 02:11:36 -07:00
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2011-05-12 02:11:36 -07:00
|
|
|
end_tick_cb = func;
|
|
|
|
end_tick_data = data;
|
|
|
|
_end_tick();
|
|
|
|
if (animators) _begin_tick();
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_unlock();
|
2011-05-12 02:11:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
ecore_animator_custom_tick(void)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_lock();
|
2011-05-12 02:11:36 -07:00
|
|
|
if (src == ECORE_ANIMATOR_SOURCE_CUSTOM) _do_tick();
|
2011-07-28 05:01:16 -07:00
|
|
|
_ecore_unlock();
|
2011-05-12 02:11:36 -07:00
|
|
|
}
|
|
|
|
|
2004-09-05 01:00:10 -07:00
|
|
|
void
|
|
|
|
_ecore_animator_shutdown(void)
|
|
|
|
{
|
2011-05-12 02:11:36 -07:00
|
|
|
_end_tick();
|
2004-09-05 01:00:10 -07:00
|
|
|
while (animators)
|
|
|
|
{
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator_Private_Data *animator;
|
2008-11-29 03:23:17 -08:00
|
|
|
|
2010-09-29 23:09:20 -07:00
|
|
|
animator = animators;
|
2012-10-10 01:19:58 -07:00
|
|
|
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);
|
2004-09-05 01:00:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-19 23:51:39 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_ecore_animator_run(void *data)
|
|
|
|
{
|
2012-10-10 01:19:58 -07:00
|
|
|
Ecore_Animator *obj = data;
|
2013-05-02 00:47:16 -07:00
|
|
|
Ecore_Animator_Private_Data *animator = eo_data_scope_get(obj, MY_CLASS);
|
2012-10-10 01:19:58 -07:00
|
|
|
|
2011-04-19 23:51:39 -07:00
|
|
|
double pos = 0.0, t;
|
|
|
|
Eina_Bool run_ret;
|
|
|
|
|
|
|
|
t = ecore_loop_time_get();
|
|
|
|
if (animator->run > 0.0)
|
|
|
|
{
|
|
|
|
pos = (t - animator->start) / animator->run;
|
|
|
|
if (pos > 1.0) pos = 1.0;
|
2011-10-20 22:40:39 -07:00
|
|
|
else if (pos < 0.0)
|
|
|
|
pos = 0.0;
|
2011-04-19 23:51:39 -07:00
|
|
|
}
|
|
|
|
run_ret = animator->run_func(animator->run_data, pos);
|
|
|
|
if (t >= (animator->start + animator->run)) run_ret = EINA_FALSE;
|
|
|
|
return run_ret;
|
|
|
|
}
|
|
|
|
|
2010-06-24 09:15:56 -07:00
|
|
|
static Eina_Bool
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_animator(void *data EINA_UNUSED)
|
2004-09-05 01:00:10 -07:00
|
|
|
{
|
2011-07-28 05:01:16 -07:00
|
|
|
Eina_Bool r;
|
|
|
|
_ecore_lock();
|
|
|
|
r = _do_tick();
|
|
|
|
_ecore_unlock();
|
|
|
|
return r;
|
2004-09-05 01:00:10 -07:00
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2012-10-10 01:19:58 -07:00
|
|
|
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)
|