[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,13 +10,16 @@
#define TEST_TIMELINE_FPS 10 #define TEST_TIMELINE_FPS 10
#define TEST_TIMELINE_FRAME_COUNT 20 #define TEST_TIMELINE_FRAME_COUNT 20
typedef struct _TestState { typedef struct _TestState
{
ClutterTimeline *timeline; ClutterTimeline *timeline;
gint prev_frame; gint prev_frame;
gint completion_count; gint completion_count;
gint passed; gint passed;
}TestState; guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
static void static void
new_frame_cb (ClutterTimeline *timeline, new_frame_cb (ClutterTimeline *timeline,
@ -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 void
test_timeline_dup_frames (TestConformSimpleFixture *fixture, test_timeline_dup_frames (TestConformSimpleFixture *fixture,
@ -91,11 +118,18 @@ test_timeline_dup_frames (TestConformSimpleFixture *fixture,
state.prev_frame = -1; state.prev_frame = -1;
state.completion_count = 0; state.completion_count = 0;
state.passed = TRUE; 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_timeline_start (state.timeline);
clutter_main(); clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline); g_object_unref (state.timeline);
} }

View File

@ -15,14 +15,18 @@
* may not be a very reliable tolerance. */ * may not be a very reliable tolerance. */
#define TEST_ERROR_TOLERANCE 20 #define TEST_ERROR_TOLERANCE 20
typedef struct _TestState { typedef struct _TestState
ClutterTimeline *timeline; {
GTimeVal start_time; ClutterTimeline *timeline;
guint new_frame_counter; GTimeVal start_time;
gint expected_frame; guint new_frame_counter;
gint completion_count; gint expected_frame;
gboolean passed; gint completion_count;
}TestState; gboolean passed;
guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
static void static void
@ -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 void
test_timeline_interpolate (TestConformSimpleFixture *fixture, test_timeline_interpolate (TestConformSimpleFixture *fixture,
@ -154,12 +182,18 @@ test_timeline_interpolate (TestConformSimpleFixture *fixture,
state.new_frame_counter = 0; state.new_frame_counter = 0;
state.passed = TRUE; state.passed = TRUE;
state.expected_frame = 0; 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); g_get_current_time (&state.start_time);
clutter_timeline_start (state.timeline); clutter_timeline_start (state.timeline);
clutter_main(); clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline); g_object_unref (state.timeline);
} }

View File

@ -8,11 +8,14 @@
#define TEST_TIMELINE_FRAME_COUNT 5 #define TEST_TIMELINE_FRAME_COUNT 5
#define TEST_WATCHDOG_KICK_IN_SECONDS 10 #define TEST_WATCHDOG_KICK_IN_SECONDS 10
typedef struct _TestState { typedef struct _TestState
ClutterTimeline *timeline; {
gint rewind_count; ClutterTimeline *timeline;
}TestState; gint rewind_count;
guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
static gboolean static gboolean
watchdog_timeout (TestState *state) watchdog_timeout (TestState *state)
@ -34,7 +37,6 @@ watchdog_timeout (TestState *state)
return FALSE; return FALSE;
} }
static void static void
new_frame_cb (ClutterTimeline *timeline, new_frame_cb (ClutterTimeline *timeline,
gint frame_num, 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 void
test_timeline_rewind (TestConformSimpleFixture *fixture, test_timeline_rewind (TestConformSimpleFixture *fixture,
@ -88,11 +114,17 @@ test_timeline_rewind (TestConformSimpleFixture *fixture,
(GSourceFunc)watchdog_timeout, (GSourceFunc)watchdog_timeout,
&state); &state);
state.rewind_count = 0; 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_timeline_start (state.timeline);
clutter_main(); clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline); g_object_unref (state.timeline);
} }

View File

@ -8,15 +8,18 @@
#define TEST_TIMELINE_FRAME_COUNT 20 #define TEST_TIMELINE_FRAME_COUNT 20
#define TEST_ERROR_TOLERANCE 5 #define TEST_ERROR_TOLERANCE 5
typedef struct _TestState { typedef struct _TestState
{
ClutterTimeline *timeline; ClutterTimeline *timeline;
GTimeVal start_time; GTimeVal start_time;
GTimeVal prev_frame_time; GTimeVal prev_frame_time;
guint frame; guint frame;
gint completion_count; gint completion_count;
gint passed; gint passed;
}TestState; guint source_id;
GTimeVal prev_tick;
gulong msecs_delta;
} TestState;
static void static void
new_frame_cb (ClutterTimeline *timeline, new_frame_cb (ClutterTimeline *timeline,
@ -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 void
test_timeline_smoothness (TestConformSimpleFixture *fixture, test_timeline_smoothness (TestConformSimpleFixture *fixture,
@ -104,12 +131,18 @@ test_timeline_smoothness (TestConformSimpleFixture *fixture,
state.frame = 0; state.frame = 0;
state.completion_count = 0; state.completion_count = 0;
state.passed = TRUE; 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); g_get_current_time (&state.start_time);
clutter_timeline_start (state.timeline); clutter_timeline_start (state.timeline);
clutter_main(); clutter_main();
g_source_remove (state.source_id);
g_object_unref (state.timeline); g_object_unref (state.timeline);
} }

View File

@ -156,7 +156,7 @@ check_timeline (ClutterTimeline *timeline,
} }
static gboolean static gboolean
timeout_cb (gpointer data) timeout_cb (gpointer data G_GNUC_UNUSED)
{ {
clutter_main_quit (); clutter_main_quit ();
@ -172,10 +172,51 @@ delay_cb (gpointer data)
return TRUE; 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 void
test_timeline (TestConformSimpleFixture *fixture, test_timeline (TestConformSimpleFixture *fixture,
gconstpointer data) gconstpointer data)
{ {
FrameCounter *counter;
ClutterTimeline *timeline_1; ClutterTimeline *timeline_1;
TimelineData data_1; TimelineData data_1;
ClutterTimeline *timeline_2; ClutterTimeline *timeline_2;
@ -185,6 +226,11 @@ test_timeline (TestConformSimpleFixture *fixture,
gchar **markers; gchar **markers;
gsize n_markers; gsize n_markers;
guint delay_tag; 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_data_init (&data_1, 1);
timeline_1 = clutter_timeline_new (FRAME_COUNT, 30); timeline_1 = clutter_timeline_new (FRAME_COUNT, 30);
@ -198,6 +244,8 @@ test_timeline (TestConformSimpleFixture *fixture,
g_assert (n_markers == 3); g_assert (n_markers == 3);
g_strfreev (markers); g_strfreev (markers);
counter->timelines = g_slist_prepend (counter->timelines, timeline_1);
timeline_data_init (&data_2, 2); timeline_data_init (&data_2, 2);
timeline_2 = clutter_timeline_clone (timeline_1); timeline_2 = clutter_timeline_clone (timeline_1);
clutter_timeline_add_marker_at_frame (timeline_2, "bar", 2); 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_assert (strcmp (markers[0], "bar") == 0);
g_strfreev (markers); g_strfreev (markers);
counter->timelines = g_slist_prepend (counter->timelines, timeline_2);
timeline_data_init (&data_3, 3); timeline_data_init (&data_3, 3);
timeline_3 = clutter_timeline_clone (timeline_1); timeline_3 = clutter_timeline_clone (timeline_1);
clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD); 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, "near-end-marker", 1);
clutter_timeline_add_marker_at_frame (timeline_3, "end-marker", 0); 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, g_signal_connect (timeline_1,
"marker-reached", G_CALLBACK (timeline_marker_reached_cb), "marker-reached", G_CALLBACK (timeline_marker_reached_cb),
&data_1); &data_1);
@ -293,4 +345,9 @@ test_timeline (TestConformSimpleFixture *fixture,
timeline_data_destroy (&data_3); timeline_data_destroy (&data_3);
g_source_remove (delay_tag); g_source_remove (delay_tag);
g_source_remove (source_id);
g_slist_free (counter->timelines);
g_free (counter);
} }