2008-03-19 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-score.[ch]: Small clean ups and refactoring.
	Use gulong instead of guint, so we have a bigger id space for
	the timelines inside a Score.
This commit is contained in:
Emmanuele Bassi 2008-03-19 11:46:57 +00:00
parent b961d5484c
commit 57f9439031
3 changed files with 119 additions and 103 deletions

View File

@ -1,3 +1,9 @@
2008-03-19 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-score.[ch]: Small clean ups and refactoring.
Use gulong instead of guint, so we have a bigger id space for
the timelines inside a Score.
2008-03-19 Chris Lord <chris@openedhand.com> 2008-03-19 Chris Lord <chris@openedhand.com>
* clutter/clutter-actor.c: * clutter/clutter-actor.c:

View File

@ -47,7 +47,8 @@
* timeline_3 = clutter_timeline_new_for_duration (500); * timeline_3 = clutter_timeline_new_for_duration (500);
* *
* score = clutter_score_new (); * score = clutter_score_new ();
* clutter_score_append (score, NULL, timeline_1); *
* clutter_score_append (score, NULL, timeline_1);
* clutter_score_append (score, timeline_1, timeline_2); * clutter_score_append (score, timeline_1, timeline_2);
* clutter_score_append (score, timeline_1, timeline_3); * clutter_score_append (score, timeline_1, timeline_3);
* *
@ -60,8 +61,8 @@
* New timelines can be appended to the #ClutterScore using * New timelines can be appended to the #ClutterScore using
* clutter_score_append() and removed using clutter_score_remove(). * clutter_score_append() and removed using clutter_score_remove().
* *
* Timelines can also be appended to a specific marker, using * Timelines can also be appended to a specific marker on the
* clutter_score_append_at_marker(). * parent timeline, using clutter_score_append_at_marker().
* *
* The score can be cleared using clutter_score_remove_all(). * The score can be cleared using clutter_score_remove_all().
* *
@ -90,17 +91,17 @@ typedef struct _ClutterScoreEntry ClutterScoreEntry;
struct _ClutterScoreEntry struct _ClutterScoreEntry
{ {
/* the entry unique id */ /* the entry unique id */
guint id; gulong id;
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterTimeline *parent; ClutterTimeline *parent;
/* the optional marker */ /* the optional marker on the parent */
gchar *marker; gchar *marker;
/* signal handlers id */ /* signal handlers id */
guint complete_id; gulong complete_id;
guint marker_id; gulong marker_id;
ClutterScore *score; ClutterScore *score;
@ -116,7 +117,7 @@ struct _ClutterScorePrivate
GHashTable *running_timelines; GHashTable *running_timelines;
guint last_id; gulong last_id;
guint is_paused : 1; guint is_paused : 1;
guint loop : 1; guint loop : 1;
@ -411,28 +412,11 @@ clutter_score_is_playing (ClutterScore *score)
return (g_hash_table_size (score->priv->running_timelines) != 0); return (g_hash_table_size (score->priv->running_timelines) != 0);
} }
typedef enum { /* destroy_entry:
FIND_BY_TIMELINE, * @node: a #GNode
FIND_BY_ID, *
REMOVE_BY_ID, * Frees the #ClutterScoreEntry attached to @node.
LIST_TIMELINES */
} TraverseAction;
typedef struct {
TraverseAction action;
ClutterScore *score;
/* parameters */
union {
ClutterTimeline *timeline;
guint id;
ClutterScoreEntry *entry;
} d;
gpointer result;
} TraverseClosure;
static gboolean static gboolean
destroy_entry (GNode *node, destroy_entry (GNode *node,
G_GNUC_UNUSED gpointer data) G_GNUC_UNUSED gpointer data)
@ -464,6 +448,28 @@ destroy_entry (GNode *node,
return FALSE; return FALSE;
} }
typedef enum {
FIND_BY_TIMELINE,
FIND_BY_ID,
REMOVE_BY_ID,
LIST_TIMELINES
} TraverseAction;
typedef struct {
TraverseAction action;
ClutterScore *score;
/* parameters */
union {
ClutterTimeline *timeline;
gulong id;
ClutterScoreEntry *entry;
} d;
gpointer result;
} TraverseClosure;
/* multi-purpose traversal function for the N-ary tree used by the score */ /* multi-purpose traversal function for the N-ary tree used by the score */
static gboolean static gboolean
traverse_children (GNode *node, traverse_children (GNode *node,
@ -561,7 +567,7 @@ find_entry_by_timeline (ClutterScore *score,
static GNode * static GNode *
find_entry_by_id (ClutterScore *score, find_entry_by_id (ClutterScore *score,
guint id) gulong id)
{ {
ClutterScorePrivate *priv = score->priv; ClutterScorePrivate *priv = score->priv;
TraverseClosure closure; TraverseClosure closure;
@ -632,7 +638,7 @@ on_timeline_completed (ClutterTimeline *timeline,
g_signal_handler_disconnect (timeline, entry->complete_id); g_signal_handler_disconnect (timeline, entry->complete_id);
entry->complete_id = 0; entry->complete_id = 0;
CLUTTER_NOTE (SCHEDULER, "timeline [%p] ('%d') completed", CLUTTER_NOTE (SCHEDULER, "timeline [%p] ('%lu') completed",
entry->timeline, entry->timeline,
entry->id); entry->id);
@ -667,6 +673,10 @@ start_entry (ClutterScoreEntry *entry)
{ {
ClutterScorePrivate *priv = entry->score->priv; ClutterScorePrivate *priv = entry->score->priv;
/* timelines attached to a marker might already be playing when we
* end up here from the ::completed handler, so we need to perform
* this check to avoid restarting those timelines
*/
if (clutter_timeline_is_playing (entry->timeline)) if (clutter_timeline_is_playing (entry->timeline))
return; return;
@ -675,7 +685,7 @@ start_entry (ClutterScoreEntry *entry)
G_CALLBACK (on_timeline_completed), G_CALLBACK (on_timeline_completed),
entry); entry);
CLUTTER_NOTE (SCHEDULER, "timeline [%p] ('%d') started", CLUTTER_NOTE (SCHEDULER, "timeline [%p] ('%lu') started",
entry->timeline, entry->timeline,
entry->id); entry->id);
@ -692,15 +702,35 @@ start_entry (ClutterScoreEntry *entry)
entry->timeline); entry->timeline);
} }
enum
{
ACTION_START,
ACTION_PAUSE,
ACTION_STOP
};
static void static void
foreach_running_timeline_start (gpointer key, foreach_running_timeline (gpointer key,
gpointer value, gpointer value,
gpointer user_data) gpointer user_data)
{ {
ClutterScoreEntry *entry = value; ClutterScoreEntry *entry = value;
gint action = GPOINTER_TO_INT (user_data);
if (!clutter_timeline_is_playing (entry->timeline)) switch (action)
clutter_timeline_start (entry->timeline); {
case ACTION_START:
clutter_timeline_start (entry->timeline);
break;
case ACTION_PAUSE:
clutter_timeline_pause (entry->timeline);
break;
case ACTION_STOP:
clutter_timeline_stop (entry->timeline);
break;
}
} }
/** /**
@ -723,8 +753,8 @@ clutter_score_start (ClutterScore *score)
if (priv->is_paused) if (priv->is_paused)
{ {
g_hash_table_foreach (priv->running_timelines, g_hash_table_foreach (priv->running_timelines,
foreach_running_timeline_start, foreach_running_timeline,
NULL); GINT_TO_POINTER (ACTION_START));
priv->is_paused = FALSE; priv->is_paused = FALSE;
} }
else else
@ -736,18 +766,6 @@ clutter_score_start (ClutterScore *score)
} }
} }
static gboolean
foreach_running_timeline_stop (gpointer key,
gpointer value,
gpointer user_data)
{
ClutterScoreEntry *entry = value;
clutter_timeline_stop (entry->timeline);
return TRUE;
}
/** /**
* clutter_score_stop: * clutter_score_stop:
* @score: A #ClutterScore * @score: A #ClutterScore
@ -767,14 +785,43 @@ clutter_score_stop (ClutterScore *score)
if (priv->running_timelines) if (priv->running_timelines)
{ {
g_hash_table_foreach_remove (priv->running_timelines, g_hash_table_foreach (priv->running_timelines,
foreach_running_timeline_stop, foreach_running_timeline,
NULL); GINT_TO_POINTER (ACTION_STOP));
g_hash_table_destroy (priv->running_timelines); g_hash_table_destroy (priv->running_timelines);
priv->running_timelines = NULL; priv->running_timelines = NULL;
} }
} }
/**
* clutter_score_pause:
* @score: a #ClutterScore
*
* Pauses a playing score @score.
*
* Since: 0.6
*/
void
clutter_score_pause (ClutterScore *score)
{
ClutterScorePrivate *priv;
g_return_if_fail (CLUTTER_IS_SCORE (score));
priv = score->priv;
if (!clutter_score_is_playing (score))
return;
g_hash_table_foreach (priv->running_timelines,
foreach_running_timeline,
GINT_TO_POINTER (ACTION_PAUSE));
priv->is_paused = TRUE;
g_signal_emit (score, score_signals[PAUSED], 0);
}
/** /**
* clutter_score_rewind: * clutter_score_rewind:
* @score: A #ClutterScore * @score: A #ClutterScore
@ -798,45 +845,6 @@ clutter_score_rewind (ClutterScore *score)
clutter_score_start (score); clutter_score_start (score);
} }
static void
foreach_running_timeline_pause (gpointer key,
gpointer value,
gpointer user_data)
{
ClutterScoreEntry *entry = value;
clutter_timeline_pause (entry->timeline);
}
/**
* clutter_score_pause:
* @score: a #ClutterScore
*
* Pauses a playing score @score.
*
* Since: 0.6
*/
void
clutter_score_pause (ClutterScore *score)
{
ClutterScorePrivate *priv;
g_return_if_fail (CLUTTER_IS_SCORE (score));
priv = score->priv;
if (!clutter_score_is_playing (score))
return;
g_hash_table_foreach (priv->running_timelines,
foreach_running_timeline_pause,
NULL);
priv->is_paused = TRUE;
g_signal_emit (score, score_signals[PAUSED], 0);
}
static inline void static inline void
clutter_score_clear (ClutterScore *score) clutter_score_clear (ClutterScore *score)
{ {
@ -853,7 +861,7 @@ clutter_score_clear (ClutterScore *score)
/** /**
* clutter_score_append: * clutter_score_append:
* @score: a #ClutterScore * @score: a #ClutterScore
* @parent: a #ClutterTimeline in the score or %NULL * @parent: a #ClutterTimeline in the score, or %NULL
* @timeline: a #ClutterTimeline * @timeline: a #ClutterTimeline
* *
* Appends a timeline to another one existing in the score; the newly * Appends a timeline to another one existing in the score; the newly
@ -870,7 +878,7 @@ clutter_score_clear (ClutterScore *score)
* *
* Since: 0.6 * Since: 0.6
*/ */
guint gulong
clutter_score_append (ClutterScore *score, clutter_score_append (ClutterScore *score,
ClutterTimeline *parent, ClutterTimeline *parent,
ClutterTimeline *timeline) ClutterTimeline *timeline)
@ -934,13 +942,15 @@ clutter_score_append (ClutterScore *score,
* If you want to append @timeline at the end of @parent, use * If you want to append @timeline at the end of @parent, use
* clutter_score_append(). * clutter_score_append().
* *
* The #ClutterScore will take a reference on @timeline.
*
* Return value: the id of the #ClutterTimeline inside the score, or * Return value: the id of the #ClutterTimeline inside the score, or
* 0 on failure. The returned id can be used with clutter_score_remove() * 0 on failure. The returned id can be used with clutter_score_remove()
* or clutter_score_get_timeline(). * or clutter_score_get_timeline().
* *
* Since: 0.8 * Since: 0.8
*/ */
guint gulong
clutter_score_append_at_marker (ClutterScore *score, clutter_score_append_at_marker (ClutterScore *score,
ClutterTimeline *parent, ClutterTimeline *parent,
const gchar *marker_name, const gchar *marker_name,
@ -1006,7 +1016,7 @@ clutter_score_append_at_marker (ClutterScore *score,
*/ */
void void
clutter_score_remove (ClutterScore *score, clutter_score_remove (ClutterScore *score,
guint id) gulong id)
{ {
ClutterScorePrivate *priv; ClutterScorePrivate *priv;
TraverseClosure closure; TraverseClosure closure;
@ -1072,7 +1082,7 @@ clutter_score_remove_all (ClutterScore *score)
*/ */
ClutterTimeline * ClutterTimeline *
clutter_score_get_timeline (ClutterScore *score, clutter_score_get_timeline (ClutterScore *score,
guint id) gulong id)
{ {
GNode *node; GNode *node;
ClutterScoreEntry *entry; ClutterScoreEntry *entry;

View File

@ -81,18 +81,18 @@ void clutter_score_set_loop (ClutterScore *score,
gboolean loop); gboolean loop);
gboolean clutter_score_get_loop (ClutterScore *score); gboolean clutter_score_get_loop (ClutterScore *score);
guint clutter_score_append (ClutterScore *score, gulong clutter_score_append (ClutterScore *score,
ClutterTimeline *parent, ClutterTimeline *parent,
ClutterTimeline *timeline); ClutterTimeline *timeline);
guint clutter_score_append_at_marker (ClutterScore *score, gulong clutter_score_append_at_marker (ClutterScore *score,
ClutterTimeline *parent, ClutterTimeline *parent,
const gchar *marker_name, const gchar *marker_name,
ClutterTimeline *timeline); ClutterTimeline *timeline);
void clutter_score_remove (ClutterScore *score, void clutter_score_remove (ClutterScore *score,
guint id); gulong id);
void clutter_score_remove_all (ClutterScore *score); void clutter_score_remove_all (ClutterScore *score);
ClutterTimeline *clutter_score_get_timeline (ClutterScore *score, ClutterTimeline *clutter_score_get_timeline (ClutterScore *score,
guint id); gulong id);
GSList * clutter_score_list_timelines (ClutterScore *score); GSList * clutter_score_list_timelines (ClutterScore *score);
void clutter_score_start (ClutterScore *score); void clutter_score_start (ClutterScore *score);