00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00055 #elif defined( CINDER_MSW )
00056 #include "cinder/msw/OutputDebugStringStream.h"
00057 #endif
00058
00059 #include <vector>
00060 #include <algorithm>
00061
00062 namespace cinder {
00063 class Timeline;
00064 }
00065
00066 namespace cinder { namespace app {
00067
00068 class App {
00069 public:
00070 class Settings {
00071 public:
00072
00073 bool isPrepared() const { return !mShouldQuit; };
00074
00076 void setWindowSize( int aWindowSizeX, int aWindowSizeY );
00077
00079 void setWindowPos( int windowPositionX, int windowPositionY ) { setWindowPos( Vec2i( windowPositionX, windowPositionY ) ); }
00081 void setWindowPos( const Vec2i &windowPos );
00083 bool isWindowPosSpecified() const { return mWindowPosSpecified; }
00085 void unspecifyWindowPos() { mWindowPosSpecified = false; }
00086
00088 bool isBorderless() const { return mBorderless; }
00090 void setBorderless( bool borderless = true ) { mBorderless = borderless; }
00092 bool isAlwaysOnTop() const { return mAlwaysOnTop; }
00094 void setAlwaysOnTop( bool alwaysOnTop = true ) { mAlwaysOnTop = alwaysOnTop; }
00095
00096
00098 void setFrameRate( float aFrameRate );
00099
00101 void enablePowerManagement( bool aPowerManagement = true );
00102
00104 bool isFullScreen() const { return mFullScreen; }
00106 int getWindowWidth() const { return mWindowSizeX; }
00108 int getWindowHeight() const { return mWindowSizeY; }
00110 Vec2i getWindowSize() const { return Vec2i( mWindowSizeX, mWindowSizeY ); }
00112 Area getWindowBounds() const { return Area( 0, 0, mWindowSizeX, mWindowSizeY ); }
00113
00115 int getWindowPosX() const { return mWindowPositionX; }
00117 int getWindowPosY() const { return mWindowPositionY; }
00119 Vec2i getWindowPos() const { return Vec2i( mWindowPositionX, mWindowPositionY ); }
00120
00122 const std::string& getTitle() const { return mTitle; }
00124 void setTitle( const std::string &title ) { mTitle = title; }
00125
00127 float getFrameRate() const { return mFrameRate; }
00129 bool isResizable() const { return mResizable; }
00131 bool getPowerManagement() const { return mPowerManagement; }
00132
00133 protected:
00134 Settings();
00135 virtual ~Settings() {}
00136
00137 bool mShouldQuit;
00138 int mWindowSizeX, mWindowSizeY;
00139
00140 bool mWindowPosSpecified;
00141 int mWindowPositionX, mWindowPositionY;
00142
00143 bool mFullScreen;
00144 float mFrameRate;
00145 bool mResizable;
00146 bool mBorderless;
00147 bool mAlwaysOnTop;
00148 bool mPowerManagement;
00149 std::string mTitle;
00150 };
00151
00152
00153 public:
00154
00155 App();
00156 virtual ~App();
00157
00159 virtual void setup() {}
00161 virtual void shutdown() {}
00162
00164 virtual void update() {}
00166 virtual void draw() {}
00167
00169 virtual void mouseDown( MouseEvent event ) {}
00171 virtual void mouseUp( MouseEvent event ) {}
00173 virtual void mouseWheel( MouseEvent event ) {}
00175 virtual void mouseMove( MouseEvent event ) {}
00177 virtual void mouseDrag( MouseEvent event ) {}
00179 virtual void keyDown( KeyEvent event ) {}
00181 virtual void keyUp( KeyEvent event ) {}
00183 virtual void resize( ResizeEvent event ) {}
00185 virtual void fileDrop( FileDropEvent event ) {}
00186
00188 virtual void quit() = 0;
00189
00191 CallbackId registerMouseDown( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseDown.registerCb( callback ); }
00193 template<typename T>
00194 CallbackId registerMouseDown( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseDown.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00196 void unregisterMouseDown( CallbackId id ) { mCallbacksMouseDown.unregisterCb( id ); }
00197
00199 CallbackId registerMouseUp( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseUp.registerCb( callback ); }
00201 template<typename T>
00202 CallbackId registerMouseUp( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseUp.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00204 void unregisterMouseUp( CallbackId id ) { mCallbacksMouseUp.unregisterCb( id ); }
00205
00207 CallbackId registerMouseWheel( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseWheel.registerCb( callback ); }
00209 template<typename T>
00210 CallbackId registerMouseWheel( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseWheel.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00212 void unregisterMouseWheel( CallbackId id ) { mCallbacksMouseWheel.unregisterCb( id ); }
00213
00215 CallbackId registerMouseMove( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseMove.registerCb( callback ); }
00217 template<typename T>
00218 CallbackId registerMouseMove( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseMove.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00220 void unregisterMouseMove( CallbackId id ) { mCallbacksMouseMove.unregisterCb( id ); }
00221
00223 CallbackId registerMouseDrag( std::function<bool (MouseEvent)> callback ) { return mCallbacksMouseDrag.registerCb( callback ); }
00225 template<typename T>
00226 CallbackId registerMouseDrag( T *obj, bool (T::*callback)(MouseEvent) ) { return mCallbacksMouseDrag.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00228 void unregisterMouseDrag( CallbackId id ) { mCallbacksMouseDrag.unregisterCb( id ); }
00229
00231 CallbackId registerKeyDown( std::function<bool (KeyEvent)> callback ) { return mCallbacksKeyDown.registerCb( callback ); }
00233 template<typename T>
00234 CallbackId registerKeyDown( T *obj, bool (T::*callback)(KeyEvent) ) { return mCallbacksKeyDown.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00236 void unregisterKeyDown( CallbackId id ) { mCallbacksKeyDown.unregisterCb( id ); }
00237
00239 CallbackId registerKeyUp( std::function<bool (KeyEvent)> callback ) { return mCallbacksKeyUp.registerCb( callback ); }
00241 template<typename T>
00242 CallbackId registerKeyUp( T *obj, bool (T::*callback)(KeyEvent) ) { return mCallbacksKeyUp.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00244 void unregisterKeyUp( CallbackId id ) { mCallbacksKeyUp.unregisterCb( id ); }
00245
00247 CallbackId registerResize( std::function<bool (ResizeEvent)> callback ) { return mCallbacksResize.registerCb( callback ); }
00249 template<typename T>
00250 CallbackId registerResize( T *obj, bool (T::*callback)(ResizeEvent) ) { return mCallbacksResize.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00252 void unregisterResize( CallbackId id ) { mCallbacksResize.unregisterCb( id ); }
00253
00255 CallbackId registerFileDrop( std::function<bool (FileDropEvent)> callback ) { return mCallbacksFileDrop.registerCb( callback ); }
00257 template<typename T>
00258 CallbackId registerFileDrop( T *obj, bool (T::*callback)(FileDropEvent) ) { return mCallbacksFileDrop.registerCb( std::bind1st( std::mem_fun( callback ), obj ) ); }
00260 void unregisterFileDrop( CallbackId id ) { mCallbacksFileDrop.unregisterCb( id ); }
00261
00262
00263 virtual const Settings& getSettings() const = 0;
00264 Renderer* getRenderer() const { return mRenderer.get(); }
00265
00267 virtual int getWindowWidth() const = 0;
00269 virtual void setWindowWidth( int windowWidth ) = 0;
00271 virtual int getWindowHeight() const = 0;
00273 virtual void setWindowHeight( int windowHeight ) = 0;
00275 virtual void setWindowSize( int windowWidth, int windowHeight ) = 0;
00277 void setWindowSize( const Vec2i &size ) { setWindowSize( size.x, size.y ); }
00279
00280 Vec2f getWindowCenter() const { return Vec2f( (float)getWindowWidth(), (float)getWindowHeight() ) * 0.5f; }
00282 Vec2i getWindowSize() const { return Vec2i( getWindowWidth(), getWindowHeight() ); }
00284 float getWindowAspectRatio() const { return getWindowWidth() / (float)getWindowHeight(); }
00286
00287 Area getWindowBounds() const { return Area( 0, 0, getWindowWidth(), getWindowHeight() ); }
00288
00290 virtual Vec2i getWindowPos() const { return Vec2i::zero(); }
00292 int getWindowPosX() const { return getWindowPos().x; }
00294 int getWindowPosY() const { return getWindowPos().y; }
00296 void setWindowPos( int x, int y ) { setWindowPos( Vec2i( x, y ) ); }
00298 virtual void setWindowPos( const Vec2i &windowPos ) {}
00299
00301 virtual float getFrameRate() const = 0;
00303 virtual void setFrameRate( float aFrameRate ) = 0;
00305 float getAverageFps() const { return mAverageFps; }
00307 double getFpsSampleInterval() const { return mFpsSampleInterval; }
00309 void setFpsSampleInterval( double sampleInterval ) { mFpsSampleInterval = sampleInterval; }
00310
00312 virtual bool isFullScreen() const = 0;
00314 virtual void setFullScreen( bool aFullScreen ) = 0;
00315
00317 virtual bool isBorderless() const { return false; }
00319 virtual void setBorderless( bool borderless = true ) { }
00321 virtual bool isAlwaysOnTop() const { return false; }
00323 virtual void setAlwaysOnTop( bool alwaysOnTop = true ) { }
00324
00326 double getElapsedSeconds() const { return mTimer.getSeconds(); }
00328 uint32_t getElapsedFrames() const { return mFrameCount; }
00329
00330
00332 static DataSourceRef loadResource( const std::string &macPath, int mswID, const std::string &mswType );
00333 #if defined( CINDER_COCOA )
00334
00335 static DataSourceRef loadResource( const std::string &macPath );
00337 static fs::path getResourcePath( const fs::path &rsrcRelativePath );
00339 static fs::path getResourcePath();
00340 #else
00341
00342 static DataSourceRef loadResource( int mswID, const std::string &mswType );
00343 #endif
00344
00346 DataSourceRef loadAsset( const fs::path &relativePath );
00348 fs::path getAssetPath( const fs::path &relativePath );
00350 void addAssetDirectory( const fs::path &dirPath );
00351
00353 virtual fs::path getAppPath() = 0;
00355
00358 fs::path getOpenFilePath( const fs::path &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() );
00360 fs::path getFolderPath(const fs::path &initialPath="");
00362
00365 fs::path getSaveFilePath( const fs::path &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() );
00366
00368 std::ostream& console();
00369
00371 Timeline& timeline() { return *mTimeline; }
00372
00374 Surface copyWindowSurface();
00376 Surface copyWindowSurface( const Area &area );
00378 void restoreWindowContext();
00379
00380
00381
00383
00384 void privateMouseDown__( const MouseEvent &event );
00385 void privateMouseUp__( const MouseEvent &event );
00386 void privateMouseWheel__( const MouseEvent &event );
00387 void privateMouseMove__( const MouseEvent &event );
00388 void privateMouseDrag__( const MouseEvent &event );
00389 void privateKeyDown__( const KeyEvent &event );
00390 void privateKeyUp__( const KeyEvent &event );
00391 void privateFileDrop__( const FileDropEvent &event );
00392
00393 virtual void privateSetup__();
00394 virtual void privateResize__( const ResizeEvent &event );
00395 virtual void privateUpdate__();
00396 virtual void privateDraw__();
00397 virtual void privateShutdown__();
00399
00400 #if defined( CINDER_MSW )
00401
00402 virtual bool getsWindowsPaintEvents() = 0;
00403 #endif
00404
00405 virtual bool receivesEvents() const { return true; }
00406
00408 static App* get() { return sInstance; }
00409
00410 protected:
00412
00413 static void prepareLaunch();
00414 static void executeLaunch( App *app, class Renderer *renderer, const char *title, int argc, char * const argv[] );
00415 static void cleanupLaunch();
00416
00417 virtual void launch( const char *title, int argc, char * const argv[] ) = 0;
00419
00420 private:
00421 void prepareAssetLoading();
00422 fs::path findAssetPath( const fs::path &relativePath );
00423
00424 #if defined( CINDER_MSW )
00425 friend class AppImplMsw;
00426 std::shared_ptr<cinder::msw::dostream> mOutputStream;
00427 #else
00428 static void *sAutoReleasePool;
00429 #endif
00430
00431 Timer mTimer;
00432 uint32_t mFrameCount;
00433 float mAverageFps;
00434 uint32_t mFpsLastSampleFrame;
00435 double mFpsLastSampleTime;
00436 double mFpsSampleInterval;
00437
00438 std::shared_ptr<Timeline> mTimeline;
00439
00440 std::shared_ptr<Renderer> mRenderer;
00441
00442 CallbackMgr<bool (MouseEvent)> mCallbacksMouseDown, mCallbacksMouseUp, mCallbacksMouseWheel, mCallbacksMouseMove, mCallbacksMouseDrag;
00443 CallbackMgr<bool (KeyEvent)> mCallbacksKeyDown, mCallbacksKeyUp;
00444 CallbackMgr<bool (ResizeEvent)> mCallbacksResize;
00445 CallbackMgr<bool (FileDropEvent)> mCallbacksFileDrop;
00446
00447
00448 bool mAssetDirectoriesInitialized;
00449
00450 std::vector<fs::path> mAssetDirectories;
00451
00452 static App* sInstance;
00453 };
00454
00459
00460 inline int getWindowWidth() { return App::get()->getWindowWidth(); }
00462 inline void setWindowPos( const Vec2i &windowPos ) { App::get()->setWindowPos( windowPos); }
00463 inline void setWindowPos( int x, int y ) { setWindowPos( Vec2i( x, y ) ); }
00465 inline void setWindowWidth( int windowWidth ) { App::get()->setWindowWidth( windowWidth ); }
00467 inline int getWindowHeight() { return App::get()->getWindowHeight(); }
00469 inline void setWindowHeight( int windowHeight ) { App::get()->setWindowHeight( windowHeight ); }
00471 inline void setWindowSize( int windowWidth, int windowHeight ) { App::get()->setWindowSize( windowWidth, windowHeight ); }
00473
00474 inline Vec2f getWindowCenter() { return App::get()->getWindowCenter(); }
00476 inline Vec2i getWindowSize() { return App::get()->getWindowSize(); }
00478 inline Vec2i getWindowPos() { return App::get()->getWindowPos(); }
00480 inline float getWindowAspectRatio() { return App::get()->getWindowAspectRatio(); }
00482
00483 inline Area getWindowBounds() { return App::get()->getWindowBounds(); }
00485 inline float getFrameRate() { return App::get()->getFrameRate(); }
00487 inline void setFrameRate( float frameRate ) { App::get()->setFrameRate( frameRate ); }
00489 inline bool isFullScreen() { return App::get()->isFullScreen(); }
00491 inline void setFullScreen( bool fullScreen = true ) { App::get()->setFullScreen( fullScreen ); }
00492
00494 inline double getElapsedSeconds() { return App::get()->getElapsedSeconds(); }
00496 inline uint32_t getElapsedFrames() { return App::get()->getElapsedFrames(); }
00497
00499 inline DataSourceRef loadResource( const std::string &macPath, int mswID, const std::string &mswType ) { return App::loadResource( macPath, mswID, mswType ); }
00500 #if defined( CINDER_COCOA )
00501
00502 inline DataSourceRef loadResource( const std::string &macPath ) { return App::loadResource( macPath ); }
00503 #else
00504
00505 inline DataSourceRef loadResource( int mswID, const std::string &mswType ) { return App::loadResource( mswID, mswType ); }
00506 #endif
00507
00509 inline DataSourceRef loadAsset( const fs::path &relativePath ) { return App::get()->loadAsset( relativePath ); }
00511 inline fs::path getAssetPath( const fs::path &relativePath ) { return App::get()->getAssetPath( relativePath ); }
00513 inline void addAssetDirectory( const fs::path &dirPath ) { App::get()->addAssetDirectory( dirPath ); }
00514
00516 inline fs::path getAppPath() { return App::get()->getAppPath(); }
00518
00521 inline fs::path getOpenFilePath( const fs::path &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ) { return App::get()->getOpenFilePath( initialPath, extensions ); }
00523
00526 inline fs::path getSaveFilePath( const fs::path &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ) { return App::get()->getSaveFilePath( initialPath, extensions ); }
00527
00529
00532 inline std::ostream& console() { return App::get()->console(); }
00533
00535 inline Timeline& timeline() { return App::get()->timeline(); }
00536
00538 inline Surface copyWindowSurface() { return App::get()->copyWindowSurface(); }
00540 inline Surface copyWindowSurface( const Area &area ) { return App::get()->copyWindowSurface( area ); }
00542 inline void restoreWindowContext() { return App::get()->restoreWindowContext(); }
00543
00544 #if defined( CINDER_COCOA )
00545
00546 inline ::CGContextRef createWindowCgContext() { return ((Renderer2d*)(App::get()->getRenderer()))->getCgContext(); }
00547 #endif
00548
00550
00552 class ResourceLoadExc : public Exception {
00553 public:
00554 #if defined( CINDER_COCOA )
00555 ResourceLoadExc( const std::string &macPath );
00556 #elif defined( CINDER_MSW )
00557 ResourceLoadExc( int mswID, const std::string &mswType );
00558 ResourceLoadExc( const std::string &macPath, int mswID, const std::string &mswType );
00559 #endif
00560
00561 virtual const char * what() const throw() { return mMessage; }
00562
00563 char mMessage[4096];
00564 };
00565
00567 class AssetLoadExc : public Exception {
00568 public:
00569 AssetLoadExc( const fs::path &relativePath );
00570
00571 virtual const char * what() const throw() { return mMessage; }
00572
00573 char mMessage[4096];
00574 };
00575
00576 } }