CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/09/05 15:48:09
Modified files: . : ChangeLog server : dlist.cpp dlist.h sprite_instance.cpp testsuite/misc-ming.all: action_execution_order_test2.c Log message: * server/dlist.{cpp,h}: also maintain a list of characters by placement and provide a visitByPlacement for visiting them. * server/sprite_instance.cpp: (advance_sprite): visit DisplayList in reverse-placement order when advancing old and newly added characters. * testsuite/misc-ming.all/action_execution_order_test2.c: one success in action execution order. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4230&r2=1.4231 http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.86&r2=1.87 http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.h?cvsroot=gnash&r1=1.49&r2=1.50 http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.327&r2=1.328 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/action_execution_order_test2.c?cvsroot=gnash&r1=1.2&r2=1.3 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4230 retrieving revision 1.4231 diff -u -b -r1.4230 -r1.4231 --- ChangeLog 5 Sep 2007 13:05:14 -0000 1.4230 +++ ChangeLog 5 Sep 2007 15:48:07 -0000 1.4231 @@ -1,3 +1,13 @@ +2007-09-05 Sandro Santilli <[EMAIL PROTECTED]> + + * server/dlist.{cpp,h}: also maintain a list of characters by + placement and provide a visitByPlacement for visiting them. + * server/sprite_instance.cpp: (advance_sprite): visit DisplayList + in reverse-placement order when advancing old and newly added + characters. + * testsuite/misc-ming.all/action_execution_order_test2.c: one success + in action execution order. + 2007-09-05 Tomas Groth Christensen <[EMAIL PROTECTED]> * backend/sound_handler_{sdl,gst}.cpp: Remove primitive Index: server/dlist.cpp =================================================================== RCS file: /sources/gnash/gnash/server/dlist.cpp,v retrieving revision 1.86 retrieving revision 1.87 diff -u -b -r1.86 -r1.87 --- server/dlist.cpp 5 Sep 2007 09:47:55 -0000 1.86 +++ server/dlist.cpp 5 Sep 2007 15:48:08 -0000 1.87 @@ -102,8 +102,8 @@ testInvariant(); int nexthighestdepth=0; - for (const_iterator it = _characters.begin(), - itEnd = _characters.end(); + for (const_iterator it = _charsByDepth.begin(), + itEnd = _charsByDepth.end(); it != itEnd; ++it) { character* ch = it->get(); @@ -126,8 +126,8 @@ //GNASH_REPORT_FUNCTION; //dump(); - for (iterator it = _characters.begin(), - itEnd = _characters.end(); + for (iterator it = _charsByDepth.begin(), + itEnd = _charsByDepth.end(); it != itEnd; ++it) { character* ch = it->get(); @@ -151,11 +151,11 @@ testInvariant(); container_type::iterator it = find_if( - _characters.begin(), - _characters.end(), + _charsByDepth.begin(), + _charsByDepth.end(), NameEquals(name)); - if ( it == _characters.end() ) return NULL; + if ( it == _charsByDepth.end() ) return NULL; else return it->get(); } @@ -166,11 +166,11 @@ testInvariant(); container_type::iterator it = find_if( - _characters.begin(), - _characters.end(), + _charsByDepth.begin(), + _charsByDepth.end(), NameEqualsNoCase(name)); - if ( it == _characters.end() ) return NULL; + if ( it == _charsByDepth.end() ) return NULL; else return it->get(); } @@ -200,15 +200,15 @@ ch->set_clip_depth(clip_depth); container_type::iterator it = find_if( - _characters.begin(), _characters.end(), + _charsByDepth.begin(), _charsByDepth.end(), DepthGreaterOrEqual(depth)); - if ( it == _characters.end() || (*it)->get_depth() != depth ) + if ( it == _charsByDepth.end() || (*it)->get_depth() != depth ) { //log_msg(_("place_character: new character at depth %d"), depth); // add the new char - _characters.insert(it, DisplayItem(ch)); + _charsByDepth.insert(it, DisplayItem(ch)); } else { @@ -221,6 +221,8 @@ // make a copy (before replacing) boost::intrusive_ptr<character> oldCh = *it; + _timelineChars.remove(oldCh); + // replace existing char (before calling unload!) *it = DisplayItem(ch); @@ -236,6 +238,7 @@ // Give life to this instance ch->construct(); + _timelineChars.push_front(DisplayItem(ch)); testInvariant(); } @@ -246,17 +249,20 @@ int depth = ch->get_depth(); container_type::iterator it = find_if( - _characters.begin(), _characters.end(), + _charsByDepth.begin(), _charsByDepth.end(), DepthGreaterOrEqual(depth)); - if ( it == _characters.end() || (*it)->get_depth() != depth ) + if ( it == _charsByDepth.end() || (*it)->get_depth() != depth ) { - _characters.insert(it, DisplayItem(ch)); + _charsByDepth.insert(it, DisplayItem(ch)); } else if ( replace ) { + _timelineChars.remove(*it); *it = DisplayItem(ch); } + _timelineChars.push_front(DisplayItem(ch)); + testInvariant(); } @@ -306,12 +312,12 @@ // ch->restart(); container_type::iterator it = find_if( - _characters.begin(), _characters.end(), + _charsByDepth.begin(), _charsByDepth.end(), DepthGreaterOrEqual(depth)); DisplayItem di(ch); - if ( it == _characters.end() || (*it)->get_depth() != depth ) + if ( it == _charsByDepth.end() || (*it)->get_depth() != depth ) { // Error, no existing object found at depth. @@ -321,7 +327,7 @@ // ); // add the new char - _characters.insert(it, di); + _charsByDepth.insert(it, di); } else @@ -346,6 +352,8 @@ // remember bounds of old char oldch->add_invalidated_bounds(old_ranges, true); + _timelineChars.remove(oldch); + // replace existing char (before calling unload) *it = di; @@ -369,6 +377,7 @@ // Give life to this instance ch->construct(); + _timelineChars.push_front(DisplayItem(ch)); testInvariant(); } @@ -444,24 +453,24 @@ //dump(); #ifndef NDEBUG - container_type::size_type size = _characters.size(); + container_type::size_type size = _charsByDepth.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(), - _characters.end(), + _charsByDepth.begin(), + _charsByDepth.end(), DepthEquals(depth)); - if ( it != _characters.end() ) + if ( it != _charsByDepth.end() ) { // Make a copy (before erasing) boost::intrusive_ptr<character> oldCh = *it; // Erase (before callign unload) - _characters.erase(it); + _charsByDepth.erase(it); if ( oldCh->unload() ) { @@ -475,7 +484,7 @@ } #ifndef NDEBUG - assert(size >= _characters.size()); + assert(size >= _charsByDepth.size()); #endif testInvariant(); @@ -507,20 +516,20 @@ assert(srcdepth != newdepth); // TODO: optimize this scan by taking ch1 depth into account ? - container_type::iterator it1 = find(_characters.begin(), _characters.end(), ch1); + container_type::iterator it1 = find(_charsByDepth.begin(), _charsByDepth.end(), ch1); // upper bound ... - container_type::iterator it2 = find_if(_characters.begin(), _characters.end(), + container_type::iterator it2 = find_if(_charsByDepth.begin(), _charsByDepth.end(), DepthGreaterOrEqual(newdepth)); - if ( it1 == _characters.end() ) + if ( it1 == _charsByDepth.end() ) { log_error("First argument to DisplayList::swapDepth() is NOT a character in the list. Call ignored."); return; } // Found another character at the given depth - if ( it2 != _characters.end() && (*it2)->get_depth() == newdepth ) + if ( it2 != _charsByDepth.end() && (*it2)->get_depth() == newdepth ) { DisplayItem ch2 = *it2; @@ -543,8 +552,8 @@ // Move the character to the new position // NOTE: insert *before* erasing, in case the list is // the only referer of the ref-counted character - _characters.insert(it2, ch1); - _characters.erase(it1); + _charsByDepth.insert(it2, ch1); + _charsByDepth.erase(it1); } // don't change depth before the iter_swap case above, as @@ -591,8 +600,8 @@ std::vector<DisplayItem> toReinsert; - iterator it = beginNonRemoved(_characters); - for (iterator itEnd = _characters.end(); it != itEnd; ) + iterator it = beginNonRemoved(_charsByDepth); + for (iterator itEnd = _charsByDepth.end(); it != itEnd; ) { testInvariant(); @@ -619,7 +628,7 @@ if ( ! info ) { // Replace (before calling unload) - it = _characters.erase(it); + it = _charsByDepth.erase(it); if ( call_unload ) { @@ -641,7 +650,7 @@ // (I guess there can't be any as_value pointing at this // if it's not ActionScriptReferenceable after all...) // - it = _characters.erase(it); + it = _charsByDepth.erase(it); continue; } @@ -652,7 +661,7 @@ // Not to be saved, killing // Replace (before calling unload) - it = _characters.erase(it); + it = _charsByDepth.erase(it); if ( call_unload ) { @@ -695,7 +704,7 @@ assert(&exclude != this); - const container_type& keepchars = exclude._characters; + const container_type& keepchars = exclude._charsByDepth; std::vector<DisplayItem> toReinsert; @@ -703,7 +712,7 @@ const_iterator keepEnd = keepchars.end(); //int called=0; - for (iterator it = _characters.begin(), itEnd = _characters.end(); it != itEnd; ) + for (iterator it = _charsByDepth.begin(), itEnd = _charsByDepth.end(); it != itEnd; ) { testInvariant(); // TODO: expensive @@ -724,9 +733,7 @@ if (is_affected == false) { - bool needReinsert = false; - - it = _characters.erase(it); + it = _charsByDepth.erase(it); if ( call_unload ) { @@ -758,11 +765,11 @@ testInvariant(); - const container_type dropchars = from._characters; + const container_type dropchars = from._charsByDepth; std::vector<DisplayItem> toReinsert; - for (iterator it = _characters.begin(), itEnd = _characters.end(); it != itEnd; ) + for (iterator it = _charsByDepth.begin(), itEnd = _charsByDepth.end(); it != itEnd; ) { // make a copy DisplayItem di = *it; @@ -779,7 +786,8 @@ if (is_affected) { - it = _characters.erase(it); + _timelineChars.remove(*it); + it = _charsByDepth.erase(it); if ( call_unload ) { @@ -808,14 +816,15 @@ testInvariant(); - for (iterator it = _characters.begin(), itEnd = _characters.end(); it != itEnd; ) + for (iterator it = _charsByDepth.begin(), itEnd = _charsByDepth.end(); it != itEnd; ) { // make a copy DisplayItem di = *it; if ( ! di->unload() ) // no event handler queued, we remove { - it = _characters.erase(it); + _timelineChars.remove(*it); // or we might simply .clear() it at the end, since we don't need them for ::advance anymore + it = _charsByDepth.erase(it); } else { @@ -825,7 +834,7 @@ testInvariant(); - return ! _characters.empty(); + return ! _charsByDepth.empty(); } @@ -837,16 +846,17 @@ testInvariant(); -// container_type::size_type size = _characters.size(); +// container_type::size_type size = _charsByDepth.size(); // That there was no crash gnash we iterate through the copy - std::list<DisplayItem> tmp_list = _characters; + //std::list<DisplayItem> tmp_list = _charsByDepth; + std::list<DisplayItem> tmp_list = _timelineChars; // 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); + //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(); + iterator it = tmp_list.begin(); for (iterator itEnd = tmp_list.end(); it != itEnd; ++it) { testInvariant(); // expensive !! @@ -874,7 +884,7 @@ // // Need to test to see what Flash does. -// if (_characters.size() != size) +// if (_charsByDepth.size() != size) // { // log_error(_("gnash bug: dlist size changed due to character actions, bailing on update")); // break; @@ -913,9 +923,9 @@ std::stack<int> clipDepthStack; // 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) + iterator it = beginNonRemoved(_charsByDepth); + //iterator it = _charsByDepth.begin(); + for(iterator endIt = _charsByDepth.end(); it != endIt; ++it) { character* ch = it->get(); assert(ch); @@ -988,8 +998,8 @@ //testInvariant(); int num=0; - for( const_iterator it = _characters.begin(), - endIt = _characters.end(); + for( const_iterator it = _charsByDepth.begin(), + endIt = _charsByDepth.end(); it != endIt; ++it) { const DisplayItem& dobj = *it; @@ -1007,8 +1017,8 @@ testInvariant(); - iterator it = beginNonRemoved(_characters); - for( iterator endIt = _characters.end(); it != endIt; ++it) + iterator it = beginNonRemoved(_charsByDepth); + for( iterator endIt = _charsByDepth.end(); it != endIt; ++it) { DisplayItem& dobj = *it; #ifndef GNASH_USE_GC @@ -1033,19 +1043,33 @@ void DisplayList::sort() { - _characters.sort(DisplayItemDepthLess()); + _charsByDepth.sort(DisplayItemDepthLess()); } std::ostream& operator<< (std::ostream& os, const DisplayList& dl) { - for (DisplayList::const_iterator it = dl._characters.begin(), - itEnd = dl._characters.end(); + os << "By depth: "; + for (DisplayList::const_iterator it = dl._charsByDepth.begin(), + itEnd = dl._charsByDepth.end(); + it != itEnd; + ++it) + { + const DisplayItem& item = *it; + if ( it != dl._charsByDepth.begin() ) os << " | "; + os << "ch id:" << item->get_id() + << " name:" << item->get_name() + << " depth:" << item->get_depth(); + } + + os << " =|= By placement: "; + for (DisplayList::const_iterator it = dl._timelineChars.begin(), + itEnd = dl._timelineChars.end(); it != itEnd; ++it) { const DisplayItem& item = *it; - if ( it != dl._characters.begin() ) os << " | "; - os << "Character id:" << item->get_id() + if ( it != dl._charsByDepth.begin() ) os << " | "; + os << "ch id:" << item->get_id() << " name:" << item->get_name() << " depth:" << item->get_depth(); } @@ -1067,12 +1091,12 @@ // TODO: optimize this by searching from the end(lowest depth). container_type::iterator it = find_if( - _characters.begin(), _characters.end(), + _charsByDepth.begin(), _charsByDepth.end(), DepthGreaterOrEqual(newDepth)); - if ( it == _characters.end() || (*it)->get_depth() != newDepth ) + if ( it == _charsByDepth.end() || (*it)->get_depth() != newDepth ) { // add the new char - _characters.insert(it, DisplayItem(ch)); + _charsByDepth.insert(it, DisplayItem(ch)); } else { @@ -1106,11 +1130,11 @@ // 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()); + //log_debug(" first invTest passed, _charsByDepth have %d entries", _charsByDepth.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()); + iterator last = std::remove_if(_charsByDepth.begin(), _charsByDepth.end(), boost::bind(&character::isUnloaded, _1)); + _charsByDepth.erase(last, _charsByDepth.end()); + //log_debug(" After remove_if, _charsByDepth have %d entries - dumping them", _charsByDepth.size()); //dump(); //log_debug(" Now testing invariant again"); testInvariant(); Index: server/dlist.h =================================================================== RCS file: /sources/gnash/gnash/server/dlist.h,v retrieving revision 1.49 retrieving revision 1.50 diff -u -b -r1.49 -r1.50 --- server/dlist.h 5 Sep 2007 09:47:55 -0000 1.49 +++ server/dlist.h 5 Sep 2007 15:48:08 -0000 1.50 @@ -59,7 +59,7 @@ 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) + for (const_iterator it=_charsByDepth.begin(), itEnd=_charsByDepth.end(); it!=itEnd; ++it) { boost::intrusive_ptr<character> ch = *it; int depth = ch->get_depth(); @@ -211,7 +211,8 @@ /// Clear the display list. void clear() { - _characters.clear(); + _charsByDepth.clear(); + _timelineChars.clear(); } /// Unload the characters in this DisplayList removing @@ -306,7 +307,7 @@ clear(); } - /// advance referenced characters. + /// advance referenced characters, by reverse-placement order void advance(float delta_time); /// \brief @@ -386,6 +387,10 @@ template <class V> inline void visitAll(V& visitor) const; + /// Visit each and all character in the list in reverse-placement order + template <class V> + inline void visitByReversePlacement(V& visitor) const; + /// dump list to logfile/stderr void dump() const; @@ -397,13 +402,13 @@ /// Return number of elements in the list size_t size() const { - return _characters.size(); + return _charsByDepth.size(); } /// Return true if the list contains no elements bool empty() const { - return _characters.empty(); + return _charsByDepth.empty(); } /// Return the next highest available depth @@ -427,9 +432,9 @@ /// void sort (); - bool operator==(const DisplayList& other) const { return _characters == other._characters; } + bool operator==(const DisplayList& other) const { return _charsByDepth == other._charsByDepth; } - bool operator!=(const DisplayList& other) const { return _characters != other._characters; } + bool operator!=(const DisplayList& other) const { return _charsByDepth != other._charsByDepth; } private: @@ -457,7 +462,10 @@ /// void reinsertRemovedCharacter(boost::intrusive_ptr<character> ch); - container_type _characters; + container_type _charsByDepth; + + // Stored by placement order (first placed first) + container_type _timelineChars; }; @@ -466,8 +474,8 @@ void DisplayList::visitForward(V& visitor) { - for (iterator it = _characters.begin(), - itEnd = _characters.end(); + for (iterator it = _charsByDepth.begin(), + itEnd = _charsByDepth.end(); it != itEnd; ++it) { DisplayItem& di = *it; @@ -479,8 +487,8 @@ void DisplayList::visitBackward(V& visitor) { - for (reverse_iterator it = _characters.rbegin(), - itEnd = _characters.rend(); + for (reverse_iterator it = _charsByDepth.rbegin(), + itEnd = _charsByDepth.rend(); it != itEnd; ++it) { DisplayItem& di = *it; @@ -492,8 +500,8 @@ void DisplayList::visitAll(V& visitor) { - for (iterator it = _characters.begin(), - itEnd = _characters.end(); + for (iterator it = _charsByDepth.begin(), + itEnd = _charsByDepth.end(); it != itEnd; ++it) { visitor(it->get()); @@ -504,8 +512,20 @@ void DisplayList::visitAll(V& visitor) const { - for (const_iterator it = _characters.begin(), - itEnd = _characters.end(); + for (const_iterator it = _charsByDepth.begin(), + itEnd = _charsByDepth.end(); + it != itEnd; ++it) + { + visitor(it->get()); + } +} + +template <class V> +void +DisplayList::visitByReversePlacement(V& visitor) const +{ + for (const_iterator it = _timelineChars.begin(), + itEnd = _timelineChars.end(); it != itEnd; ++it) { visitor(it->get()); Index: server/sprite_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v retrieving revision 1.327 retrieving revision 1.328 diff -u -b -r1.327 -r1.328 --- server/sprite_instance.cpp 5 Sep 2007 09:47:55 -0000 1.327 +++ server/sprite_instance.cpp 5 Sep 2007 15:48:08 -0000 1.328 @@ -2338,8 +2338,7 @@ // { AdvancerVisitor visitor(delta_time); - DisplayList stillAlive = oldDisplayList; - stillAlive.visitAll(visitor); + oldDisplayList.visitByReversePlacement(visitor); } // Now execute actions on this timeline, after actions @@ -3690,8 +3689,12 @@ m_display_list.visitAll(marker); + m_display_list.visitByReversePlacement(marker); + oldDisplayList.visitAll(marker); + oldDisplayList.visitByReversePlacement(marker); + _drawable->setReachable(); _drawable_inst->setReachable(); Index: testsuite/misc-ming.all/action_execution_order_test2.c =================================================================== RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/action_execution_order_test2.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -b -r1.2 -r1.3 --- testsuite/misc-ming.all/action_execution_order_test2.c 1 Jul 2007 10:54:48 -0000 1.2 +++ testsuite/misc-ming.all/action_execution_order_test2.c 5 Sep 2007 15:48:08 -0000 1.3 @@ -134,7 +134,7 @@ SWFMovie_nextFrame(mo); /* 4th frame */ - xcheck_equals(mo, "_root.x2", "'depth11+depth12+depth10+depth9+depth13+'"); + check_equals(mo, "_root.x2", "'depth11+depth12+depth10+depth9+depth13+'"); add_actions(mo, " _root.totals(); stop(); "); SWFMovie_nextFrame(mo); /* 5th frame */ _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit