Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/app/App.h

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2010, The Barbarian Group
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00006  the following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009     the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00011     the following disclaimer in the documentation and/or other materials provided with the distribution.
00012 
00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00020  POSSIBILITY OF SUCH DAMAGE.
00021 */
00022 
00023 #pragma once
00024 
00025 #include "cinder/Cinder.h"
00026 #include "cinder/app/Renderer.h"
00027 #include "cinder/Vector.h"
00028 #include "cinder/app/MouseEvent.h"
00029 #include "cinder/app/KeyEvent.h"
00030 #include "cinder/app/FileDropEvent.h"
00031 #include "cinder/app/ResizeEvent.h"
00032 #include "cinder/Stream.h"
00033 #include "cinder/Display.h"
00034 #include "cinder/DataSource.h"
00035 #include "cinder/Timer.h"
00036 #include "cinder/Function.h"
00037 #if defined( CINDER_COCOA )
00038     #if defined( CINDER_COCOA_TOUCH )
00039         #if defined( __OBJC__ )
00040             #import <UIKit/UIKit.h>
00041             #import <CoreFoundation/CoreFoundation.h>
00042         #endif
00043     #else
00044         #include <ApplicationServices/ApplicationServices.h>
00045     #endif
00046     #if defined __OBJC__
00047         @class CinderView;
00048         @class AppImplCocoaRendererQuartz;
00049         @class AppImplCocoaRendererGl;
00050     #else
00051         class AppImplCocoaRendererQuartz;
00052         class AppImplCocoaRendererGl;
00053     #endif
00054 //  class CinderView;
00055 #elif defined( CINDER_MSW )
00056     #include "cinder/msw/OutputDebugStringStream.h"
00057 #endif
00058 
00059 #include <vector>
00060 #include <algorithm>
00061 
00062 namespace cinder { namespace app { 
00063 
00064 class App {
00065  public:
00066     class Settings {
00067       public:
00068         // whether or not the app should terminate prior to launching
00069         bool    isPrepared() const { return !mShouldQuit; };
00070 
00072         void    setWindowSize( int aWindowSizeX, int aWindowSizeY );
00073 
00075         void    setFrameRate( float aFrameRate );
00076 
00078         void    enablePowerManagement( bool aPowerManagement = true );
00079 
00081         bool    isFullScreen() const { return mFullScreen; }
00083         int     getWindowWidth() const { return mWindowSizeX; }
00085         int     getWindowHeight() const { return mWindowSizeY; }
00087         Vec2i   getWindowSize() const { return Vec2i( mWindowSizeX, mWindowSizeY ); }
00089         Area    getWindowBounds() const { return Area( 0, 0, mWindowSizeX, mWindowSizeY ); }
00090         
00092         const std::string& getTitle() const { return mTitle; }
00094         void    setTitle( const std::string &title ) { mTitle = title; }
00095 
00097         float   getFrameRate() const { return mFrameRate; }
00099         bool    isResizable() const { return mResizable; }
00101         bool    getPowerManagement() const { return mPowerManagement; }
00102 
00103       protected:
00104         Settings();
00105         virtual ~Settings() {}    
00106       
00107         bool            mShouldQuit; // defaults to false, facilitates early termination
00108         int             mWindowSizeX, mWindowSizeY; // default: 640x480
00109         bool            mFullScreen; // window covers screen. default: false
00110         float           mFrameRate;
00111         bool            mResizable; // window is Resizable. default: true
00112         bool            mPowerManagement; // allow screensavers or power management to hide app. default: false
00113         std::string     mTitle;
00114     };
00115 
00116 
00117  public:
00118     // interface
00119     App();
00120     virtual ~App();
00121 
00123     virtual void    setup() {}
00125     virtual void    shutdown() {}
00126 
00128     virtual void    update() {}
00130     virtual void    draw() {}
00131     
00133     virtual void    mouseDown( MouseEvent event ) {}
00135     virtual void    mouseUp( MouseEvent event ) {}  
00137     virtual void    mouseWheel( MouseEvent event ) {}
00139     virtual void    mouseMove( MouseEvent event ) {}
00141     virtual void    mouseDrag( MouseEvent event ) {}    
00143     virtual void    keyDown( KeyEvent event ) {}
00145     virtual void    keyUp( KeyEvent event ) {}
00147     virtual void    resize( ResizeEvent event ) {}
00149     virtual void    fileDrop( FileDropEvent event ) {}
00150     
00152     virtual void    quit() = 0;
00153 
00155     CallbackId      registerMouseDown( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseDown.registerCb( callback ); }
00157     template<typename T>
00158     CallbackId      registerMouseDown( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseDown.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00160     void            unregisterMouseDown( CallbackId id ) { mCallbacksMouseDown.unregisterCb( id ); }
00161 
00163     CallbackId      registerMouseUp( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseUp.registerCb( callback ); }
00165     template<typename T>
00166     CallbackId      registerMouseUp( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseUp.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00168     void            unregisterMouseUp( CallbackId id ) { mCallbacksMouseUp.unregisterCb( id ); }
00169 
00171     CallbackId      registerMouseWheel( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseWheel.registerCb( callback ); }
00173     template<typename T>
00174     CallbackId      registerMouseWheel( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseWheel.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00176     void            unregisterMouseWheel( CallbackId id ) { mCallbacksMouseWheel.unregisterCb( id ); }
00177 
00179     CallbackId      registerMouseMove( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseMove.registerCb( callback ); }
00181     template<typename T>
00182     CallbackId      registerMouseMove( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseMove.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00184     void            unregisterMouseMove( CallbackId id ) { mCallbacksMouseMove.unregisterCb( id ); }
00185 
00187     CallbackId      registerMouseDrag( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseDrag.registerCb( callback ); }
00189     template<typename T>
00190     CallbackId      registerMouseDrag( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseDrag.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00192     void            unregisterMouseDrag( CallbackId id ) { mCallbacksMouseDrag.unregisterCb( id ); }
00193 
00195     CallbackId      registerKeyDown( std::function<bool (KeyEvent)> callback ) { return mCallbacksKeyDown.registerCb( callback ); }
00197     template<typename T>
00198     CallbackId      registerKeyDown( T *obj, bool (T::*callback)(KeyEvent) ) { return mCallbacksKeyDown.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00200     void            unregisterKeyDown( CallbackId id ) { mCallbacksKeyDown.unregisterCb( id ); }
00201 
00203     CallbackId      registerKeyUp( std::function<bool (KeyEvent)> callback ) { return mCallbacksKeyUp.registerCb( callback ); }
00205     template<typename T>
00206     CallbackId      registerKeyUp( T *obj, bool (T::*callback)(KeyEvent) ) { return mCallbacksKeyUp.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00208     void            unregisterKeyUp( CallbackId id ) { mCallbacksKeyUp.unregisterCb( id ); }
00209 
00211     CallbackId      registerResize( std::function<bool (ResizeEvent)> callback ) { return mCallbacksResize.registerCb( callback ); }
00213     template<typename T>
00214     CallbackId      registerResize( T *obj, bool (T::*callback)(ResizeEvent) ) { return mCallbacksResize.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00216     void            unregisterResize( CallbackId id ) { mCallbacksResize.unregisterCb( id ); }
00217 
00219     CallbackId      registerFileDrop( std::function<bool (FileDropEvent)> callback ) { return mCallbacksFileDrop.registerCb( callback ); }
00221     template<typename T>
00222     CallbackId      registerFileDrop( T *obj, bool (T::*callback)(FileDropEvent) ) { return mCallbacksFileDrop.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00224     void            unregisterFileDrop( CallbackId id ) { mCallbacksFileDrop.unregisterCb( id ); }
00225 
00226     // Accessors
00227     virtual const Settings& getSettings() const = 0;
00228     Renderer*               getRenderer() const { return mRenderer.get(); }
00229     
00231     virtual int         getWindowWidth() const = 0;
00233     virtual void        setWindowWidth( int windowWidth ) = 0;
00235     virtual int         getWindowHeight() const = 0;
00237     virtual void        setWindowHeight( int windowHeight ) = 0;
00239     virtual void        setWindowSize( int windowWidth, int windowHeight ) = 0;
00241     void                setWindowSize( const Vec2i &size ) { setWindowSize( size.x, size.y ); }
00243 
00244     Vec2f               getWindowCenter() const { return Vec2f( (float)getWindowWidth(), (float)getWindowHeight() ) * 0.5f; }
00246     Vec2i               getWindowSize() const { return Vec2i( getWindowWidth(), getWindowHeight() ); }
00248     float               getWindowAspectRatio() const { return getWindowWidth() / (float)getWindowHeight(); }
00250 
00251     Area                getWindowBounds() const { return Area( 0, 0, getWindowWidth(), getWindowHeight() ); }
00253     virtual float       getFrameRate() const = 0;
00255     virtual void        setFrameRate( float aFrameRate ) = 0;
00257     float               getAverageFps() const { return mAverageFps; }
00259     double              getFpsSampleInterval() const { return mFpsSampleInterval; }
00261     void                setFpsSampleInterval( double sampleInterval ) { mFpsSampleInterval = sampleInterval; }  
00262 
00264     virtual bool        isFullScreen() const = 0;
00266     virtual void        setFullScreen( bool aFullScreen ) = 0;
00267 
00269     double              getElapsedSeconds() const { return mTimer.getSeconds(); }
00271     uint32_t            getElapsedFrames() const { return mFrameCount; }
00272     
00273     // utilities
00275     static DataSourceRef        loadResource( const std::string &macPath, int mswID, const std::string &mswType );
00276 #if defined( CINDER_COCOA )
00277 
00278     static DataSourcePathRef    loadResource( const std::string &macPath );
00280     static std::string          getResourcePath( const std::string &rsrcRelativePath );
00282     static std::string          getResourcePath();
00283 #else
00284 
00285     static DataSourceBufferRef  loadResource( int mswID, const std::string &mswType );
00286 #endif
00287     
00289     virtual std::string         getAppPath() = 0;
00291 
00294     std::string     getOpenFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() );
00296     std::string     getFolderPath(const std::string &initialPath="");
00298 
00301     std::string     getSaveFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() );
00302 
00304     std::ostream&   console();
00305 
00307     Surface copyWindowSurface();
00309     Surface copyWindowSurface( const Area &area );
00311     void    restoreWindowContext();
00312 
00313     
00314     // DO NOT CALL - should be private but aren't for esoteric reasons
00316     // Internal handlers - these are called into by AppImpl's. If you are calling one of these, you have likely strayed far off the path.
00317     void    privateMouseDown__( const MouseEvent &event );
00318     void    privateMouseUp__( const MouseEvent &event );
00319     void    privateMouseWheel__( const MouseEvent &event );
00320     void    privateMouseMove__( const MouseEvent &event );
00321     void    privateMouseDrag__( const MouseEvent &event );
00322     void    privateKeyDown__( const KeyEvent &event );
00323     void    privateKeyUp__( const KeyEvent &event );
00324     void    privateFileDrop__( const FileDropEvent &event );
00325 
00326     virtual void    privateSetup__();
00327     virtual void    privateResize__( const ResizeEvent &event );    
00328     virtual void    privateUpdate__();
00329     virtual void    privateDraw__();
00330     virtual void    privateShutdown__();
00332 
00333 #if defined( CINDER_MSW )
00334     // Not all Windows target types receive paint events, and the AppImplMswRenderer* needs to know that.
00335     virtual bool        getsWindowsPaintEvents() = 0;
00336 #endif
00337 
00338     virtual bool        receivesEvents() const { return true; }
00339 
00341     static App*         get() { return sInstance; }
00342 
00343   protected:
00345     // These are called by application instantation macros and are only used in the launch process
00346     static void     prepareLaunch();
00347     static void     executeLaunch( App *app, class Renderer *renderer, const char *title, int argc, char * const argv[] );
00348     static void     cleanupLaunch();
00349     
00350     virtual void    launch( const char *title, int argc, char * const argv[] ) = 0;
00352 
00353   private:
00354   
00355 #if defined( CINDER_MSW )
00356     friend class AppImplMsw;
00357     std::shared_ptr<cinder::msw::dostream>  mOutputStream;
00358 #else
00359     static void             *sAutoReleasePool;
00360 #endif
00361 
00362     Timer                   mTimer;
00363     uint32_t                mFrameCount;
00364     float                   mAverageFps;
00365     uint32_t                mFpsLastSampleFrame;
00366     double                  mFpsLastSampleTime;
00367     double                  mFpsSampleInterval;
00368 
00369     std::shared_ptr<Renderer>   mRenderer;
00370     
00371     CallbackMgr<bool (MouseEvent)>      mCallbacksMouseDown, mCallbacksMouseUp, mCallbacksMouseWheel, mCallbacksMouseMove, mCallbacksMouseDrag;
00372     CallbackMgr<bool (KeyEvent)>        mCallbacksKeyDown, mCallbacksKeyUp;
00373     CallbackMgr<bool (ResizeEvent)>     mCallbacksResize;
00374     CallbackMgr<bool (FileDropEvent)>   mCallbacksFileDrop;
00375     
00376     static App*     sInstance;
00377 };
00378 
00383 
00384 inline int  getWindowWidth() { return App::get()->getWindowWidth(); }
00386 inline void setWindowWidth( int windowWidth ) { App::get()->setWindowWidth( windowWidth ); }
00388 inline int  getWindowHeight() { return App::get()->getWindowHeight(); }
00390 inline void setWindowHeight( int windowHeight ) { App::get()->setWindowHeight( windowHeight ); }
00392 inline void     setWindowSize( int windowWidth, int windowHeight ) { App::get()->setWindowSize( windowWidth, windowHeight ); }
00394 
00395 inline Vec2f    getWindowCenter() { return App::get()->getWindowCenter(); }
00397 inline Vec2i    getWindowSize() { return App::get()->getWindowSize(); }
00399 inline float    getWindowAspectRatio() { return App::get()->getWindowAspectRatio(); }
00401 
00402 inline Area     getWindowBounds() { return App::get()->getWindowBounds(); }
00404 inline float    getFrameRate() { return App::get()->getFrameRate(); }
00406 inline void     setFrameRate( float frameRate ) { App::get()->setFrameRate( frameRate ); }
00408 inline bool     isFullScreen() { return App::get()->isFullScreen(); }
00410 inline void     setFullScreen( bool fullScreen = true ) { App::get()->setFullScreen( fullScreen ); }
00411 
00413 inline double   getElapsedSeconds() { return App::get()->getElapsedSeconds(); }
00415 inline uint32_t getElapsedFrames() { return App::get()->getElapsedFrames(); }
00416 
00418 inline DataSourceRef            loadResource( const std::string &macPath, int mswID, const std::string &mswType ) { return App::loadResource( macPath, mswID, mswType ); }
00419 #if defined( CINDER_COCOA )
00420 
00421     inline DataSourcePathRef    loadResource( const std::string &macPath ) { return App::loadResource( macPath ); }
00422 #else
00423 
00424     inline DataSourceBufferRef  loadResource( int mswID, const std::string &mswType ) { return App::loadResource( mswID, mswType ); }
00425 #endif
00426 
00428 inline std::string      getAppPath() { return App::get()->getAppPath(); }
00430 
00433 inline std::string      getOpenFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ) { return App::get()->getOpenFilePath( initialPath, extensions ); }
00435 
00438 inline std::string      getSaveFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ) { return App::get()->getSaveFilePath( initialPath, extensions ); }
00439 
00441 
00444 inline std::ostream&    console() { return App::get()->console(); }
00445 
00447 inline Surface  copyWindowSurface() { return App::get()->copyWindowSurface(); }
00449 inline Surface  copyWindowSurface( const Area &area ) { return App::get()->copyWindowSurface( area ); }
00451 inline void     restoreWindowContext() { return App::get()->restoreWindowContext(); }
00452 
00453 #if defined( CINDER_COCOA )
00454 
00455 inline ::CGContextRef   createWindowCgContext() { return ((Renderer2d*)(App::get()->getRenderer()))->getCgContext(); }
00456 #endif
00457 
00459 
00461 class ResourceLoadExc : public Exception {
00462   public:
00463 #if defined( CINDER_COCOA )
00464     ResourceLoadExc( const std::string &macPath );
00465 #elif defined( CINDER_MSW )
00466     ResourceLoadExc( int mswID, const std::string &mswType );
00467     ResourceLoadExc( const std::string &macPath, int mswID, const std::string &mswType );
00468 #endif
00469 
00470     virtual const char * what() const throw() { return mMessage; }
00471 
00472     char mMessage[4096];
00473 };
00474 
00475 } } // namespace cinder::app