[Swfdec] 6 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_event.c libswfdec/swfdec_event.h libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_resource.c libswfdec/swfdec_resource.h libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite_movie_as.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_sprite_movie.h libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_swf_decoder.h libswfdec/swfdec_tag.c libswfdec/swfdec_text_field_movie.c

Benjamin Otte company at kemper.freedesktop.org
Thu Oct 25 02:46:08 PDT 2007


 libswfdec/swfdec_as_interpret.c     |    6 -
 libswfdec/swfdec_event.c            |   59 +---------
 libswfdec/swfdec_event.h            |   38 +++----
 libswfdec/swfdec_movie.c            |  124 ++++++++++++----------
 libswfdec/swfdec_movie.h            |    4 
 libswfdec/swfdec_player.c           |  195 ++++++++++++++++++++++--------------
 libswfdec/swfdec_player_internal.h  |   23 ++--
 libswfdec/swfdec_resource.c         |   53 +--------
 libswfdec/swfdec_resource.h         |    5 
 libswfdec/swfdec_sprite.c           |    1 
 libswfdec/swfdec_sprite_movie.c     |  149 ++++++++++++++++-----------
 libswfdec/swfdec_sprite_movie.h     |    1 
 libswfdec/swfdec_sprite_movie_as.c  |    6 -
 libswfdec/swfdec_swf_decoder.c      |   58 ----------
 libswfdec/swfdec_swf_decoder.h      |   21 ---
 libswfdec/swfdec_tag.c              |   67 ------------
 libswfdec/swfdec_text_field_movie.c |   10 -
 17 files changed, 341 insertions(+), 479 deletions(-)

New commits:
commit b0b423c35cd3e06ab2004534a87c90090c2b7b88
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 25 11:40:26 2007 +0200

    remove all debug g_print statements

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 7ee4903..93887f4 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1913,7 +1913,6 @@ swfdec_player_get_export_class (SwfdecPlayer *player, const char *name)
   SwfdecAsObject *ret;
   
   ret = g_hash_table_lookup (player->registered_classes, name);
-  g_print ("found registered class %p for %p %s\n", ret, name, name);
   if (ret) {
     SWFDEC_LOG ("found registered class %p for %s", ret, name);
     return ret;
@@ -1937,7 +1936,6 @@ swfdec_player_set_export_class (SwfdecPlayer *player, const char *name, SwfdecAs
   g_return_if_fail (name != NULL);
   g_return_if_fail (object == NULL || SWFDEC_IS_AS_OBJECT (object));
 
-  g_print ("setting class %p for %p %s\n", object, name, name);
   if (object) {
     SWFDEC_LOG ("setting class %p for %s", object, name);
     g_hash_table_insert (player->registered_classes, (gpointer) name, object);
diff --git a/libswfdec/swfdec_player_as.c b/libswfdec/swfdec_player_as.c
index 5636c7a..1b0bf23 100644
--- a/libswfdec/swfdec_player_as.c
+++ b/libswfdec/swfdec_player_as.c
@@ -277,14 +277,12 @@ swfdec_player_object_registerClass (SwfdecAsContext *cx, SwfdecAsObject *object,
 {
   const char *name;
   
-  g_print ("WOOT!\n");
   name = swfdec_as_value_to_string (cx, &argv[0]);
   if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[1])) {
     SWFDEC_AS_VALUE_SET_BOOLEAN (rval, FALSE);
     return;
   }
   
-  g_print ("exporting %p as %s\n", SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]), name);
   swfdec_player_set_export_class (SWFDEC_PLAYER (cx), name, 
       SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]));
   SWFDEC_AS_VALUE_SET_BOOLEAN (rval, TRUE);
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 7d4eb27..1bbb201 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -278,7 +278,6 @@ swfdec_resource_get_export (SwfdecResource *instance, const char *name)
   g_return_val_if_fail (SWFDEC_IS_RESOURCE (instance), NULL);
   g_return_val_if_fail (name != NULL, NULL);
 
-  g_print ("export for %s\n", name);
   return g_hash_table_lookup (instance->exports, name);
 }
 
@@ -288,7 +287,6 @@ swfdec_resource_get_export_name (SwfdecResource *instance, SwfdecCharacter *char
   g_return_val_if_fail (SWFDEC_IS_RESOURCE (instance), NULL);
   g_return_val_if_fail (SWFDEC_IS_CHARACTER (character), NULL);
 
-  g_print ("export name for %u\n", character->id);
   return g_hash_table_lookup (instance->export_names, character);
 }
 
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index e8d4062..10fc011 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -363,7 +363,6 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
 	    SWFDEC_ERROR ("cannot export id %u, no name was given", id);
 	  } else {
 	    SWFDEC_LOG ("exporting %s %u as %s", G_OBJECT_TYPE_NAME (object), id, name);
-	    g_print ("exporting %s %u as %s\n", G_OBJECT_TYPE_NAME (object), id, name);
 	    g_object_ref (object);
 	    swfdec_resource_add_export (resource, object, name); 
 	  }
@@ -397,7 +396,6 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
 	sprite->init_action = swfdec_script_new_from_bits (&bits, name, SWFDEC_AS_CONTEXT (player)->version);
 	g_free (name);
 	if (sprite->init_action) {
-	  g_print ("Executing init action for sprite %u\n", id);
 	  swfdec_player_add_action_script (player, mov, sprite->init_action, 0);
 	}
       }
commit 5bf1eac786f898737cfa60fe05eabb380720c577
Merge: 2fd2b47... d625a49...
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 25 11:37:18 2007 +0200

    Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec/swfdec
    
    Conflicts:
    
    	libswfdec/swfdec_text_field_movie_as.c

commit 2fd2b47130ade099c528e6698a56237e946e84ec
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 25 11:35:22 2007 +0200

    completely reorganize action execution order once again
    
    The testsuite still passes, Yutube still plays.
    Sorry this didn't work in a smaller diff, I kept hacking until it worked. :/

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 823e161..99a1215 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2467,12 +2467,6 @@ swfdec_action_clone_sprite (SwfdecAsContext *cx, guint action, const guint8 *dat
     new_movie = swfdec_movie_duplicate (movie, new_name, depth);
     if (new_movie) {
       SWFDEC_LOG ("duplicated %s as %s to depth %u", movie->name, new_movie->name, new_movie->depth);
-      if (SWFDEC_IS_SPRITE_MOVIE (new_movie)) {
-	g_queue_push_tail (SWFDEC_PLAYER (cx)->init_queue, new_movie);
-	swfdec_movie_queue_script (new_movie, SWFDEC_EVENT_LOAD);
-	swfdec_movie_run_construct (new_movie);
-      }
-      swfdec_movie_initialize (new_movie);
     }
   }
   swfdec_as_stack_pop_n (cx, 3);
diff --git a/libswfdec/swfdec_event.c b/libswfdec/swfdec_event.c
index 03f05fa..c368ae3 100644
--- a/libswfdec/swfdec_event.c
+++ b/libswfdec/swfdec_event.c
@@ -145,56 +145,14 @@ swfdec_event_list_free (SwfdecEventList *list)
   g_free (list);
 }
 
-static const char *
-swfdec_event_list_condition_name (guint conditions)
-{
-  if (conditions & SWFDEC_EVENT_LOAD)
-    return "Load";
-  if (conditions & SWFDEC_EVENT_ENTER)
-    return "Enter";
-  if (conditions & SWFDEC_EVENT_UNLOAD)
-    return "Unload";
-  if (conditions & SWFDEC_EVENT_MOUSE_MOVE)
-    return "MouseMove";
-  if (conditions & SWFDEC_EVENT_MOUSE_DOWN)
-    return "MouseDown";
-  if (conditions & SWFDEC_EVENT_MOUSE_UP)
-    return "MouseUp";
-  if (conditions & SWFDEC_EVENT_KEY_UP)
-    return "KeyUp";
-  if (conditions & SWFDEC_EVENT_KEY_DOWN)
-    return "KeyDown";
-  if (conditions & SWFDEC_EVENT_DATA)
-    return "Data";
-  if (conditions & SWFDEC_EVENT_INITIALIZE)
-    return "Initialize";
-  if (conditions & SWFDEC_EVENT_PRESS)
-    return "Press";
-  if (conditions & SWFDEC_EVENT_RELEASE)
-    return "Release";
-  if (conditions & SWFDEC_EVENT_RELEASE_OUTSIDE)
-    return "ReleaseOutside";
-  if (conditions & SWFDEC_EVENT_ROLL_OVER)
-    return "RollOver";
-  if (conditions & SWFDEC_EVENT_ROLL_OUT)
-    return "RollOut";
-  if (conditions & SWFDEC_EVENT_DRAG_OVER)
-    return "DragOver";
-  if (conditions & SWFDEC_EVENT_DRAG_OUT)
-    return "DragOut";
-  if (conditions & SWFDEC_EVENT_KEY_PRESS)
-    return "KeyPress";
-  if (conditions & SWFDEC_EVENT_CONSTRUCT)
-    return "Construct";
-  return "No Event";
-}
-
+#define N_CONDITIONS 19
 void
 swfdec_event_list_parse (SwfdecEventList *list, SwfdecBits *bits, int version,
     guint conditions, guint8 key, const char *description)
 {
   SwfdecEvent event;
   char *name;
+  guint i;
 
   g_return_if_fail (list != NULL);
   g_return_if_fail (list->refcount == 1);
@@ -202,8 +160,9 @@ swfdec_event_list_parse (SwfdecEventList *list, SwfdecBits *bits, int version,
 
   event.conditions = conditions;
   event.key = key;
-  name = g_strconcat (description, ".", 
-      swfdec_event_list_condition_name (conditions), NULL);
+  i = g_bit_nth_lsf (conditions, -1);
+  name = g_strconcat (description, ".", i < N_CONDITIONS ? 
+      swfdec_event_type_get_name (i) : "???", NULL);
   event.script = swfdec_script_new_from_bits (bits, name, version);
   g_free (name);
   if (event.script) 
@@ -219,7 +178,9 @@ swfdec_event_list_execute (SwfdecEventList *list, SwfdecAsObject *object,
   g_return_if_fail (list != NULL);
   g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
   g_return_if_fail (SWFDEC_IS_SECURITY (sec));
+  g_return_if_fail (condition < N_CONDITIONS);
 
+  condition = (1 << condition);
   /* FIXME: Do we execute all events if the event list is gone already? */
   /* need to ref here because followup code could free all references to the list */
   list = swfdec_event_list_copy (list);
@@ -239,20 +200,18 @@ swfdec_event_list_has_conditions (SwfdecEventList *list, SwfdecAsObject *object,
     guint condition, guint8 key)
 {
   guint i;
-  const char *name;
 
   g_return_val_if_fail (list != NULL, FALSE);
   g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE);
+  g_return_val_if_fail (condition < N_CONDITIONS, FALSE);
 
+  condition = 1 << condition;
   for (i = 0; i < list->events->len; i++) {
     SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
     if ((event->conditions & condition) &&
 	event->key == key)
       return TRUE;
   }
-  name = swfdec_event_type_get_name (condition);
-  if (name)
-    return swfdec_as_object_has_function (object, name);
   return FALSE;
 }
 
diff --git a/libswfdec/swfdec_event.h b/libswfdec/swfdec_event.h
index 3ee42cc..0e51f0a 100644
--- a/libswfdec/swfdec_event.h
+++ b/libswfdec/swfdec_event.h
@@ -29,25 +29,25 @@
 G_BEGIN_DECLS
 
 typedef enum _SwfdecEventType {
-  SWFDEC_EVENT_LOAD		= (1 << 0),
-  SWFDEC_EVENT_ENTER		= (1 << 1),
-  SWFDEC_EVENT_UNLOAD		= (1 << 2),
-  SWFDEC_EVENT_MOUSE_MOVE	= (1 << 3),
-  SWFDEC_EVENT_MOUSE_DOWN	= (1 << 4),
-  SWFDEC_EVENT_MOUSE_UP		= (1 << 5),
-  SWFDEC_EVENT_KEY_UP		= (1 << 6),
-  SWFDEC_EVENT_KEY_DOWN		= (1 << 7),
-  SWFDEC_EVENT_DATA		= (1 << 8),
-  SWFDEC_EVENT_INITIALIZE	= (1 << 9),
-  SWFDEC_EVENT_PRESS		= (1 << 10),
-  SWFDEC_EVENT_RELEASE		= (1 << 11),
-  SWFDEC_EVENT_RELEASE_OUTSIDE	= (1 << 12),
-  SWFDEC_EVENT_ROLL_OVER	= (1 << 13),
-  SWFDEC_EVENT_ROLL_OUT		= (1 << 14),
-  SWFDEC_EVENT_DRAG_OVER	= (1 << 15),
-  SWFDEC_EVENT_DRAG_OUT		= (1 << 16),
-  SWFDEC_EVENT_KEY_PRESS	= (1 << 17),
-  SWFDEC_EVENT_CONSTRUCT	= (1 << 18)
+  SWFDEC_EVENT_LOAD = 0,
+  SWFDEC_EVENT_ENTER = 1,
+  SWFDEC_EVENT_UNLOAD = 2,
+  SWFDEC_EVENT_MOUSE_MOVE = 3,
+  SWFDEC_EVENT_MOUSE_DOWN = 4,
+  SWFDEC_EVENT_MOUSE_UP = 5,
+  SWFDEC_EVENT_KEY_UP = 6,
+  SWFDEC_EVENT_KEY_DOWN = 7,
+  SWFDEC_EVENT_DATA = 8,
+  SWFDEC_EVENT_INITIALIZE = 9,
+  SWFDEC_EVENT_PRESS = 10,
+  SWFDEC_EVENT_RELEASE = 11,
+  SWFDEC_EVENT_RELEASE_OUTSIDE = 12,
+  SWFDEC_EVENT_ROLL_OVER = 13,
+  SWFDEC_EVENT_ROLL_OUT = 14,
+  SWFDEC_EVENT_DRAG_OVER = 15,
+  SWFDEC_EVENT_DRAG_OUT = 16,
+  SWFDEC_EVENT_KEY_PRESS = 17,
+  SWFDEC_EVENT_CONSTRUCT = 18
 } SwfdecEventType;
 
 const char *		swfdec_event_type_get_name	(SwfdecEventType      type);
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index f3b1ee9..1079fbf 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -269,10 +269,7 @@ swfdec_movie_do_remove (SwfdecMovie *movie)
   swfdec_movie_invalidate (movie);
   swfdec_movie_set_depth (movie, -32769 - movie->depth); /* don't ask me why... */
 
-  if (SWFDEC_IS_SPRITE_MOVIE (movie))
-    return !swfdec_movie_queue_script (movie, SWFDEC_EVENT_UNLOAD);
-  else
-    return TRUE;
+  return !swfdec_movie_queue_script (movie, SWFDEC_EVENT_UNLOAD);
 }
 
 /**
@@ -327,8 +324,6 @@ swfdec_movie_destroy (SwfdecMovie *movie)
   }
   /* FIXME: figure out how to handle destruction pre-init/construct.
    * This is just a stop-gap measure to avoid dead movies in those queues */
-  g_queue_remove (player->init_queue, movie);
-  g_queue_remove (player->construct_queue, movie);
   swfdec_player_remove_all_actions (player, movie);
   if (klass->finish_movie)
     klass->finish_movie (movie);
@@ -339,52 +334,46 @@ swfdec_movie_destroy (SwfdecMovie *movie)
   g_object_unref (movie);
 }
 
-/**
- * swfdec_movie_run_init:
- * @movie: a #SwfdecMovie
- *
- * Runs onClipEvent(initialize) on the given @movie.
- */
-void
-swfdec_movie_run_init (SwfdecMovie *movie)
+static void
+swfdec_movie_set_constructor (SwfdecSpriteMovie *movie)
 {
-  SwfdecPlayer *player;
+  SwfdecMovie *mov = SWFDEC_MOVIE (movie);
+  SwfdecAsContext *context = SWFDEC_AS_OBJECT (movie)->context;
+  SwfdecAsObject *constructor = NULL;
 
-  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+  g_assert (mov->resource != NULL);
 
-  player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);
-  g_queue_remove (player->init_queue, movie);
-  swfdec_movie_execute_script (movie, SWFDEC_EVENT_INITIALIZE);
-}
+  if (movie->sprite) {
+    const char *name;
 
-/**
- * swfdec_movie_run_construct:
- * @movie: a #SwfdecMovie
- *
- * Runs the constructors for @movie. This is (in the given order) 
- * onClipEvent(construct), movie.onConstruct and the constructor registered
- * via Object.registerClass.
- **/
-void
-swfdec_movie_run_construct (SwfdecMovie *movie)
-{
-  SwfdecPlayer *player;
-
-  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+    name = swfdec_resource_get_export_name (mov->resource,
+	SWFDEC_CHARACTER (movie->sprite));
+    if (name != NULL) {
+      name = swfdec_as_context_get_string (context, name);
+      constructor = swfdec_player_get_export_class (SWFDEC_PLAYER (context),
+	  name);
+    }
+  }
+  if (constructor == NULL)
+    constructor = SWFDEC_PLAYER (context)->MovieClip;
 
-  player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);
-  g_queue_remove (player->construct_queue, movie);
-  swfdec_movie_execute_script (movie, SWFDEC_EVENT_CONSTRUCT);
-  swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_STR_constructor, 0, NULL, NULL);
+  swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), constructor);
 }
 
 void
-swfdec_movie_execute_script (SwfdecMovie *movie, SwfdecEventType condition)
+swfdec_movie_execute (SwfdecMovie *movie, SwfdecEventType condition)
 {
   const char *name;
 
   g_return_if_fail (SWFDEC_IS_MOVIE (movie));
-  g_return_if_fail (condition != 0);
+
+  /* special cases */
+  if (condition == SWFDEC_EVENT_CONSTRUCT) {
+    swfdec_movie_set_constructor (SWFDEC_SPRITE_MOVIE (movie));
+  } else if (condition == SWFDEC_EVENT_ENTER) {
+    if (movie->will_be_removed)
+      return;
+  }
 
   if (movie->events) {
     swfdec_event_list_execute (movie->events, SWFDEC_AS_OBJECT (movie), 
@@ -395,12 +384,8 @@ swfdec_movie_execute_script (SwfdecMovie *movie, SwfdecEventType condition)
     swfdec_as_object_call_with_security (SWFDEC_AS_OBJECT (movie), 
 	SWFDEC_SECURITY (movie->resource), name, 0, NULL, NULL);
   }
-}
-
-static void
-swfdec_movie_do_execute_script (gpointer movie, gpointer condition)
-{
-  swfdec_movie_execute_script (movie, GPOINTER_TO_UINT (condition));
+  if (condition == SWFDEC_EVENT_CONSTRUCT)
+    swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_STR_constructor, 0, NULL, NULL);
 }
 
 /**
@@ -416,25 +401,40 @@ gboolean
 swfdec_movie_queue_script (SwfdecMovie *movie, SwfdecEventType condition)
 {
   SwfdecPlayer *player;
+  gboolean ret = FALSE;
+  guint importance;
   
   g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), FALSE);
-  g_return_val_if_fail (condition != 0, FALSE);
 
-  if (movie->events) {
-    if (!swfdec_event_list_has_conditions (movie->events, 
-	  SWFDEC_AS_OBJECT (movie), condition, 0))
-      return FALSE;
+  if (!SWFDEC_IS_SPRITE_MOVIE (movie))
+    return FALSE;
+
+  switch (condition) {
+    case SWFDEC_EVENT_INITIALIZE:
+      importance = 0;
+      break;
+    case SWFDEC_EVENT_CONSTRUCT:
+      importance = 1;
+      break;
+    default:
+      importance = 2;
+      break;
+  }
+
+  if (movie->events &&
+      swfdec_event_list_has_conditions (movie->events, 
+	  SWFDEC_AS_OBJECT (movie), condition, 0)) {
+      ret = TRUE;
   } else {
     const char *name = swfdec_event_type_get_name (condition);
-    if (name == NULL ||
-	!swfdec_as_object_has_function (SWFDEC_AS_OBJECT (movie), name))
-      return FALSE;
+    if (name != NULL &&
+	swfdec_as_object_has_function (SWFDEC_AS_OBJECT (movie), name))
+      ret = TRUE;
   }
 
   player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);
-  swfdec_player_add_action (player, movie, swfdec_movie_do_execute_script, 
-      GUINT_TO_POINTER (condition));
-  return TRUE;
+  swfdec_player_add_action (player, movie, condition, importance);
+  return ret;
 }
 
 /**
@@ -1391,6 +1391,12 @@ swfdec_movie_duplicate (SwfdecMovie *movie, const char *name, int depth)
   swfdec_movie_set_static_properties (copy, &movie->original_transform,
       &movie->original_ctrans, movie->original_ratio, movie->clip_depth, 
       movie->blend_mode, movie->events);
+  if (SWFDEC_IS_SPRITE_MOVIE (copy)) {
+    swfdec_movie_queue_script (copy, SWFDEC_EVENT_INITIALIZE);
+    swfdec_movie_queue_script (copy, SWFDEC_EVENT_LOAD);
+    swfdec_movie_execute (copy, SWFDEC_EVENT_CONSTRUCT);
+  }
+  swfdec_movie_initialize (movie);
   return copy;
 }
 
@@ -1413,8 +1419,8 @@ swfdec_movie_new_for_content (SwfdecMovie *parent, const SwfdecContent *content)
       content->has_color_transform ? &content->color_transform : NULL, 
       content->ratio, content->clip_depth, content->blend_mode, content->events);
   if (SWFDEC_IS_SPRITE_MOVIE (movie)) {
-    g_queue_push_tail (player->init_queue, movie);
-    g_queue_push_tail (player->construct_queue, movie);
+    swfdec_movie_queue_script (movie, SWFDEC_EVENT_INITIALIZE);
+    swfdec_movie_queue_script (movie, SWFDEC_EVENT_CONSTRUCT);
     swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);
   }
   swfdec_movie_initialize (movie);
diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h
index d074ba9..d33d53b 100644
--- a/libswfdec/swfdec_movie.h
+++ b/libswfdec/swfdec_movie.h
@@ -240,7 +240,7 @@ void		swfdec_movie_render		(SwfdecMovie *		movie,
 						 cairo_t *		cr, 
 						 const SwfdecColorTransform *trans,
 						 const SwfdecRect *	inval);
-void		swfdec_movie_execute_script	(SwfdecMovie *		movie,
+void		swfdec_movie_execute		(SwfdecMovie *		movie,
 						 SwfdecEventType	condition);
 gboolean      	swfdec_movie_queue_script	(SwfdecMovie *		movie,
   						 SwfdecEventType	condition);
@@ -256,8 +256,6 @@ int		swfdec_movie_compare_depths	(gconstpointer		a,
 SwfdecDepthClass
 		swfdec_depth_classify		(int			depth);
 
-void		swfdec_movie_run_init		(SwfdecMovie *		movie);
-void		swfdec_movie_run_construct	(SwfdecMovie *		movie);
 /* in swfdec_movie_asprops.c */
 gboolean	swfdec_movie_set_asprop		(SwfdecMovie *		movie,
 						 const char *		name,
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 4ff1cb2..7ee4903 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -326,17 +326,23 @@ swfdec_player_remove_timeout (SwfdecPlayer *player, SwfdecTimeout *timeout)
 /*** Actions ***/
 
 typedef struct {
-  gpointer		object;
-  SwfdecActionFunc	func;
-  gpointer		data;
+  SwfdecMovie *		movie;		/* the movie to trigger the action on */
+  SwfdecScript *	script;		/* script to execute or NULL to trigger action */
+  SwfdecEventType	event;		/* the action to trigger */
 } SwfdecPlayerAction;
 
+typedef struct {
+  gpointer             object;
+  SwfdecActionFunc     func;
+  gpointer             data;
+} SwfdecPlayerExternalAction;
+
 /**
- * swfdec_player_add_action:
+ * swfdec_player_add_event:
  * @player: a #SwfdecPlayer
- * @object: object identifying the action
- * @action_func: function to execute
- * @action_data: additional data to pass to @func
+ * @movie: the movie on which to trigger the event
+ * @type: type of the event
+ * @importance: importance of the event
  *
  * Adds an action to the @player. Actions are used by Flash player to solve
  * reentrancy issues. Instead of calling back into the Actionscript engine,
@@ -344,53 +350,91 @@ typedef struct {
  * is calling Actionscript code, you want to do this by using actions.
  **/
 void
-swfdec_player_add_action (SwfdecPlayer *player, gpointer object,
-    SwfdecActionFunc action_func, gpointer action_data)
+swfdec_player_add_action (SwfdecPlayer *player, SwfdecMovie *movie, SwfdecEventType type,
+    guint importance)
 {
   SwfdecPlayerAction *action;
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (action_func != NULL);
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+  g_return_if_fail (importance < SWFDEC_PLAYER_N_ACTION_QUEUES);
 
-  SWFDEC_LOG ("adding action %p %p %p", object, action_func, action_data);
-  action = swfdec_ring_buffer_push (player->actions);
+  SWFDEC_LOG ("adding action %s %u", movie->name, type);
+  action = swfdec_ring_buffer_push (player->actions[importance]);
   if (action == NULL) {
     /* FIXME: limit number of actions to not get inf loops due to scripts? */
-    swfdec_ring_buffer_set_size (player->actions,
-	swfdec_ring_buffer_get_size (player->actions) + 16);
-    action = swfdec_ring_buffer_push (player->actions);
+    if (swfdec_ring_buffer_get_size (player->actions[importance]) >= 256) {
+      /* FIXME: try to remove empty entries first? */
+      swfdec_as_context_abort (SWFDEC_AS_CONTEXT (player), 
+	  "256 levels of recursion were exceeded in one action list.");
+      return;
+    }
+    swfdec_ring_buffer_set_size (player->actions[importance],
+	swfdec_ring_buffer_get_size (player->actions[importance]) + 16);
+    action = swfdec_ring_buffer_push (player->actions[importance]);
     g_assert (action);
   }
-  action->object = object;
-  action->func = action_func;
-  action->data = action_data;
+  action->movie = movie;
+  action->script = NULL;
+  action->event = type;
+}
+
+void
+swfdec_player_add_action_script	(SwfdecPlayer *player, SwfdecMovie *movie,
+    SwfdecScript *script, guint importance)
+{
+  SwfdecPlayerAction *action;
+
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+  g_return_if_fail (script != NULL);
+  g_return_if_fail (importance < SWFDEC_PLAYER_N_ACTION_QUEUES);
+
+  SWFDEC_LOG ("adding action script %s %s", movie->name, script->name);
+  action = swfdec_ring_buffer_push (player->actions[importance]);
+  if (action == NULL) {
+    /* FIXME: limit number of actions to not get inf loops due to scripts? */
+    if (swfdec_ring_buffer_get_size (player->actions[importance]) >= 256) {
+      /* FIXME: try to remove empty entries first? */
+      swfdec_as_context_abort (SWFDEC_AS_CONTEXT (player), 
+	  "256 levels of recursion were exceeded in one action list.");
+      return;
+    }
+    swfdec_ring_buffer_set_size (player->actions[importance],
+	swfdec_ring_buffer_get_size (player->actions[importance]) + 16);
+    action = swfdec_ring_buffer_push (player->actions[importance]);
+    g_assert (action);
+  }
+  action->movie = movie;
+  action->script = script;
 }
 
 /**
  * swfdec_player_remove_all_actions:
  * @player: a #SwfdecPlayer
- * @object: object pointer identifying the actions to be removed
+ * @movie: movie pointer identifying the actions to be removed
  *
- * Removes all actions associated with @object. See swfdec_player_add_action()
- * for details about actions.
+ * Removes all actions associated with @movie that have not yet been executed.
+ * See swfdec_player_add_action() for details about actions.
  **/
 void
-swfdec_player_remove_all_actions (SwfdecPlayer *player, gpointer object)
+swfdec_player_remove_all_actions (SwfdecPlayer *player, SwfdecMovie *movie)
 {
   SwfdecPlayerAction *action;
-  guint i;
+  guint i, j;
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
-  g_return_if_fail (object != NULL);
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
 
-  for (i = 0; i < swfdec_ring_buffer_get_n_elements (player->actions); i++) {
-    action = swfdec_ring_buffer_peek_nth (player->actions, i);
+  for (i = 0; i < SWFDEC_PLAYER_N_ACTION_QUEUES; i++) {
+    for (j = 0; j < swfdec_ring_buffer_get_n_elements (player->actions[i]); j++) {
+      action = swfdec_ring_buffer_peek_nth (player->actions[i], j);
 
-    if (action->object == object) {
-      SWFDEC_LOG ("removing action %p %p %p", 
-	  action->object, action->func, action->data);
-      action->object = NULL;
+      if (action->movie == movie) {
+	SWFDEC_LOG ("removing action %p %u", 
+	    action->movie, action->event);
+	action->movie = NULL;
+      }
     }
   }
 }
@@ -399,35 +443,32 @@ static gboolean
 swfdec_player_do_action (SwfdecPlayer *player)
 {
   SwfdecPlayerAction *action;
-  SwfdecMovie *movie;
+  guint i;
 
-  movie = g_queue_peek_head (player->init_queue);
-  if (movie) {
-    swfdec_movie_run_init (movie);
-    return TRUE;
-  }
-  movie = g_queue_peek_head (player->construct_queue);
-  if (movie) {
-    swfdec_movie_run_construct (movie);
-    return TRUE;
+  for (i = 0; i < SWFDEC_PLAYER_N_ACTION_QUEUES; i++) {
+    do {
+      action = swfdec_ring_buffer_pop (player->actions[i]);
+      if (action == NULL)
+	break;
+    } while (action->movie == NULL); /* skip removed actions */
+    if (action) {
+      if (action->script) {
+	swfdec_as_object_run_with_security (SWFDEC_AS_OBJECT (action->movie), 
+	  action->script, SWFDEC_SECURITY (action->movie->resource));
+      } else {
+	swfdec_movie_execute (action->movie, action->event);
+      }
+      return TRUE;
+    }
   }
-  do {
-    action = swfdec_ring_buffer_pop (player->actions);
-    if (action == NULL)
-      return FALSE;
-  } while (action->object == NULL); /* skip removed actions */
-
-  SWFDEC_LOG ("executing action %p %p %p", 
-      action->object, action->func, action->data);
-  action->func (action->object, action->data);
 
-  return TRUE;
+  return FALSE;
 }
 
 static void
 swfdec_player_perform_external_actions (SwfdecPlayer *player)
 {
-  SwfdecPlayerAction *action;
+  SwfdecPlayerExternalAction *action;
   guint i;
 
   /* remove timeout if it exists - do this before executing stuff below */
@@ -463,7 +504,7 @@ void
 swfdec_player_add_external_action (SwfdecPlayer *player, gpointer object, 
     SwfdecActionFunc action_func, gpointer action_data)
 {
-  SwfdecPlayerAction *action;
+  SwfdecPlayerExternalAction *action;
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
   g_return_if_fail (object != NULL);
@@ -502,7 +543,7 @@ swfdec_player_add_external_action (SwfdecPlayer *player, gpointer object,
 void
 swfdec_player_remove_all_external_actions (SwfdecPlayer *player, gpointer object)
 {
-  SwfdecPlayerAction *action;
+  SwfdecPlayerExternalAction *action;
   guint i;
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
@@ -768,6 +809,7 @@ static void
 swfdec_player_dispose (GObject *object)
 {
   SwfdecPlayer *player = SWFDEC_PLAYER (object);
+  guint i;
 
   swfdec_player_stop_all_sounds (player);
   g_hash_table_destroy (player->registered_classes);
@@ -785,17 +827,24 @@ swfdec_player_dispose (GObject *object)
   swfdec_player_remove_all_external_actions (player, player);
 #ifndef G_DISABLE_ASSERT
   {
-    SwfdecPlayerAction *action;
+    SwfdecPlayerExternalAction *action;
     while ((action = swfdec_ring_buffer_pop (player->external_actions)) != NULL) {
       g_assert (action->object == NULL); /* skip removed actions */
     }
-    while ((action = swfdec_ring_buffer_pop (player->actions)) != NULL) {
-      g_assert (action->object == NULL); /* skip removed actions */
+  }
+  {
+    SwfdecPlayerAction *action;
+    for (i = 0; i < SWFDEC_PLAYER_N_ACTION_QUEUES; i++) {
+      while ((action = swfdec_ring_buffer_pop (player->actions[i])) != NULL) {
+	g_assert (action->movie == NULL); /* skip removed actions */
+      }
     }
   }
 #endif
   swfdec_ring_buffer_free (player->external_actions);
-  swfdec_ring_buffer_free (player->actions);
+  for (i = 0; i < SWFDEC_PLAYER_N_ACTION_QUEUES; i++) {
+    swfdec_ring_buffer_free (player->actions[i]);
+  }
   g_assert (player->movies == NULL);
   g_assert (player->audio == NULL);
   if (player->external_timeout.callback)
@@ -807,10 +856,6 @@ swfdec_player_dispose (GObject *object)
   g_list_free (player->intervals);
   g_list_free (player->load_objects);
   player->intervals = NULL;
-  g_assert (g_queue_is_empty (player->init_queue));
-  g_assert (g_queue_is_empty (player->construct_queue));
-  g_queue_free (player->init_queue);
-  g_queue_free (player->construct_queue);
   swfdec_cache_unref (player->cache);
   if (player->system) {
     g_object_unref (player->system);
@@ -1232,7 +1277,10 @@ gboolean
 swfdec_player_lock (SwfdecPlayer *player)
 {
   g_return_val_if_fail (SWFDEC_IS_PLAYER (player), FALSE);
-  g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[0]) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[1]) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[2]) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[3]) == 0);
 
   if (swfdec_as_context_is_aborted (SWFDEC_AS_CONTEXT (player)))
     return FALSE;
@@ -1261,7 +1309,10 @@ swfdec_player_unlock (SwfdecPlayer *player)
   SwfdecAsContext *context;
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
-  g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[0]) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[1]) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[2]) == 0);
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions[3]) == 0);
   context = SWFDEC_AS_CONTEXT (player);
   g_return_if_fail (context->state != SWFDEC_AS_CONTEXT_INTERRUPTED);
 
@@ -1516,11 +1567,15 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
 static void
 swfdec_player_init (SwfdecPlayer *player)
 {
+  guint i;
+
   player->system = swfdec_system_new ();
   player->registered_classes = g_hash_table_new (g_direct_hash, g_direct_equal);
 
-  player->actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 16);
-  player->external_actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 8);
+  for (i = 0; i < SWFDEC_PLAYER_N_ACTION_QUEUES; i++) {
+    player->actions[i] = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 16);
+  }
+  player->external_actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerExternalAction, 8);
   player->cache = swfdec_cache_new (50 * 1024 * 1024); /* 100 MB */
   player->bgcolor = SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF);
 
@@ -1529,8 +1584,6 @@ swfdec_player_init (SwfdecPlayer *player)
   player->mouse_visible = TRUE;
   player->mouse_cursor = SWFDEC_MOUSE_CURSOR_NORMAL;
   player->iterate_timeout.callback = swfdec_player_iterate;
-  player->init_queue = g_queue_new ();
-  player->construct_queue = g_queue_new ();
   player->stage_width = -1;
   player->stage_height = -1;
 }
@@ -1836,7 +1889,7 @@ swfdec_player_initialize (SwfdecPlayer *player, guint version,
   player->internal_height = player->stage_height >= 0 ? (guint) player->stage_height : player->height;
   player->initialized = TRUE;
   if (rate) {
-    player->iterate_timeout.timestamp = player->time;
+    player->iterate_timeout.timestamp = player->time + SWFDEC_TICKS_PER_SECOND * 256 / player->rate;
     swfdec_player_add_timeout (player, &player->iterate_timeout);
     SWFDEC_LOG ("initialized iterate timeout %p to %"G_GUINT64_FORMAT" (now %"G_GUINT64_FORMAT")",
 	&player->iterate_timeout, player->iterate_timeout.timestamp, player->time);
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index 3baa77f..3f443c0 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -23,6 +23,7 @@
 #include <libswfdec/swfdec_player.h>
 #include <libswfdec/swfdec_as_context.h>
 #include <libswfdec/swfdec_audio.h>
+#include <libswfdec/swfdec_event.h>
 #include <libswfdec/swfdec_rect.h>
 #include <libswfdec/swfdec_ringbuffer.h>
 #include <libswfdec/swfdec_security.h>
@@ -47,6 +48,8 @@ struct _SwfdecTimeout {
   void			(* free)		(SwfdecTimeout *advance);
 };
 
+#define SWFDEC_PLAYER_N_ACTION_QUEUES 4
+
 struct _SwfdecPlayer
 {
   SwfdecAsContext	context;
@@ -118,13 +121,11 @@ struct _SwfdecPlayer
   SwfdecTimeout		iterate_timeout;      	/* callback for iterating */
   GTimer *		runtime;		/* for checking how long we've been running */
   gulong		max_runtime;		/* maximum number of seconds the player may run */
-  /* iterating */
-  GList *		movies;			/* list of all moveis that want to be iterated */
-  SwfdecRingBuffer *	actions;		/* all actions we've queued up so far */
   SwfdecRingBuffer *	external_actions;     	/* external actions we've queued up, like resize or loader stuff */
   SwfdecTimeout		external_timeout;      	/* callback for iterating */
-  GQueue *		init_queue;		/* all movies that require an init event */
-  GQueue *		construct_queue;      	/* all movies that require an construct event */
+  /* iterating */
+  GList *		movies;			/* list of all movies that want to be iterated */
+  SwfdecRingBuffer *	actions[SWFDEC_PLAYER_N_ACTION_QUEUES]; /* all actions we've queued up so far */
 };
 
 struct _SwfdecPlayerClass
@@ -182,11 +183,15 @@ void		swfdec_player_remove_all_external_actions
 						(SwfdecPlayer *      	player,
 						 gpointer		object);
 void		swfdec_player_add_action	(SwfdecPlayer *		player,
-						 gpointer		object,
-						 SwfdecActionFunc   	action_func,
-						 gpointer		action_data);
+						 SwfdecMovie *		movie,
+						 SwfdecEventType	type,
+						 guint			importance);
+void		swfdec_player_add_action_script	(SwfdecPlayer *		player,
+						 SwfdecMovie *		movie,
+						 SwfdecScript *		script,
+						 guint			importance);
 void		swfdec_player_remove_all_actions (SwfdecPlayer *      	player,
-						 gpointer		object);
+						 SwfdecMovie *		movie);
 
 void		swfdec_player_set_drag_movie	(SwfdecPlayer *		player,
 						 SwfdecMovie *		drag,
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 7e953d5..7d4eb27 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -78,6 +78,8 @@ swfdec_resource_loader_target_image (SwfdecResource *instance)
     SwfdecSwfDecoder *dec = SWFDEC_SWF_DECODER (instance->decoder);
 
     movie->sprite = dec->main_sprite;
+    g_assert (movie->sprite->parse_frame > 0);
+    movie->n_frames = movie->sprite->n_frames;
     swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
     swfdec_resource_check_rights (instance);
   } else if (SWFDEC_IS_FLV_DECODER (instance->decoder)) {
@@ -85,6 +87,7 @@ swfdec_resource_loader_target_image (SwfdecResource *instance)
   } else {
     g_assert_not_reached ();
   }
+  swfdec_movie_initialize (SWFDEC_MOVIE (movie));
 }
 
 static void
@@ -189,16 +192,12 @@ static void
 swfdec_resource_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loader)
 {
   SwfdecResource *resource = SWFDEC_RESOURCE (target);
-  SwfdecMovie *movie;
 
   if (resource->initial)
     return;
 
   swfdec_resource_open (resource, loader);
   swfdec_resource_parse (resource, loader);
-  /* FIXME: This someow initializes the first frame here. Is this ok? */
-  movie = SWFDEC_MOVIE (resource->movie);
-  swfdec_movie_initialize (movie);
 }
 
 static void
diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index 6b358f1..51a9b0f 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -172,6 +172,7 @@ swfdec_sprite_create_movie (SwfdecGraphic *graphic, gsize *size)
   SwfdecSpriteMovie *ret = g_object_new (SWFDEC_TYPE_SPRITE_MOVIE, NULL);
 
   ret->sprite = SWFDEC_SPRITE (graphic);
+  ret->n_frames = ret->sprite->n_frames;
   *size = sizeof (SwfdecSpriteMovie);
 
   return SWFDEC_MOVIE (ret);
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index fb39bb6..e8d4062 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -52,13 +52,6 @@ swfdec_sprite_movie_remove_child (SwfdecMovie *movie, int depth)
   return TRUE;
 }
 
-static void
-swfdec_sprite_movie_run_script (gpointer movie, gpointer data)
-{
-  swfdec_as_object_run_with_security (movie, data, 
-      SWFDEC_SECURITY (SWFDEC_MOVIE (movie)->resource));
-}
-
 static int
 swfdec_get_clipeventflags (SwfdecMovie *movie, SwfdecBits * bits)
 {
@@ -213,15 +206,16 @@ swfdec_sprite_movie_perform_place (SwfdecSpriteMovie *movie, SwfdecBits *bits, g
       SwfdecBits action_bits;
 
       swfdec_bits_init_bits (&action_bits, bits, length);
-      if (event_flags & SWFDEC_EVENT_KEY_PRESS)
+      if (event_flags & (1<<SWFDEC_EVENT_KEY_PRESS))
 	key_code = swfdec_bits_get_u8 (&action_bits);
       else
 	key_code = 0;
 
       SWFDEC_INFO ("clip event with flags 0x%X, key code %d", event_flags, key_code);
 #define SWFDEC_IMPLEMENTED_EVENTS \
-  (SWFDEC_EVENT_LOAD | SWFDEC_EVENT_UNLOAD | SWFDEC_EVENT_ENTER | SWFDEC_EVENT_INITIALIZE | SWFDEC_EVENT_CONSTRUCT | \
-   SWFDEC_EVENT_MOUSE_DOWN | SWFDEC_EVENT_MOUSE_MOVE | SWFDEC_EVENT_MOUSE_UP)
+  ((1<< SWFDEC_EVENT_LOAD) | (1<<SWFDEC_EVENT_UNLOAD) | (1<<SWFDEC_EVENT_ENTER) | \
+   (1<< SWFDEC_EVENT_INITIALIZE) | (1<<SWFDEC_EVENT_CONSTRUCT) | \
+   (1<< SWFDEC_EVENT_MOUSE_DOWN) | (1<<SWFDEC_EVENT_MOUSE_MOVE) | (1<<SWFDEC_EVENT_MOUSE_UP))
       if (event_flags & ~SWFDEC_IMPLEMENTED_EVENTS) {
 	SWFDEC_ERROR ("using non-implemented clip events %u", event_flags & ~SWFDEC_IMPLEMENTED_EVENTS);
       }
@@ -266,11 +260,9 @@ swfdec_sprite_movie_perform_place (SwfdecSpriteMovie *movie, SwfdecBits *bits, g
     cur = swfdec_movie_new (player, depth, mov, mov->resource, graphic, name);
     swfdec_movie_set_static_properties (cur, has_transform ? &transform : NULL, 
 	has_ctrans ? &ctrans : NULL, ratio, clip_depth, blend_mode, events);
-    if (SWFDEC_IS_SPRITE_MOVIE (cur)) {
-      g_queue_push_tail (player->init_queue, cur);
-      g_queue_push_tail (player->construct_queue, cur);
-      swfdec_movie_queue_script (cur, SWFDEC_EVENT_LOAD);
-    }
+    swfdec_movie_queue_script (cur, SWFDEC_EVENT_INITIALIZE);
+    swfdec_movie_queue_script (cur, SWFDEC_EVENT_CONSTRUCT);
+    swfdec_movie_queue_script (cur, SWFDEC_EVENT_LOAD);
     swfdec_movie_initialize (cur);
   }
 
@@ -316,7 +308,7 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
 	SwfdecScript *script = swfdec_swf_decoder_get_script (
 	    SWFDEC_SWF_DECODER (mov->resource->decoder), buffer->data);
 	g_assert (script);
-	swfdec_player_add_action (player, mov, swfdec_sprite_movie_run_script, script);
+	swfdec_player_add_action_script (player, mov, script, 2);
       }
       return TRUE;
     case SWFDEC_TAG_PLACEOBJECT2:
@@ -406,8 +398,7 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
 	g_free (name);
 	if (sprite->init_action) {
 	  g_print ("Executing init action for sprite %u\n", id);
-	  swfdec_as_object_run_with_security (SWFDEC_AS_OBJECT (mov), 
-	      sprite->init_action, SWFDEC_SECURITY (mov->resource));
+	  swfdec_player_add_action_script (player, mov, sprite->init_action, 0);
 	}
       }
       return TRUE;
@@ -571,47 +562,20 @@ swfdec_sprite_movie_dispose (GObject *object)
 }
 
 static void
-swfdec_sprite_movie_do_enter_frame (gpointer movie, gpointer unused)
+swfdec_sprite_movie_init_movie (SwfdecMovie *movie)
 {
-  if (SWFDEC_MOVIE (movie)->will_be_removed)
-    return;
-  swfdec_movie_execute_script (movie, SWFDEC_EVENT_ENTER);
+  swfdec_sprite_movie_goto (SWFDEC_SPRITE_MOVIE (movie), 1);
 }
 
 static void
-swfdec_sprite_movie_do_init_movie (SwfdecSpriteMovie *movie)
+swfdec_sprite_movie_add (SwfdecAsObject *object)
 {
-  SwfdecMovie *mov = SWFDEC_MOVIE (movie);
-  SwfdecAsContext *context = SWFDEC_AS_OBJECT (movie)->context;
-  SwfdecAsObject *constructor = NULL;
-
-  g_assert (mov->resource != NULL);
-
-  if (movie->sprite) {
-    const char *name;
-
-    g_assert (movie->sprite->parse_frame > 0);
-    movie->n_frames = movie->sprite->n_frames;
-    name = swfdec_resource_get_export_name (mov->resource,
-	SWFDEC_CHARACTER (movie->sprite));
-    if (name != NULL) {
-      name = swfdec_as_context_get_string (context, name);
-      constructor = swfdec_player_get_export_class (SWFDEC_PLAYER (context),
-	  name);
-    }
-    g_print ("setting constructor for %u to %s %p\n", SWFDEC_CHARACTER (movie->sprite)->id, name, constructor);
-  }
-  if (constructor == NULL)
-    constructor = SWFDEC_PLAYER (context)->MovieClip;
+  SwfdecPlayer *player = SWFDEC_PLAYER (object->context);
 
-  swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), constructor);
-}
+  if (player->MovieClip)
+    swfdec_as_object_set_constructor (object, player->MovieClip);
 
-static void
-swfdec_sprite_movie_init_movie (SwfdecMovie *movie)
-{
-  swfdec_sprite_movie_do_init_movie (SWFDEC_SPRITE_MOVIE (movie)); 
-  swfdec_sprite_movie_goto (SWFDEC_SPRITE_MOVIE (movie), 1);
+  SWFDEC_AS_OBJECT_CLASS (swfdec_sprite_movie_parent_class)->add (object);
 }
 
 static void
@@ -624,10 +588,7 @@ swfdec_sprite_movie_iterate (SwfdecMovie *mov)
   if (mov->will_be_removed)
     return;
 
-  if (movie->sprite != NULL && movie->frame == 0)
-    swfdec_sprite_movie_do_init_movie (movie);
-
-  swfdec_player_add_action (player, movie, swfdec_sprite_movie_do_enter_frame, NULL);
+  swfdec_player_add_action (player, mov, SWFDEC_EVENT_ENTER, 2);
   if (movie->playing && movie->sprite != NULL) {
     if (movie->frame == movie->n_frames)
       goto_frame = 1;
@@ -740,6 +701,7 @@ swfdec_sprite_movie_class_init (SwfdecSpriteMovieClass * g_class)
 
   object_class->dispose = swfdec_sprite_movie_dispose;
 
+  asobject_class->add = swfdec_sprite_movie_add;
   asobject_class->mark = swfdec_sprite_movie_mark;
 
   movie_class->init_movie = swfdec_sprite_movie_init_movie;
diff --git a/libswfdec/swfdec_sprite_movie_as.c b/libswfdec/swfdec_sprite_movie_as.c
index 301f2c0..b751327 100644
--- a/libswfdec/swfdec_sprite_movie_as.c
+++ b/libswfdec/swfdec_sprite_movie_as.c
@@ -417,12 +417,6 @@ swfdec_sprite_movie_duplicateMovieClip (SwfdecAsContext *cx, SwfdecAsObject *obj
   if (new == NULL)
     return;
   swfdec_sprite_movie_copy_props (new, movie);
-  if (SWFDEC_IS_SPRITE_MOVIE (new)) {
-    g_queue_push_tail (SWFDEC_PLAYER (cx)->init_queue, new);
-    swfdec_movie_queue_script (new, SWFDEC_EVENT_LOAD);
-    swfdec_movie_run_construct (new);
-  }
-  swfdec_movie_initialize (new);
   SWFDEC_LOG ("duplicated %s as %s to depth %u", movie->name, new->name, new->depth);
   SWFDEC_AS_VALUE_SET_OBJECT (rval, SWFDEC_AS_OBJECT (new));
 }
commit 14cf3c497de4520408aedb01fff9451f02c98e14
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 24 15:27:21 2007 +0200

    make root actions be enqueued like normal tags
    
    This breaks Youtube \o/

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index c167bcb..4ff1cb2 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1860,8 +1860,9 @@ swfdec_player_get_export_class (SwfdecPlayer *player, const char *name)
   SwfdecAsObject *ret;
   
   ret = g_hash_table_lookup (player->registered_classes, name);
+  g_print ("found registered class %p for %p %s\n", ret, name, name);
   if (ret) {
-    SWFDEC_LOG ("found registered class %p for %s\n", ret, name);
+    SWFDEC_LOG ("found registered class %p for %s", ret, name);
     return ret;
   }
   return player->MovieClip;
@@ -1883,8 +1884,9 @@ swfdec_player_set_export_class (SwfdecPlayer *player, const char *name, SwfdecAs
   g_return_if_fail (name != NULL);
   g_return_if_fail (object == NULL || SWFDEC_IS_AS_OBJECT (object));
 
+  g_print ("setting class %p for %p %s\n", object, name, name);
   if (object) {
-    SWFDEC_LOG ("setting class %p for %s\n", object, name);
+    SWFDEC_LOG ("setting class %p for %s", object, name);
     g_hash_table_insert (player->registered_classes, (gpointer) name, object);
   } else {
     g_hash_table_remove (player->registered_classes, name);
diff --git a/libswfdec/swfdec_player_as.c b/libswfdec/swfdec_player_as.c
index 1b0bf23..5636c7a 100644
--- a/libswfdec/swfdec_player_as.c
+++ b/libswfdec/swfdec_player_as.c
@@ -277,12 +277,14 @@ swfdec_player_object_registerClass (SwfdecAsContext *cx, SwfdecAsObject *object,
 {
   const char *name;
   
+  g_print ("WOOT!\n");
   name = swfdec_as_value_to_string (cx, &argv[0]);
   if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[1])) {
     SWFDEC_AS_VALUE_SET_BOOLEAN (rval, FALSE);
     return;
   }
   
+  g_print ("exporting %p as %s\n", SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]), name);
   swfdec_player_set_export_class (SWFDEC_PLAYER (cx), name, 
       SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]));
   SWFDEC_AS_VALUE_SET_BOOLEAN (rval, TRUE);
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index d9be02e..7e953d5 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -240,7 +240,8 @@ static void
 swfdec_resource_init (SwfdecResource *instance)
 {
   instance->exports = g_hash_table_new (swfdec_str_case_hash, swfdec_str_case_equal);
-  instance->export_names = g_hash_table_new (g_direct_hash, g_direct_equal);
+  instance->export_names = g_hash_table_new_full (g_direct_hash, g_direct_equal, 
+      g_object_unref, g_free);
 }
 
 SwfdecResource *
@@ -278,6 +279,7 @@ swfdec_resource_get_export (SwfdecResource *instance, const char *name)
   g_return_val_if_fail (SWFDEC_IS_RESOURCE (instance), NULL);
   g_return_val_if_fail (name != NULL, NULL);
 
+  g_print ("export for %s\n", name);
   return g_hash_table_lookup (instance->exports, name);
 }
 
@@ -287,11 +289,13 @@ swfdec_resource_get_export_name (SwfdecResource *instance, SwfdecCharacter *char
   g_return_val_if_fail (SWFDEC_IS_RESOURCE (instance), NULL);
   g_return_val_if_fail (SWFDEC_IS_CHARACTER (character), NULL);
 
+  g_print ("export name for %u\n", character->id);
   return g_hash_table_lookup (instance->export_names, character);
 }
 
-static void
-swfdec_resource_add_export (SwfdecResource *instance, SwfdecCharacter *character, const char *name)
+/* NB: Takes ownership of name and character */
+void
+swfdec_resource_add_export (SwfdecResource *instance, SwfdecCharacter *character, char *name)
 {
   g_return_if_fail (SWFDEC_IS_RESOURCE (instance));
   g_return_if_fail (SWFDEC_IS_CHARACTER (character));
@@ -301,41 +305,3 @@ swfdec_resource_add_export (SwfdecResource *instance, SwfdecCharacter *character
   g_hash_table_insert (instance->export_names, character, (char *) name);
 }
 
-void
-swfdec_resource_advance (SwfdecResource *instance)
-{
-  SwfdecSwfDecoder *s;
-  GArray *array;
-  guint i;
-
-  g_return_if_fail (SWFDEC_IS_RESOURCE (instance));
-
-  s = SWFDEC_SWF_DECODER (instance->decoder);
-  SWFDEC_LOG ("performing actions for frame %u", instance->parse_frame);
-  if (s->root_actions) {
-    array = s->root_actions[instance->parse_frame];
-  } else {
-    array = NULL;
-  }
-  instance->parse_frame++;
-  if (array == NULL)
-    return;
-  for (i = 0; i < array->len; i++) {
-    SwfdecRootAction *action = &g_array_index (array, SwfdecRootAction, i);
-    switch (action->type) {
-      case SWFDEC_ROOT_ACTION_INIT_SCRIPT:
-	swfdec_as_object_run_with_security (SWFDEC_AS_OBJECT (instance->movie), 
-	    action->data, SWFDEC_SECURITY (instance));
-	break;
-      case SWFDEC_ROOT_ACTION_EXPORT:
-	{
-	  SwfdecRootExportData *data = action->data;
-	  swfdec_resource_add_export (instance, data->character, data->name);
-	}
-	break;
-      default:
-	g_assert_not_reached ();
-    }
-  }
-}
-
diff --git a/libswfdec/swfdec_resource.h b/libswfdec/swfdec_resource.h
index c5fd4e2..1a38ea0 100644
--- a/libswfdec/swfdec_resource.h
+++ b/libswfdec/swfdec_resource.h
@@ -63,8 +63,9 @@ SwfdecResource *swfdec_resource_new			(SwfdecLoader *		loader,
 void		swfdec_resource_set_movie		(SwfdecResource *	resource,
 							 SwfdecSpriteMovie *	movie);
 
-void		swfdec_resource_advance			(SwfdecResource *	instance);
-
+void		swfdec_resource_add_export		(SwfdecResource *	instance,
+							 SwfdecCharacter *	character,
+							 char *			name);
 gpointer	swfdec_resource_get_export		(SwfdecResource *	root,
 							 const char *		name);
 const char *	swfdec_resource_get_export_name    	(SwfdecResource *	root,
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index ca2d962..fb39bb6 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -33,7 +33,7 @@
 #include "swfdec_graphic_movie.h"
 #include "swfdec_player_internal.h"
 #include "swfdec_ringbuffer.h"
-#include "swfdec_script.h"
+#include "swfdec_script_internal.h"
 #include "swfdec_sprite.h"
 #include "swfdec_resource.h"
 #include "swfdec_tag.h"
@@ -298,7 +298,7 @@ swfdec_sprite_movie_start_sound (SwfdecMovie *movie, SwfdecBits *bits)
 
 static gboolean
 swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, SwfdecBuffer *buffer,
-    gboolean skip_scripts)
+    gboolean skip_scripts, gboolean first_time)
 {
   SwfdecMovie *mov = SWFDEC_MOVIE (movie);
   SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (mov)->context);
@@ -347,6 +347,70 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
 	SWFDEC_ERROR ("too many ShowFrame tags");
       }
       return FALSE;
+    case SWFDEC_TAG_EXPORTASSETS:
+      {
+	SwfdecResource *resource = swfdec_movie_get_own_resource (mov);
+	guint i, count;
+
+	g_assert (resource); /* must hold, ExportAssets can only be in root movies */
+	if (!first_time)
+	  return TRUE;
+	count = swfdec_bits_get_u16 (&bits);
+	SWFDEC_LOG ("exporting %u assets", count);
+	for (i = 0; i < count && swfdec_bits_left (&bits); i++) {
+	  guint id;
+	  SwfdecCharacter *object;
+	  char *name;
+	  id = swfdec_bits_get_u16 (&bits);
+	  object = swfdec_swf_decoder_get_character (SWFDEC_SWF_DECODER (resource->decoder), id);
+	  name = swfdec_bits_get_string_with_version (&bits, SWFDEC_AS_CONTEXT (player)->version);
+	  if (object == NULL) {
+	    SWFDEC_ERROR ("cannot export id %u as %s, id wasn't found", id, name);
+	    g_free (name);
+	  } else if (name == NULL) {
+	    SWFDEC_ERROR ("cannot export id %u, no name was given", id);
+	  } else {
+	    SWFDEC_LOG ("exporting %s %u as %s", G_OBJECT_TYPE_NAME (object), id, name);
+	    g_print ("exporting %s %u as %s\n", G_OBJECT_TYPE_NAME (object), id, name);
+	    g_object_ref (object);
+	    swfdec_resource_add_export (resource, object, name); 
+	  }
+	}
+      }
+      return TRUE;
+    case SWFDEC_TAG_DOINITACTION:
+      if (!first_time)
+	return TRUE;
+      if (!swfdec_movie_get_own_resource (mov)) {
+	SWFDEC_FIXME ("behavior of init actions in DefineSprite untested");
+      }
+      {
+	guint id;
+	SwfdecSprite *sprite;
+	char *name;
+
+	id = swfdec_bits_get_u16 (&bits);
+	SWFDEC_LOG ("InitAction");
+	SWFDEC_LOG ("  id = %u", id);
+	sprite = swfdec_swf_decoder_get_character (SWFDEC_SWF_DECODER (mov->resource->decoder), id);
+	if (!SWFDEC_IS_SPRITE (sprite)) {
+	  SWFDEC_ERROR ("character %u is not a sprite", id);
+	  return TRUE;
+	}
+	if (sprite->init_action != NULL) {
+	  SWFDEC_ERROR ("sprite %u already has an init action", id);
+	  return TRUE;
+	}
+	name = g_strdup_printf ("InitAction %u", id);
+	sprite->init_action = swfdec_script_new_from_bits (&bits, name, SWFDEC_AS_CONTEXT (player)->version);
+	g_free (name);
+	if (sprite->init_action) {
+	  g_print ("Executing init action for sprite %u\n", id);
+	  swfdec_as_object_run_with_security (SWFDEC_AS_OBJECT (mov), 
+	      sprite->init_action, SWFDEC_SECURITY (mov->resource));
+	}
+      }
+      return TRUE;
     default:
       g_assert_not_reached ();
       return FALSE;
@@ -437,15 +501,18 @@ swfdec_sprite_movie_goto (SwfdecSpriteMovie *movie, guint goto_frame)
   }
   while (n) {
     guint tag;
+    gboolean first_time;
     SwfdecBuffer *buffer;
-    SwfdecResource *resource = swfdec_movie_get_own_resource (mov);
-    /* FIXME: These actions should probably just be added to the action queue */
-    if (resource && resource->parse_frame <= movie->frame)
-      swfdec_resource_advance (resource);
     if (!swfdec_sprite_get_action (movie->sprite, movie->next_action, &tag, &buffer))
       break;
     movie->next_action++;
-    if (!swfdec_sprite_movie_perform_one_action (movie, tag, buffer, n > 1))
+    if (movie->next_action > movie->max_action) {
+      first_time = TRUE;
+      movie->max_action = movie->next_action;
+    } else {
+      first_time = FALSE;
+    }
+    if (!swfdec_sprite_movie_perform_one_action (movie, tag, buffer, n > 1, first_time))
       n--;
   }
   /* now try to copy eventual movies */
@@ -532,6 +599,7 @@ swfdec_sprite_movie_do_init_movie (SwfdecSpriteMovie *movie)
       constructor = swfdec_player_get_export_class (SWFDEC_PLAYER (context),
 	  name);
     }
+    g_print ("setting constructor for %u to %s %p\n", SWFDEC_CHARACTER (movie->sprite)->id, name, constructor);
   }
   if (constructor == NULL)
     constructor = SWFDEC_PLAYER (context)->MovieClip;
@@ -709,6 +777,7 @@ swfdec_sprite_movie_unload (SwfdecSpriteMovie *movie)
   movie->frame = 0;
   movie->n_frames = 0;
   movie->next_action = 0;
+  movie->max_action = 0;
   movie->sprite = NULL;
 }
 
diff --git a/libswfdec/swfdec_sprite_movie.h b/libswfdec/swfdec_sprite_movie.h
index 0573d92..fa15e7b 100644
--- a/libswfdec/swfdec_sprite_movie.h
+++ b/libswfdec/swfdec_sprite_movie.h
@@ -44,6 +44,7 @@ struct _SwfdecSpriteMovie
 
   /* frame information */
   guint			next_action;	/* next action in sprite to perform */
+  guint			max_action;	/* next action in sprite tthat has never ben executed (used to detect first-time execution) */
   guint			frame;		/* current frame */
   guint			n_frames;	/* amount of frames */
   gboolean		playing;	/* TRUE if the movie automatically advances */
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index a864ecb..1e4e247 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.c
@@ -54,38 +54,6 @@ static void
 swfdec_swf_decoder_dispose (GObject *object)
 {
   SwfdecSwfDecoder *s = SWFDEC_SWF_DECODER (object);
-  guint i,j;
-
-  if (s->root_actions) {
-    for (i = 0; i < s->main_sprite->n_frames; i++) {
-      GArray *array = s->root_actions[i];
-      if (array) {
-	for (j = 0; j < array->len; j++) {
-	  SwfdecRootAction *action = &g_array_index (array, SwfdecRootAction, j);
-
-	  switch (action->type) {
-	    case SWFDEC_ROOT_ACTION_EXPORT:
-	      {
-		SwfdecRootExportData *data = action->data;
-		g_free (data->name);
-		g_object_unref (data->character);
-		g_free (data);
-	      }
-	      break;
-	    case SWFDEC_ROOT_ACTION_INIT_SCRIPT:
-	      swfdec_script_unref (action->data);
-	      break;
-	    default:
-	      g_assert_not_reached ();
-	      break;
-	  }
-	}
-	g_array_free (array, TRUE);
-      }
-    }
-    g_free (s->root_actions);
-    s->root_actions = NULL;
-  }
 
   g_hash_table_destroy (s->characters);
   g_object_unref (s->main_sprite);
@@ -446,32 +414,6 @@ swfdec_swf_decoder_create_character (SwfdecSwfDecoder * s, guint id, GType type)
 }
 
 void
-swfdec_swf_decoder_add_root_action (SwfdecSwfDecoder *s,
-    SwfdecRootActionType type, gpointer data)
-{
-  SwfdecSprite *sprite;
-  GArray *array;
-  SwfdecRootAction action;
-
-  g_return_if_fail (SWFDEC_IS_SWF_DECODER (s));
-  sprite = s->main_sprite;
-  g_return_if_fail (sprite->parse_frame < sprite->n_frames);
-
-  if (s->root_actions == NULL)
-    s->root_actions = g_new0 (GArray *, sprite->n_frames);
-
-  array = s->root_actions[sprite->parse_frame];
-  if (array == NULL) {
-    s->root_actions[sprite->parse_frame] = 
-      g_array_new (FALSE, FALSE, sizeof (SwfdecRootAction));
-    array = s->root_actions[sprite->parse_frame];
-  }
-  action.type = type;
-  action.data = data;
-  g_array_append_val (array, action);
-}
-
-void
 swfdec_swf_decoder_add_script (SwfdecSwfDecoder *s, SwfdecScript *script)
 {
   g_return_if_fail (SWFDEC_IS_SWF_DECODER (s));
diff --git a/libswfdec/swfdec_swf_decoder.h b/libswfdec/swfdec_swf_decoder.h
index ab88628..dcd2e16 100644
--- a/libswfdec/swfdec_swf_decoder.h
+++ b/libswfdec/swfdec_swf_decoder.h
@@ -35,23 +35,6 @@ G_BEGIN_DECLS
 //typedef struct _SwfdecSwfDecoder SwfdecSwfDecoder;
 typedef struct _SwfdecSwfDecoderClass SwfdecSwfDecoderClass;
 typedef int (* SwfdecTagFunc) (SwfdecSwfDecoder *, guint);
-typedef struct _SwfdecRootExportData SwfdecRootExportData;
-
-typedef enum {
-  SWFDEC_ROOT_ACTION_EXPORT,		/* contains a SwfdecExportData */
-  SWFDEC_ROOT_ACTION_INIT_SCRIPT,	/* contains a SwfdecScript */
-} SwfdecRootActionType;
-
-typedef struct _SwfdecRootAction SwfdecRootAction;
-struct _SwfdecRootAction {
-  guint type;
-  gpointer data;
-};
-
-struct _SwfdecRootExportData {
-  char *		name;
-  SwfdecCharacter *	character;
-};
 
 #define SWFDEC_TYPE_SWF_DECODER                    (swfdec_swf_decoder_get_type())
 #define SWFDEC_IS_SWF_DECODER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_SWF_DECODER))
@@ -79,7 +62,6 @@ struct _SwfdecSwfDecoder
   GHashTable *		characters;   	/* list of all objects with an id (called characters) */
   SwfdecSprite *	main_sprite;	/* the root sprite */
   SwfdecSprite *	parse_sprite;	/* the sprite that parsed at the moment */
-  GArray **		root_actions; 	/* actions to be executed by the root sprite */
   GHashTable *		scripts;      	/* buffer -> script mapping for all scripts */
 
   gboolean		use_network;	/* allow network or local access */
@@ -102,9 +84,6 @@ gpointer	swfdec_swf_decoder_create_character	(SwfdecSwfDecoder *	s,
 							 guint	        	id,
 							 GType			type);
 
-void		swfdec_swf_decoder_add_root_action	(SwfdecSwfDecoder *	s,
-							 SwfdecRootActionType	type,
-							 gpointer		data);
 void		swfdec_swf_decoder_add_script		(SwfdecSwfDecoder *	s,
 							 SwfdecScript *		script);
 SwfdecScript *	swfdec_swf_decoder_get_script		(SwfdecSwfDecoder *	s,
diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c
index 61827e7..dd552e4 100644
--- a/libswfdec/swfdec_tag.c
+++ b/libswfdec/swfdec_tag.c
@@ -525,69 +525,6 @@ tag_func_file_attributes (SwfdecSwfDecoder *s, guint tag)
 }
 
 static int
-tag_func_export_assets (SwfdecSwfDecoder * s, guint tag)
-{
-  SwfdecBits *bits = &s->b;
-  guint count, i;
-
-  count = swfdec_bits_get_u16 (bits);
-  SWFDEC_LOG ("exporting %u assets", count);
-  for (i = 0; i < count && swfdec_bits_left (bits); i++) {
-    guint id;
-    SwfdecCharacter *object;
-    char *name;
-    id = swfdec_bits_get_u16 (bits);
-    object = swfdec_swf_decoder_get_character (s, id);
-    name = swfdec_bits_get_string_with_version (bits, s->version);
-    if (object == NULL) {
-      SWFDEC_ERROR ("cannot export id %u as %s, id wasn't found", id, name);
-      g_free (name);
-    } else if (name == NULL) {
-      SWFDEC_ERROR ("cannot export id %u, no name was given", id);
-    } else {
-      SwfdecRootExportData *data = g_new (SwfdecRootExportData, 1);
-      data->name = name;
-      data->character = object;
-      SWFDEC_LOG ("exporting %s %u as %s", G_OBJECT_TYPE_NAME (object), id, name);
-      g_object_ref (object);
-      swfdec_swf_decoder_add_root_action (s, SWFDEC_ROOT_ACTION_EXPORT, data);
-    }
-  }
-
-  return SWFDEC_STATUS_OK;
-}
-
-static int
-tag_func_do_init_action (SwfdecSwfDecoder * s, guint tag)
-{
-  SwfdecBits *bits = &s->b;
-  guint id;
-  SwfdecSprite *sprite;
-  char *name;
-
-  id = swfdec_bits_get_u16 (bits);
-  SWFDEC_LOG ("  id = %u", id);
-  sprite = swfdec_swf_decoder_get_character (s, id);
-  if (!SWFDEC_IS_SPRITE (sprite)) {
-    SWFDEC_ERROR ("character %u is not a sprite", id);
-    return SWFDEC_STATUS_OK;
-  }
-  if (sprite->init_action != NULL) {
-    SWFDEC_ERROR ("sprite %u already has an init action", id);
-    return SWFDEC_STATUS_OK;
-  }
-  name = g_strdup_printf ("InitAction %u", id);
-  sprite->init_action = swfdec_script_new_from_bits (bits, name, s->version);
-  g_free (name);
-  if (sprite->init_action) {
-    swfdec_script_ref (sprite->init_action);
-    swfdec_swf_decoder_add_root_action (s, SWFDEC_ROOT_ACTION_INIT_SCRIPT, sprite->init_action);
-  }
-
-  return SWFDEC_STATUS_OK;
-}
-
-static int
 tag_func_enqueue (SwfdecSwfDecoder *s, guint tag)
 {
   SwfdecBuffer *buffer;
@@ -694,10 +631,10 @@ static struct tag_func_struct tag_funcs[] = {
   [SWFDEC_TAG_TEMPLATECOMMAND] = {"TemplateCommand", NULL, 0},
   [SWFDEC_TAG_GENERATOR3] = {"Generator3", NULL, 0},
   [SWFDEC_TAG_EXTERNALFONT] = {"ExternalFont", NULL, 0},
-  [SWFDEC_TAG_EXPORTASSETS] = {"ExportAssets", tag_func_export_assets, 0},
+  [SWFDEC_TAG_EXPORTASSETS] = {"ExportAssets", tag_func_enqueue, 0},
   [SWFDEC_TAG_IMPORTASSETS] = {"ImportAssets", NULL, 0},
   [SWFDEC_TAG_ENABLEDEBUGGER] = {"EnableDebugger", NULL, 0},
-  [SWFDEC_TAG_DOINITACTION] = {"DoInitAction", tag_func_do_init_action, SWFDEC_TAG_DEFINE_SPRITE },
+  [SWFDEC_TAG_DOINITACTION] = {"DoInitAction", tag_func_enqueue, SWFDEC_TAG_DEFINE_SPRITE },
   [SWFDEC_TAG_DEFINEVIDEOSTREAM] = {"DefineVideoStream", tag_func_define_video, 0},
   [SWFDEC_TAG_VIDEOFRAME] = {"VideoFrame", tag_func_video_frame, SWFDEC_TAG_DEFINE_SPRITE },
   [SWFDEC_TAG_DEFINEFONTINFO2] = {"DefineFontInfo2", tag_func_define_font_info, 0},
commit 5ad11a73e87e281aaa668687f72314f11ed5b07c
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 24 11:25:32 2007 +0200

    silence sign warnings

diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index 516e270..bd42350 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -1030,7 +1030,7 @@ swfdec_text_field_movie_set_text_format (SwfdecTextFieldMovie *text,
   g_return_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text));
   g_return_if_fail (SWFDEC_IS_TEXT_FORMAT (format));
   g_return_if_fail (start_index < end_index);
-  g_return_if_fail (end_index <= g_utf8_strlen (text->input->str, -1));
+  g_return_if_fail (end_index <= (guint) g_utf8_strlen (text->input->str, -1));
 
   g_assert (text->formats != NULL);
   g_assert (text->formats->data != NULL);
@@ -1110,7 +1110,7 @@ swfdec_text_field_movie_get_text_format (SwfdecTextFieldMovie *text,
 
   g_assert (SWFDEC_IS_TEXT_FIELD_MOVIE (text));
   g_assert (start_index < end_index);
-  g_assert (end_index <= g_utf8_strlen (text->input->str, -1));
+  g_assert (end_index <= (guint) g_utf8_strlen (text->input->str, -1));
 
   g_assert (text->formats != NULL);
   g_assert (text->formats->data != NULL);
@@ -1557,7 +1557,7 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text,
   gboolean first;
 
   g_return_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text));
-  g_return_if_fail (end_index <= g_utf8_strlen (text->input->str, -1));
+  g_return_if_fail (end_index <= (guint) g_utf8_strlen (text->input->str, -1));
   g_return_if_fail (start_index <= end_index);
   g_return_if_fail (str != NULL);
 
@@ -1582,7 +1582,7 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text,
     findex = iter->data;
 
     if (findex->index >= start_index) {
-      if (end_index == g_utf8_strlen (text->input->str, -1) ||
+      if (end_index == (guint) g_utf8_strlen (text->input->str, -1) ||
 	  (iter->next != NULL &&
 	   ((SwfdecFormatIndex *)iter->next->data)->index <= end_index))
       {
@@ -1601,7 +1601,7 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text,
     }
     prev = iter;
   }
-  if (end_index == g_utf8_strlen (text->input->str, -1)) {
+  if (end_index == (guint) g_utf8_strlen (text->input->str, -1)) {
     if (SWFDEC_AS_OBJECT (text)->context->version < 8) {
       SWFDEC_FIXME ("replaceText to the end of the TextField might use wrong text format on version 7");
     }
commit 97f5dc34bcff9bf2eab1ad52f35a6db17e05e55e
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 24 11:25:19 2007 +0200

    perform length calculation just once
    
    Also gets around sign warnings on 32bit

diff --git a/libswfdec/swfdec_text_field_movie_as.c b/libswfdec/swfdec_text_field_movie_as.c
index 6e953a4..2835edd 100644
--- a/libswfdec/swfdec_text_field_movie_as.c
+++ b/libswfdec/swfdec_text_field_movie_as.c
@@ -1035,7 +1035,7 @@ swfdec_text_field_movie_getTextFormat (SwfdecAsContext *cx,
 {
   SwfdecTextFieldMovie *text;
   SwfdecTextFormat *format;
-  guint start_index, end_index;
+  guint start_index, end_index, len;
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
@@ -1044,13 +1044,13 @@ swfdec_text_field_movie_getTextFormat (SwfdecAsContext *cx,
     end_index = g_utf8_strlen (text->input->str, -1);
   } else {
     start_index = swfdec_as_value_to_integer (cx, &argv[0]);
-    start_index = MIN (start_index, g_utf8_strlen (text->input->str, -1));
+    len = g_utf8_strlen (text->input->str, -1);
+    start_index = MIN (start_index, len);
     if (argc == 1) {
       end_index = start_index + 1;
     } else {
       end_index = swfdec_as_value_to_integer (cx, &argv[1]);
-      end_index =
-	CLAMP (end_index, start_index, g_utf8_strlen (text->input->str, -1));
+      end_index = CLAMP (end_index, start_index, len);
     }
   }
 


More information about the Swfdec mailing list