gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/character.cpp server/cha...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/character.cpp server/cha...
Date: Sat, 01 Sep 2007 01:20:47 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/09/01 01:20:47

Modified files:
        .              : ChangeLog 
        server         : character.cpp character.h dlist.cpp dlist.h 
                         movie_root.cpp movie_root.h sprite_instance.cpp 
                         sprite_instance.h 
        testsuite/actionscript.all: MovieClip.as 
        testsuite/misc-ming.all: loop_test7.c loop_test8.c 
                                 unload_movieclip_test1.c 
        testsuite/misc-swfc.all: movieclip_destruction_test2.sc 
        testsuite/swfdec: PASSING 

Log message:
                * server/dlist.{cpp,h}: when unloaded character's unload() 
method
                  returns true (character or any of its childs has onUnload 
methods to
                  be run) don't really remove it from the list, but just shift 
it
                  down to the "removed" zone. Advance and display only 
non-removed
                  characters (depth-zone based for now, possibly too weak).
                  Add lots of paranoid invariant testing (not enough, missing 
the
                  one for no unloaded characters out of "removed" depth zone).
                * server/character.{cpp,h}: more info about removedDepthOffset,
                  assertion preveing double unload of a character (this can be
                  probably easily broken by a focused testcase using 
removeMovieClip
                  on a removed but still-reachable character).
                * server/movie_root.{cpp,h}: added cleanupDisplayList() method, 
and
                  call it at the end of actions execution to properly cleanup 
removed
                  but still-reachable characters.
                * server/sprite_instance.{cpp,h}: implement a 
cleanupDisplayList, to
                  be called by movie_root, make sure to not include unloaded
                  characters when visiting the DisplayList for bounds 
extractions and
                  similar.
                * testsuite/actionscript.all/MovieClip.as: soft-references 
successes
                * testsuite/misc-ming.all/: loop_test7.c, loop_test8.c:
                  keep-alive-for-onUnload successes
                * testsuite/misc-ming.all/unload_movieclip_test1.c: successes
                * testsuite/misc-swfc.all/movieclip_destruction_test2.sc: 
successes
                * testsuite/swfdec/PASSING: remove-depths-*.swf successes

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4179&r2=1.4180
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.cpp?cvsroot=gnash&r1=1.50&r2=1.51
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.h?cvsroot=gnash&r1=1.91&r2=1.92
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.80&r2=1.81
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.h?cvsroot=gnash&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.82&r2=1.83
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.70&r2=1.71
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.319&r2=1.320
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.h?cvsroot=gnash&r1=1.134&r2=1.135
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/MovieClip.as?cvsroot=gnash&r1=1.87&r2=1.88
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/loop_test7.c?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/loop_test8.c?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/unload_movieclip_test1.c?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-swfc.all/movieclip_destruction_test2.sc?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/swfdec/PASSING?cvsroot=gnash&r1=1.27&r2=1.28

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4179
retrieving revision 1.4180
diff -u -b -r1.4179 -r1.4180
--- ChangeLog   31 Aug 2007 22:16:49 -0000      1.4179
+++ ChangeLog   1 Sep 2007 01:20:45 -0000       1.4180
@@ -1,3 +1,30 @@
+2007-09-01 Sandro Santilli <address@hidden>
+
+       * server/dlist.{cpp,h}: when unloaded character's unload() method
+         returns true (character or any of its childs has onUnload methods to
+         be run) don't really remove it from the list, but just shift it
+         down to the "removed" zone. Advance and display only non-removed
+         characters (depth-zone based for now, possibly too weak).
+         Add lots of paranoid invariant testing (not enough, missing the
+         one for no unloaded characters out of "removed" depth zone).
+       * server/character.{cpp,h}: more info about removedDepthOffset,
+         assertion preveing double unload of a character (this can be 
+         probably easily broken by a focused testcase using removeMovieClip
+         on a removed but still-reachable character).
+       * server/movie_root.{cpp,h}: added cleanupDisplayList() method, and
+         call it at the end of actions execution to properly cleanup removed
+         but still-reachable characters.
+       * server/sprite_instance.{cpp,h}: implement a cleanupDisplayList, to
+         be called by movie_root, make sure to not include unloaded
+         characters when visiting the DisplayList for bounds extractions and
+         similar.
+       * testsuite/actionscript.all/MovieClip.as: soft-references successes
+       * testsuite/misc-ming.all/: loop_test7.c, loop_test8.c:
+         keep-alive-for-onUnload successes
+       * testsuite/misc-ming.all/unload_movieclip_test1.c: successes
+       * testsuite/misc-swfc.all/movieclip_destruction_test2.sc: successes
+       * testsuite/swfdec/PASSING: remove-depths-*.swf successes
+
 2007-08-31 Sandro Santilli <address@hidden>
 
        * server/asobj/gen-asclass.sh: add the getObjectInterface call.

Index: server/character.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/character.cpp,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- server/character.cpp        31 Aug 2007 15:40:05 -0000      1.50
+++ server/character.cpp        1 Sep 2007 01:20:46 -0000       1.51
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 // 
 
-/* $Id: character.cpp,v 1.50 2007/08/31 15:40:05 strk Exp $ */
+/* $Id: character.cpp,v 1.51 2007/09/01 01:20:46 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -676,8 +676,9 @@
 bool
 character::unload()
 {
-       assert(!_unloaded);
+       assert(!_unloaded); // don't unload characters twice !
        _unloaded = true;
+
        //log_msg(_("Queuing unload event for character %p"), this);
        return queueEventHandler(event_id::UNLOAD);
        //on_event(event_id::UNLOAD);

Index: server/character.h
===================================================================
RCS file: /sources/gnash/gnash/server/character.h,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -b -r1.91 -r1.92
--- server/character.h  30 Aug 2007 14:13:07 -0000      1.91
+++ server/character.h  1 Sep 2007 01:20:46 -0000       1.92
@@ -19,7 +19,7 @@
 //
 //
 
-/* $Id: character.h,v 1.91 2007/08/30 14:13:07 strk Exp $ */
+/* $Id: character.h,v 1.92 2007/09/01 01:20:46 strk Exp $ */
 
 #ifndef GNASH_CHARACTER_H
 #define GNASH_CHARACTER_H
@@ -350,6 +350,13 @@
     ///          depth -32829 (-32769-60) when unloaded and
     ///          an onUnload event handler is defined for it.
     ///
+    /// So, to recap:
+    ///                1:  -32769 to -16385 are removed
+    ///                2:  -16384 to      0 are statics
+    ///                3:  Max depth for a PlaceoObject call is 16384 (which 
becomes 0 in the statics)
+    ///        (all of the above correct?)
+    ///
+    ///
     static const int removedDepthOffset = -32769; // -32769;
     
     /// This value is used for m_clip_depth when the value has no meaning, ie.

Index: server/dlist.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.cpp,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -b -r1.80 -r1.81
--- server/dlist.cpp    31 Aug 2007 14:49:47 -0000      1.80
+++ server/dlist.cpp    1 Sep 2007 01:20:46 -0000       1.81
@@ -28,6 +28,7 @@
 #include <iostream>
 #include <algorithm>
 #include <stack>
+#include <boost/bind.hpp>
 
 namespace gnash {
 
@@ -98,6 +99,8 @@
 int
 DisplayList::getNextHighestDepth() const
 {
+       testInvariant();
+
        int nexthighestdepth=0;
        for (const_iterator it = _characters.begin(),
                        itEnd = _characters.end();
@@ -118,6 +121,8 @@
 character*
 DisplayList::get_character_at_depth(int depth)
 {
+       testInvariant();
+
        //GNASH_REPORT_FUNCTION;
        //dump();
 
@@ -143,6 +148,8 @@
 character*
 DisplayList::get_character_by_name(const std::string& name)
 {
+       testInvariant();
+
        container_type::iterator it = find_if(
                        _characters.begin(),
                        _characters.end(),
@@ -156,6 +163,8 @@
 character*
 DisplayList::get_character_by_name_i(const std::string& name)
 {
+       testInvariant();
+
        container_type::iterator it = find_if(
                        _characters.begin(),
                        _characters.end(),
@@ -182,6 +191,7 @@
        //dump();
 
        assert(ch);
+       assert(!ch->isUnloaded());
        ch->set_invalidated();
        ch->set_depth(depth);
        ch->set_cxform(color_xform);
@@ -208,16 +218,23 @@
                InvalidatedRanges old_ranges;   
                (*it)->add_invalidated_bounds(old_ranges, true);        
        
-               (*it)->unload();
+               boost::intrusive_ptr<character> oldCh = *it;
+               bool hasUnloadEvent = oldCh->unload();
+
                // replace existing char
                *it = DisplayItem(ch);
                
+               // reinsert removed character if needed
+               if ( hasUnloadEvent ) reinsertRemovedCharacter(oldCh);
+               
                // extend invalidated bounds
                ch->extend_invalidated_bounds(old_ranges);                      
        
        }
 
        // Give life to this instance
        ch->construct();
+
+       testInvariant();
 }
 
 void
@@ -236,17 +253,23 @@
        {
                *it = DisplayItem(ch);
        }
+
+       testInvariant();
 }
 
 void
 DisplayList::addAll(std::vector<character*>& chars, bool replace)
 {
+       testInvariant();
+
        for (std::vector<character*>::iterator it=chars.begin(),
                        itEnd=chars.end();
                        it != itEnd; ++it)
        {
                add(*it, replace);
        }
+
+       testInvariant();
 }
 
 void
@@ -258,7 +281,11 @@
        int ratio,
        int clip_depth)
 {
+       testInvariant();
+
        //GNASH_REPORT_FUNCTION;
+       assert(ch);
+       assert(!ch->isUnloaded());
 
        ch->set_invalidated();
        ch->set_depth(depth);
@@ -292,7 +319,7 @@
        }
        else
        {
-               character* oldch = it->get();
+               boost::intrusive_ptr<character> oldch = *it;
 
                InvalidatedRanges old_ranges;
        
@@ -312,11 +339,14 @@
                oldch->add_invalidated_bounds(old_ranges, true);                
 
                // Unload old char
-               (*it)->unload();
+               bool hasUnloadEvent = oldch->unload();
 
                // replace existing char                
                *it = di;
                
+               // reinsert removed character if needed
+               if ( hasUnloadEvent ) reinsertRemovedCharacter(oldch);
+               
                // extend invalidated bounds
                // WARNING: when a new Button character is added,
                //          the invalidated bounds computation will likely
@@ -330,6 +360,8 @@
 
        // Give life to this instance
        ch->construct();
+
+       testInvariant();
 }
        
        
@@ -343,6 +375,8 @@
        int ratio,
        int /* clip_depth */)
 {
+       testInvariant();
+
        //GNASH_REPORT_FUNCTION;
        //IF_VERBOSE_DEBUG(log_msg(_("dl::move(%d)"), depth));
 
@@ -358,6 +392,12 @@
                return;
        }
 
+       if ( ch->isUnloaded() )
+       {
+               log_error("Request to move an unloaded character");
+               assert(!ch->isUnloaded());
+       }
+
        // TODO: is sign of depth related to accepting anim moves ?
        if (ch->get_accept_anim_moves() == false)
        {
@@ -378,6 +418,8 @@
        {
                ch->set_ratio(ratio);
        }
+
+       testInvariant();
 }
        
        
@@ -387,6 +429,8 @@
 {
        //GNASH_REPORT_FUNCTION;
 
+       testInvariant();
+
        //log_msg(_("Before removing, list is:"));
        //dump();
 
@@ -394,6 +438,8 @@
        container_type::size_type size = _characters.size();
 #endif
 
+       // TODO: would it be legal to call remove_display_object with a depth
+       //       in the "removed" zone ?
        // TODO: optimize to take by-depth order into account
        container_type::iterator it = find_if(
                        _characters.begin(),
@@ -402,15 +448,25 @@
 
        if ( it != _characters.end() )
        {
-               (*it)->unload();
+               boost::intrusive_ptr<character> oldCh = *it;
+               bool hasUnloadEvent = oldCh->unload();
+
                _characters.erase(it);
 
+               // reinsert removed character if needed
+               // NOTE: could be optimized if we knew exactly how
+               //       to handle the case in which the target depth
+               //       (after the shift) is occupied already
+               //
+               if ( hasUnloadEvent ) reinsertRemovedCharacter(oldCh);
        }
 
 #ifndef NDEBUG
        assert(size >= _characters.size());
 #endif
 
+       testInvariant();
+
        //log_msg(_("Done removing, list is:"));
        //dump();
 }
@@ -419,6 +475,7 @@
 void
 DisplayList::swapDepths(character* ch1, int newdepth)
 {
+       testInvariant();
 
        if ( newdepth < character::staticDepthOffset )
        {
@@ -429,8 +486,14 @@
                return;
        }
 
-       assert(ch1->get_depth() != newdepth);
+       int srcdepth = ch1->get_depth();
+
+       // what if source char is at a lower depth ?
+       assert(srcdepth >= character::staticDepthOffset);
 
+       assert(srcdepth != newdepth);
+
+       // TODO: optimize this scan by taking ch1 depth into account ?
        container_type::iterator it1 = find(_characters.begin(), 
_characters.end(), ch1);
 
        // upper bound ...
@@ -448,8 +511,6 @@
        {
                DisplayItem ch2 = *it2;
 
-               int srcdepth = ch1->get_depth();
-
                ch2->set_depth(srcdepth);
 
                // TODO: we're not actually invalidated ourselves, rather our 
parent is...
@@ -485,17 +546,14 @@
        // See displaylist_depths_test6.swf for more info.
        ch1->transformedByScript();
 
-#ifndef NDEBUG
-       // TODO: make this a testInvariant() method for DisplayList
-       DisplayList sorted = *this;
-       sorted.sort();
-       assert(*this == sorted); // check we didn't screw up ordering
-#endif
+       testInvariant();
 
 }
        
 void DisplayList::reset(movie_definition& movieDef, size_t tgtFrame, bool 
call_unload)
 {
+       testInvariant();
+
        //GNASH_REPORT_FUNCTION;
 
        // 1. Find all "timeline depth" for the target frame, querying the
@@ -513,20 +571,24 @@
        cout << "Current DisplayList: " << *this << endl;
 #endif
 
-
        typedef std::vector<int>::iterator SeekIter;
 
        SeekIter startSeek = save.begin();
     SeekIter endSeek = save.end();
 
-       for (iterator it = _characters.begin(), itEnd = _characters.end(); it 
!= itEnd; )
+       std::vector<DisplayItem> toReinsert;
+
+       iterator it = beginNonRemoved(_characters);
+       for (iterator itEnd = _characters.end(); it != itEnd; )
        {
+               testInvariant();
+
                DisplayItem& di = *it;
 
                int di_depth = di->get_depth();
 
                /// We won't scan chars in the dynamic depth zone
-               if ( di_depth >= 0 ) return;
+               if ( di_depth >= 0 ) break;
 
                /// Always remove non-timeline instances ?
                /// Seems so, at least for duplicateMovieClip
@@ -536,7 +598,13 @@
                if ( ! info )
                {
                        // Not to be saved, killing
-                       if ( call_unload ) di->unload();
+                       if ( call_unload )
+                       {
+                               if ( di->unload() )
+                               {
+                                       toReinsert.push_back(di);
+                               }
+                       }
                        it = _characters.erase(it);
                        continue;
                }
@@ -546,6 +614,10 @@
                // we need to do this in some corner cases. 
                if(!di->isActionScriptReferenceable())
                {
+                       // TODO: no unload() call needed here ? would help GC ?
+                       // (I guess there can't be any as_value pointing at this
+                       // if it's not ActionScriptReferenceable after all...)
+                       //
                        it = _characters.erase(it);
                        continue;
                }
@@ -555,7 +627,13 @@
                if( match == save.end())
                {
                        // Not to be saved, killing
-                       if ( call_unload ) di->unload();
+                       if ( call_unload )
+                       {
+                               if ( di->unload() )
+                               {
+                                       toReinsert.push_back(di);
+                               }
+                       }
                        it = _characters.erase(it);
                        continue;
                }
@@ -570,23 +648,44 @@
 
                ++it;
        }
-}
 
+       testInvariant();
+
+       std::for_each(toReinsert.begin(), toReinsert.end(),
+               boost::bind(&DisplayList::reinsertRemovedCharacter, this, _1));
+
+       testInvariant();
+}
 
 void
 DisplayList::clear_except(const DisplayList& exclude, bool call_unload)
 {
+       //log_debug("clear_except(DislpayList, %d) called", call_unload);
        //GNASH_REPORT_FUNCTION;
 
+       testInvariant();
+       //log_debug("First invariant test worked");
+
+
        assert(&exclude != this);
        const container_type& keepchars = exclude._characters;
 
+       std::vector<DisplayItem> toReinsert;
+
+       const_iterator keepStart = beginNonRemoved(keepchars);
+       const_iterator keepEnd = keepchars.end();
+
+       //int called=0;
        for (iterator it = _characters.begin(), itEnd = _characters.end(); it 
!= itEnd; )
        {
+               
+               testInvariant(); // TODO: expensive
+               //log_debug("Invariant test in iteration %d worked", called++);
+
                DisplayItem& di = *it;
 
                bool is_affected = false;
-               for (const_iterator kit = keepchars.begin(), kitEnd = 
keepchars.end(); kit != kitEnd; ++kit)
+               for (const_iterator kit = keepStart; kit != keepEnd; ++kit)
                {
                        if ( *kit == di )
                        {
@@ -597,12 +696,27 @@
 
                if (is_affected == false)
                {
-                       if ( call_unload ) di->unload();
+                       if ( call_unload )
+                       {
+                               if ( di->unload() )
+                               {
+                                       toReinsert.push_back(di);
+                               }
+                       }
                        it = _characters.erase(it);
                        continue;
                }
                it++;
        }
+
+       testInvariant();
+       //log_debug("Invariant test after cleanup worked");
+
+       std::for_each(toReinsert.begin(), toReinsert.end(),
+               boost::bind(&DisplayList::reinsertRemovedCharacter, this, _1));
+
+       testInvariant();
+       //log_debug("Invariant test after reinsertion worked");
 }
 
 void
@@ -610,8 +724,12 @@
 {
        //GNASH_REPORT_FUNCTION;
 
+       testInvariant();
+
        const container_type dropchars = from._characters;
 
+       std::vector<DisplayItem> toReinsert;
+
        for (iterator it = _characters.begin(), itEnd = _characters.end(); it 
!= itEnd; )
        {
                DisplayItem& di = *it;
@@ -628,12 +746,25 @@
 
                if (is_affected)
                {
-                       if ( call_unload ) di->unload();
+                       if ( call_unload )
+                       {
+                               if ( di->unload() )
+                               {
+                                       toReinsert.push_back(di);
+                               }
+                       }
                        it = _characters.erase(it);
                        continue;
                }
                it++;
        }
+
+       testInvariant();
+
+       std::for_each(toReinsert.begin(), toReinsert.end(),
+               boost::bind(&DisplayList::reinsertRemovedCharacter, this, _1));
+
+       testInvariant();
 }
        
 void
@@ -642,14 +773,22 @@
 {
        //GNASH_REPORT_FUNCTION;
 
+       testInvariant(); 
+
 //     container_type::size_type size = _characters.size();
 
        // That there was no crash gnash we iterate through the copy
        std::list<DisplayItem> tmp_list = _characters;
 
-       for (iterator it = tmp_list.begin(), itEnd = tmp_list.end();
-               it != itEnd; ++it)
+        // We only advance characters which are out of the "removed" zone (or 
should we check isUnloaded?)
+        // TODO: remove when copying _character to tmp_list directly ?
+       iterator it = beginNonRemoved(tmp_list);
+       //if ( it != tmp_list.end() ) log_debug("First non-removed char at 
depth %d", (*it)->get_depth());
+       //iterator it = tmp_list.begin();
+       for (iterator itEnd = tmp_list.end(); it != itEnd; ++it)
        {
+               testInvariant(); // expensive !!
+
                // @@@@ TODO FIX: If array changes size due to
                // character actions, the iteration may not be
                // correct!
@@ -684,9 +823,18 @@
                boost::intrusive_ptr<character> ch = *it;
                assert(ch!=NULL);
 
+               if ( ch->isUnloaded() ) // debugging
+               {
+                       log_error("character at depth %d is unloaded", 
ch->get_depth());
+                       abort();
+               }
+               assert(! ch->isUnloaded() ); // we don't advance unloaded chars
+
+
                ch->advance(delta_time);
        }
 
+       testInvariant();
 }
        
        
@@ -695,15 +843,27 @@
 void
 DisplayList::display()
 {
+       testInvariant();
+
     //GNASH_REPORT_FUNCTION;
     std::stack<int> clipDepthStack;
     
-    for( iterator it = _characters.begin(), endIt = _characters.end();
-                  it != endIt; ++it)
+    // We only advance characters which are out of the "removed" zone (or 
should we check isUnloaded?)
+    iterator it = beginNonRemoved(_characters);
+    //iterator it = _characters.begin();
+    for(iterator endIt = _characters.end(); it != endIt; ++it)
     {
         character* ch = it->get();
         assert(ch);
 
+       if ( ch->isUnloaded() ) // debugging
+       {
+               log_error("character at depth %d is unloaded", ch->get_depth());
+               abort();
+       }
+       assert(! ch->isUnloaded() ); // we don't advance unloaded chars
+
+
         // Check if this charater or any of its parents is a mask.
         // Characters act as masks should always be rendered to the
         // mask buffer despite their visibility.
@@ -761,26 +921,30 @@
 void
 DisplayList::dump() const
 {
+       //testInvariant();
+
        int num=0;
        for( const_iterator it = _characters.begin(),
                        endIt = _characters.end();
                it != endIt; ++it)
        {
                const DisplayItem& dobj = *it;
-               log_msg(_("Item %d at depth %d (char id %d, name %s, type %s"),
+               log_msg(_("Item %d at depth %d (char id %d, name %s, type %s)"),
                        num, dobj->get_depth(), dobj->get_id(),
-                       dobj->get_name().c_str(), typeid(*dobj).name());
+                       dobj->get_name().c_str(), typeName(*dobj).c_str());
                num++;
        }
 }
 
 
 void 
-DisplayList::add_invalidated_bounds(InvalidatedRanges& ranges, bool force) {
+DisplayList::add_invalidated_bounds(InvalidatedRanges& ranges, bool force)
+{
     
-       for( iterator it = _characters.begin(),
-                       endIt = _characters.end();
-               it != endIt; ++it)
+       testInvariant();
+
+       iterator it = beginNonRemoved(_characters);
+       for( iterator endIt = _characters.end(); it != endIt; ++it)
        {
     DisplayItem& dobj = *it;
 #ifndef GNASH_USE_GC
@@ -825,6 +989,69 @@
        return os;
 }
 
+void
+DisplayList::reinsertRemovedCharacter(boost::intrusive_ptr<character> ch)
+{
+       assert(ch->isUnloaded());
+
+       // TODO: have this done by character::unload() instead ?
+       int oldDepth = ch->get_depth();
+       int newDepth = character::removedDepthOffset - oldDepth;
+       ch->set_depth(newDepth);
+
+       testInvariant();
+
+       container_type::iterator it = find_if(
+                       _characters.begin(), _characters.end(),
+                       DepthGreaterOrEqual(newDepth));
+       if ( it == _characters.end() || (*it)->get_depth() != newDepth )
+       {
+               // add the new char
+               _characters.insert(it, DisplayItem(ch));
+       }
+       else
+       {
+               // the character should not be in the displaylist already !
+               assert(it->get() != ch.get());
+
+               log_error("DisplayList::insertCharacter: target depth (%d) is 
occupied, and we don't know what we're supposed to do - we'll avoid inserting 
the character for now", newDepth);
+       }
+
+       testInvariant();
+}
+
+/*private static*/
+DisplayList::iterator
+DisplayList::beginNonRemoved(container_type& c)
+{
+       return std::find_if(c.begin(), c.end(),
+                       DepthGreaterOrEqual(character::removedDepthOffset - 
character::staticDepthOffset));
+}
+
+/*private static*/
+DisplayList::const_iterator
+DisplayList::beginNonRemoved(const container_type& c)
+{
+       return std::find_if(c.begin(), c.end(), 
DepthGreaterOrEqual(character::removedDepthOffset+1));
+}
+
+void
+DisplayList::removeUnloaded()
+{
+       // TODO: erase from begin() to beginNonRemoved()-1 ?
+       //log_debug("removeUnloaded called (dlist:%p)", (void*)this);
+       testInvariant();
+       //log_debug(" first invTest passed, _characters have %d entries", 
_characters.size());
+       //dump();
+       iterator last = std::remove_if(_characters.begin(), _characters.end(), 
boost::bind(&character::isUnloaded, _1));
+       _characters.erase(last, _characters.end());
+       //log_debug(" After remove_if, _characters have %d entries - dumping 
them", _characters.size());
+       //dump();
+       //log_debug(" Now testing invariant again");
+       testInvariant();
+       //log_debug(" second invTest passed");
+}
+
 } // namespace gnash
 
 

Index: server/dlist.h
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.h,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- server/dlist.h      30 Aug 2007 21:21:58 -0000      1.47
+++ server/dlist.h      1 Sep 2007 01:20:46 -0000       1.48
@@ -28,6 +28,10 @@
 
 #include <list>
 #include <iosfwd>
+#ifndef NDEBUG
+#include "log.h"
+#include <set>  // for testInvariant
+#endif
 
 namespace gnash {
        class cxform;
@@ -49,6 +53,27 @@
 
 public:
 
+       void testInvariant() const
+       {
+#ifndef NDEBUG
+               DisplayList sorted = *this;
+               // check no duplicated depths in list
+               std::set<int> depths;
+               for (const_iterator it=_characters.begin(), 
itEnd=_characters.end(); it!=itEnd; ++it)
+               {
+                       boost::intrusive_ptr<character> ch = *it;
+                       int depth = ch->get_depth();
+                       if ( ! depths.insert(depth).second )
+                       {
+                               log_debug("Depth %d is duplicated in 
DisplayList %p", depth, (void*)this);
+                               abort();
+                       }
+               }
+               sorted.sort();
+               assert(*this == sorted); // check we didn't screw up ordering
+#endif
+       }
+
        /// Output operator
        friend std::ostream& operator<< (std::ostream&, const DisplayList&);
 
@@ -172,6 +197,17 @@
        ///
        void    remove_display_object(int depth);
 
+       /// Remove all unloaded character from the list
+       //
+       /// Removed characters still in the list are those
+       /// on which onUnload event handlers were defined..
+       ///
+       /// NOTE: we don't call the function recursively in the 
+       ///       contained elements, as that should not be needed
+       ///       (ie: any inned thing will not be accessible anyway)
+       ///
+       void removeUnloaded();
+
        /// Clear the display list.
        void clear()
        {
@@ -194,7 +230,7 @@
 
        /// \brief
        /// Clear all characters in this DisplayList except the ones
-       /// contained in the given DisplayList
+       /// contained in the given DisplayList and not unloaded
        //
        /// @param exclude
        ///     A DisplayList containing character instances to keep.
@@ -298,6 +334,11 @@
        /// The visitor functor will 
        /// receive a character pointer; must return true if
        /// it wants next item or false to exit the loop.
+       ///
+       /// NOTE: all elements in the list are visited, even
+       ///       the removed ones (unloaded)
+       /// TODO: inspect if worth providing an arg to skip removed
+       ///
        template <class V>
        inline void visitForward(V& visitor);
 
@@ -309,6 +350,11 @@
        /// will receive a character pointer; must return true if
        /// it wants next item or false
        /// to exit the loop.
+       ///
+       /// NOTE: all elements in the list are visited, even
+       ///       the removed ones (unloaded)
+       /// TODO: inspect if worth providing an arg to skip removed
+       ///
        template <class V>
        inline void visitBackward(V& visitor);
 
@@ -320,6 +366,11 @@
        ///
        /// The visitor functor will receive a character pointer,
        /// it's return value is not used so can return void.
+       ///
+       /// NOTE: all elements in the list are visited, even
+       ///       the removed ones (unloaded)
+       /// TODO: inspect if worth providing an arg to skip removed
+       ///
        template <class V>
        inline void visitAll(V& visitor);
 
@@ -379,6 +430,24 @@
        typedef container_type::reverse_iterator reverse_iterator;
        typedef container_type::const_reverse_iterator const_reverse_iterator;
 
+       /// Return an iterator to the first element of the container NOT in the 
"removed" depth zone
+       static iterator beginNonRemoved(container_type& c);
+
+       /// Return an iterator to the first element of the container NOT in the 
"removed" depth zone
+       static const_iterator beginNonRemoved(const container_type& c);
+
+       /// Re-insert a removed-from-stage character after appropriately
+       /// shifting its depth based on the character::removedDepthOffset
+       /// value.
+       //
+       /// PRE-CONDITIONS 
+       ///     - ch::isUnloaded() returns true (assertion fails otherwise)
+       ///     - ch is not already in the list (assertion fails otherwise)
+       ///
+       /// TODO: inspect what should happen if the target depth is already 
occupied
+       ///
+       void reinsertRemovedCharacter(boost::intrusive_ptr<character> ch);
+
        container_type _characters;
 
 

Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -b -r1.82 -r1.83
--- server/movie_root.cpp       3 Aug 2007 21:44:32 -0000       1.82
+++ server/movie_root.cpp       1 Sep 2007 01:20:46 -0000       1.83
@@ -670,6 +670,10 @@
 #endif
        processActionQueue();
 
+       // Delete characters removed from the stage
+       // from the display lists
+       cleanupDisplayList();
+
 #ifdef GNASH_USE_GC
        // Run the garbage collector (step back !!)
        GC::get().collect();
@@ -1197,6 +1201,18 @@
 }
 
 void
+movie_root::cleanupDisplayList()
+{
+       // scan a backup copy of the levels, so that movies advancement won't
+       // invalidate iterators
+       Levels cached = _movies;
+       for (Levels::reverse_iterator i=cached.rbegin(), e=cached.rend(); i!=e; 
++i)
+       {
+               i->second->cleanupDisplayList();
+       }
+}
+
+void
 movie_root::advanceMovie(boost::intrusive_ptr<sprite_instance> movie, float 
delta_time)
 {
 #ifdef GNASH_DEBUG

Index: server/movie_root.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.h,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -b -r1.70 -r1.71
--- server/movie_root.h 2 Aug 2007 22:07:26 -0000       1.70
+++ server/movie_root.h 1 Sep 2007 01:20:46 -0000       1.71
@@ -15,7 +15,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: movie_root.h,v 1.70 2007/08/02 22:07:26 strk Exp $ */
+/* $Id: movie_root.h,v 1.71 2007/09/01 01:20:46 strk Exp $ */
 
 /// \page events_handling Handling of user events
 ///
@@ -669,6 +669,10 @@
     // Advance all levels
     void advanceAllLevels(float delta_time);
 
+    /// Delete characters removed from the stage
+    /// from the display lists
+    void cleanupDisplayList();
+
     // Advance a given level
     void advanceMovie(boost::intrusive_ptr<sprite_instance> movie, float 
delta_time);
 

Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.319
retrieving revision 1.320
diff -u -b -r1.319 -r1.320
--- server/sprite_instance.cpp  31 Aug 2007 21:53:31 -0000      1.319
+++ server/sprite_instance.cpp  1 Sep 2007 01:20:46 -0000       1.320
@@ -1630,6 +1630,8 @@
        {}
        void operator() (character* ch)
        {
+               // don't include bounds of unloaded characters
+               if ( ch->isUnloaded() ) return;
                geometry::Range2d<float> chb = ch->getBounds();
                matrix m = ch->get_matrix();
                m.transform(chb);
@@ -1655,6 +1657,9 @@
 
        void operator() (character* ch) 
        {
+               // don't include bounds of unloaded characters
+               if ( ch->isUnloaded() ) return;
+
                // TODO: Are script-transformed object to be kept ?
                //       Need a testcase for this
                //if ( ! ch->get_accept_anim_moves() )
@@ -1681,10 +1686,12 @@
                unloadEvents(0)
        {}
 
-       bool operator() (character* ch)
+       void operator() (character* ch)
        {
+               // don't unload already unloaded characters
+               if ( ch->isUnloaded() ) return;
+
                if ( ch->unload() ) ++unloadEvents;
-               return true;
        }
 
        bool foundUnloadEvents() const 
@@ -2325,6 +2332,8 @@
        // to need oldDisplayList again later, to extract the list of
        // newly added characters
        //
+       //oldDisplayList.removeUnloaded(); // TODO: clean oldDisplayList here 
instead than in cleanupDisplayList ?
+       oldDisplayList.sort(); // this is to avoid failing assertions, since we 
know characters might have changed depth...
        DisplayList stillAlive = oldDisplayList;
        stillAlive.clear_except(m_display_list, false);
        //log_msg(_("Advancing %d pre-existing children of %s"), 
stillAlive.size(), getTargetPath().c_str());
@@ -2335,15 +2344,12 @@
        //log_msg(_("Executing actions in %s timeline"), 
getTargetPath().c_str());
        do_actions();
 
-       // Call UNLOAD event of just removed chars !
-       //DisplayList justRemoved = oldDisplayList;
-       //justRemoved.clear_except(m_display_list, false); // true;
-       // No, dont' call UNLOAD event, as it should be called by 
remove_display_object!
-
-       // Finally, execute actions in newly added childs
+       // Finally, execute actions in (we actually "advance") newly added
+       // (and not unloaded) childs
        //
        // These are elements in the current DisplayList, cleared
-       // by all elements in oldDisplayList.
+       // by all unloaded elements and by non-unloaded elements in
+       // oldDisplayList.
        //
        // Of course we do NOT call UNLOAD events here, as
        // the chars we're clearing have *not* been removed:
@@ -2351,6 +2357,7 @@
        //
        DisplayList newlyAdded = m_display_list;
        //log_msg(_("%s has %d current children and %d old children"), 
getTargetPath().c_str(), m_display_list.size(), oldDisplayList.size());
+       newlyAdded.removeUnloaded();
        newlyAdded.clear(oldDisplayList, false);
        //log_msg(_("Advancing %d newly-added (after clearing) children of 
%s"), newlyAdded.size(), getTargetPath().c_str());
        newlyAdded.advance(delta_time);
@@ -3372,7 +3379,7 @@
 #endif
 
        UnloaderVisitor visitor;
-       m_display_list.visitForward(visitor);
+       m_display_list.visitAll(visitor);
 
        return character::unload() || visitor.foundUnloadEvents();
 
@@ -3628,6 +3635,9 @@
 
        void operator() (character* ch)
        {
+               // don't enumerate unloaded characters
+               if ( ch->isUnloaded() ) return;
+
                _env.push(ch->get_name());
        }
 };
@@ -3639,6 +3649,14 @@
        m_display_list.visitAll(visitor);
 }
 
+void
+sprite_instance::cleanupDisplayList()
+{
+        //log_debug("%s.cleanDisplayList() called, current dlist is %p, old is 
%p", getTarget().c_str(), (void*)&m_display_list, (void*)&oldDisplayList);
+       m_display_list.removeUnloaded();
+       oldDisplayList.removeUnloaded(); // TODO: move unloaded-cleanup of 
oldDisplayList in advance_sprite ?
+}
+
 #ifdef GNASH_USE_GC
 struct ReachableMarker {
        void operator() (character *ch)

Index: server/sprite_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.h,v
retrieving revision 1.134
retrieving revision 1.135
diff -u -b -r1.134 -r1.135
--- server/sprite_instance.h    31 Aug 2007 07:56:11 -0000      1.134
+++ server/sprite_instance.h    1 Sep 2007 01:20:47 -0000       1.135
@@ -748,6 +748,10 @@
                return _origTarget;
        }
 
+       /// Delete characters removed from the stage
+       /// from the display lists
+       void cleanupDisplayList();
+
 private:
 
        /// \brief

Index: testsuite/actionscript.all/MovieClip.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/MovieClip.as,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -b -r1.87 -r1.88
--- testsuite/actionscript.all/MovieClip.as     31 Aug 2007 21:53:33 -0000      
1.87
+++ testsuite/actionscript.all/MovieClip.as     1 Sep 2007 01:20:47 -0000       
1.88
@@ -20,7 +20,7 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-rcsid="$Id: MovieClip.as,v 1.87 2007/08/31 21:53:33 strk Exp $";
+rcsid="$Id: MovieClip.as,v 1.88 2007/09/01 01:20:47 strk Exp $";
 
 #include "check.as"
 
@@ -481,23 +481,23 @@
 #endif
 
 check_equals(typeof(hardref), 'undefined');
-xcheck_equals(typeof(hardref2), 'movieclip');
-xcheck_equals(typeof(hardref3), 'movieclip'); // still accessible due to 
onUnload defined for its child
-xcheck_equals(hardref2.getDepth(), -32839);
-xcheck_equals(hardref3.getDepth(), -32849);
-xcheck_equals(hardref3.hardref3child.getDepth(), 1);
+check_equals(typeof(hardref2), 'movieclip');
+check_equals(typeof(hardref3), 'movieclip'); // still accessible due to 
onUnload defined for its child
+check_equals(hardref2.getDepth(), -32839);
+check_equals(hardref3.getDepth(), -32849);
+check_equals(hardref3.hardref3child.getDepth(), 1);
 check_equals(typeof(softref), 'movieclip');
 check_equals(typeof(softref2), 'movieclip');
 check_equals(typeof(softref3), 'movieclip');
 check_equals(typeof(softref3child), 'movieclip');
 check_equals(typeof(softref.member), 'undefined');
 check_equals(typeof(softref._target), 'undefined');
-xcheck_equals(softref2.member, 2);
-xcheck_equals(softref2._target, '/hardref2');
-xcheck_equals(softref3.member, 3);
-xcheck_equals(softref3._target, '/hardref3');
-xcheck_equals(softref3child.member, '3child');
-xcheck_equals(softref3child._target, '/hardref3/hardref3child');
+check_equals(softref2.member, 2);
+check_equals(softref2._target, '/hardref2');
+check_equals(softref3.member, 3);
+check_equals(softref3._target, '/hardref3');
+check_equals(softref3child.member, '3child');
+check_equals(softref3child._target, '/hardref3/hardref3child');
 hardref = 4;
 // Delete is needed, or further inspection functions will hit the variable 
before the character
 delete hardref;

Index: testsuite/misc-ming.all/loop_test7.c
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/loop_test7.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- testsuite/misc-ming.all/loop_test7.c        1 Jul 2007 10:54:57 -0000       
1.5
+++ testsuite/misc-ming.all/loop_test7.c        1 Sep 2007 01:20:47 -0000       
1.6
@@ -122,7 +122,7 @@
   // RemoveObject2 is *before* the DoAction, then typeof(movieClip1) will 
reurn 'undefined'.
   // So Gnash fails here because of action execution order!
   // TODO: add testcase for this(RemoveObject2 placed *before* DoAction within 
the same frame).
-  xcheck_equals(mo, "typeof(movieClip1)", "'movieclip'"); // kept alive for 
calling onUnload!
+  check_equals(mo, "typeof(movieClip1)", "'movieclip'"); // kept alive for 
calling onUnload!
   check_equals(mo, "_root.mc1Constructed", "1");
   SWFMovie_nextFrame(mo);  
   
@@ -133,7 +133,7 @@
 
   check_equals(mo, "typeof(movieClip1)", "'undefined'");
   SWFMovie_add(mo, (SWFBlock)newSWFAction( "gotoAndStop(4);"));
-  xcheck_equals(mo, "typeof(movieClip1)", "'movieclip'");
+  check_equals(mo, "typeof(movieClip1)", "'movieclip'");
 
   // onConstruct is called twice
   check_equals(mo, "_root.mc1Constructed", "2");

Index: testsuite/misc-ming.all/loop_test8.c
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/loop_test8.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- testsuite/misc-ming.all/loop_test8.c        1 Jul 2007 10:54:57 -0000       
1.6
+++ testsuite/misc-ming.all/loop_test8.c        1 Sep 2007 01:20:47 -0000       
1.7
@@ -221,7 +221,7 @@
   check_equals(mo, "typeof(mc2)", "'undefined'"); 
   check_equals(mo, "typeof(mc3)", "'movieclip'"); 
   check_equals(mo, "typeof(mc4)", "'movieclip'"); 
-  xcheck_equals(mo, "typeof(mc5)", "'movieclip'"); // Gnash fails because of 
action execution order 
+  check_equals(mo, "typeof(mc5)", "'movieclip'"); // Gnash fails because of 
action execution order 
   check_equals(mo, "mc1Constructed", "1");
   check_equals(mo, "mc2Constructed", "1"); 
   check_equals(mo, "mc3Constructed", "2"); 

Index: testsuite/misc-ming.all/unload_movieclip_test1.c
===================================================================
RCS file: 
/sources/gnash/gnash/testsuite/misc-ming.all/unload_movieclip_test1.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- testsuite/misc-ming.all/unload_movieclip_test1.c    20 Jul 2007 02:02:08 
-0000      1.3
+++ testsuite/misc-ming.all/unload_movieclip_test1.c    1 Sep 2007 01:20:47 
-0000       1.4
@@ -88,7 +88,7 @@
   add_actions(mo, "mc.onUnload = function () { "
                   "    _root.x = this._currentframe; "
                   "    _root.check_equals(typeof(this),  'movieclip'); "
-                  "    _root.xcheck_equals(this, _root.mc); "
+                  "    _root.check_equals(this, _root.mc); "
                   "};");
   SWFMovie_nextFrame(mo);
   
@@ -99,7 +99,7 @@
   
   // Frame 4: checks
   
-  xcheck_equals(mo, "_root.x", "1");
+  check_equals(mo, "_root.x", "1");
   
   add_actions(mo, "_root.totals(); stop(); ");
   SWFMovie_nextFrame(mo);

Index: testsuite/misc-swfc.all/movieclip_destruction_test2.sc
===================================================================
RCS file: 
/sources/gnash/gnash/testsuite/misc-swfc.all/movieclip_destruction_test2.sc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- testsuite/misc-swfc.all/movieclip_destruction_test2.sc      31 Aug 2007 
14:49:48 -0000      1.5
+++ testsuite/misc-swfc.all/movieclip_destruction_test2.sc      1 Sep 2007 
01:20:47 -0000       1.6
@@ -87,12 +87,12 @@
     { 
        _root.mc2UnlaodedCount++;     
        // mc2.testvar keeps alive as long as mc2 is alive
-       _root.xcheck_equals(mc2.testvar, 100); 
+       _root.check_equals(mc2.testvar, 100); 
     };
     mc3.onUnload = function ()  
     { 
        _root.mc3UnlaodedCount++; 
-       _root.xcheck_equals(mc3.testvar, 100);
+       _root.check_equals(mc3.testvar, 100);
     };
     
     mc2.testvar = 100;
@@ -114,38 +114,38 @@
     xcheck_equals(mc2UnlaodedCount, 1); //mc2.onUnload triggered
     xcheck_equals(mc2UnlaodedCount, 1); //mc3.onUnload triggered
     check_equals(mc1Ref.valueOf(), null);
-    xcheck_equals(mc2Ref, mc2);
-    xcheck_equals(mc3Ref, mc3);
+    check_equals(mc2Ref, mc2);
+    check_equals(mc3Ref, mc3);
     
     check_equals(typeof(mc1), 'undefined'); //cann't access the hard reference
-    xcheck_equals(typeof(mc2), 'movieclip'); // mc2 is still accessable
-    xcheck_equals(typeof(mc3), 'movieclip'); // mc3 is still accessable
-    xcheck_equals(mc2.getDepth(), -16387);   // depth of mc2 changed after 
onUnload
-    xcheck_equals(mc3.getDepth(), -16388);   // depth of mc3 changed after 
onUnload
+    check_equals(typeof(mc2), 'movieclip'); // mc2 is still accessable
+    check_equals(typeof(mc3), 'movieclip'); // mc3 is still accessable
+    check_equals(mc2.getDepth(), -16387);   // depth of mc2 changed after 
onUnload
+    check_equals(mc3.getDepth(), -16388);   // depth of mc3 changed after 
onUnload
     
     mc2.swapDepths(mc3);      
-    xcheck_equals(mc2.getDepth(), -16387);  // depth not change after 
swapDepths
-    xcheck_equals(mc3.getDepth(), -16388);  // depth not change after 
swapDepths
+    check_equals(mc2.getDepth(), -16387);  // depth not change after swapDepths
+    check_equals(mc3.getDepth(), -16388);  // depth not change after swapDepths
     
     mc2.swapDephts(-10);
     mc2.swapDephts(10);
-    xcheck_equals(mc2.getDepth(), -16387);  // depth not change after 
swapDepths
-    xcheck_equals(mc3.getDepth(), -16388);  // depth not change after 
swapDepths
+    check_equals(mc2.getDepth(), -16387);  // depth not change after swapDepths
+    check_equals(mc3.getDepth(), -16388);  // depth not change after swapDepths
     
-    xcheck_equals(mc2.testvar, 100);       
-    xcheck_equals(mc3.testvar, 100); 
+    check_equals(mc2.testvar, 100);       
+    check_equals(mc3.testvar, 100); 
     mc2.removMovieClip();
     mc3.removMovieClip();
     xcheck_equals(mc2UnlaodedCount, 1); //mc2.onUnload not triggered again
     xcheck_equals(mc2UnlaodedCount, 1); //mc3.onUnload not triggered again
-    xcheck_equals(typeof(mc2), 'movieclip'); // mc2 is still accessible
-    xcheck_equals(typeof(mc3), 'movieclip'); // mc3 is still accessible
-    xcheck_equals(mc2.getDepth(), -16387); 
-    xcheck_equals(mc3.getDepth(), -16388);  
-    xcheck_equals(mc2._x, 200); 
-    xcheck_equals(mc3._y, 300);  
-    xcheck_equals(mc2.testvar, 100); 
-    xcheck_equals(mc3.testvar, 100); 
+    check_equals(typeof(mc2), 'movieclip'); // mc2 is still accessible
+    check_equals(typeof(mc3), 'movieclip'); // mc3 is still accessible
+    check_equals(mc2.getDepth(), -16387); 
+    check_equals(mc3.getDepth(), -16388);  
+    check_equals(mc2._x, 200); 
+    check_equals(mc3._y, 300);  
+    check_equals(mc2.testvar, 100); 
+    check_equals(mc3.testvar, 100); 
     
     mc2.onUnload();
     mc3.onUnload();

Index: testsuite/swfdec/PASSING
===================================================================
RCS file: /sources/gnash/gnash/testsuite/swfdec/PASSING,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- testsuite/swfdec/PASSING    31 Aug 2007 21:53:33 -0000      1.27
+++ testsuite/swfdec/PASSING    1 Sep 2007 01:20:47 -0000       1.28
@@ -193,3 +193,6 @@
 with-outobject-6.swf
 with-outobject-7.swf
 with-outobject-8.swf
+remove-depths-6.swf
+remove-depths-7.swf
+remove-depths-8.swf




reply via email to

[Prev in Thread] Current Thread [Next in Thread]