[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gnash-commit] gnash ChangeLog server/character.cpp server/cha...
From: |
zou lunkai |
Subject: |
Re: [Gnash-commit] gnash ChangeLog server/character.cpp server/cha... |
Date: |
Tue, 4 Sep 2007 14:57:35 +0800 |
> + std::for_each(toReinsert.begin(), toReinsert.end(),
> + boost::bind(&DisplayList::reinsertRemovedCharacter, this,
> _1));
> +
I understand this is still under working. Just for a discussion.
Is it too expensive to re-insert all removed characters? I think
re-insertion is only needed for sprites. AFAIK, no other characters
support onUnload/onLoad.
On 9/1/07, Sandro Santilli <address@hidden> wrote:
> 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
>
>
> _______________________________________________
> Gnash-commit mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/gnash-commit
>