Update with current status
[gnash.git] / testsuite / MovieTester.h
blob8d86a07e940fa921891a6b2f4eb8d49b36ab6478
1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 * Free Software Foundation, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
22 #ifndef GNASH_MOVIETESTER_H
23 #define GNASH_MOVIETESTER_H
25 #ifdef HAVE_CONFIG_H
26 # include "gnashconfig.h" // For exp2 test
27 #endif
29 #include "Range2d.h"
30 #include "GnashKey.h"
31 #include "sound_handler.h" // for creating the "test" sound handlers
32 #include "Renderer.h" // for dtor visibility by unique_ptr
33 #include "Movie.h"
34 #include "ManualClock.h" // for composition
35 #include "RunResources.h" // For initialization.
36 #include "movie_root.h"
38 #include <boost/intrusive_ptr.hpp>
39 #include <vector>
40 #include <memory> // for unique_ptr
41 #include <string>
42 #include <cmath>
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
59 namespace gnash {
60 class movie_definition;
61 class movie_root;
62 class MovieClip;
63 class DisplayObject;
64 class FuzzyPixel;
65 class VirtualClock;
66 class rgba;
69 namespace gnash {
71 /// A table of built renderers
73 ///
74 class TestingRenderer
77 public:
79 TestingRenderer(std::shared_ptr<Renderer> renderer,
80 const std::string& name)
82 _name(name),
83 _renderer(renderer)
86 const std::string& getName() const { return _name; }
88 /// Return the underlying render handler
89 std::shared_ptr<Renderer> getRenderer() const { return _renderer; }
91 private:
93 std::string _name;
94 std::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.
105 class MovieTester
107 public:
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 ~MovieTester();
119 /// Advance the movie by one frame
121 /// Note that the default testing behaviour does not mirror actual
122 /// playback; under normal circumstances, movie_root::advance() is
123 /// called at a heartbeat rate, while movie_root calculates when to
124 /// advance the frame. In order to reproduce this behaviour, call
125 /// MovieTester::advance(false), then MovieTester::advanceClock(x), where
126 /// x is the heartbeat interval in ms.
128 /// Rendering is only triggered when the frame advanced.
130 /// @param updateClock
131 /// If true (the default), this method also
132 /// advances the clock by the nominal delay expected
133 /// between frame advancements before performing the
134 /// actual playhead advancement.
135 void advance(bool updateClock = true);
137 /// Advance the clock by the given amount of milliseconds
138 void advanceClock(unsigned long ms);
140 /// Fully redraw of current frame
142 /// This function forces complete redraw in all testing
143 /// renderers.
145 void redraw();
147 /// Return the invalidated ranges in PIXELS
149 /// This is to debug/test partial rendering
151 geometry::SnappingRanges2d<int> getInvalidatedRanges() const;
153 /// Find a DisplayObject in the display list of a sprite by name.
155 /// Return NULL if there's no DisplayObject with that name in
156 /// the sprite's display list.
158 DSOTEXPORT const DisplayObject* findDisplayItemByName(const MovieClip& mc,
159 const std::string& name);
161 /// Find a DisplayObject on the stage by full target name.
163 /// Return NULL if there's no DisplayObject reachable with that target.
165 const DisplayObject* findDisplayItemByTarget(const std::string& tgt);
167 /// Find a DisplayObject in the display list of a sprite by depth.
169 /// Return NULL if there's no DisplayObject at that depth in
170 /// the sprite's display list.
172 const DisplayObject* findDisplayItemByDepth(const MovieClip& mc,
173 int depth);
175 /// Get the topmost sprite instance of this movie
177 /// We const_cast this because we don't care.
178 gnash::MovieClip* getRootMovie() {
179 return const_cast<Movie*>(&_movie_root->getRootMovie());
182 /// Get the nominal frame rate of the movie associated with this run
183 float getFrameRate() const;
185 /// Notify mouse pointer movement to the given coordinate
187 /// Coordinates are in pixels
189 void movePointerTo(int x, int y);
191 /// Check color of the average pixel under the mouse pointer
194 /// This method will test any built renderer.
196 /// @param x
197 /// The x coordinate of the point being the center
198 /// of the circle you want to compute the average color of.
200 /// @param y
201 /// The y coordinate of the point being the center
202 /// of the circle you want to compute the average color of.
204 /// @param radius
205 /// Radius defining the average zone used.
206 /// 1 means a single pixel.
207 /// Behaviour of passing 0 is undefined.
209 /// @param color
210 /// The color we expect to find under the pointer.
212 /// @param tolerance
213 /// The tolerated difference of any r,g,b,a values.
214 /// Note that the actual tolerance used for comparison might
215 /// be bigger then the given one depending on the minimum tolerance
216 /// supported by the renderers being tested, being a function of color
217 /// depth. For example, comparisions against 16bpp renderers will use
218 /// at tolerance of at least 8.
220 /// @param label
221 /// A label to use in test results.
223 /// @param expectFailure
224 /// Set to true if a failure is expected. Defaults to false.
226 void checkPixel(int x, int y, unsigned radius, const rgba& color,
227 short unsigned tolerance, const std::string& label, bool expectFailure=false) const;
229 VM& vm() {
230 assert(_movie_root);
231 return _movie_root->getVM();
234 /// Notify mouse button was pressed
235 void pressMouseButton();
237 /// Notify mouse button was depressed
238 void depressMouseButton();
240 /// Simulate a mouse click (press and depress mouse button)
241 void click();
243 /// Simulate a mouse scroll.
245 /// The only values seen so far are -1 and 1, but documented to be
246 /// usually between -3 and 3. 1 is up, -1 is down.
247 void scrollMouse(int delta);
249 /// Notify key press
251 /// See key codes in namespace gnash::key (GnashKey.h)
253 void pressKey(key::code k);
255 /// Notify key release
257 /// See key codes in namespace gnash::key (GnashKey.h)
259 void releaseKey(key::code k);
261 /// Return true if the currently active
262 /// DisplayObject is over a DisplayObject that
263 /// handles mouse events
264 bool isMouseOverMouseEntity();
266 /// Return true if a gui would be using an hand
267 /// cursor in the current position.
268 bool usingHandCursor();
270 /// Return true if a streaming sound is active, false if not.
271 bool streamingSound() const;
273 /// \brief
274 /// Return the number of times a sound has been stopped,
275 /// or 0 if sound testing is not supported. See canTestSound().
277 int soundsStopped();
279 /// \brief
280 /// Return the number of times a sound has been started,
281 /// or 0 if sound testing is not supported. See canTestSound().
283 int soundsStarted();
285 /// Return true if this build of MovieTester supports sound testing
287 /// Sound will be supported as long as a sound handler was compiled in.
289 bool canTestSound() const { return _sound_handler.get() != NULL; }
291 /// Return true if this build of MovieTester supports pixel checking
293 /// Pixel checking will be supported as long as a testing-capable render handler
294 /// was compiled in. Testing-capable means capable of off-screen rendering, which
295 /// is implementing the Renderer::initTestBuffer method.
297 bool canTestRendering() const { return ! _testingRenderers.empty(); }
299 /// Return true if this build of gnash supports video
300 bool canTestVideo() const;
302 /// Restart the movie
304 /// NOTE: the movie returned by getRootMovie() will likely be
305 /// NOT the real root movie anymore, so call getRootMovie
306 /// again after this call.
308 void restart();
310 /// Simulate a manually resized view.
312 /// If scaleMode != noScale, the renderers are instructed
313 /// to scale the view.
314 void resizeStage(int x, int y) ;
316 private:
318 /// Initialize testing renderers
319 void initTestingRenderers();
321 /// Initialize sound handlers
323 /// For now this function initializes a single sound handler,
324 /// the one enabled at configure time.
325 /// In the future it might initialize multiple ones (maybe)
327 void initTestingSoundHandlers();
329 /// Initialize media handlers
331 /// For now this function initializes a single media handler,
332 /// the one enabled at configure time.
333 /// In the future it might initialize multiple ones (maybe)
335 void initTestingMediaHandlers();
337 /// Render the current movie to all testing renderers
339 /// This function calls movie_root::display internally
341 void render();
343 /// Render the current movie to a specific testing renderer
345 /// @param renderer
346 /// The renderer to draw to. It will be temporarly set as
347 /// the global renderer in the gnash core lib.
349 /// @param invalidated
350 /// The invalidated ranges as computed by the core lib.
352 void render(std::shared_ptr<Renderer> renderer,
353 InvalidatedRanges& invalidated);
355 /// Add a testing renderer to the list, initializing it with current
356 //viewport size
357 void addTestingRenderer(std::shared_ptr<Renderer> h,
358 const std::string& name);
360 RunResources _runResources;
362 std::shared_ptr<sound::sound_handler> _sound_handler;
364 boost::intrusive_ptr<gnash::movie_definition> _movie_def;
366 std::shared_ptr<media::MediaHandler> _mediaHandler;
368 std::unique_ptr<gnash::movie_root> _movie_root;
370 /// Current pointer position - X ordinate
371 int _x;
373 /// Current pointer position - Y ordinate
374 int _y;
376 /// Current viewport width
377 unsigned _width;
379 /// Current viewport height
380 unsigned _height;
382 /// Invalidated bounds of the movie after last
383 /// advance call. They are cached here so we
384 /// can safely call ::display w/out wiping this
385 /// information out.
386 InvalidatedRanges _invalidatedBounds;
388 typedef std::vector<TestingRenderer> TestingRenderers;
390 TestingRenderers _testingRenderers;
392 // When true, pass world invalidated ranges
393 // to the renderer(s) at ::render time.
394 bool _forceRedraw;
396 /// Virtual clock to use to let test runners
397 /// control time flow
398 ManualClock _clock;
400 /// number of samples fetched
401 unsigned int _samplesFetched;
404 } // namespace gnash
406 #endif // _GNASH_MOVIETESTER_H