Gnash 0.8.9

movie_root.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
00003 //   2011 Free Software Foundation, Inc
00004 // 
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 
00062 
00063 
00064 #ifndef GNASH_MOVIE_ROOT_H
00065 #define GNASH_MOVIE_ROOT_H
00066 
00067 #ifdef HAVE_CONFIG_H
00068 #include "gnashconfig.h" //USE_SWFTREE
00069 #endif
00070 
00071 #include <map>
00072 #include <string>
00073 #include <vector>
00074 #include <list>
00075 #include <set>
00076 #include <bitset>
00077 #include <boost/array.hpp>
00078 #include <boost/ptr_container/ptr_deque.hpp>
00079 #include <boost/noncopyable.hpp>
00080 #include <boost/any.hpp>
00081 
00082 #include "smart_ptr.h" 
00083 #include "dsodefs.h" // DSOEXPORT
00084 #include "MouseButtonState.h" // for composition
00085 #include "DragState.h" // for composition
00086 #include "GnashKey.h" // key::code
00087 #include "Movie.h"
00088 #include "GnashEnums.h" 
00089 #include "MovieClip.h"
00090 #include "SimpleBuffer.h" // for LoadCallback
00091 #include "MovieLoader.h"
00092 #include "ExternalInterface.h"
00093 #include "GC.h"
00094 #include "VM.h"
00095 #include "HostInterface.h"
00096 #include "log.h"
00097 
00098 #ifdef USE_SWFTREE
00099 # include "tree.hh"
00100 #endif
00101 
00102 // GNASH_PARANOIA_LEVEL:
00103 // 0 : (not unimplemented)
00104 // 1 : quick assertions
00105 // 2 : add testInvariant
00106 //
00107 #ifndef GNASH_PARANOIA_LEVEL
00108 # define GNASH_PARANOIA_LEVEL 1
00109 #endif
00110 
00111 // Forward declarations
00112 namespace gnash {
00113     class ExecutableCode; 
00114     class URL;
00115     class Timer;
00116     class MovieClip;
00117     class VirtualClock;
00118     class IOChannel;
00119     class RunResources;
00120     class Button;
00121     class VM;
00122 }
00123 
00124 namespace gnash {
00125 
00126 struct DepthComparator
00127 {
00128     typedef MovieClip* LevelMovie;
00129     bool operator()(const LevelMovie& d1, const LevelMovie& d2) const {
00130         return d1->get_depth() < d2->get_depth();
00131     }
00132 };
00133 
00135 //
00140 //
00143 //
00148 //
00150 class DSOEXPORT movie_root : public GcRoot, boost::noncopyable
00151 {
00152 public:
00153     
00155     typedef std::list<Button*> Listeners;
00156 
00157     class LoadCallback {
00158     public:
00159         LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o)
00160             :
00161             _stream(s),
00162             _obj(o)
00163         {}
00164         bool processLoad();
00165         void setReachable() const;
00166     private:
00167         boost::shared_ptr<IOChannel> _stream;
00168         SimpleBuffer _buf;
00169         as_object* _obj;
00170     };
00171     typedef std::list<LoadCallback> LoadCallbacks;        
00172 
00173     typedef std::bitset<key::KEYCOUNT> Keys;
00174 
00176     //
00180     movie_root(const movie_definition& def, VirtualClock& clock,
00181             const RunResources& runResources);
00182 
00183     ~movie_root();
00184 
00186     //
00188     // 
00194     Movie* init(movie_definition* def,
00195             const MovieClip::MovieVariables& variables);
00196 
00198     //
00202     MovieClip* getLevel(unsigned int num) const;
00203 
00205     //
00210     void setLevel(unsigned int num, Movie* movie);
00211 
00213     //
00221     void replaceLevel(unsigned int num, Movie* external_movie);
00222 
00224     //
00237     void swapLevels(MovieClip* sp, int depth);
00238 
00240     //
00248     void dropLevel(int depth);
00249 
00251     //
00254     //
00257     void setDimensions(size_t w, size_t h);
00258 
00260     size_t getStageWidth() const;
00261 
00263     size_t getStageHeight() const;
00264 
00266     //
00275     DSOEXPORT bool mouseMoved(boost::int32_t x, boost::int32_t y);
00276 
00278     //
00281     DSOEXPORT bool mouseClick(bool press);
00282 
00284     //
00289     DSOEXPORT bool mouseWheel(int delta);
00290 
00292     //
00296     DSOEXPORT bool keyEvent(key::code k, bool down);
00297 
00299     //
00301     std::pair<boost::int32_t, boost::int32_t> mousePosition() const;
00302 
00303     void setDragState(const DragState& st);
00304 
00306     //
00308     Movie& getRootMovie() {
00309         return *_rootMovie;
00310     }
00311 
00313     //
00315     float frameRate() const {
00316         return _rootMovie->frameRate();
00317     }
00318 
00319     void stop_drag() {
00320         _dragState.reset();
00321     }
00322 
00324     //
00334     boost::uint32_t addIntervalTimer(std::auto_ptr<Timer> timer);
00335 
00337     //
00341     //
00343     //
00346     //
00349     //
00352     void addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str);
00353 
00354     void addAdvanceCallback(ActiveRelay* obj);
00355 
00356     void removeAdvanceCallback(ActiveRelay* obj);
00357 
00359     //
00361     bool clearIntervalTimer(boost::uint32_t x);
00362 
00364     //
00368     size_t get_current_frame() const {
00369         return _rootMovie->get_current_frame();
00370     }
00371 
00372     void set_background_color(const rgba& color);
00373 
00374     void set_background_alpha(float alpha);
00375 
00377     VM& getVM() { return _vm; }
00378  
00381     //
00385     bool advance();
00386 
00390     //
00393     int timeToNextFrame() const;
00394 
00396     //
00406     void advanceMovie();
00407 
00409     //
00411     void goto_frame(size_t target_frame_number) {
00412         _rootMovie->goto_frame(target_frame_number);
00413     }
00414 
00415     void display();
00416 
00418     size_t nextUnnamedInstance() {
00419         return ++_unnamedInstance;
00420     }
00421 
00423     void add_key_listener(Button* listener);
00424 
00426     void remove_key_listener(Button* listener);
00427 
00429     //
00435     DisplayObject* getFocus();
00436 
00438     //
00444     bool setFocus(DisplayObject* to);
00445     
00446     DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges,
00447             bool force);
00448     
00450     //
00457     DisplayObject* getActiveEntityUnderPointer() const;
00458 
00460     //
00464     const DisplayObject* getEntityUnderPointer() const;
00465 
00467     DisplayObject* getDraggingCharacter() const;
00468 
00469     bool testInvariant() const;
00470 
00472     enum DisplayState {
00473         DISPLAYSTATE_NORMAL,
00474         DISPLAYSTATE_FULLSCREEN
00475     };
00476 
00478     enum ScaleMode {
00479         SCALEMODE_SHOWALL,
00480         SCALEMODE_NOSCALE,
00481         SCALEMODE_EXACTFIT,
00482         SCALEMODE_NOBORDER
00483     };
00484 
00486     enum StageHorizontalAlign {
00487         STAGE_H_ALIGN_C,
00488         STAGE_H_ALIGN_L,
00489         STAGE_H_ALIGN_R
00490     };
00491 
00493     enum StageVerticalAlign {
00494         STAGE_V_ALIGN_C,
00495         STAGE_V_ALIGN_T,       
00496         STAGE_V_ALIGN_B
00497     };
00498 
00500     enum AlignMode {
00501         STAGE_ALIGN_L,
00502         STAGE_ALIGN_T,
00503         STAGE_ALIGN_R,
00504         STAGE_ALIGN_B
00505     };
00506 
00508     enum AllowScriptAccessMode {
00509         SCRIPT_ACCESS_NEVER,
00510         SCRIPT_ACCESS_SAME_DOMAIN,
00511         SCRIPT_ACCESS_ALWAYS
00512     };
00513 
00515     void setQuality(Quality q);
00516 
00518     Quality getQuality() const { return _quality; }
00519 
00522     void setStageAlignment(short s);
00523 
00526     void setAllowScriptAccess(AllowScriptAccessMode mode);
00527     
00529     AllowScriptAccessMode getAllowScriptAccess();
00530 
00531     typedef std::pair<StageHorizontalAlign, StageVerticalAlign> StageAlign;
00532 
00535     StageAlign getStageAlignment() const;
00536 
00539     bool getShowMenuState() const;
00540     
00543     void setShowMenuState(bool state);
00544 
00546     void setStageScaleMode(ScaleMode sm);
00547     
00549     ScaleMode getStageScaleMode() const { return _scaleMode; }
00550 
00551     // The string representation of the current align mode.
00552     std::string getStageAlignMode() const;
00553 
00555     DisplayState getStageDisplayState() const { return _displayState; }
00556 
00557     // The string representation of the current align mode.
00558     void setStageDisplayState(const DisplayState ds);
00559 
00561     enum ActionPriorityLevel {
00563         PRIORITY_INIT,
00565         PRIORITY_CONSTRUCT,
00567         PRIORITY_DOACTION,
00569         PRIORITY_SIZE
00570     };
00571 
00573     //
00577     typedef boost::array<boost::ptr_deque<ExecutableCode>, PRIORITY_SIZE>
00578         ActionQueue;
00579 
00581     void pushAction(std::auto_ptr<ExecutableCode> code, size_t lvl);
00582 
00584     void pushAction(const action_buffer& buf, DisplayObject* target);
00585 
00587     //
00598     void markReachableResources() const;
00599 
00603     //
00608     void addLiveChar(MovieClip* ch)
00609     {
00610         // Don't register the object in the list twice 
00611 #if GNASH_PARANOIA_LEVEL > 1
00612         assert(std::find(_liveChars.begin(), _liveChars.end(), ch) ==
00613             _liveChars.end());
00614 #endif
00615         _liveChars.push_front(ch);
00616     }
00617 
00619     void reset();
00620 
00622     //
00632     void disableScripts();
00633 
00635     bool scriptsDisabled() const { return _disableScripts; };
00636 
00639     //
00645     void flushHigherPriorityActionQueues();
00646 
00647     DisplayObject* findCharacterByTarget(const std::string& tgtstr) const;
00648 
00650     //
00654     //
00666     void loadMovie(const std::string& url, const std::string& target,
00667             const std::string& data, MovieClip::VariablesMethod method,
00668             as_object* handler=0)
00669     {
00670         _movieLoader.loadMovie(url, target, data, method, handler);
00671     }
00672 
00674     //
00678     //
00686     void getURL(const std::string& urlstr, const std::string& target,
00687             const std::string& data, MovieClip::VariablesMethod method);
00688 
00689 
00690     key::code lastKeyEvent() const {
00691         return _lastKeyEvent;
00692     }
00693 
00694     const Keys& unreleasedKeys() const {
00695         return _unreleasedKeys;
00696     }
00697 
00700     void setHostFD(int fd) {
00701         assert(fd >= 0);
00702         _hostfd = fd;
00703     }
00704 
00707     void setControlFD(int fd) {
00708         _controlfd = fd;
00709     }
00710 
00715     int getHostFD() const {
00716         return _hostfd;
00717     }
00718 
00719     int getControlFD() const {
00720         return _controlfd;
00721     }
00722 
00732     DSOEXPORT void registerFSCommandCallback(FsCallback* handler) {
00733         _fsCommandHandler = handler;
00734     }
00735 
00737     DSOEXPORT void handleFsCommand(const std::string& cmd,
00738             const std::string& arg) const;
00739     
00746     DSOEXPORT void registerEventCallback(HostInterface* handler) {
00747         _interfaceHandler = handler;
00748     }
00749 
00751     //
00753     void callInterface(const HostInterface::Message& e) const;
00754 
00756     //
00761     //
00764     template<typename T> T callInterface(const HostInterface::Message& e) const;
00765 
00770     //
00781     void setScriptLimits(boost::uint16_t recursion, boost::uint16_t timeout);
00782     
00785     boost::uint16_t getRecursionLimit() const {
00786         return _recursionLimit;
00787     }
00788 
00791     boost::uint16_t getTimeoutLimit() const
00792     {
00793         return _timeoutLimit;
00794     }
00795 
00796 #ifdef USE_SWFTREE
00797     typedef tree<std::pair<std::string, std::string> > InfoTree;
00798     void getMovieInfo(InfoTree& tr, InfoTree::iterator it);
00799     void getCharacterTree(InfoTree& tr, InfoTree::iterator it);
00800 #endif
00801 
00802     const RunResources& runResources() const { return _runResources; }
00803 
00805     void addExternalCallback(const std::string& name, as_object* callback);
00806 
00807     bool processInvoke(ExternalInterface::invoke_t *);
00808 
00809     std::string callExternalCallback(const std::string &name, 
00810                                      const std::vector<as_value>& args);
00811     
00812     std::string callExternalJavascript(const std::string &name, 
00813                                        const std::vector<as_value>& args);
00814 
00816     //
00821     void removeQueuedConstructor(DisplayObject* target);
00822 
00823     GC& gc() {
00824         return _gc;
00825     }
00826 
00827 private:
00828 
00830     //
00852     void setRootMovie(Movie* movie);
00853 
00855     bool notify_mouse_listeners(const event_id& event);
00856     
00860     bool fire_mouse_event();
00861 
00863     void doMouseDrag();
00864 
00866     void executeAdvanceCallbacks();
00867     
00869     void executeTimers();
00870 
00872     void cleanupAndCollect();
00873 
00877     //
00889     InteractiveObject* getTopmostMouseEntity(boost::int32_t x,
00890             boost::int32_t y) const;
00891 
00894     void cleanupDisplayList();
00895 
00897     void advanceLiveChars();
00898 
00902     void setInvalidated() { _invalidated = true; }
00903 
00905     //
00908     void clearInvalidated() { _invalidated = false; }
00909 
00911     //
00918     bool isInvalidated() { return _invalidated; }
00919 
00921     //
00924     size_t minPopulatedPriorityQueue() const;
00925 
00929     size_t processActionQueue(size_t lvl);
00930 
00931     bool processingActions() const {
00932         return (_processingActionLevel < PRIORITY_SIZE);
00933     }
00934 
00935     const DisplayObject* findDropTarget(boost::int32_t x, boost::int32_t y,
00936             DisplayObject* dragging) const;
00937 
00938     void handleActionLimitHit(const std::string& ref);
00939 
00941     //
00946     //
00948     Listeners _keyListeners;
00949 
00950     GC _gc;
00951 
00952     const RunResources& _runResources; 
00953 
00956     VM _vm;
00957 
00959     HostInterface* _interfaceHandler;
00960 
00962     FsCallback* _fsCommandHandler;
00963 
00965     //
00970     typedef std::list<MovieClip*> LiveChars;
00971 
00973     LiveChars _liveChars;
00974 
00975     ActionQueue _actionQueue;
00976 
00978     void processActionQueue();
00979 
00981     size_t _stageWidth;
00982     size_t _stageHeight;
00983 
00984     rgba m_background_color;
00985     bool m_background_color_set;
00986 
00987     boost::int32_t _mouseX;
00988     boost::int32_t _mouseY;
00989 
00990     MouseButtonState  _mouseButtonState;
00991 
00993     typedef std::set<ActiveRelay*> ObjectCallbacks;
00994     ObjectCallbacks _objectCallbacks;
00995 
00996     LoadCallbacks _loadCallbacks;
00997     
00998     typedef std::map<boost::uint32_t, boost::shared_ptr<Timer> > TimerMap;
00999 
01000     TimerMap _intervalTimers;
01001 
01002     size_t _lastTimerId;
01003 
01005     Keys _unreleasedKeys;   
01006 
01007     key::code _lastKeyEvent;
01008 
01010     DisplayObject* _currentFocus;
01011 
01013     DragState _dragState;
01014 
01015     typedef std::map<int, MovieClip*> Levels;
01016 
01018     //
01022     Levels _movies;
01023 
01027     Movie* _rootMovie;
01028 
01030     bool _invalidated;
01031 
01034     bool _disableScripts;
01035     int _processingActionLevel;
01036     
01038     //
01040     int _hostfd;
01041     int _controlfd;
01042 
01044     //
01047     Quality _quality;
01048 
01050     std::bitset<4u> _alignMode;
01051 
01052     AllowScriptAccessMode _allowScriptAccess;
01053 
01055     bool _showMenu;
01056 
01058     ScaleMode _scaleMode;
01059 
01061     DisplayState _displayState;
01062     
01063     // Maximum number of recursions set in the ScriptLimits tag.
01064     boost::uint16_t _recursionLimit;
01065 
01066     // Timeout in seconds for script execution, set in the ScriptLimits tag.
01067     boost::uint16_t _timeoutLimit;
01068 
01069     // delay between movie advancement, in milliseconds
01070     size_t _movieAdvancementDelay;
01071 
01072     // time of last movie advancement, in milliseconds
01073     size_t _lastMovieAdvancement;
01074 
01076     size_t _unnamedInstance;
01077 
01078     MovieLoader _movieLoader;
01079 };
01080 
01082 //
01090 bool isLevelTarget(int version, const std::string& name, unsigned int& levelno);
01091 
01092 DSOEXPORT short stringToStageAlign(const std::string& s);
01093 
01094 template<typename T>
01095 T
01096 movie_root::callInterface(const HostInterface::Message& e) const
01097 {
01098     if (!_interfaceHandler) {
01099         log_error("Hosting application registered no callback for "
01100                 "messages, can't call %s(%s)");
01101         return T();
01102     }
01103 
01104     try {
01105         return boost::any_cast<T>(_interfaceHandler->call(e));
01106     }
01107     catch (const boost::bad_any_cast&) {
01108         log_error(_("Unexpected type from host interface when requesting "
01109                 "%1%"), e); 
01110         return T();
01111     }
01112 }
01113 
01114 
01115 } // namespace gnash
01116 
01117 #endif // GNASH_MOVIE_ROOT_H
01118 
01119 // Local Variables:
01120 // mode: C++
01121 // indent-tabs-mode: nil
01122 // End: