CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/07/10 23:48:42
Modified files: . : ChangeLog server : movie_root.cpp movie_root.h server/vm : ASHandlers.cpp Log message: * server/vm/ASHandlers.cpp (CommonGetUrl): implement _level loading. Fixes bug #19968. * server/movie_root.{cpp,h}: add loadLevel() method, store levels in a map rather then a vector. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3705&r2=1.3706 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.75&r2=1.76 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.66&r2=1.67 http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.111&r2=1.112 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.3705 retrieving revision 1.3706 diff -u -b -r1.3705 -r1.3706 --- ChangeLog 10 Jul 2007 21:42:59 -0000 1.3705 +++ ChangeLog 10 Jul 2007 23:48:41 -0000 1.3706 @@ -1,5 +1,12 @@ 2007-07-10 Sandro Santilli <[EMAIL PROTECTED]> + * server/vm/ASHandlers.cpp (CommonGetUrl): implement _level loading. + Fixes bug #19968. + * server/movie_root.{cpp,h}: add loadLevel() method, store levels in + a map rather then a vector. + +2007-07-10 Sandro Santilli <[EMAIL PROTECTED]> + * server/: movie_instance.h, character.h: make get_root() a const method. * server/movie_root.{cpp,h}: support multiple levels. Untested. Index: server/movie_root.cpp =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.cpp,v retrieving revision 1.75 retrieving revision 1.76 diff -u -b -r1.75 -r1.76 --- server/movie_root.cpp 10 Jul 2007 21:06:29 -0000 1.75 +++ server/movie_root.cpp 10 Jul 2007 23:48:42 -0000 1.76 @@ -31,6 +31,7 @@ #include "ExecutableCode.h" #include "Stage.h" #include "utility.h" +#include "URL.h" #ifdef NEW_KEY_LISTENER_LIST_DESIGN #include "action.h" #endif @@ -104,13 +105,19 @@ setLevel(0, movie); } +/* private */ void movie_root::setLevel(unsigned int num, boost::intrusive_ptr<movie_instance> movie) { assert(movie != NULL); + assert(static_cast<unsigned int>(movie->get_depth()) == num); + + //movie->setLevel(num) + //movie->set_depth(num); + //movie->set_name(ss.str().c_str()); - if ( _movies.size() < num+1 ) _movies.resize(num+1); - _movies[num] = movie; + //if ( _movies.size() < num+1 ) _movies.resize(num+1); + _movies[num] = movie; // [num] = movie; movie->set_invalidated(); @@ -121,15 +128,49 @@ assert(testInvariant()); } -boost::intrusive_ptr<movie_instance> -movie_root::getLevel(unsigned int num) const +bool +movie_root::loadLevel(unsigned int num, const URL& url) { - if ( _movies.size() < num+1 ) return 0; - else + boost::intrusive_ptr<movie_definition> md ( create_library_movie(url) ); + if (md == NULL) { - assert(boost::dynamic_pointer_cast<movie_instance>(_movies[num])); - return boost::static_pointer_cast<movie_instance>(_movies[num]); + log_error(_("can't create movie_definition for %s"), + url.str().c_str()); + return false; } + + boost::intrusive_ptr<movie_instance> extern_movie; + extern_movie = md->create_movie_instance(); + if (extern_movie == NULL) + { + log_error(_("can't create extern movie_instance " + "for %s"), url.str().c_str()); + return false; + } + + // Parse query string + sprite_instance::VariableMap vars; + url.parse_querystring(url.querystring(), vars); + extern_movie->setVariables(vars); + + character* ch = extern_movie.get(); + ch->set_depth(num); + + save_extern_movie(extern_movie.get()); + + setLevel(num, extern_movie); + + return true; +} + +boost::intrusive_ptr<movie_instance> +movie_root::getLevel(unsigned int num) const +{ + Levels::const_iterator i = _movies.find(num); + if ( i == _movies.end() ) return 0; + + assert(boost::dynamic_pointer_cast<movie_instance>(i->second)); + return boost::static_pointer_cast<movie_instance>(i->second); } void @@ -137,7 +178,7 @@ { for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) { - (*i)->restart(); + i->second->restart(); } } @@ -146,7 +187,7 @@ { for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) { - (*i)->clear_invalidated(); + i->second->clear_invalidated(); } } @@ -636,7 +677,7 @@ for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) { - boost::intrusive_ptr<sprite_instance> movie = *i; + boost::intrusive_ptr<sprite_instance> movie = i->second; movie->clear_invalidated(); @@ -966,7 +1007,7 @@ { for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) { - (*i)->add_invalidated_bounds(ranges, force); + i->second->add_invalidated_bounds(ranges, force); } } @@ -1072,7 +1113,7 @@ // TODO: mark all levels !! for (Levels::const_reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) { - (*i)->setReachable(); + i->second->setReachable(); } // Mark mouse entities @@ -1115,7 +1156,7 @@ { for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) { - character* ret = (*i)->get_topmost_mouse_entity(x, y); + character* ret = i->second->get_topmost_mouse_entity(x, y); if ( ret ) return ret; } return NULL; @@ -1124,9 +1165,12 @@ void movie_root::advanceAllLevels(float delta_time) { - for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) + // 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) { - advanceMovie(*i, delta_time); + advanceMovie(i->second, delta_time); } } Index: server/movie_root.h =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.h,v retrieving revision 1.66 retrieving revision 1.67 diff -u -b -r1.66 -r1.67 --- server/movie_root.h 10 Jul 2007 21:06:29 -0000 1.66 +++ server/movie_root.h 10 Jul 2007 23:48:42 -0000 1.67 @@ -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.66 2007/07/10 21:06:29 strk Exp $ */ +/* $Id: movie_root.h,v 1.67 2007/07/10 23:48:42 strk Exp $ */ /// \page events_handling Handling of user events /// @@ -87,11 +87,22 @@ namespace gnash { class ExecutableCode; // for ActionQueue class Stage; + class URL; } namespace gnash { +struct DepthComparator +{ + typedef boost::intrusive_ptr<sprite_instance> LevelMovie; + + bool operator() (const LevelMovie& d1, const LevelMovie& d2) + { + return d1->get_depth() < d2->get_depth(); + } +}; + #ifdef NEW_KEY_LISTENER_LIST_DESIGN class KeyListener{ public: @@ -178,18 +189,32 @@ /// @param movie /// The movie_instance to wrap. /// Will be stored in an intrusive_ptr. + /// Must have a depth of 0. /// void setRootMovie(movie_instance* movie); /// Return the movie at the given level (0 if unloaded level). + // + /// POST CONDITIONS: + /// - The returned character has a depth equal to 'num' + /// boost::intrusive_ptr<movie_instance> getLevel(unsigned int num) const; - /// Put the given movie at the given level + /// Load movie at the specified URL in the given level // /// Note that the display viewport will be updated to reflect /// the new layout. /// - void setLevel(unsigned int num, boost::intrusive_ptr<movie_instance> movie); + /// @param num + /// The level number to load into. + /// + /// @param url + /// The url to load the movie from. + /// Can contain a query string, which would be parsed. + /// + /// @return false on error, true on success + /// + bool loadLevel(unsigned int num, const URL& url); /// @@ should this delegate to _level0? probably ! void set_member( @@ -298,7 +323,7 @@ sprite_instance* get_root_movie() { if ( _movies.empty() ) return NULL; - return _movies[0].get(); + return getLevel(0).get(); } void stop_drag() @@ -623,7 +648,12 @@ /// to avoid having to replicate all of the base class /// interface to the movie_instance class definition /// - typedef std::vector< boost::intrusive_ptr<sprite_instance> > Levels; + /// TODO: use a different container, to allow for _level0 and _level100 + /// to exist while just taking 2 elements in the container. + /// Appropriate container could be list, set or map (order is important) + /// + typedef boost::intrusive_ptr<sprite_instance> LevelMovie; + typedef std::map<unsigned int, LevelMovie> Levels; Levels _movies; /// This function should return TRUE iff any action triggered @@ -659,6 +689,18 @@ // Advance a given level void advanceMovie(boost::intrusive_ptr<sprite_instance> movie, float delta_time); + /// Put the given movie at the given level + // + /// Note that the display viewport will be updated to reflect + /// the new layout. + /// + /// @param movie + /// The movie_instance to store at the given level. + /// Will be stored in an intrusive_ptr. + /// It's depth will be set to <num> and it's name to + /// _level<num> + /// + void setLevel(unsigned int num, boost::intrusive_ptr<movie_instance> movie); }; Index: server/vm/ASHandlers.cpp =================================================================== RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v retrieving revision 1.111 retrieving revision 1.112 diff -u -b -r1.111 -r1.112 --- server/vm/ASHandlers.cpp 7 Jul 2007 03:37:29 -0000 1.111 +++ server/vm/ASHandlers.cpp 10 Jul 2007 23:48:42 -0000 1.112 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: ASHandlers.cpp,v 1.111 2007/07/07 03:37:29 strk Exp $ */ +/* $Id: ASHandlers.cpp,v 1.112 2007/07/10 23:48:42 strk Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -1774,12 +1774,6 @@ if ( ! target.is_undefined() && ! target.is_null() ) { target_string = target.to_string(&env); - if ( target_string.substr(0, 6) == "_level" ) - { - // Might set loadTargetFlag to true, but _level# would likely not - // be resolved anyway - log_unimpl(_("GetUrl with target %s unsupported"), target_string.c_str()); - } } // If the url starts with "FSCommand:", then this is @@ -1827,7 +1821,13 @@ log_msg(_("get url: target=%s, url=%s (%s), method=%x"), target_string.c_str(), url.str().c_str(), url_c, method); - if ( loadTargetFlag ) + if ( target_string.compare(0, 6, "_level") == 0 && target_string.find_first_not_of("0123456789", 7) == string::npos ) + { + unsigned int levelno = atoi(target_string.c_str()+6); + log_debug(_("Testing _level loading (level %u)"), levelno); + VM::get().getRoot().loadLevel(levelno, url); + } + else if ( loadTargetFlag ) { character* target_ch = env.find_target(target); if ( ! target_ch ) _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit