forked from enlightenment/efl
animator - use select not uslleep so we can wake up during a sleep
if you change animator frametime while we are sleeping for a frame... we can't wake up and adjust. this allows that with a pipe and select.
This commit is contained in:
parent
c2b1e670b4
commit
24f9e6a458
|
@ -5,6 +5,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <Eo.h>
|
#include <Eo.h>
|
||||||
|
|
||||||
|
@ -54,26 +59,16 @@ static Ecore_Cb end_tick_cb = NULL;
|
||||||
static const void *end_tick_data = NULL;
|
static const void *end_tick_data = NULL;
|
||||||
static Eina_Bool animator_ran = EINA_FALSE;
|
static Eina_Bool animator_ran = EINA_FALSE;
|
||||||
|
|
||||||
|
static int timer_fd_read = -1;
|
||||||
static Eina_Thread_Queue *timer_thq = NULL;
|
static int timer_fd_write = -1;
|
||||||
static Ecore_Thread *timer_thread = NULL;
|
static Ecore_Thread *timer_thread = NULL;
|
||||||
static volatile int timer_event_is_busy = 0;
|
static volatile int timer_event_is_busy = 0;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
Eina_Thread_Queue_Msg head;
|
|
||||||
char val;
|
|
||||||
} Msg;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_tick_send(char val)
|
_tick_send(char val)
|
||||||
{
|
{
|
||||||
Msg *msg;
|
|
||||||
void *ref;
|
|
||||||
DBG("_tick_send(%i)", val);
|
DBG("_tick_send(%i)", val);
|
||||||
msg = eina_thread_queue_send(timer_thq, sizeof(Msg), &ref);
|
write(timer_fd_write, &val, 1);
|
||||||
msg->val = val;
|
|
||||||
eina_thread_queue_send_done(timer_thq, ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -91,51 +86,52 @@ _timer_send_time(double t)
|
||||||
static void
|
static void
|
||||||
_timer_tick_core(void *data EINA_UNUSED, Ecore_Thread *thread)
|
_timer_tick_core(void *data EINA_UNUSED, Ecore_Thread *thread)
|
||||||
{
|
{
|
||||||
Msg *msg;
|
fd_set rfds, wfds, exfds;
|
||||||
void *ref;
|
struct timeval tv;
|
||||||
int tick = 0;
|
unsigned int t;
|
||||||
|
char tick = 0;
|
||||||
|
double t0, d;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (!ecore_thread_check(thread))
|
while (!ecore_thread_check(thread))
|
||||||
{
|
{
|
||||||
DBG("------- timer_event_is_busy=%i", timer_event_is_busy);
|
DBG("------- timer_event_is_busy=%i", timer_event_is_busy);
|
||||||
if (!timer_event_is_busy)
|
FD_ZERO(&rfds);
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_ZERO(&exfds);
|
||||||
|
FD_SET(timer_fd_read, &rfds);
|
||||||
|
|
||||||
|
t0 = ecore_time_get();
|
||||||
|
d = fmod(t0, animators_frametime);
|
||||||
|
if (tick)
|
||||||
{
|
{
|
||||||
DBG("wait...");
|
DBG("sleep...");
|
||||||
msg = eina_thread_queue_wait(timer_thq, &ref);
|
t = (animators_frametime - d) * 1000000.0;
|
||||||
if (msg)
|
tv.tv_sec = t / 1000000;
|
||||||
{
|
tv.tv_usec = t % 1000000;
|
||||||
tick = msg->val;
|
ret = select(timer_fd_read + 1, &rfds, &wfds, &exfds, &tv);
|
||||||
eina_thread_queue_wait_done(timer_thq, ref);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG("poll...");
|
DBG("wait...");
|
||||||
msg = eina_thread_queue_poll(timer_thq, &ref);
|
ret = select(timer_fd_read + 1, &rfds, &wfds, &exfds, NULL);
|
||||||
if (msg)
|
|
||||||
{
|
|
||||||
tick = msg->val;
|
|
||||||
eina_thread_queue_wait_done(timer_thq, ref);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DBG("tick = %i", tick);
|
if ((ret == 1) && (FD_ISSET(timer_fd_read, &rfds)))
|
||||||
if (tick == -1)
|
|
||||||
{
|
{
|
||||||
goto done;
|
read(timer_fd_read, &tick, sizeof(tick));
|
||||||
|
DBG("tick = %i", tick);
|
||||||
|
if (tick == -1) goto done;
|
||||||
}
|
}
|
||||||
else if (tick)
|
else
|
||||||
{
|
{
|
||||||
double t0 = ecore_time_get();
|
if (tick) _timer_send_time(t0 - d + animators_frametime);
|
||||||
double d = fmod(t0, animators_frametime);
|
|
||||||
|
|
||||||
usleep((animators_frametime - d) * 1000000);
|
|
||||||
_timer_send_time(t0 - d + animators_frametime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
if (timer_thq) eina_thread_queue_free(timer_thq);
|
close(timer_fd_read);
|
||||||
timer_thq = NULL;
|
timer_fd_read = -1;
|
||||||
timer_thread = NULL;
|
close(timer_fd_write);
|
||||||
|
timer_fd_write = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -159,16 +155,28 @@ static void
|
||||||
_timer_tick_finished(void *data EINA_UNUSED, Ecore_Thread *thread EINA_UNUSED)
|
_timer_tick_finished(void *data EINA_UNUSED, Ecore_Thread *thread EINA_UNUSED)
|
||||||
{
|
{
|
||||||
timer_thread = NULL;
|
timer_thread = NULL;
|
||||||
if (timer_thq) eina_thread_queue_free(timer_thq);
|
if (timer_fd_read >= 0)
|
||||||
timer_thq = NULL;
|
{
|
||||||
|
close(timer_fd_read);
|
||||||
|
timer_fd_read = -1;
|
||||||
|
}
|
||||||
|
if (timer_fd_write >= 0)
|
||||||
|
{
|
||||||
|
close(timer_fd_write);
|
||||||
|
timer_fd_write = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_timer_tick_begin(void)
|
_timer_tick_begin(void)
|
||||||
{
|
{
|
||||||
if (!timer_thq)
|
if (timer_fd_read < 0)
|
||||||
{
|
{
|
||||||
timer_thq = eina_thread_queue_new();
|
int fds[2];
|
||||||
|
|
||||||
|
if (pipe(fds) != 0) return;
|
||||||
|
timer_fd_read = fds[0];
|
||||||
|
timer_fd_write = fds[1];
|
||||||
timer_thread = ecore_thread_feedback_run(_timer_tick_core,
|
timer_thread = ecore_thread_feedback_run(_timer_tick_core,
|
||||||
_timer_tick_notify,
|
_timer_tick_notify,
|
||||||
_timer_tick_finished,
|
_timer_tick_finished,
|
||||||
|
@ -182,7 +190,7 @@ _timer_tick_begin(void)
|
||||||
static void
|
static void
|
||||||
_timer_tick_end(void)
|
_timer_tick_end(void)
|
||||||
{
|
{
|
||||||
if (!timer_thq) return;
|
if (timer_fd_read < 0) return;
|
||||||
timer_event_is_busy = 0;
|
timer_event_is_busy = 0;
|
||||||
_tick_send(0);
|
_tick_send(0);
|
||||||
}
|
}
|
||||||
|
@ -192,7 +200,7 @@ _timer_tick_quit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!timer_thq) return;
|
if (timer_fd_read < 0) return;
|
||||||
_tick_send(-1);
|
_tick_send(-1);
|
||||||
for (i = 0; (i < 500) && (timer_thread); i++)
|
for (i = 0; (i < 500) && (timer_thread); i++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue