diff --git a/ChangeLog b/ChangeLog index 569b0d7d4..0a44655a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-10-18 Matthew Allum + + * clutter/clutter-score.c: + * clutter/clutter-score.h: + * tests/test-score.c: + Implement more ClutterScore functionality. + 2007-10-17 Emmanuele Bassi * clutter/clutter-actor.c: diff --git a/clutter/clutter-score.c b/clutter/clutter-score.c index 45a0526a9..ff398c3df 100644 --- a/clutter/clutter-score.c +++ b/clutter/clutter-score.c @@ -75,6 +75,7 @@ struct _ClutterScorePrivate { GSList *entries; GHashTable *running_timelines; + guint paused :1; guint loop : 1; }; @@ -94,7 +95,7 @@ enum LAST_SIGNAL }; -/* static int score_signals[LAST_SIGNAL] = { 0 }; */ +static int score_signals[LAST_SIGNAL] = { 0 }; static void start_entry (ClutterScoreEntry *entry); @@ -184,11 +185,10 @@ clutter_score_class_init (ClutterScoreClass *klass) g_type_class_add_private (klass, sizeof (ClutterScorePrivate)); -#if 0 /** - * ClutterScore::new-frame: + * ClutterScore::new-timeline: * @score: the score which received the signal - * @timeline: the number of the new frame + * @timeline: the current timeline * * The ::new-timeline signal is emitted each time a new timeline in the * score is reached. @@ -197,7 +197,7 @@ clutter_score_class_init (ClutterScoreClass *klass) g_signal_new ("new-timeline", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterScoreClass, new_frame), + G_STRUCT_OFFSET (ClutterScoreClass, new_timeline), NULL, NULL, clutter_marshal_VOID__OBJECT, G_TYPE_NONE, @@ -226,7 +226,7 @@ clutter_score_class_init (ClutterScoreClass *klass) NULL, NULL, clutter_marshal_VOID__VOID, G_TYPE_NONE, 0); -#endif + } static void @@ -279,19 +279,6 @@ clutter_score_get_loop (ClutterScore *score) return score->priv->loop; } -/** - * clutter_score_rewind: - * @score: A #ClutterScore - * - * Rewinds #ClutterScore to frame 0. - **/ -void -clutter_score_rewind (ClutterScore *score) -{ - g_return_if_fail (CLUTTER_IS_SCORE (score)); - -} - /** * clutter_score_is_playing: * @score: A #ClutterScore @@ -305,6 +292,8 @@ clutter_score_is_playing (ClutterScore *score) { g_return_val_if_fail (CLUTTER_IS_SCORE (score), FALSE); + /* FIXME: paused state currently counts as playing */ + return !!g_hash_table_size(score->priv->running_timelines); } @@ -316,9 +305,10 @@ on_timeline_finish (ClutterTimeline *timeline, g_hash_table_remove (entry->score->priv->running_timelines, GINT_TO_POINTER(entry->handler_id)); + g_signal_handler_disconnect (timeline, entry->handler_id); - printf("completed %li\n", entry->handler_id); + printf("completed %p %li\n", entry->timeline, entry->handler_id); for (item = entry->child_entries; item != NULL; item = item->next) { @@ -331,6 +321,8 @@ on_timeline_finish (ClutterTimeline *timeline, /* Score has finished - fire 'completed' signal */ /* Also check if looped etc */ printf("looks like we finished\n"); + + g_signal_emit (entry->score, score_signals[COMPLETED], 0); } } @@ -342,13 +334,24 @@ start_entry (ClutterScoreEntry *entry) G_CALLBACK (on_timeline_finish), entry); - printf("started %li\n", entry->handler_id); + printf("started %p %li\n", entry->timeline, entry->handler_id); g_hash_table_insert (entry->score->priv->running_timelines, GINT_TO_POINTER(entry->handler_id), entry); clutter_timeline_start (entry->timeline); + + g_signal_emit (entry->score, score_signals[NEW_TIMELINE], + 0, entry->timeline); +} + +void +on_foreach_running_timeline_start (gpointer key, + gpointer value, + gpointer user_data) +{ + clutter_timeline_start (CLUTTER_TIMELINE(value)); } /** @@ -369,28 +372,101 @@ clutter_score_start (ClutterScore *score) priv = score->priv; - for (item = priv->entries; item != NULL; item = item->next) + if (priv->paused) { - ClutterScoreEntry *entry = item->data; - - start_entry (entry); + g_hash_table_foreach (priv->running_timelines, + (GHFunc)on_foreach_running_timeline_start, + NULL); + priv->paused = 0; + } + else + { + for (item = priv->entries; item != NULL; item = item->next) + { + ClutterScoreEntry *entry = item->data; + start_entry (entry); + } } } +gboolean +on_foreach_running_timeline_stop (gpointer key, + gpointer value, + gpointer user_data) +{ + clutter_timeline_stop (CLUTTER_TIMELINE(value)); + return TRUE; +} + /** - * clutter_score_start: + * clutter_score_stop: * @score: A #ClutterScore * - * Query state of a #ClutterScore instance. + * Stops and rewinds a playing #ClutterScore instance. * - * Return Value: TRUE if score is currently playing, FALSE if not. */ void clutter_score_stop (ClutterScore *score) { + ClutterScorePrivate *priv; + g_return_if_fail (CLUTTER_IS_SCORE (score)); - /* foreach hash / pause */ + priv = score->priv; + + g_hash_table_foreach_remove (priv->running_timelines, + (GHRFunc)on_foreach_running_timeline_stop, + NULL); +} + +/** + * clutter_score_rewind: + * @score: A #ClutterScore + * + * Rewinds a #ClutterScore to inital timeline. + **/ +void +clutter_score_rewind (ClutterScore *score) +{ + gboolean was_playing; + + g_return_if_fail (CLUTTER_IS_SCORE (score)); + + was_playing = clutter_score_is_playing (score); + + clutter_score_stop (score); + + if (was_playing) + clutter_score_start (score); +} + +void +on_foreach_running_timeline_pause (gpointer key, + gpointer value, + gpointer user_data) +{ + clutter_timeline_pause (CLUTTER_TIMELINE(value)); +} + +void +clutter_score_pause (ClutterScore *score) +{ + ClutterScorePrivate *priv; + + g_return_if_fail (CLUTTER_IS_SCORE (score)); + + priv = score->priv; + + if (priv->paused || !clutter_score_is_playing (score)) + return; + + g_hash_table_foreach (priv->running_timelines, + (GHFunc)on_foreach_running_timeline_pause, + NULL); + + priv->paused = 1; + + g_signal_emit (score, score_signals[PAUSED], 0); } static ClutterScoreEntry* @@ -442,9 +518,10 @@ clutter_score_append (ClutterScore *score, if ((entry = find_entry (priv->entries, timeline_existing)) != NULL) { entry_new = g_new0(ClutterScoreEntry, 1); - entry->timeline = g_object_ref (timeline_new); - entry->score = score; - entry->child_entries = g_slist_append (entry->child_entries, entry); + entry_new->timeline = g_object_ref (timeline_new); + entry_new->score = score; + + entry->child_entries = g_slist_append (entry->child_entries, entry_new); } } @@ -470,6 +547,8 @@ clutter_score_add (ClutterScore *score, entry->timeline = g_object_ref (timeline); entry->score = score; score->priv->entries = g_slist_append (score->priv->entries, entry); + + printf("added %p\n", entry->timeline); } void diff --git a/clutter/clutter-score.h b/clutter/clutter-score.h index 3eb81c3fd..f28c5c853 100644 --- a/clutter/clutter-score.h +++ b/clutter/clutter-score.h @@ -70,6 +70,7 @@ struct _ClutterScoreClass { GObjectClass parent_class; + void (*new_timeline) (ClutterScore *score, ClutterTimeline *timeline); void (*started) (ClutterScore *score); void (*completed) (ClutterScore *score); void (*paused) (ClutterScore *score); @@ -97,12 +98,16 @@ clutter_score_rewind (ClutterScore *score); gboolean clutter_score_is_playing (ClutterScore *score); + void clutter_score_start (ClutterScore *score); void clutter_score_stop (ClutterScore *score); +void +clutter_score_pause (ClutterScore *score); + void clutter_score_append (ClutterScore *score, ClutterTimeline *timeline_existing, diff --git a/tests/test-score.c b/tests/test-score.c index 6dd18d383..eee76d739 100644 --- a/tests/test-score.c +++ b/tests/test-score.c @@ -2,7 +2,6 @@ #include #include - int main (int argc, char **argv) { @@ -10,19 +9,21 @@ main (int argc, char **argv) ClutterTimeline *timeline_1; ClutterTimeline *timeline_2; ClutterTimeline *timeline_3; + ClutterTimeline *timeline_4; clutter_init (&argc, &argv); timeline_1 = clutter_timeline_new (10, 120); timeline_2 = clutter_timeline_clone (timeline_1); timeline_3 = clutter_timeline_clone (timeline_1); + timeline_4 = clutter_timeline_clone (timeline_1); score = clutter_score_new(); clutter_score_add (score, timeline_1); clutter_score_append (score, timeline_1, timeline_2); -#if 0 - clutter_score_append (score, timeline_2, timeline_3); -#endif + clutter_score_append (score, timeline_1, timeline_3); + clutter_score_append (score, timeline_3, timeline_4); + clutter_score_start (score); clutter_main ();