From 2800b00e1d5d46f374d50c279eb16aebd521ca4e Mon Sep 17 00:00:00 2001 From: Matt Watson Date: Thu, 24 Mar 2016 23:43:15 -0700 Subject: [PATCH] cssanimation: port to progress tracker --- gtk/gtkcssanimatedstyle.c | 1 - gtk/gtkcssanimation.c | 119 +++++++++++++++-------------------- gtk/gtkcssanimationprivate.h | 6 +- 3 files changed, 51 insertions(+), 75 deletions(-) diff --git a/gtk/gtkcssanimatedstyle.c b/gtk/gtkcssanimatedstyle.c index e3a22604cc..f0246e91cf 100644 --- a/gtk/gtkcssanimatedstyle.c +++ b/gtk/gtkcssanimatedstyle.c @@ -369,7 +369,6 @@ gtk_css_animated_style_create_css_animations (GSList *animation if (animation) { animation = _gtk_css_animation_copy (GTK_CSS_ANIMATION (animation), - timestamp, _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i))); } else diff --git a/gtk/gtkcssanimation.c b/gtk/gtkcssanimation.c index c1b10c7efd..af479345aa 100644 --- a/gtk/gtkcssanimation.c +++ b/gtk/gtkcssanimation.c @@ -22,41 +22,25 @@ #include "gtkcssanimationprivate.h" #include "gtkcsseasevalueprivate.h" +#include "gtkprogresstrackerprivate.h" #include G_DEFINE_TYPE (GtkCssAnimation, _gtk_css_animation, GTK_TYPE_STYLE_ANIMATION) -/* NB: Return value can be negative (if animation hasn't started yet) */ -static gint64 -gtk_css_animation_get_elapsed (GtkCssAnimation *animation, - gint64 for_time_us) -{ - if (animation->play_state == GTK_CSS_PLAY_STATE_PAUSED) - return animation->timestamp; - else - return for_time_us - animation->timestamp; -} -/* NB: Return value can be negative and +-Inf */ -static double -gtk_css_animation_get_iteration (GtkCssAnimation *animation, - gint64 for_time_us) -{ - return (double) gtk_css_animation_get_elapsed (animation, for_time_us) / animation->duration; -} - static gboolean -gtk_css_animation_is_executing_at_iteration (GtkCssAnimation *animation, - double iteration) +gtk_css_animation_is_executing (GtkCssAnimation *animation) { + GtkProgressState state = gtk_progress_tracker_get_state (&animation->tracker); + switch (animation->fill_mode) { case GTK_CSS_FILL_NONE: - return iteration >= 0 && iteration <= animation->iteration_count; + return state == GTK_PROGRESS_STATE_DURING; case GTK_CSS_FILL_FORWARDS: - return iteration >= 0; + return state != GTK_PROGRESS_STATE_BEFORE; case GTK_CSS_FILL_BACKWARDS: - return iteration <= animation->iteration_count; + return state != GTK_PROGRESS_STATE_AFTER; case GTK_CSS_FILL_BOTH: return TRUE; default: @@ -65,38 +49,31 @@ gtk_css_animation_is_executing_at_iteration (GtkCssAnimation *animation, } static double -gtk_css_animation_get_progress_from_iteration (GtkCssAnimation *animation, - double iteration) +gtk_css_animation_get_progress (GtkCssAnimation *animation) { - gboolean reverse; - double completed; - - iteration = CLAMP (iteration, 0.0, animation->iteration_count); - completed = floor (iteration); + gboolean reverse, odd_iteration; + gint cycle = gtk_progress_tracker_get_iteration_cycle (&animation->tracker); + odd_iteration = cycle % 2 > 0; switch (animation->direction) { case GTK_CSS_DIRECTION_NORMAL: - reverse = completed == iteration && iteration > 0; + reverse = FALSE; break; case GTK_CSS_DIRECTION_REVERSE: - reverse = !(completed == iteration && iteration > 0); + reverse = TRUE; break; case GTK_CSS_DIRECTION_ALTERNATE: - reverse = fmod (iteration, 2) >= 1.0; + reverse = odd_iteration; break; case GTK_CSS_DIRECTION_ALTERNATE_REVERSE: - reverse = !(fmod (iteration, 2) >= 1.0); + reverse = !odd_iteration; break; default: g_return_val_if_reached (0.0); } - iteration -= completed; - if (reverse) - iteration = 1.0 - iteration; - - return iteration; + return gtk_progress_tracker_get_progress (&animation->tracker, reverse); } static void @@ -105,17 +82,20 @@ gtk_css_animation_set_values (GtkStyleAnimation *style_animation, GtkCssAnimatedStyle *style) { GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation); - double iteration, progress; + double progress; guint i; - iteration = gtk_css_animation_get_iteration (animation, for_time_us); + if (animation->play_state != GTK_CSS_PLAY_STATE_PAUSED) + gtk_progress_tracker_advance_frame (&animation->tracker, for_time_us); + else + gtk_progress_tracker_skip_frame (&animation->tracker, for_time_us); - if (!gtk_css_animation_is_executing_at_iteration (animation, iteration)) + if (!gtk_css_animation_is_executing (animation)) return; - progress = gtk_css_animation_get_progress_from_iteration (animation, iteration); + progress = gtk_css_animation_get_progress (animation); progress = _gtk_css_ease_value_transform (animation->ease, progress); - + for (i = 0; i < _gtk_css_keyframes_get_n_properties (animation->keyframes); i++) { GtkCssValue *value; @@ -144,14 +124,11 @@ gtk_css_animation_is_static (GtkStyleAnimation *style_animation, gint64 at_time_us) { GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation); - double iteration; if (animation->play_state == GTK_CSS_PLAY_STATE_PAUSED) return TRUE; - iteration = gtk_css_animation_get_iteration (animation, at_time_us); - - return iteration >= animation->iteration_count; + return gtk_progress_tracker_get_state (&animation->tracker) == GTK_PROGRESS_STATE_AFTER; } static void @@ -207,17 +184,16 @@ _gtk_css_animation_new (const char *name, animation->name = g_strdup (name); animation->keyframes = _gtk_css_keyframes_ref (keyframes); - if (play_state == GTK_CSS_PLAY_STATE_PAUSED) - animation->timestamp = - delay_us; - else - animation->timestamp = timestamp + delay_us; - - animation->duration = duration_us; animation->ease = _gtk_css_value_ref (ease); animation->direction = direction; animation->play_state = play_state; animation->fill_mode = fill_mode; - animation->iteration_count = iteration_count; + + gtk_progress_tracker_start (&animation->tracker, duration_us, delay_us, iteration_count); + if (animation->play_state == GTK_CSS_PLAY_STATE_PAUSED) + gtk_progress_tracker_skip_frame (&animation->tracker, timestamp); + else + gtk_progress_tracker_advance_frame (&animation->tracker, timestamp); return GTK_STYLE_ANIMATION (animation); } @@ -231,24 +207,27 @@ _gtk_css_animation_get_name (GtkCssAnimation *animation) } GtkStyleAnimation * -_gtk_css_animation_copy (GtkCssAnimation *animation, - gint64 at_time_us, +_gtk_css_animation_copy (GtkCssAnimation *source, GtkCssPlayState play_state) { - g_return_val_if_fail (GTK_IS_CSS_ANIMATION (animation), NULL); + GtkCssAnimation *animation; - if (animation->play_state == play_state) - return g_object_ref (animation); + g_return_val_if_fail (GTK_IS_CSS_ANIMATION (source), NULL); - return _gtk_css_animation_new (animation->name, - animation->keyframes, - at_time_us, - - gtk_css_animation_get_elapsed (animation, at_time_us), - animation->duration, - animation->ease, - animation->direction, - play_state, - animation->fill_mode, - animation->iteration_count); + if (source->play_state == play_state) + return g_object_ref (source); + + animation = g_object_new (GTK_TYPE_CSS_ANIMATION, NULL); + + animation->name = g_strdup (source->name); + animation->keyframes = _gtk_css_keyframes_ref (source->keyframes); + animation->ease = _gtk_css_value_ref (source->ease); + animation->direction = source->direction; + animation->play_state = play_state; + animation->fill_mode = source->fill_mode; + + memcpy (&animation->tracker, &source->tracker, sizeof (source->tracker)); + + return GTK_STYLE_ANIMATION (animation); } diff --git a/gtk/gtkcssanimationprivate.h b/gtk/gtkcssanimationprivate.h index 928b6147ff..c0d6fa2c1b 100644 --- a/gtk/gtkcssanimationprivate.h +++ b/gtk/gtkcssanimationprivate.h @@ -23,6 +23,7 @@ #include "gtkstyleanimationprivate.h" #include "gtkcsskeyframesprivate.h" +#include "gtkprogresstrackerprivate.h" G_BEGIN_DECLS @@ -43,12 +44,10 @@ struct _GtkCssAnimation char *name; GtkCssKeyframes *keyframes; GtkCssValue *ease; - gint64 timestamp; /* elapsed time when paused, start time when playing (can be negative) */ - gint64 duration; /* duration of 1 cycle */ - double iteration_count; GtkCssDirection direction; GtkCssPlayState play_state; GtkCssFillMode fill_mode; + GtkProgressTracker tracker; }; struct _GtkCssAnimationClass @@ -70,7 +69,6 @@ GtkStyleAnimation * _gtk_css_animation_new (const char * double iteration_count); GtkStyleAnimation * _gtk_css_animation_copy (GtkCssAnimation *animation, - gint64 at_time_us, GtkCssPlayState play_state); const char * _gtk_css_animation_get_name (GtkCssAnimation *animation);