[tests] Manually advance the timelines

The units in the Timeline test suite just rely on the timeline
being a timeout automatically advanced by the main loop. This
is not the case anymore, since the merge of the master-clock.

To make the test units work again we need to "emulate" the master
clock without effectively having a stage to redraw; we do this
by creating a frame source and manually advancing the timelines
we create for test purposes, using the advance_msecs() "protected"
method.
This commit is contained in:
Emmanuele Bassi 2009-05-01 15:08:42 +01:00
parent 5be29cf9bc
commit cf28c023a0
5 changed files with 214 additions and 24 deletions

View File

@ -10,14 +10,17 @@
#define TEST_TIMELINE_FPS 10
#define TEST_TIMELINE_FRAME_COUNT 20
typedef struct _TestState {
typedef struct _TestState
{
ClutterTimeline *timeline;
gint prev_frame;
gint completion_count;
gint passed;
guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
static void
new_frame_cb (ClutterTimeline *timeline,
gint frame_num,
@ -68,6 +71,30 @@ completed_cb (ClutterTimeline *timeline,
}
}
static gboolean
frame_tick (gpointer data)
{
TestState *state = data;
GTimeVal cur_tick = { 0, };
GSList *l;
gulong msecs;
g_get_current_time (&cur_tick);
if (state->prev_tick.tv_sec == 0)
state->prev_tick = cur_tick;
msecs = (cur_tick.tv_sec - state->prev_tick.tv_sec) * 1000
+ (cur_tick.tv_usec - state->prev_tick.tv_usec) / 1000;
if (clutter_timeline_is_playing (state->timeline))
clutter_timeline_advance_delta (state->timeline, msecs);
state->msecs_delta = msecs;
state->prev_tick = cur_tick;
return TRUE;
}
void
test_timeline_dup_frames (TestConformSimpleFixture *fixture,
@ -91,11 +118,18 @@ test_timeline_dup_frames (TestConformSimpleFixture *fixture,
state.prev_frame = -1;
state.completion_count = 0;
state.passed = TRUE;
state.prev_tick.tv_sec = 0;
state.prev_tick.tv_usec = 0;
state.msecs_delta = 0;
state.source_id =
clutter_threads_add_frame_source (60, frame_tick, &state);
clutter_timeline_start (state.timeline);
clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline);
}

View File

@ -15,13 +15,17 @@
* may not be a very reliable tolerance. */
#define TEST_ERROR_TOLERANCE 20
typedef struct _TestState {
typedef struct _TestState
{
ClutterTimeline *timeline;
GTimeVal start_time;
guint new_frame_counter;
gint expected_frame;
gint completion_count;
gboolean passed;
guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
@ -130,6 +134,30 @@ completed_cb (ClutterTimeline *timeline,
}
}
static gboolean
frame_tick (gpointer data)
{
TestState *state = data;
GTimeVal cur_tick = { 0, };
GSList *l;
gulong msecs;
g_get_current_time (&cur_tick);
if (state->prev_tick.tv_sec == 0)
state->prev_tick = cur_tick;
msecs = (cur_tick.tv_sec - state->prev_tick.tv_sec) * 1000
+ (cur_tick.tv_usec - state->prev_tick.tv_usec) / 1000;
if (clutter_timeline_is_playing (state->timeline))
clutter_timeline_advance_delta (state->timeline, msecs);
state->msecs_delta = msecs;
state->prev_tick = cur_tick;
return TRUE;
}
void
test_timeline_interpolate (TestConformSimpleFixture *fixture,
@ -154,12 +182,18 @@ test_timeline_interpolate (TestConformSimpleFixture *fixture,
state.new_frame_counter = 0;
state.passed = TRUE;
state.expected_frame = 0;
state.prev_tick.tv_sec = 0;
state.prev_tick.tv_usec = 0;
state.msecs_delta = 0;
state.source_id =
clutter_threads_add_frame_source (60, frame_tick, &state);
g_get_current_time (&state.start_time);
clutter_timeline_start (state.timeline);
clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline);
}

View File

@ -8,12 +8,15 @@
#define TEST_TIMELINE_FRAME_COUNT 5
#define TEST_WATCHDOG_KICK_IN_SECONDS 10
typedef struct _TestState {
typedef struct _TestState
{
ClutterTimeline *timeline;
gint rewind_count;
guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
static gboolean
watchdog_timeout (TestState *state)
{
@ -34,7 +37,6 @@ watchdog_timeout (TestState *state)
return FALSE;
}
static void
new_frame_cb (ClutterTimeline *timeline,
gint frame_num,
@ -68,6 +70,30 @@ new_frame_cb (ClutterTimeline *timeline,
}
}
static gboolean
frame_tick (gpointer data)
{
TestState *state = data;
GTimeVal cur_tick = { 0, };
GSList *l;
gulong msecs;
g_get_current_time (&cur_tick);
if (state->prev_tick.tv_sec == 0)
state->prev_tick = cur_tick;
msecs = (cur_tick.tv_sec - state->prev_tick.tv_sec) * 1000
+ (cur_tick.tv_usec - state->prev_tick.tv_usec) / 1000;
if (clutter_timeline_is_playing (state->timeline))
clutter_timeline_advance_delta (state->timeline, msecs);
state->msecs_delta = msecs;
state->prev_tick = cur_tick;
return TRUE;
}
void
test_timeline_rewind (TestConformSimpleFixture *fixture,
@ -88,11 +114,17 @@ test_timeline_rewind (TestConformSimpleFixture *fixture,
(GSourceFunc)watchdog_timeout,
&state);
state.rewind_count = 0;
state.prev_tick.tv_sec = 0;
state.prev_tick.tv_usec = 0;
state.msecs_delta = 0;
state.source_id =
clutter_threads_add_frame_source (60, frame_tick, &state);
clutter_timeline_start (state.timeline);
clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline);
}

View File

@ -8,16 +8,19 @@
#define TEST_TIMELINE_FRAME_COUNT 20
#define TEST_ERROR_TOLERANCE 5
typedef struct _TestState {
typedef struct _TestState
{
ClutterTimeline *timeline;
GTimeVal start_time;
GTimeVal prev_frame_time;
guint frame;
gint completion_count;
gint passed;
guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
static void
new_frame_cb (ClutterTimeline *timeline,
gint frame_num,
@ -81,6 +84,30 @@ completed_cb (ClutterTimeline *timeline,
}
}
static gboolean
frame_tick (gpointer data)
{
TestState *state = data;
GTimeVal cur_tick = { 0, };
GSList *l;
gulong msecs;
g_get_current_time (&cur_tick);
if (state->prev_tick.tv_sec == 0)
state->prev_tick = cur_tick;
msecs = (cur_tick.tv_sec - state->prev_tick.tv_sec) * 1000
+ (cur_tick.tv_usec - state->prev_tick.tv_usec) / 1000;
if (clutter_timeline_is_playing (state->timeline))
clutter_timeline_advance_delta (state->timeline, msecs);
state->msecs_delta = msecs;
state->prev_tick = cur_tick;
return TRUE;
}
void
test_timeline_smoothness (TestConformSimpleFixture *fixture,
@ -104,12 +131,18 @@ test_timeline_smoothness (TestConformSimpleFixture *fixture,
state.frame = 0;
state.completion_count = 0;
state.passed = TRUE;
state.prev_tick.tv_sec = 0;
state.prev_tick.tv_usec = 0;
state.msecs_delta = 0;
state.source_id =
clutter_threads_add_frame_source (60, frame_tick, &state);
g_get_current_time (&state.start_time);
clutter_timeline_start (state.timeline);
clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline);
}

View File

@ -156,7 +156,7 @@ check_timeline (ClutterTimeline *timeline,
}
static gboolean
timeout_cb (gpointer data)
timeout_cb (gpointer data G_GNUC_UNUSED)
{
clutter_main_quit ();
@ -172,10 +172,51 @@ delay_cb (gpointer data)
return TRUE;
}
typedef struct _FrameCounter FrameCounter;
struct _FrameCounter
{
GTimeVal prev_tick;
gulong msecs_delta;
GSList *timelines;
};
static gboolean
frame_tick (gpointer data)
{
FrameCounter *counter = data;
GTimeVal cur_tick = { 0, };
GSList *l;
gulong msecs;
g_get_current_time (&cur_tick);
if (counter->prev_tick.tv_sec == 0)
counter->prev_tick = cur_tick;
msecs = (cur_tick.tv_sec - counter->prev_tick.tv_sec) * 1000
+ (cur_tick.tv_usec - counter->prev_tick.tv_usec) / 1000;
for (l = counter->timelines; l != NULL; l = l->next)
{
ClutterTimeline *timeline = l->data;
if (clutter_timeline_is_playing (timeline))
clutter_timeline_advance_delta (timeline, msecs);
}
counter->msecs_delta = msecs;
counter->prev_tick = cur_tick;
return TRUE;
}
void
test_timeline (TestConformSimpleFixture *fixture,
gconstpointer data)
{
FrameCounter *counter;
ClutterTimeline *timeline_1;
TimelineData data_1;
ClutterTimeline *timeline_2;
@ -185,6 +226,11 @@ test_timeline (TestConformSimpleFixture *fixture,
gchar **markers;
gsize n_markers;
guint delay_tag;
guint source_id;
counter = g_new0 (FrameCounter, 1);
source_id = clutter_threads_add_frame_source (60, frame_tick, counter);
timeline_data_init (&data_1, 1);
timeline_1 = clutter_timeline_new (FRAME_COUNT, 30);
@ -198,6 +244,8 @@ test_timeline (TestConformSimpleFixture *fixture,
g_assert (n_markers == 3);
g_strfreev (markers);
counter->timelines = g_slist_prepend (counter->timelines, timeline_1);
timeline_data_init (&data_2, 2);
timeline_2 = clutter_timeline_clone (timeline_1);
clutter_timeline_add_marker_at_frame (timeline_2, "bar", 2);
@ -207,6 +255,8 @@ test_timeline (TestConformSimpleFixture *fixture,
g_assert (strcmp (markers[0], "bar") == 0);
g_strfreev (markers);
counter->timelines = g_slist_prepend (counter->timelines, timeline_2);
timeline_data_init (&data_3, 3);
timeline_3 = clutter_timeline_clone (timeline_1);
clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD);
@ -215,6 +265,8 @@ test_timeline (TestConformSimpleFixture *fixture,
clutter_timeline_add_marker_at_frame (timeline_3, "near-end-marker", 1);
clutter_timeline_add_marker_at_frame (timeline_3, "end-marker", 0);
counter->timelines = g_slist_prepend (counter->timelines, timeline_3);
g_signal_connect (timeline_1,
"marker-reached", G_CALLBACK (timeline_marker_reached_cb),
&data_1);
@ -293,4 +345,9 @@ test_timeline (TestConformSimpleFixture *fixture,
timeline_data_destroy (&data_3);
g_source_remove (delay_tag);
g_source_remove (source_id);
g_slist_free (counter->timelines);
g_free (counter);
}