CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/09/13 13:57:49
Modified files: . : ChangeLog server : button_character_instance.cpp dlist.cpp dlist.h movie_root.cpp movie_root.h sprite_instance.cpp video_stream_instance.cpp video_stream_instance.h testsuite/misc-ming.all: action_execution_order_test11.c Log message: * server/dlist.{cpp,h}: drop the second list only used for chils advancement (_timelineChars) and associated accessors (visitAllByReversePlacement). * server/movie_root.{cpp,h}: Add a global "advanceable" characters list, used for advancement (in ::advance); provide an addLiveChar() method to add characters that are willing to be advanced there. * server/button_character_instance.cpp (construct): register as live character with the movie_root. * server/video_stream_instance.{cpp,h}: add a ::construct() method to properly register as live character with the movie_root * server/sprite_instance.cpp (advance_sprite): forget about advancing childs, movie_root will take care of that; (construct): register self as a live character with the movie_root. * testsuite/misc-ming.all/action_execution_order_test11.c: no more expected failures here. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4302&r2=1.4303 http://cvs.savannah.gnu.org/viewcvs/gnash/server/button_character_instance.cpp?cvsroot=gnash&r1=1.54&r2=1.55 http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.91&r2=1.92 http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.h?cvsroot=gnash&r1=1.51&r2=1.52 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.87&r2=1.88 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.73&r2=1.74 http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.339&r2=1.340 http://cvs.savannah.gnu.org/viewcvs/gnash/server/video_stream_instance.cpp?cvsroot=gnash&r1=1.37&r2=1.38 http://cvs.savannah.gnu.org/viewcvs/gnash/server/video_stream_instance.h?cvsroot=gnash&r1=1.19&r2=1.20 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/action_execution_order_test11.c?cvsroot=gnash&r1=1.3&r2=1.4 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4302 retrieving revision 1.4303 diff -u -b -r1.4302 -r1.4303 --- ChangeLog 13 Sep 2007 10:14:56 -0000 1.4302 +++ ChangeLog 13 Sep 2007 13:57:48 -0000 1.4303 @@ -1,5 +1,23 @@ 2007-09-13 Sandro Santilli <[EMAIL PROTECTED]> + * server/dlist.{cpp,h}: drop the second list only used for + chils advancement (_timelineChars) and associated accessors + (visitAllByReversePlacement). + * server/movie_root.{cpp,h}: Add a global "advanceable" characters + list, used for advancement (in ::advance); provide an addLiveChar() + method to add characters that are willing to be advanced there. + * server/button_character_instance.cpp (construct): register as + live character with the movie_root. + * server/video_stream_instance.{cpp,h}: add a ::construct() method + to properly register as live character with the movie_root + * server/sprite_instance.cpp (advance_sprite): forget about advancing + childs, movie_root will take care of that; (construct): register + self as a live character with the movie_root. + * testsuite/misc-ming.all/action_execution_order_test11.c: no more + expected failures here. + +2007-09-13 Sandro Santilli <[EMAIL PROTECTED]> + * server/sprite_instance.{cpp,h}: drop obsoleted oldDisplayList. 2007-09-13 Sandro Santilli <[EMAIL PROTECTED]> Index: server/button_character_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/button_character_instance.cpp,v retrieving revision 1.54 retrieving revision 1.55 diff -u -b -r1.54 -r1.55 --- server/button_character_instance.cpp 9 Aug 2007 17:25:47 -0000 1.54 +++ server/button_character_instance.cpp 13 Sep 2007 13:57:49 -0000 1.55 @@ -859,6 +859,9 @@ void button_character_instance::construct() { + // Register this button instance as a live character + _vm.getRoot().addLiveChar(this); + size_t r, r_num = m_def->m_button_records.size(); m_record_character.resize(r_num); Index: server/dlist.cpp =================================================================== RCS file: /sources/gnash/gnash/server/dlist.cpp,v retrieving revision 1.91 retrieving revision 1.92 diff -u -b -r1.91 -r1.92 --- server/dlist.cpp 10 Sep 2007 09:07:24 -0000 1.91 +++ server/dlist.cpp 13 Sep 2007 13:57:49 -0000 1.92 @@ -221,8 +221,6 @@ // make a copy (before replacing) boost::intrusive_ptr<character> oldCh = *it; - _timelineChars.remove(oldCh); - // replace existing char (before calling unload!) *it = DisplayItem(ch); @@ -238,7 +236,6 @@ // Give life to this instance ch->construct(); - _timelineChars.push_front(DisplayItem(ch)); testInvariant(); } @@ -257,12 +254,9 @@ } else if ( replace ) { - _timelineChars.remove(*it); *it = DisplayItem(ch); } - _timelineChars.push_front(DisplayItem(ch)); - testInvariant(); } @@ -352,8 +346,6 @@ // remember bounds of old char oldch->add_invalidated_bounds(old_ranges, true); - _timelineChars.remove(oldch); - // replace existing char (before calling unload) *it = di; @@ -377,7 +369,6 @@ // Give life to this instance ch->construct(); - _timelineChars.push_front(DisplayItem(ch)); testInvariant(); } @@ -787,7 +778,6 @@ if (is_affected) { - _timelineChars.remove(*it); it = _charsByDepth.erase(it); if ( call_unload ) @@ -824,7 +814,6 @@ if ( ! di->unload() ) // no event handler queued, we remove { - _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 @@ -839,80 +828,6 @@ } -void -DisplayList::advance(float delta_time) -// advance referenced characters. -{ - //GNASH_REPORT_FUNCTION; - - testInvariant(); - -// container_type::size_type size = _charsByDepth.size(); - - // That there was no crash gnash we iterate through the copy - //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); - //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! - // - // What's the correct thing to do here? Options: - // - // * copy the display list at the beginning, - // iterate through the copy - // - // * use (or emulate) a linked list instead of - // an array (still has problems; e.g. what - // happens if the next or current object gets - // removed from the dlist?) - // - // * iterate through current array in depth - // order. Always find the next object using a - // search of current array (but optimize the - // common case where nothing has changed). - // - // * ??? - // - // Need to test to see what Flash does. - -// if (_charsByDepth.size() != size) -// { -// log_error(_("gnash bug: dlist size changed due to character actions, bailing on update")); -// break; -// } - - // keep the character alive in case actions in it - // will remove it from displaylist. - boost::intrusive_ptr<character> ch = *it; - assert(ch!=NULL); - - if ( ch->isUnloaded() ) // debugging - { - log_error("character at depth %d is unloaded", ch->get_depth()); - // No need to advance an unloaded character. It would be better - // if unloaded characters are not even in this list. - continue; - } - assert(! ch->isUnloaded() ); // we don't advance unloaded chars - - - ch->advance(delta_time); - } - - testInvariant(); -} - - // Display the referenced characters. Lower depths // are obscured by higher depths. void @@ -1062,19 +977,6 @@ << " 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._timelineChars.begin() ) os << " | "; - os << "ch id:" << item->get_id() - << " name:" << item->get_name() - << " depth:" << item->get_depth(); - } - return os; } @@ -1134,9 +1036,6 @@ iterator last = std::remove_if(_charsByDepth.begin(), _charsByDepth.end(), boost::bind(&character::isUnloaded, _1)); _charsByDepth.erase(last, _charsByDepth.end()); - last = std::remove_if(_timelineChars.begin(), _timelineChars.end(), boost::bind(&character::isUnloaded, _1)); - _timelineChars.erase(last, _timelineChars.end()); - testInvariant(); } Index: server/dlist.h =================================================================== RCS file: /sources/gnash/gnash/server/dlist.h,v retrieving revision 1.51 retrieving revision 1.52 diff -u -b -r1.51 -r1.52 --- server/dlist.h 7 Sep 2007 14:49:10 -0000 1.51 +++ server/dlist.h 13 Sep 2007 13:57:49 -0000 1.52 @@ -212,7 +212,6 @@ void clear() { _charsByDepth.clear(); - _timelineChars.clear(); } /// Unload the characters in this DisplayList removing @@ -307,9 +306,6 @@ clear(); } - /// advance referenced characters, by reverse-placement order - void advance(float delta_time); - /// \brief /// Display the referenced characters. /// Lower depths are obscured by higher depths. @@ -387,10 +383,6 @@ 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; @@ -464,10 +456,6 @@ container_type _charsByDepth; - // Stored by placement order (first placed first) - container_type _timelineChars; - - }; template <class V> @@ -520,18 +508,6 @@ } } -template <class V> -void -DisplayList::visitByReversePlacement(V& visitor) const -{ - for (const_iterator it = _timelineChars.begin(), - itEnd = _timelineChars.end(); - it != itEnd; ++it) - { - visitor(it->get()); - } -} - std::ostream& operator<< (std::ostream&, const DisplayList&); } // namespace gnash Index: server/movie_root.cpp =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.cpp,v retrieving revision 1.87 retrieving revision 1.88 diff -u -b -r1.87 -r1.88 --- server/movie_root.cpp 12 Sep 2007 10:57:05 -0000 1.87 +++ server/movie_root.cpp 13 Sep 2007 13:57:49 -0000 1.88 @@ -41,6 +41,7 @@ #include <typeinfo> #include <cassert> #include <boost/algorithm/string/case_conv.hpp> +#include <boost/bind.hpp> using namespace std; @@ -670,7 +671,9 @@ // 2. by different machines the random gave different numbers tu_random::next_random(); - advanceAllLevels(delta_time); + // Advance all non-unloaded characters in the LiveChars list + // in reverse order (last added, first advanced) + advanceLiveChars(delta_time); #ifdef NEW_KEY_LISTENER_LIST_DESIGN cleanup_key_listeners(); @@ -1181,6 +1184,15 @@ // Mark global key object if ( _keyobject ) _keyobject->setReachable(); + + // TODO: check if we need to mark _liveChars too + // it should be checked that all characters there + // are NOT unloaded as GC collector is run *after* + // cleanup of the list (supposedly). + // Also, it's likely that any non-unloaded character + // will be also marked as reachable by scanning the + // DisplayList... + // } #endif // GNASH_USE_GC @@ -1196,51 +1208,58 @@ } void -movie_root::advanceAllLevels(float delta_time) +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) + // Remove unloaded characters from the _liveChars list + _liveChars.remove_if(boost::bind(&character::isUnloaded, _1)); + + // Let every sprite cleanup the local DisplayList + // + // TODO: we might skip this additinal scan by delegating + // cleanup of the local DisplayLists in the ::display + // method of each sprite, but that will introduce + // problems when we'll implement skipping ::display() + // when late on FPS. Alternatively we may have the + // sprite_instance::markReachableResources take care + // of cleaning up unloaded... but that will likely + // introduce problems when allowing the GC to run + // at arbitrary times. + // The invariant to keep is that cleanup of unloaded characters + // in local display lists must happen at the *end* of global action + // queue processing. + // + for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) { - advanceMovie(i->second, delta_time); + i->second->cleanupDisplayList(); } } +/*static private*/ void -movie_root::cleanupDisplayList() +movie_root::advanceLiveChar(boost::intrusive_ptr<character> ch, float delta_time) { - // 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) + if ( ! ch->isUnloaded() ) { - i->second->cleanupDisplayList(); +#ifdef GNASH_DEBUG + log_debug(" advancing character %s", ch->getTarget().c_str()); +#endif + ch->advance(delta_time); } +#ifdef GNASH_DEBUG + else { + log_debug(" character %s is unloaded, not advancing it", ch->getTarget().c_str()); + } +#endif } void -movie_root::advanceMovie(boost::intrusive_ptr<sprite_instance> movie, float delta_time) +movie_root::advanceLiveChars(float delta_time) { #ifdef GNASH_DEBUG - size_t totframes = movie->get_frame_count(); - size_t prevframe = movie->get_current_frame(); -#endif - - movie->advance(delta_time); - -#ifdef GNASH_DEBUG - size_t curframe = movie->get_current_frame(); - - log_msg("movie_root::advance advanced level %d movie from " - SIZET_FMT "/" SIZET_FMT - " to " SIZET_FMT "/" SIZET_FMT - " (movie is %s%s)", - movie->get_depth(), prevframe, totframes, curframe, totframes, - typeName(*movie).c_str(), - movie->get_play_state() == sprite_instance::STOP ? " - now in STOP mode" : ""); + log_debug("---- movie_root::advance: %d live characters in the global list", _liveChars.size()); #endif + std::for_each(_liveChars.begin(), _liveChars.end(), boost::bind(advanceLiveChar, _1, delta_time)); } } // namespace gnash Index: server/movie_root.h =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.h,v retrieving revision 1.73 retrieving revision 1.74 diff -u -b -r1.73 -r1.74 --- server/movie_root.h 12 Sep 2007 10:57:05 -0000 1.73 +++ server/movie_root.h 13 Sep 2007 13:57:49 -0000 1.74 @@ -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.73 2007/09/12 10:57:05 bwy Exp $ */ +/* $Id: movie_root.h,v 1.74 2007/09/13 13:57:49 strk Exp $ */ /// \page events_handling Handling of user events /// @@ -440,9 +440,23 @@ /// Restart all levels void restart(); + /// Entry point for movie advancement + // + /// This function does: + /// - Execute all timers + /// - Reset the next Random number + /// - Advance all advanceable characters in reverse-placement order + /// - Cleanup key listeners + /// - Process all queued actions + /// - Remove unloaded characters from the advanceable characters list. + /// - Run the GC collector + /// void advance(float delta_time); /// 0-based!! delegates to _level0 + // + /// TODO: drop this method ? + /// void goto_frame(size_t target_frame_number) { getLevel(0)->goto_frame(target_frame_number); @@ -544,8 +558,36 @@ void markReachableResources() const; #endif // GNASH_USE_GC + /// \brief + /// Register a newly born advanceable character to the + /// list of characters to be advanced on next ::advance call. + // + /// The character will only be advanced if not unloaded when + /// its turn comes. Characters are advanced in reverse-placement + /// order (first registered is advanced last) + /// + void addLiveChar(boost::intrusive_ptr<character> ch) + { + _liveChars.push_front(ch); + } + private: + /// An element of the advanceable characters + typedef boost::intrusive_ptr<character> AdvanceableCharacter; + + /// A list of AdvanceableCharacters + // + /// This is a list (not a vector) as we want to allow + /// ::advance of each element to insert new characters before + /// the start w/out invalidating iterators scanning the + /// list forward for proper movie advancement + /// + typedef std::list<AdvanceableCharacter> LiveChars; + + /// The list of advanceable character, in placement order + LiveChars _liveChars; + /// Forbid copy movie_root(const movie_root& ) { assert(0); } @@ -666,15 +708,23 @@ /// character* getTopmostMouseEntity(float x, float y); - // 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); + /// Advance a live character + // + /// @param ch + /// The character to advance, will NOT be advanced if unloaded + /// + /// @param delta_time + /// A left-over parameter from the ancient times... will be forwarded + /// to the calls to ::advance + /// + static void advanceLiveChar(boost::intrusive_ptr<character> ch, float delta_time); + + /// Advance all non-unloaded live chars + void advanceLiveChars(float delta_time); /// Put the given movie at the given level // Index: server/sprite_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v retrieving revision 1.339 retrieving revision 1.340 diff -u -b -r1.339 -r1.340 --- server/sprite_instance.cpp 13 Sep 2007 10:14:57 -0000 1.339 +++ server/sprite_instance.cpp 13 Sep 2007 13:57:49 -0000 1.340 @@ -1692,26 +1692,6 @@ } }; -/// A DisplayList visitor used to advance all non-unloaded characters -class AdvancerVisitor { - - float delta_time; - -public: - AdvancerVisitor(float dt) - : - delta_time(dt) - {} - - void operator() (character* ch) - { - // don't advance unloaded characters - if ( ! ch->isUnloaded() ) ch->advance(delta_time); - } - -}; - - //------------------------------------------------ // sprite_instance //------------------------------------------------ @@ -2262,7 +2242,7 @@ } -void sprite_instance::advance_sprite(float delta_time) +void sprite_instance::advance_sprite(float /*delta_time*/) { //GNASH_REPORT_FUNCTION; @@ -2283,17 +2263,6 @@ frame_count); #endif - // Advance DisplayList elements already placed (even if looping back ?) - { -#ifdef GNASH_DEBUG - log_debug("Advancing %d childs of sprite %s in current DisplayList:", m_display_list.size(), getTarget().c_str()); - m_display_list.dump(); -#endif - AdvancerVisitor visitor(delta_time); - m_display_list.visitByReversePlacement(visitor); - } - - queueEvent(event_id::ENTER_FRAME); // Update current and next frames. @@ -3283,6 +3252,9 @@ log_debug(_("Constructing sprite '%s'"), _origTarget.c_str()); #endif + // Register this sprite as a live one + _vm.getRoot().addLiveChar(this); + // Take note of our original target (for soft references) _origTarget = getTarget(); @@ -3690,8 +3662,6 @@ m_display_list.visitAll(marker); - m_display_list.visitByReversePlacement(marker); - _drawable->setReachable(); _drawable_inst->setReachable(); Index: server/video_stream_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/video_stream_instance.cpp,v retrieving revision 1.37 retrieving revision 1.38 diff -u -b -r1.37 -r1.38 --- server/video_stream_instance.cpp 6 Sep 2007 12:21:06 -0000 1.37 +++ server/video_stream_instance.cpp 13 Sep 2007 13:57:49 -0000 1.38 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_instance.cpp,v 1.37 2007/09/06 12:21:06 tgc Exp $ +// $Id: video_stream_instance.cpp,v 1.38 2007/09/13 13:57:49 strk Exp $ #include "sprite_instance.h" #include "video_stream_instance.h" @@ -230,6 +230,14 @@ } void +video_stream_instance::construct() +{ + // Register this video instance as a live character + _vm.getRoot().addLiveChar(this); +} + + +void video_stream_instance::advance(float /*delta_time*/) { if (_ns) { Index: server/video_stream_instance.h =================================================================== RCS file: /sources/gnash/gnash/server/video_stream_instance.h,v retrieving revision 1.19 retrieving revision 1.20 diff -u -b -r1.19 -r1.20 --- server/video_stream_instance.h 7 Sep 2007 22:24:41 -0000 1.19 +++ server/video_stream_instance.h 13 Sep 2007 13:57:49 -0000 1.20 @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_instance.h,v 1.19 2007/09/07 22:24:41 strk Exp $ +// $Id: video_stream_instance.h,v 1.20 2007/09/13 13:57:49 strk Exp $ #ifndef GNASH_VIDEO_STREAM_INSTANCE_H #define GNASH_VIDEO_STREAM_INSTANCE_H @@ -58,7 +58,13 @@ return m_def->get_bound().getRange(); } + /// We use the call to ::advance to properly set invalidated status virtual void advance(float delta_time); + + /// construct is needed to register this instance as an "advanceable" character + /// with movie_root + virtual void construct(); + void display(); // For sure isActionScriptReferenceable... Index: testsuite/misc-ming.all/action_execution_order_test11.c =================================================================== RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/action_execution_order_test11.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -b -r1.3 -r1.4 --- testsuite/misc-ming.all/action_execution_order_test11.c 10 Sep 2007 08:21:06 -0000 1.3 +++ testsuite/misc-ming.all/action_execution_order_test11.c 13 Sep 2007 13:57:49 -0000 1.4 @@ -233,10 +233,10 @@ SWFMovie_nextFrame(mo); // _root frame7 check_equals(mo, "_root.loadOrder", "'0+1+2+3+4+5+'"); - xcheck_equals(mo, "_root.enterFrameOrder", "'0+2+1+3+2+1+4+3+2+1+5+4+3+2+1+'"); + check_equals(mo, "_root.enterFrameOrder", "'0+2+1+3+2+1+4+3+2+1+5+4+3+2+1+'"); check_equals(mo, "_root.unloadOrder", "'0+1+2+3+4+5+'"); - xcheck_equals(mo, "_root.doActionOrder", "'0+1+2+3+4+5+'"); - xcheck_equals(mo, "_root.asOrder", "'0+1+2+3+4+5+6+3+8+4+10+6+3+4+14+15+25+10+26+6+27+3+28+4+29+20+21+22+23+24+'"); + check_equals(mo, "_root.doActionOrder", "'0+1+2+3+4+5+'"); + check_equals(mo, "_root.asOrder", "'0+1+2+3+4+5+6+3+8+4+10+6+3+4+14+15+25+10+26+6+27+3+28+4+29+20+21+22+23+24+'"); add_actions(mo, " _root.totals(); stop(); "); SWFMovie_nextFrame(mo); // _root frame8 _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit