CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/07/10 21:06:29
Modified files: . : ChangeLog server : movie_root.cpp movie_root.h Log message: * server/movie_root.{cpp,h}: support multiple levels. Untested. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3703&r2=1.3704 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.74&r2=1.75 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.65&r2=1.66 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.3703 retrieving revision 1.3704 diff -u -b -r1.3703 -r1.3704 --- ChangeLog 10 Jul 2007 16:21:40 -0000 1.3703 +++ ChangeLog 10 Jul 2007 21:06:28 -0000 1.3704 @@ -1,5 +1,9 @@ 2007-07-10 Sandro Santilli <[EMAIL PROTECTED]> + * server/movie_root.{cpp,h}: support multiple levels. Untested. + +2007-07-10 Sandro Santilli <[EMAIL PROTECTED]> + * server/parser/movie_def_impl.cpp (add_sound_sample): fix verbosity to use log_parse and depend on IF_VERBOSE_PARSE. * server/button_character_instance.cpp (on_event): don't require a Index: server/movie_root.cpp =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.cpp,v retrieving revision 1.74 retrieving revision 1.75 diff -u -b -r1.74 -r1.75 --- server/movie_root.cpp 10 Jul 2007 12:22:34 -0000 1.74 +++ server/movie_root.cpp 10 Jul 2007 21:06:29 -0000 1.75 @@ -30,9 +30,11 @@ #include "tu_random.h" #include "ExecutableCode.h" #include "Stage.h" +#include "utility.h" #ifdef NEW_KEY_LISTENER_LIST_DESIGN #include "action.h" #endif + #include <iostream> #include <string> #include <typeinfo> @@ -48,7 +50,7 @@ movie_root::testInvariant() const { // TODO: fill this function ! - assert(_movie.get()); + assert( ! _movies.empty() ); return true; } @@ -99,18 +101,55 @@ void movie_root::setRootMovie(movie_instance* movie) { + setLevel(0, movie); +} + +void +movie_root::setLevel(unsigned int num, boost::intrusive_ptr<movie_instance> movie) +{ assert(movie != NULL); - _movie = movie; - _movie->set_invalidated(); + if ( _movies.size() < num+1 ) _movies.resize(num+1); + _movies[num] = movie; + + movie->set_invalidated(); set_display_viewport(0, 0, - (int) _movie->get_movie_definition()->get_width_pixels(), - (int) _movie->get_movie_definition()->get_height_pixels()); + (int) movie->get_movie_definition()->get_width_pixels(), + (int) movie->get_movie_definition()->get_height_pixels()); assert(testInvariant()); } +boost::intrusive_ptr<movie_instance> +movie_root::getLevel(unsigned int num) const +{ + if ( _movies.size() < num+1 ) return 0; + else + { + assert(boost::dynamic_pointer_cast<movie_instance>(_movies[num])); + return boost::static_pointer_cast<movie_instance>(_movies[num]); + } +} + +void +movie_root::restart() +{ + for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) + { + (*i)->restart(); + } +} + +void +movie_root::clear_invalidated() +{ + for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) + { + (*i)->clear_invalidated(); + } +} + boost::intrusive_ptr<Stage> movie_root::getStageObject() { @@ -137,7 +176,7 @@ //log_msg("Rescaling allowed"); // should we cache this ? it's immutable after all ! - const rect& frame_size = _movie->get_frame_size(); + const rect& frame_size = _movies[0]->get_frame_size(); float scale_x = m_viewport_width / TWIPS_TO_PIXELS(frame_size.width()); float scale_y = m_viewport_height / TWIPS_TO_PIXELS(frame_size.height()); @@ -467,8 +506,7 @@ assert(testInvariant()); // Generate a mouse event - m_mouse_button_state.m_topmost_entity = - _movie->get_topmost_mouse_entity(PIXELS_TO_TWIPS(m_mouse_x), PIXELS_TO_TWIPS(m_mouse_y)); + m_mouse_button_state.m_topmost_entity = getTopmostMouseEntity(PIXELS_TO_TWIPS(m_mouse_x), PIXELS_TO_TWIPS(m_mouse_y)); m_mouse_button_state.m_mouse_button_state_current = (m_mouse_buttons & 1); bool need_redraw = generate_mouse_button_events(&m_mouse_button_state); @@ -573,38 +611,13 @@ // 2. by different machines the random gave different numbers tu_random::next_random(); -#ifdef GNASH_DEBUG - size_t totframes = _movie->get_frame_count(); - size_t prevframe = _movie->get_current_frame(); -#endif + advanceAllLevels(delta_time); - // Keep root sprite alive during actions execution. - // - // This is *very* important, as actions in the movie itself - // could get rid of it. A simple example: - // - // _root.loadMovie(other); - // - boost::intrusive_ptr<sprite_instance> keepMovieAlive(_movie.get()); - - _movie->advance(delta_time); #ifdef NEW_KEY_LISTENER_LIST_DESIGN cleanup_key_listeners(); #endif processActionQueue(); -#ifdef GNASH_DEBUG - size_t curframe = _movie->get_current_frame(); - - log_msg("movie_root::advance advanced top-level movie from " - SIZET_FMT "/" SIZET_FMT - " to " SIZET_FMT "/" SIZET_FMT - " (_movie is %s%s)", - prevframe, totframes, curframe, totframes, - typeid(*_movie).name(), - _movie->get_play_state() == sprite_instance::STOP ? " - now in STOP mode" : ""); -#endif - #ifdef GNASH_USE_GC // Run the garbage collector (step back !!) GC::get().collect(); @@ -621,20 +634,19 @@ assert(testInvariant()); - _movie->clear_invalidated(); - -// GNASH_REPORT_FUNCTION; - if (_movie->get_visible() == false) + for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) { - // Don't display. - return; - } + boost::intrusive_ptr<sprite_instance> movie = *i; + + movie->clear_invalidated(); + + if (movie->get_visible() == false) continue; // should we cache this ? it's immutable after all ! - const rect& frame_size = _movie->get_frame_size(); + const rect& frame_size = movie->get_frame_size(); // null frame size ? don't display ! - if ( frame_size.is_null() ) return; + if ( frame_size.is_null() ) continue; render::begin_display( m_background_color, @@ -643,9 +655,10 @@ frame_size.get_x_min(), frame_size.get_x_max(), frame_size.get_y_min(), frame_size.get_y_max()); - _movie->display(); + movie->display(); render::end_display(); + } } @@ -657,7 +670,7 @@ va_list args; va_start(args, method_arg_fmt); - const char* result = _movie->call_method_args(method_name, + const char* result = getLevel(0)->call_method_args(method_name, method_arg_fmt, args); va_end(args); @@ -669,7 +682,7 @@ const char* method_arg_fmt, va_list args) { assert(testInvariant()); - return _movie->call_method_args(method_name, method_arg_fmt, args); + return getLevel(0)->call_method_args(method_name, method_arg_fmt, args); } #ifdef NEW_KEY_LISTENER_LIST_DESIGN @@ -711,6 +724,8 @@ { //log_msg("Notifying " SIZET_FMT " keypress listeners", _keyListeners.size()); + as_environment env; + for (std::vector<KeyListener>::iterator iter = _keyListeners.begin(); iter != _keyListeners.end(); ++iter) { @@ -730,7 +745,7 @@ method = ch->getUserDefinedEventHandler("onKeyDown"); if ( method ) { - call_method0(as_value(method.get()), &(_movie->get_environment()), ch); + call_method0(as_value(method.get()), &env, ch); } } // invoke onClipKeyPress handler @@ -748,7 +763,7 @@ method = ch->getUserDefinedEventHandler("onKeyUp"); if ( method ) { - call_method0(as_value(method.get()), &(_movie->get_environment()), ch); + call_method0(as_value(method.get()), &env, ch); } } } @@ -949,7 +964,10 @@ void movie_root::add_invalidated_bounds(InvalidatedRanges& ranges, bool force) { - _movie->add_invalidated_bounds(ranges, force); + for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) + { + (*i)->add_invalidated_bounds(ranges, force); + } } void @@ -1037,7 +1055,6 @@ if ( timer->expired() ) { //cout << " EXPIRED, start time is now " << timer.getStart() << endl; - //_movie->on_event_interval_timer(); (*timer)(); } } @@ -1053,7 +1070,10 @@ { // Mark root movie as reachable // TODO: mark all levels !! - _movie->setReachable(); + for (Levels::const_reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) + { + (*i)->setReachable(); + } // Mark mouse entities m_mouse_button_state.markReachableResources(); @@ -1090,5 +1110,49 @@ } #endif // GNASH_USE_GC +character * +movie_root::getTopmostMouseEntity(float x, float y) +{ + for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) + { + character* ret = (*i)->get_topmost_mouse_entity(x, y); + if ( ret ) return ret; + } + return NULL; +} + +void +movie_root::advanceAllLevels(float delta_time) +{ + for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; ++i) + { + advanceMovie(*i, delta_time); + } +} + +void +movie_root::advanceMovie(boost::intrusive_ptr<sprite_instance> movie, 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" : ""); +#endif + +} + } // namespace gnash Index: server/movie_root.h =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.h,v retrieving revision 1.65 retrieving revision 1.66 diff -u -b -r1.65 -r1.66 --- server/movie_root.h 10 Jul 2007 12:22:34 -0000 1.65 +++ server/movie_root.h 10 Jul 2007 21:06:29 -0000 1.66 @@ -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.65 2007/07/10 12:22:34 zoulunkai Exp $ */ +/* $Id: movie_root.h,v 1.66 2007/07/10 21:06:29 strk Exp $ */ /// \page events_handling Handling of user events /// @@ -74,9 +74,10 @@ #include "mouse_button_state.h" // for composition #include "drag_state.h" // for composition -#include "sprite_instance.h" // for inlines +#include "movie_instance.h" // for inlines #include "timers.h" // for composition #include "asobj/Key.h" +#include "smart_ptr.h" // for memory management #include <vector> #include <list> @@ -136,7 +137,8 @@ /// The movie stage (absolute top level node in the characters hierarchy) // -/// This is a wrapper around the top-level movie_instance that is being played. +/// This is a wrapper around the set of loaded levels being played. +/// /// There is a *single* instance of this class for each run; /// loading external movies will *not* create a new instance of it. /// @@ -171,20 +173,32 @@ /// Note that the display viewport will be updated to match /// the size of given movie. /// + /// A call to this method is equivalent to a call to setLevel(0, movie). + /// /// @param movie /// The movie_instance to wrap. /// Will be stored in an intrusive_ptr. /// void setRootMovie(movie_instance* movie); - /// @@ should this delegate to _movie? probably ! + /// Return the movie at the given level (0 if unloaded level). + boost::intrusive_ptr<movie_instance> getLevel(unsigned int num) const; + + /// Put the given movie at 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); + + /// @@ should this delegate to _level0? probably ! void set_member( const std::string& /*name*/, const as_value& /*val*/) { } - /// @@ should this delegate to _movie? probably ! + /// @@ should this delegate to _level0? probably ! bool get_member(const std::string& /*name*/, as_value* /*val*/) { @@ -280,8 +294,12 @@ void set_drag_state(const drag_state& st); - /// @return current top-level root sprite - sprite_instance* get_root_movie() { return _movie.get(); } + /// @return current top-level root sprite (_level0) + sprite_instance* get_root_movie() + { + if ( _movies.empty() ) return NULL; + return _movies[0].get(); + } void stop_drag() { @@ -289,9 +307,14 @@ m_drag_state.reset(); } - movie_definition* get_movie_definition() const { - assert(_movie); - return _movie->get_movie_definition(); + /// Return definition of _level0 + // + /// TODO: drop this function ? + /// + movie_definition* get_movie_definition() const + { + assert(!_movies.empty()); + return getLevel(0)->get_movie_definition(); } /// Add an interval timer @@ -314,9 +337,14 @@ /// bool clear_interval_timer(unsigned int x); - /// 0-based!! - size_t get_current_frame() const { - return _movie->get_current_frame(); + /// Return 0-based frame index of _level0 + // + /// TODO: drop this function + /// + size_t get_current_frame() const + { + assert(!_movies.empty()); + return getLevel(0)->get_current_frame(); } // @@ should this be in movie_instance ? @@ -334,9 +362,12 @@ } // @@ Is this one necessary? + // + // TODO: drop this character* get_character(int character_id) { - return _movie->get_character(character_id); + assert(!_movies.empty()); + return getLevel(0)->get_character(character_id); } void set_background_color(const rgba& color) @@ -354,34 +385,44 @@ return m_background_color.m_a / 255.0f; } - /// Delegate to current top-level root sprite - void restart() { _movie->restart(); } + /// Restart all levels + void restart(); void advance(float delta_time); - /// 0-based!! - void goto_frame(size_t target_frame_number) { - _movie->goto_frame(target_frame_number); + /// 0-based!! delegates to _level0 + void goto_frame(size_t target_frame_number) + { + getLevel(0)->goto_frame(target_frame_number); } - bool has_looped() const { - return _movie->has_looped(); +#if 0 + /// delegates to _level0 + bool has_looped() const + { + return getLevel(0)->has_looped(); } +#endif void display(); - /// Delegate to wrapped movie_instance +#if 0 + /// Delegate to _level0 bool goto_labeled_frame(const char* label) { return _movie->goto_labeled_frame(label); } +#endif - /// Delegate to wrapped movie_instance - void set_play_state(sprite_instance::play_state s) { - _movie->set_play_state(s); + /// Delegate to _level0 + void set_play_state(sprite_instance::play_state s) + { + getLevel(0)->set_play_state(s); } - /// Delegate to wrapped movie_instance - sprite_instance::play_state get_play_state() const { +#if 0 + /// Delegate to _level0 + sprite_instance::play_state get_play_state() const + { return _movie->get_play_state(); } @@ -398,13 +439,27 @@ { _movie->set_variable(path_to_var, new_value); } +#endif /// For ActionScript interfacing convenience. + // + /// TODO: check if we really need this. I guess we might + /// need for fscommand:, but we lack documentation + /// about where to find the method (which level?) + /// const char* call_method(const char* method_name, const char* method_arg_fmt, ...); + + /// For ActionScript interfacing convenience. + // + /// TODO: check if we really need this. I guess we might + /// need for fscommand:, but we lack documentation + /// about where to find the method (which level?) + /// const char* call_method_args(const char* method_name, const char* method_arg_fmt, va_list args); +#if 0 /// Delegate to wrapped movie_instance void set_visible(bool visible) { _movie->set_visible(visible); @@ -413,6 +468,7 @@ bool get_visible() const { return _movie->get_visible(); } +#endif void * get_userdata() { return m_userdata; } void set_userdata(void * ud ) { m_userdata = ud; } @@ -456,9 +512,8 @@ bool testInvariant() const; - void clear_invalidated() { - _movie->clear_invalidated(); - } + // Clear invalidated flag for all levels + void clear_invalidated(); /// Push an executable code to the ActionQueue void pushAction(std::auto_ptr<ExecutableCode> code); @@ -474,7 +529,7 @@ // /// Resources reachable from movie_root are: /// - /// - All _level# movies (_movie) + /// - All _level# movies (_movies) /// - Mouse entities (m_mouse_button_state) /// - Timer targets (_intervalTimers) /// - Resources reachable by ActionQueue code (_actionQueue) @@ -568,7 +623,8 @@ /// to avoid having to replicate all of the base class /// interface to the movie_instance class definition /// - boost::intrusive_ptr<sprite_instance> _movie; + typedef std::vector< boost::intrusive_ptr<sprite_instance> > Levels; + Levels _movies; /// This function should return TRUE iff any action triggered /// by the event requires redraw, see \ref events_handling for @@ -579,6 +635,30 @@ /// If set to false, no rescale should be performed /// when changing viewport size bool _allowRescale; + + /// \brief + /// Return the topmost entity covering the given point + /// and enabled to receive mouse events. + // + /// Return NULL if no "active" entity is found under the pointer. + /// + /// Coordinates of the point are given in world coordinate space. + /// (twips) + /// + /// @param x + /// X ordinate of the pointer, in world coordinate space (twips) + /// + /// @param y + /// Y ordinate of the pointer, in world coordiante space (twips). + /// + character* getTopmostMouseEntity(float x, float y); + + // Advance all levels + void advanceAllLevels(float delta_time); + + // Advance a given level + void advanceMovie(boost::intrusive_ptr<sprite_instance> movie, float delta_time); + }; _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit