Gnash 0.8.10dev
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 "dsodefs.h" // DSOEXPORT
00083 #include "MouseButtonState.h" // for composition
00084 #include "DragState.h" // for composition
00085 #include "GnashKey.h" // key::code
00086 #include "Movie.h"
00087 #include "GnashEnums.h" 
00088 #include "MovieClip.h"
00089 #include "SimpleBuffer.h" // for LoadCallback
00090 #include "MovieLoader.h"
00091 #include "ExternalInterface.h"
00092 #include "GC.h"
00093 #include "VM.h"
00094 #include "HostInterface.h"
00095 #include "log.h"
00096 
00097 #ifdef USE_SWFTREE
00098 # include "tree.hh"
00099 #endif
00100 
00101 // GNASH_PARANOIA_LEVEL:
00102 // 0 : (not unimplemented)
00103 // 1 : quick assertions
00104 // 2 : add testInvariant
00105 //
00106 #ifndef GNASH_PARANOIA_LEVEL
00107 # define GNASH_PARANOIA_LEVEL 1
00108 #endif
00109 
00110 // Forward declarations
00111 namespace gnash {
00112     class ExecutableCode; 
00113     class URL;
00114     class Timer;
00115     class MovieClip;
00116     class VirtualClock;
00117     class IOChannel;
00118     class RunResources;
00119     class Button;
00120     class VM;
00121 }
00122 
00123 namespace gnash {
00124 
00125 struct DepthComparator
00126 {
00127     typedef MovieClip* LevelMovie;
00128     bool operator()(const LevelMovie& d1, const LevelMovie& d2) const {
00129         return d1->get_depth() < d2->get_depth();
00130     }
00131 };
00132 
00134 //
00139 //
00142 //
00147 //
00149 class DSOEXPORT movie_root : public GcRoot, boost::noncopyable
00150 {
00151 public:
00152     
00154     typedef std::list<Button*> Listeners;
00155 
00156     class LoadCallback {
00157     public:
00158         LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o)
00159             :
00160             _stream(s),
00161             _obj(o)
00162         {}
00163         bool processLoad();
00164         void setReachable() const;
00165     private:
00166         boost::shared_ptr<IOChannel> _stream;
00167         SimpleBuffer _buf;
00168         as_object* _obj;
00169     };
00170     typedef std::list<LoadCallback> LoadCallbacks;        
00171 
00172     typedef std::bitset<key::KEYCOUNT> Keys;
00173 
00175     //
00178     movie_root(VirtualClock& clock, const RunResources& runResources);
00179 
00180     ~movie_root();
00181 
00183     //
00185     // 
00191     Movie* init(movie_definition* def,
00192             const MovieClip::MovieVariables& variables);
00193 
00195     //
00199     MovieClip* getLevel(unsigned int num) const;
00200 
00202     //
00207     void setLevel(unsigned int num, Movie* movie);
00208 
00210     //
00218     void replaceLevel(unsigned int num, Movie* external_movie);
00219 
00221     //
00234     void swapLevels(MovieClip* sp, int depth);
00235 
00237     //
00245     void dropLevel(int depth);
00246 
00248     //
00251     //
00254     void setDimensions(size_t w, size_t h);
00255 
00257     size_t getStageWidth() const;
00258 
00260     size_t getStageHeight() const;
00261 
00263     //
00272     DSOEXPORT bool mouseMoved(boost::int32_t x, boost::int32_t y);
00273 
00275     //
00278     DSOEXPORT bool mouseClick(bool press);
00279 
00281     //
00286     DSOEXPORT bool mouseWheel(int delta);
00287 
00289     //
00293     DSOEXPORT bool keyEvent(key::code k, bool down);
00294 
00296     //
00298     std::pair<boost::int32_t, boost::int32_t> mousePosition() const;
00299 
00300     void setDragState(const DragState& st);
00301 
00303     //
00305     Movie& getRootMovie() {
00306         return *_rootMovie;
00307     }
00308 
00309     void stop_drag() {
00310         _dragState.reset();
00311     }
00312 
00314     //
00324     boost::uint32_t addIntervalTimer(std::auto_ptr<Timer> timer);
00325 
00327     //
00331     //
00333     //
00336     //
00339     //
00342     void addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str);
00343 
00344     void addAdvanceCallback(ActiveRelay* obj);
00345 
00346     void removeAdvanceCallback(ActiveRelay* obj);
00347 
00349     //
00351     bool clearIntervalTimer(boost::uint32_t x);
00352 
00353     void set_background_color(const rgba& color);
00354 
00355     void set_background_alpha(float alpha);
00356 
00358     VM& getVM() { return _vm; }
00359  
00362     //
00366     bool advance();
00367 
00371     //
00374     int timeToNextFrame() const;
00375 
00377     //
00387     void advanceMovie();
00388 
00389     void display();
00390 
00392     size_t nextUnnamedInstance() {
00393         return ++_unnamedInstance;
00394     }
00395 
00397     void add_key_listener(Button* listener);
00398 
00400     void remove_key_listener(Button* listener);
00401 
00403     //
00409     DisplayObject* getFocus();
00410 
00412     //
00418     bool setFocus(DisplayObject* to);
00419     
00420     DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges,
00421             bool force);
00422     
00424     //
00431     DisplayObject* getActiveEntityUnderPointer() const;
00432 
00434     //
00438     const DisplayObject* getEntityUnderPointer() const;
00439 
00441     DisplayObject* getDraggingCharacter() const;
00442 
00443     bool testInvariant() const;
00444 
00446     enum DisplayState {
00447         DISPLAYSTATE_NORMAL,
00448         DISPLAYSTATE_FULLSCREEN
00449     };
00450 
00452     enum ScaleMode {
00453         SCALEMODE_SHOWALL,
00454         SCALEMODE_NOSCALE,
00455         SCALEMODE_EXACTFIT,
00456         SCALEMODE_NOBORDER
00457     };
00458 
00460     enum StageHorizontalAlign {
00461         STAGE_H_ALIGN_C,
00462         STAGE_H_ALIGN_L,
00463         STAGE_H_ALIGN_R
00464     };
00465 
00467     enum StageVerticalAlign {
00468         STAGE_V_ALIGN_C,
00469         STAGE_V_ALIGN_T,       
00470         STAGE_V_ALIGN_B
00471     };
00472 
00474     enum AlignMode {
00475         STAGE_ALIGN_L,
00476         STAGE_ALIGN_T,
00477         STAGE_ALIGN_R,
00478         STAGE_ALIGN_B
00479     };
00480 
00482     enum AllowScriptAccessMode {
00483         SCRIPT_ACCESS_NEVER,
00484         SCRIPT_ACCESS_SAME_DOMAIN,
00485         SCRIPT_ACCESS_ALWAYS
00486     };
00487 
00489     void setQuality(Quality q);
00490 
00492     Quality getQuality() const { return _quality; }
00493 
00496     void setStageAlignment(short s);
00497 
00500     void setAllowScriptAccess(AllowScriptAccessMode mode);
00501     
00503     AllowScriptAccessMode getAllowScriptAccess();
00504 
00505     typedef std::pair<StageHorizontalAlign, StageVerticalAlign> StageAlign;
00506 
00509     StageAlign getStageAlignment() const;
00510 
00513     bool getShowMenuState() const;
00514     
00517     void setShowMenuState(bool state);
00518 
00520     void setStageScaleMode(ScaleMode sm);
00521     
00523     ScaleMode getStageScaleMode() const { return _scaleMode; }
00524 
00525     // The string representation of the current align mode.
00526     std::string getStageAlignMode() const;
00527 
00529     DisplayState getStageDisplayState() const { return _displayState; }
00530 
00531     // The string representation of the current align mode.
00532     void setStageDisplayState(const DisplayState ds);
00533 
00535     enum ActionPriorityLevel {
00537         PRIORITY_INIT,
00539         PRIORITY_CONSTRUCT,
00541         PRIORITY_DOACTION,
00543         PRIORITY_SIZE
00544     };
00545 
00547     //
00551     typedef boost::array<boost::ptr_deque<ExecutableCode>, PRIORITY_SIZE>
00552         ActionQueue;
00553 
00555     void pushAction(std::auto_ptr<ExecutableCode> code, size_t lvl);
00556 
00558     void pushAction(const action_buffer& buf, DisplayObject* target);
00559 
00561     //
00572     void markReachableResources() const;
00573 
00577     //
00582     void addLiveChar(MovieClip* ch)
00583     {
00584         // Don't register the object in the list twice 
00585 #if GNASH_PARANOIA_LEVEL > 1
00586         assert(std::find(_liveChars.begin(), _liveChars.end(), ch) ==
00587             _liveChars.end());
00588 #endif
00589         _liveChars.push_front(ch);
00590     }
00591 
00593     void reset();
00594 
00596     //
00606     void disableScripts();
00607 
00609     bool scriptsDisabled() const { return _disableScripts; };
00610 
00613     //
00619     void flushHigherPriorityActionQueues();
00620 
00621     DisplayObject* findCharacterByTarget(const std::string& tgtstr) const;
00622 
00624     //
00628     //
00640     void loadMovie(const std::string& url, const std::string& target,
00641             const std::string& data, MovieClip::VariablesMethod method,
00642             as_object* handler=0)
00643     {
00644         _movieLoader.loadMovie(url, target, data, method, handler);
00645     }
00646 
00648     //
00652     //
00660     void getURL(const std::string& urlstr, const std::string& target,
00661             const std::string& data, MovieClip::VariablesMethod method);
00662 
00663 
00664     key::code lastKeyEvent() const {
00665         return _lastKeyEvent;
00666     }
00667 
00668     const Keys& unreleasedKeys() const {
00669         return _unreleasedKeys;
00670     }
00671 
00674     void setHostFD(int fd) {
00675         assert(fd >= 0);
00676         _hostfd = fd;
00677     }
00678 
00681     void setControlFD(int fd) {
00682         _controlfd = fd;
00683     }
00684 
00689     int getHostFD() const {
00690         return _hostfd;
00691     }
00692 
00693     int getControlFD() const {
00694         return _controlfd;
00695     }
00696 
00706     DSOEXPORT void registerFSCommandCallback(FsCallback* handler) {
00707         _fsCommandHandler = handler;
00708     }
00709 
00711     DSOEXPORT void handleFsCommand(const std::string& cmd,
00712             const std::string& arg) const;
00713     
00720     DSOEXPORT void registerEventCallback(HostInterface* handler) {
00721         _interfaceHandler = handler;
00722     }
00723 
00725     //
00727     void callInterface(const HostInterface::Message& e) const;
00728 
00730     //
00735     //
00738     template<typename T> T callInterface(const HostInterface::Message& e) const;
00739 
00744     //
00755     void setScriptLimits(boost::uint16_t recursion, boost::uint16_t timeout);
00756     
00759     boost::uint16_t getRecursionLimit() const {
00760         return _recursionLimit;
00761     }
00762 
00765     boost::uint16_t getTimeoutLimit() const
00766     {
00767         return _timeoutLimit;
00768     }
00769 
00770 #ifdef USE_SWFTREE
00771     typedef tree<std::pair<std::string, std::string> > InfoTree;
00772     void getMovieInfo(InfoTree& tr, InfoTree::iterator it);
00773     void getCharacterTree(InfoTree& tr, InfoTree::iterator it);
00774 #endif
00775 
00776     const RunResources& runResources() const { return _runResources; }
00777 
00779     void addExternalCallback(const std::string& name, as_object* callback);
00780 
00781     bool processInvoke(ExternalInterface::invoke_t *);
00782 
00783     std::string callExternalCallback(const std::string &name, 
00784                                      const std::vector<as_value>& args);
00785     
00786     std::string callExternalJavascript(const std::string &name, 
00787                                        const std::vector<as_value>& args);
00788 
00790     //
00795     void removeQueuedConstructor(DisplayObject* target);
00796 
00797     GC& gc() {
00798         return _gc;
00799     }
00800 
00801     bool abortOnScriptTimeout(const std::string& when) const;
00802 
00803 private:
00804 
00806     //
00828     void setRootMovie(Movie* movie);
00829 
00831     bool notify_mouse_listeners(const event_id& event);
00832     
00836     bool fire_mouse_event();
00837 
00839     void doMouseDrag();
00840 
00842     void executeAdvanceCallbacks();
00843     
00845     void executeTimers();
00846 
00848     void cleanupAndCollect();
00849 
00853     //
00865     InteractiveObject* getTopmostMouseEntity(boost::int32_t x,
00866             boost::int32_t y) const;
00867 
00870     void cleanupDisplayList();
00871 
00873     void advanceLiveChars();
00874 
00878     void setInvalidated() { _invalidated = true; }
00879 
00881     //
00884     void clearInvalidated() { _invalidated = false; }
00885 
00887     //
00894     bool isInvalidated() { return _invalidated; }
00895 
00897     //
00900     size_t minPopulatedPriorityQueue() const;
00901 
00905     size_t processActionQueue(size_t lvl);
00906 
00907     bool processingActions() const {
00908         return (_processingActionLevel < PRIORITY_SIZE);
00909     }
00910 
00911     const DisplayObject* findDropTarget(boost::int32_t x, boost::int32_t y,
00912             DisplayObject* dragging) const;
00913 
00914     void handleActionLimitHit(const std::string& ref);
00915 
00917     //
00922     //
00924     Listeners _keyListeners;
00925 
00926     GC _gc;
00927 
00928     const RunResources& _runResources; 
00929 
00932     VM _vm;
00933 
00935     HostInterface* _interfaceHandler;
00936 
00938     FsCallback* _fsCommandHandler;
00939 
00941     //
00946     typedef std::list<MovieClip*> LiveChars;
00947 
00949     LiveChars _liveChars;
00950 
00951     ActionQueue _actionQueue;
00952 
00954     void processActionQueue();
00955 
00957     size_t _stageWidth;
00958     size_t _stageHeight;
00959 
00960     rgba m_background_color;
00961     bool m_background_color_set;
00962 
00963     boost::int32_t _mouseX;
00964     boost::int32_t _mouseY;
00965 
00966     MouseButtonState  _mouseButtonState;
00967 
00969     typedef std::set<ActiveRelay*> ObjectCallbacks;
00970     ObjectCallbacks _objectCallbacks;
00971 
00972     LoadCallbacks _loadCallbacks;
00973     
00974     typedef std::map<boost::uint32_t, boost::shared_ptr<Timer> > TimerMap;
00975 
00976     TimerMap _intervalTimers;
00977 
00978     size_t _lastTimerId;
00979 
00981     Keys _unreleasedKeys;   
00982 
00983     key::code _lastKeyEvent;
00984 
00986     DisplayObject* _currentFocus;
00987 
00989     DragState _dragState;
00990 
00991     typedef std::map<int, MovieClip*> Levels;
00992 
00994     //
00998     Levels _movies;
00999 
01003     Movie* _rootMovie;
01004 
01006     bool _invalidated;
01007 
01010     bool _disableScripts;
01011     int _processingActionLevel;
01012     
01014     //
01016     int _hostfd;
01017     int _controlfd;
01018 
01020     //
01023     Quality _quality;
01024 
01026     std::bitset<4u> _alignMode;
01027 
01028     AllowScriptAccessMode _allowScriptAccess;
01029 
01031     bool _showMenu;
01032 
01034     ScaleMode _scaleMode;
01035 
01037     DisplayState _displayState;
01038     
01039     // Maximum number of recursions set in the ScriptLimits tag.
01040     boost::uint16_t _recursionLimit;
01041 
01042     // Timeout in seconds for script execution, set in the ScriptLimits tag.
01043     boost::uint16_t _timeoutLimit;
01044 
01045     // delay between movie advancement, in milliseconds
01046     size_t _movieAdvancementDelay;
01047 
01048     // time of last movie advancement, in milliseconds
01049     size_t _lastMovieAdvancement;
01050 
01052     size_t _unnamedInstance;
01053 
01054     MovieLoader _movieLoader;
01055 };
01056 
01058 //
01066 bool isLevelTarget(int version, const std::string& name, unsigned int& levelno);
01067 
01068 DSOEXPORT short stringToStageAlign(const std::string& s);
01069 
01070 template<typename T>
01071 T
01072 movie_root::callInterface(const HostInterface::Message& e) const
01073 {
01074     if (!_interfaceHandler) {
01075         log_error("Hosting application registered no callback for "
01076                 "messages, can't call %s(%s)");
01077         return T();
01078     }
01079 
01080     try {
01081         return boost::any_cast<T>(_interfaceHandler->call(e));
01082     }
01083     catch (const boost::bad_any_cast&) {
01084         log_error(_("Unexpected type from host interface when requesting "
01085                 "%1%"), e); 
01086         return T();
01087     }
01088 }
01089 
01090 
01091 } // namespace gnash
01092 
01093 #endif // GNASH_MOVIE_ROOT_H
01094 
01095 // Local Variables:
01096 // mode: C++
01097 // indent-tabs-mode: nil
01098 // End: