2008-03-05 11:04:06 -05:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include <clutter/clutter.h>
|
|
|
|
|
2020-03-25 11:31:41 -04:00
|
|
|
#include "tests/clutter-test-utils.h"
|
2008-11-07 14:32:28 -05:00
|
|
|
|
2021-03-01 08:38:32 -05:00
|
|
|
#define TEST_TIMELINE_DURATION 3000
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make the test tolarate being half a second off track in each direction,
|
|
|
|
* the thing we're testing for will still be tested for.
|
2020-03-25 11:31:41 -04:00
|
|
|
*/
|
2021-03-01 08:38:32 -05:00
|
|
|
#define TEST_ERROR_TOLERANCE 500
|
2008-03-05 11:04:06 -05:00
|
|
|
|
2009-05-01 10:08:42 -04:00
|
|
|
typedef struct _TestState
|
|
|
|
{
|
|
|
|
ClutterTimeline *timeline;
|
2021-03-08 09:05:18 -05:00
|
|
|
int64_t start_time_us;
|
2021-03-01 08:38:09 -05:00
|
|
|
int new_frame_counter;
|
|
|
|
int expected_frame;
|
|
|
|
int completion_count;
|
2021-03-01 08:38:32 -05:00
|
|
|
int cycle_frame_counter;
|
2009-05-01 10:08:42 -04:00
|
|
|
} TestState;
|
2008-03-05 11:04:06 -05:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
new_frame_cb (ClutterTimeline *timeline,
|
2021-03-01 08:38:09 -05:00
|
|
|
int frame_num,
|
|
|
|
TestState *state)
|
2008-03-05 11:04:06 -05:00
|
|
|
{
|
2021-03-08 09:05:18 -05:00
|
|
|
int64_t current_time_us;
|
|
|
|
int current_frame_ms;
|
2021-03-01 08:38:09 -05:00
|
|
|
long msec_diff;
|
|
|
|
int loop_overflow = 0;
|
2008-11-07 14:32:28 -05:00
|
|
|
|
2021-03-08 09:05:18 -05:00
|
|
|
current_time_us = g_get_monotonic_time ();
|
|
|
|
current_frame_ms = clutter_timeline_get_elapsed_time (state->timeline);
|
|
|
|
msec_diff = us2ms (current_time_us - state->start_time_us);
|
2008-11-07 14:32:28 -05:00
|
|
|
|
2008-03-05 11:04:06 -05:00
|
|
|
/* If we expect to have interpolated past the end of the timeline
|
|
|
|
* we keep track of the overflow so we can determine when
|
2009-06-11 05:55:52 -04:00
|
|
|
* the next timeout will happen. We then clip expected_frames
|
|
|
|
* to TEST_TIMELINE_DURATION since clutter-timeline
|
|
|
|
* semantics guaranty this frame is always signaled before
|
|
|
|
* looping */
|
2009-06-04 08:05:12 -04:00
|
|
|
if (state->expected_frame > TEST_TIMELINE_DURATION)
|
2008-03-05 11:04:06 -05:00
|
|
|
{
|
2009-06-04 08:05:12 -04:00
|
|
|
loop_overflow = state->expected_frame - TEST_TIMELINE_DURATION;
|
2009-06-11 05:55:52 -04:00
|
|
|
state->expected_frame = TEST_TIMELINE_DURATION;
|
2008-03-05 11:04:06 -05:00
|
|
|
}
|
|
|
|
|
2021-03-01 08:38:32 -05:00
|
|
|
switch (state->cycle_frame_counter)
|
2008-03-05 11:04:06 -05:00
|
|
|
{
|
2021-03-01 08:38:32 -05:00
|
|
|
case 0:
|
|
|
|
case 1:
|
2021-03-08 09:05:18 -05:00
|
|
|
if (current_frame_ms >= (state->expected_frame - TEST_ERROR_TOLERANCE) &&
|
|
|
|
current_frame_ms <= (state->expected_frame + TEST_ERROR_TOLERANCE))
|
2021-03-01 08:38:32 -05:00
|
|
|
{
|
|
|
|
g_test_message ("elapsed milliseconds=%-5li "
|
|
|
|
"expected frame=%-4i actual frame=%-4i (OK)",
|
|
|
|
msec_diff,
|
|
|
|
state->expected_frame,
|
2021-03-08 09:05:18 -05:00
|
|
|
current_frame_ms);
|
2021-03-01 08:38:32 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_test_message ("elapsed milliseconds=%-5li "
|
|
|
|
"expected frame=%-4i actual frame=%-4i (FAILED)",
|
|
|
|
msec_diff,
|
|
|
|
state->expected_frame,
|
2021-03-08 09:05:18 -05:00
|
|
|
current_frame_ms);
|
2021-03-01 08:38:32 -05:00
|
|
|
g_test_fail ();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2021-03-08 09:05:18 -05:00
|
|
|
g_assert_cmpint (current_frame_ms, ==, TEST_TIMELINE_DURATION);
|
2021-03-01 08:38:32 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
2008-03-05 11:04:06 -05:00
|
|
|
}
|
2008-11-07 14:32:28 -05:00
|
|
|
|
2021-03-01 08:38:32 -05:00
|
|
|
/* We already tested that we interpolated when looping, lets stop now. */
|
|
|
|
if (state->completion_count == 1 &&
|
|
|
|
state->cycle_frame_counter == 0)
|
2008-03-05 11:04:06 -05:00
|
|
|
{
|
2021-03-01 08:38:32 -05:00
|
|
|
clutter_timeline_stop (timeline);
|
|
|
|
return;
|
2008-03-05 11:04:06 -05:00
|
|
|
}
|
2008-11-07 14:32:28 -05:00
|
|
|
|
2021-03-01 08:38:32 -05:00
|
|
|
switch (state->cycle_frame_counter)
|
2008-03-05 11:04:06 -05:00
|
|
|
{
|
2021-03-01 08:38:32 -05:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* First frame, sleep so we're about in the middle of the cycle,
|
|
|
|
* before the end of the timeline cycle.
|
|
|
|
*/
|
|
|
|
int delay_ms = ms (1500);
|
|
|
|
|
2021-03-08 09:05:18 -05:00
|
|
|
state->expected_frame = current_frame_ms + delay_ms;
|
2021-03-01 08:38:32 -05:00
|
|
|
g_test_message ("Sleeping for 1.5 seconds "
|
|
|
|
"so next frame should be (%d + %d) = %d",
|
2021-03-08 09:05:18 -05:00
|
|
|
current_frame_ms,
|
2021-03-01 08:38:32 -05:00
|
|
|
delay_ms,
|
|
|
|
state->expected_frame);
|
|
|
|
g_usleep (ms2us (delay_ms));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Second frame, we're about in the middle of the cycle; sleep one cycle,
|
|
|
|
* and check that we end up in the middle again.
|
|
|
|
*/
|
|
|
|
int delay_ms = TEST_TIMELINE_DURATION;
|
|
|
|
|
2021-03-08 09:05:18 -05:00
|
|
|
state->expected_frame = current_frame_ms + delay_ms;
|
2021-03-01 08:38:32 -05:00
|
|
|
g_test_message ("Sleeping for %d seconds "
|
|
|
|
"so next frame should be (%d + %d) = %d, "
|
|
|
|
"which is %d into the next cycle",
|
|
|
|
TEST_TIMELINE_DURATION / 1000,
|
2021-03-08 09:05:18 -05:00
|
|
|
current_frame_ms,
|
2021-03-01 08:38:32 -05:00
|
|
|
delay_ms,
|
|
|
|
state->expected_frame,
|
|
|
|
state->expected_frame - TEST_TIMELINE_DURATION);
|
|
|
|
g_usleep (ms2us (delay_ms));
|
|
|
|
|
|
|
|
g_assert_cmpint (state->expected_frame, >, TEST_TIMELINE_DURATION);
|
|
|
|
|
|
|
|
state->expected_frame += loop_overflow;
|
|
|
|
state->expected_frame -= TEST_TIMELINE_DURATION;
|
|
|
|
g_test_message ("End of timeline reached: "
|
|
|
|
"Wrapping expected frame too %d",
|
|
|
|
state->expected_frame);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2008-03-05 11:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
state->new_frame_counter++;
|
2021-03-01 08:38:32 -05:00
|
|
|
state->cycle_frame_counter++;
|
2008-03-05 11:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
completed_cb (ClutterTimeline *timeline,
|
2021-03-01 08:38:09 -05:00
|
|
|
TestState *state)
|
2008-03-05 11:04:06 -05:00
|
|
|
{
|
2008-11-07 14:32:28 -05:00
|
|
|
state->completion_count++;
|
2021-03-01 08:38:32 -05:00
|
|
|
state->cycle_frame_counter = 0;
|
2008-11-07 14:32:28 -05:00
|
|
|
|
2021-03-01 08:38:32 -05:00
|
|
|
if (state->completion_count >= 2)
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
stopped_cb (ClutterTimeline *timeline,
|
|
|
|
gboolean is_finished,
|
|
|
|
TestState *state)
|
|
|
|
{
|
|
|
|
g_assert_cmpint (state->completion_count, ==, 1);
|
|
|
|
|
|
|
|
clutter_test_quit ();
|
2008-03-05 11:04:06 -05:00
|
|
|
}
|
|
|
|
|
2020-03-25 11:31:41 -04:00
|
|
|
static void
|
2010-10-12 12:31:15 -04:00
|
|
|
timeline_interpolation (void)
|
2008-03-05 11:04:06 -05:00
|
|
|
{
|
2020-05-29 13:31:22 -04:00
|
|
|
ClutterActor *stage;
|
2008-03-05 11:04:06 -05:00
|
|
|
TestState state;
|
|
|
|
|
2020-05-29 13:31:22 -04:00
|
|
|
stage = clutter_test_get_stage ();
|
|
|
|
|
2008-03-05 11:04:06 -05:00
|
|
|
state.timeline =
|
2020-04-17 03:03:44 -04:00
|
|
|
clutter_timeline_new_for_actor (stage, TEST_TIMELINE_DURATION);
|
2020-04-16 04:04:04 -04:00
|
|
|
clutter_timeline_set_repeat_count (state.timeline, -1);
|
2021-03-01 08:38:09 -05:00
|
|
|
g_signal_connect (state.timeline,
|
|
|
|
"new-frame",
|
|
|
|
G_CALLBACK (new_frame_cb),
|
|
|
|
&state);
|
|
|
|
g_signal_connect (state.timeline,
|
|
|
|
"completed",
|
|
|
|
G_CALLBACK (completed_cb),
|
|
|
|
&state);
|
2021-03-01 08:38:32 -05:00
|
|
|
g_signal_connect (state.timeline,
|
|
|
|
"stopped",
|
|
|
|
G_CALLBACK (stopped_cb),
|
|
|
|
&state);
|
2008-03-05 11:04:06 -05:00
|
|
|
|
|
|
|
state.completion_count = 0;
|
|
|
|
state.new_frame_counter = 0;
|
2021-03-01 08:38:32 -05:00
|
|
|
state.cycle_frame_counter = 0;
|
2008-03-05 11:04:06 -05:00
|
|
|
state.expected_frame = 0;
|
2009-05-01 10:08:42 -04:00
|
|
|
|
2020-05-29 13:31:22 -04:00
|
|
|
clutter_actor_show (stage);
|
|
|
|
|
2021-03-08 09:05:18 -05:00
|
|
|
state.start_time_us = g_get_monotonic_time ();
|
2008-03-05 11:04:06 -05:00
|
|
|
clutter_timeline_start (state.timeline);
|
2021-03-01 08:38:09 -05:00
|
|
|
|
2020-07-09 15:28:57 -04:00
|
|
|
clutter_test_main ();
|
2008-03-05 11:04:06 -05:00
|
|
|
|
2008-11-07 14:32:28 -05:00
|
|
|
g_object_unref (state.timeline);
|
2008-03-05 11:04:06 -05:00
|
|
|
}
|
2020-03-25 11:31:41 -04:00
|
|
|
|
|
|
|
CLUTTER_TEST_SUITE (
|
|
|
|
CLUTTER_TEST_UNIT ("/timeline/interpolate", timeline_interpolation)
|
|
|
|
)
|