2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef GNASH_MOVIETESTER_H
22 #define GNASH_MOVIETESTER_H
25 # include "gnashconfig.h" // For exp2 test
30 #include "sound_handler.h" // for creating the "test" sound handlers
31 #include "Renderer.h" // for dtor visibility by auto_ptr
33 #include "ManualClock.h" // for composition
34 #include "RunResources.h" // For initialization.
35 #include "movie_root.h"
37 #include <boost/intrusive_ptr.hpp>
39 #include <memory> // for auto_ptr
41 #include <boost/shared_ptr.hpp>
44 #define check_pixel(x, y, radius, color, tolerance) \
46 std::stringstream ss; \
47 ss << "[" << __FILE__ << ":" << __LINE__ << "]"; \
48 tester.checkPixel(x, y, radius, color, tolerance, ss.str(), false); \
51 #define xcheck_pixel(x, y, radius, color, tolerance) \
53 std::stringstream ss; \
54 ss << "[" << __FILE__ << ":" << __LINE__ << "]"; \
55 tester.checkPixel(x, y, radius, color, tolerance, ss.str(), true); \
58 // Forward declarations
60 class movie_definition
;
71 /// A table of built renderers
79 TestingRenderer(boost::shared_ptr
<Renderer
> renderer
,
80 const std::string
& name
)
86 const std::string
& getName() const { return _name
; }
88 /// Return the underlying render handler
89 boost::shared_ptr
<Renderer
> getRenderer() const { return _renderer
; }
94 boost::shared_ptr
<Renderer
> _renderer
;
97 /// An utility class for testing movie playback
99 /// This is a just born implementation and doesn't
100 /// have much more then simply loading a movie and
101 /// providing a function to find DisplayItems by name
103 /// More functions will be added when needed.
108 /// Fully load the movie at the specified location
109 /// and create an instance of it.
110 /// Also, initialize any built renderer capable of in-memory
111 /// rendering to allow testing of it.
112 /// The renderer(s) will be initialized with a memory
113 /// buffer with the size found in the SWF header
115 MovieTester(const std::string
& filespec
);
117 /// Advance the movie by one frame
119 /// @param updateClock
120 /// If true (the default), this method also
121 /// advances the clock by the nominal delay expected
122 /// between frame advancements before performing the
123 /// actual playhead advancement.
125 void advance(bool updateClock
=true);
127 /// Advance the clock by the given amount of milliseconds
128 void advanceClock(unsigned long ms
);
130 /// Fully redraw of current frame
132 /// This function forces complete redraw in all testing
137 /// Return the invalidated ranges in PIXELS
139 /// This is to debug/test partial rendering
141 geometry::SnappingRanges2d
<int> getInvalidatedRanges() const;
143 /// Find a DisplayObject in the display list of a sprite by name.
145 /// Return NULL if there's no DisplayObject with that name in
146 /// the sprite's display list.
148 const DisplayObject
* findDisplayItemByName(const MovieClip
& mc
,
149 const std::string
& name
);
151 /// Find a DisplayObject on the stage by full target name.
153 /// Return NULL if there's no DisplayObject reachable with that target.
155 const DisplayObject
* findDisplayItemByTarget(const std::string
& tgt
);
157 /// Find a DisplayObject in the display list of a sprite by depth.
159 /// Return NULL if there's no DisplayObject at that depth in
160 /// the sprite's display list.
162 const DisplayObject
* findDisplayItemByDepth(const MovieClip
& mc
,
165 /// Get the topmost sprite instance of this movie
167 /// We const_cast this because we don't care.
168 gnash::MovieClip
* getRootMovie() {
169 return const_cast<Movie
*>(&_movie_root
->getRootMovie());
172 /// Notify mouse pointer movement to the given coordinate
174 /// Coordinates are in pixels
176 void movePointerTo(int x
, int y
);
178 /// Check color of the average pixel under the mouse pointer
181 /// This method will test any built renderer.
184 /// The x coordinate of the point being the center
185 /// of the circle you want to compute the average color of.
188 /// The y coordinate of the point being the center
189 /// of the circle you want to compute the average color of.
192 /// Radius defining the average zone used.
193 /// 1 means a single pixel.
194 /// Behaviour of passing 0 is undefined.
197 /// The color we expect to find under the pointer.
200 /// The tolerated difference of any r,g,b,a values.
201 /// Note that the actual tolerance used for comparison might
202 /// be bigger then the given one depending on the minimum tolerance
203 /// supported by the renderers being tested, being a function of color
204 /// depth. For example, comparisions against 16bpp renderers will use
205 /// at tolerance of at least 8.
208 /// A label to use in test results.
210 /// @param expectFailure
211 /// Set to true if a failure is expected. Defaults to false.
213 void checkPixel(int x
, int y
, unsigned radius
, const rgba
& color
,
214 short unsigned tolerance
, const std::string
& label
, bool expectFailure
=false) const;
218 return _movie_root
->getVM();
221 /// Notify mouse button was pressed
222 void pressMouseButton();
224 /// Notify mouse button was depressed
225 void depressMouseButton();
227 /// Simulate a mouse click (press and depress mouse button)
230 /// Simulate a mouse scroll.
232 /// The only values seen so far are -1 and 1, but documented to be
233 /// usually between -3 and 3. 1 is up, -1 is down.
234 void scrollMouse(int delta
);
238 /// See key codes in namespace gnash::key (GnashKey.h)
240 void pressKey(key::code k
);
242 /// Notify key release
244 /// See key codes in namespace gnash::key (GnashKey.h)
246 void releaseKey(key::code k
);
248 /// Return true if the currently active
249 /// DisplayObject is over a DisplayObject that
250 /// handles mouse events
251 bool isMouseOverMouseEntity();
253 /// Return true if a gui would be using an hand
254 /// cursor in the current position.
255 bool usingHandCursor();
258 /// Return the number of times a sound has been stopped,
259 /// or 0 if sound testing is not supported. See canTestSound().
264 /// Return the number of times a sound has been started,
265 /// or 0 if sound testing is not supported. See canTestSound().
269 /// Return true if this build of MovieTester supports sound testing
271 /// Sound will be supported as long as a sound handler was compiled in.
273 bool canTestSound() const { return _sound_handler
.get() != NULL
; }
275 /// Return true if this build of MovieTester supports pixel checking
277 /// Pixel checking will be supported as long as a testing-capable render handler
278 /// was compiled in. Testing-capable means capable of off-screen rendering, which
279 /// is implementing the Renderer::initTestBuffer method.
281 bool canTestRendering() const { return ! _testingRenderers
.empty(); }
283 /// Return true if this build of gnash supports video
284 bool canTestVideo() const;
286 /// Restart the movie
288 /// NOTE: the movie returned by getRootMovie() will likely be
289 /// NOT the real root movie anymore, so call getRootMovie
290 /// again after this call.
294 /// Simulate a manually resized view.
296 /// If scaleMode != noScale, the renderers are instructed
297 /// to scale the view.
298 void resizeStage(int x
, int y
) ;
302 /// Initialize testing renderers
303 void initTestingRenderers();
305 /// Initialize sound handlers
307 /// For now this function initializes a single sound handler,
308 /// the one enabled at configure time.
309 /// In the future it might initialize multiple ones (maybe)
311 void initTestingSoundHandlers();
313 /// Initialize media handlers
315 /// For now this function initializes a single media handler,
316 /// the one enabled at configure time.
317 /// In the future it might initialize multiple ones (maybe)
319 void initTestingMediaHandlers();
321 /// Render the current movie to all testing renderers
323 /// This function calls movie_root::display internally
327 /// Render the current movie to a specific testing renderer
330 /// The renderer to draw to. It will be temporarly set as
331 /// the global renderer in the gnash core lib.
333 /// @param invalidated
334 /// The invalidated ranges as computed by the core lib.
336 void render(boost::shared_ptr
<Renderer
> renderer
,
337 InvalidatedRanges
& invalidated
);
339 /// Add a testing renderer to the list, initializing it with current
341 void addTestingRenderer(boost::shared_ptr
<Renderer
> h
,
342 const std::string
& name
);
344 gnash::movie_root
* _movie_root
;
346 boost::intrusive_ptr
<gnash::movie_definition
> _movie_def
;
348 boost::shared_ptr
<sound::sound_handler
> _sound_handler
;
350 boost::shared_ptr
<media::MediaHandler
> _mediaHandler
;
352 std::auto_ptr
<RunResources
> _runResources
;
353 /// Current pointer position - X ordinate
356 /// Current pointer position - Y ordinate
359 /// Current viewport width
362 /// Current viewport height
365 /// Invalidated bounds of the movie after last
366 /// advance call. They are cached here so we
367 /// can safely call ::display w/out wiping this
369 InvalidatedRanges _invalidatedBounds
;
371 typedef std::vector
<TestingRenderer
> TestingRenderers
;
373 TestingRenderers _testingRenderers
;
375 // When true, pass world invalidated ranges
376 // to the renderer(s) at ::render time.
379 /// Virtual clock to use to let test runners
380 /// control time flow
383 /// number of samples fetched
384 unsigned int _samplesFetched
;
387 // exp2 isn't part of standard C++, so is defined here in case the compiler
388 // doesn't supply it (e.g. in BSD)
390 inline double exp2(double x
) { return std::pow((double)2, double(x
)); }
395 #endif // _GNASH_MOVIETESTER_H