[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/movie_root.cpp server/mo...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/movie_root.cpp server/mo... |
Date: |
Tue, 10 Jul 2007 21:06:29 +0000 |
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 <address@hidden>
+ * server/movie_root.{cpp,h}: support multiple levels. Untested.
+
+2007-07-10 Sandro Santilli <address@hidden>
+
* 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);
+
};