7c248135ae896624c429c1cf2b97d0a3b8d3bf92
[framework/uifw/ecore.git] / src / lib / ecore / ecore_anim.c
1 #include "ecore_private.h"
2 #include "Ecore.h"
3
4 static int _ecore_animator(void *data);
5
6 static Ecore_Timer    *timer = NULL;
7 static int             animators_delete_me = 0;
8 static Ecore_Animator *animators = NULL;
9 static double          animators_frametime = 1.0 / 30.0;
10
11 /**
12  * Add a animator to tick off at every animaton tick during main loop execution.
13  * @param func The function to call when it ticks off
14  * @param data The data to pass to the function
15  * @return A handle to the new animator
16  * @ingroup Ecore_Animator_Group
17  * 
18  * This function adds a animator and returns its handle on success and NULL on
19  * failure. The function @p func will be called every N seconds where N is the
20  * frametime interval set by ecore_animator_frametime_set(). The function will
21  * be passed the @p data pointer as its parameter.
22  * 
23  * When the animator @p func is called, it must return a value of either 1 or 0. 
24  * If it returns 1 (or ECORE_CALLBACK_RENEW), it will be called again at the 
25  * next tick, or if it returns 0 (or ECORE_CALLBACK_CANCEL) it will be deleted 
26  * automatically making any references/handles for it invalid.
27  */
28 EAPI Ecore_Animator *
29 ecore_animator_add(int (*func) (void *data), const void *data)
30 {
31    Ecore_Animator *animator;
32    
33    if (!func) return NULL;
34    animator = calloc(1, sizeof(Ecore_Animator));
35    if (!animator) return NULL;
36    ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR);
37    animator->func = func;
38    animator->data = (void *)data;
39    animators = _ecore_list2_append(animators, animator);
40    if (!timer)
41      timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL);
42    return animator;
43 }
44
45 /**
46  * Delete the specified animator from the animator list.
47  * @param animator The animator to delete
48  * @return The data pointer set for the animator
49  * @ingroup Ecore_Animator_Group
50  * 
51  * Delete the specified @p aqnimator from the set of animators that are executed
52  * during main loop execution. This function returns the data parameter that
53  * was being passed to the callback on success, or NULL on failure. After this
54  * call returns the specified animator object @p animator is invalid and should not
55  * be used again. It will not get called again after deletion.
56  */
57 EAPI void *
58 ecore_animator_del(Ecore_Animator *animator)
59 {
60    if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
61      {
62         ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
63                          "ecore_animator_del");
64         return NULL;
65      }
66    if (animator->delete_me) return animator->data;
67    animator->delete_me = 1;
68    animators_delete_me++;
69    return animator->data;
70 }
71
72 /**
73  * Set the animator call interval in seconds.
74  * @param frametime The time in seconds in between animator ticks.
75  * 
76  * This function sets the time interval (in seconds) inbetween animator ticks.
77  */
78 EAPI void
79 ecore_animator_frametime_set(double frametime)
80 {
81    if (frametime < 0.0) frametime = 0.0;
82    if (animators_frametime == frametime) return;
83    animators_frametime = frametime;
84    if (timer)
85      {
86         ecore_timer_del(timer);
87         timer = NULL;
88      }
89    if (animators)
90      timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL);
91 }
92
93 /**
94  * Get the animator call interval in seconds.
95  * @return The time in second in between animator ticks.
96  * 
97  * this function retrieves the time inbetween animator ticks, in seconds.
98  */
99 EAPI double
100 ecore_animator_frametime_get(void)
101 {
102    return animators_frametime;
103 }
104
105 void
106 _ecore_animator_shutdown(void)
107 {
108    if (timer)
109      {
110         ecore_timer_del(timer);
111         timer = NULL;
112      } 
113    while (animators)
114      {
115         Ecore_Animator *animator;
116         
117         animator = animators;
118         animators = _ecore_list2_remove(animators, animator);
119         ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
120         free(animator);
121      }
122 }
123
124 static int
125 _ecore_animator(void *data __UNUSED__)
126 {
127    Ecore_List2 *l;
128
129    for (l = (Ecore_List2 *)animators; l;)
130      {
131         Ecore_Animator *animator;
132         
133         animator = (Ecore_Animator *)l;
134         l = l->next;
135         if (!animator->delete_me)
136           {
137              if (!animator->func(animator->data))
138                {
139                   animator->delete_me = 1;
140                   animators_delete_me++;
141                }
142           }
143      }
144    if (animators_delete_me)
145      {
146         for (l = (Ecore_List2 *)animators; l;)
147           {
148              Ecore_Animator *animator;
149              
150              animator = (Ecore_Animator *)l;
151              l = l->next;
152              if (animator->delete_me)
153                {
154                   animators = _ecore_list2_remove(animators, animator);
155                   ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
156                   free(animator);
157                   animators_delete_me--;
158                   if (animators_delete_me == 0) break;
159                }
160           }
161      }
162    if (!animators)
163      {
164         timer = NULL;
165         return 0;
166      }
167    return 1;
168 }