{
GSList *entries;
GHashTable *running_timelines;
+ guint paused :1;
guint loop : 1;
};
LAST_SIGNAL
};
-/* static int score_signals[LAST_SIGNAL] = { 0 }; */
+static int score_signals[LAST_SIGNAL] = { 0 };
static void start_entry (ClutterScoreEntry *entry);
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.
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,
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
-#endif
+
}
static void
}
/**
- * 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
*
{
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);
}
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)
{
/* 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);
}
}
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));
}
/**
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*
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);
}
}
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
#include <stdlib.h>
#include <clutter/clutter.h>
-
int
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 ();