| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// | 
|---|
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// | 
|---|
| 3 | #pragma once | 
|---|
| 4 |  | 
|---|
| 5 | #include "BsCorePrerequisites.h" | 
|---|
| 6 | #include "Utility/BsModule.h" | 
|---|
| 7 | #include "RenderAPI/BsRenderWindow.h" | 
|---|
| 8 | #include "Utility/BsEvent.h" | 
|---|
| 9 |  | 
|---|
| 10 | namespace bs | 
|---|
| 11 | { | 
|---|
| 12 | /** @addtogroup Application-Core | 
|---|
| 13 | *  @{ | 
|---|
| 14 | */ | 
|---|
| 15 |  | 
|---|
| 16 | /**	Structure containing parameters for starting the application. */ | 
|---|
| 17 | struct BS_SCRIPT_EXPORT(m:Application,pl:true,api:bsf) START_UP_DESC | 
|---|
| 18 | { | 
|---|
| 19 | String renderAPI; /**< Name of the render system plugin to use. */ | 
|---|
| 20 | String renderer; /**< Name of the renderer plugin to use. */ | 
|---|
| 21 | String physics; /**< Name of physics plugin to use. */ | 
|---|
| 22 | String audio; /**< Name of the audio plugin to use. */ | 
|---|
| 23 | String input; /**< Name of the input plugin to use. */ | 
|---|
| 24 |  | 
|---|
| 25 | /** | 
|---|
| 26 | * True if physics cooking library should be loaded. Cooking is useful for creating collision meshes during | 
|---|
| 27 | * development type, but might be unnecessary in the final application. When turned off you can save on space by | 
|---|
| 28 | * not shipping the cooking library. | 
|---|
| 29 | */ | 
|---|
| 30 | bool physicsCooking = true; | 
|---|
| 31 |  | 
|---|
| 32 | RENDER_WINDOW_DESC primaryWindowDesc; /**< Describes the window to create during start-up. */ | 
|---|
| 33 |  | 
|---|
| 34 | Vector<String> importers; /**< A list of importer plugins to load. */ | 
|---|
| 35 | }; | 
|---|
| 36 |  | 
|---|
| 37 | /** | 
|---|
| 38 | * Represents the primary entry point for the core systems. Handles start-up, shutdown, primary loop and allows you to | 
|---|
| 39 | * load and unload plugins. | 
|---|
| 40 | * | 
|---|
| 41 | * @note	Sim thread only. | 
|---|
| 42 | */ | 
|---|
| 43 | class BS_CORE_EXPORT CoreApplication : public Module<CoreApplication> | 
|---|
| 44 | { | 
|---|
| 45 | public: | 
|---|
| 46 | CoreApplication(START_UP_DESC desc); | 
|---|
| 47 | virtual ~CoreApplication(); | 
|---|
| 48 |  | 
|---|
| 49 | /** | 
|---|
| 50 | * Executes the main loop. This will update your components and modules, queue objects for rendering and run | 
|---|
| 51 | * the simulation. Usually called immediately after startUp(). | 
|---|
| 52 | * | 
|---|
| 53 | * This will run infinitely until stopMainLoop is called (usually from another thread or internally). | 
|---|
| 54 | */ | 
|---|
| 55 | void runMainLoop(); | 
|---|
| 56 |  | 
|---|
| 57 | /**	Stops the (infinite) main loop from running. The loop will complete its current cycle before stopping. */ | 
|---|
| 58 | void stopMainLoop(); | 
|---|
| 59 |  | 
|---|
| 60 | /** Changes the maximum FPS the application is allowed to run in. Zero means unlimited. */ | 
|---|
| 61 | void setFPSLimit(UINT32 limit); | 
|---|
| 62 |  | 
|---|
| 63 | /** | 
|---|
| 64 | * Issues a request for the application to close. Application may choose to ignore the request depending on the | 
|---|
| 65 | * circumstances and the implementation. | 
|---|
| 66 | */ | 
|---|
| 67 | virtual void quitRequested(); | 
|---|
| 68 |  | 
|---|
| 69 | /**	Returns the main window that was created on application start-up. */ | 
|---|
| 70 | SPtr<RenderWindow> getPrimaryWindow() const { return mPrimaryWindow; } | 
|---|
| 71 |  | 
|---|
| 72 | /** | 
|---|
| 73 | * Returns the id of the simulation thread. | 
|---|
| 74 | * | 
|---|
| 75 | * @note	Thread safe. | 
|---|
| 76 | */ | 
|---|
| 77 | ThreadId getSimThreadId() const { return mSimThreadId; } | 
|---|
| 78 |  | 
|---|
| 79 | /**	Returns true if the application is running in an editor, false if standalone. */ | 
|---|
| 80 | virtual bool isEditor() const { return false; } | 
|---|
| 81 |  | 
|---|
| 82 | /** | 
|---|
| 83 | * Loads a plugin. | 
|---|
| 84 | * | 
|---|
| 85 | * @param[in]	pluginName	Name of the plugin to load, without extension. | 
|---|
| 86 | * @param[out]	library		Specify as not null to receive a reference to the loaded library. | 
|---|
| 87 | * @param[in]	passThrough	Optional parameter that will be passed to the loadPlugin function. | 
|---|
| 88 | * @return					Value returned from the plugin start-up method. | 
|---|
| 89 | */ | 
|---|
| 90 | void* loadPlugin(const String& pluginName, DynLib** library = nullptr, void* passThrough = nullptr); | 
|---|
| 91 |  | 
|---|
| 92 | /**	Unloads a previously loaded plugin. */ | 
|---|
| 93 | void unloadPlugin(DynLib* library); | 
|---|
| 94 |  | 
|---|
| 95 | protected: | 
|---|
| 96 | /** @copydoc Module::onStartUp */ | 
|---|
| 97 | void onStartUp() override; | 
|---|
| 98 |  | 
|---|
| 99 | /**	Called for each iteration of the main loop. Called before any game objects or plugins are updated. */ | 
|---|
| 100 | virtual void preUpdate(); | 
|---|
| 101 |  | 
|---|
| 102 | /**	Called for each iteration of the main loop. Called after all game objects and plugins are updated. */ | 
|---|
| 103 | virtual void postUpdate(); | 
|---|
| 104 |  | 
|---|
| 105 | /** Called during the fixed update of the main loop. Called after preUpdate and before postUpdate. */ | 
|---|
| 106 | virtual void fixedUpdate(); | 
|---|
| 107 |  | 
|---|
| 108 | /**	Initializes the renderer specified during construction. Called during initialization. */ | 
|---|
| 109 | virtual void startUpRenderer(); | 
|---|
| 110 |  | 
|---|
| 111 | /**	Returns a handler that is used for resolving shader include file paths. */ | 
|---|
| 112 | virtual SPtr<IShaderIncludeHandler> getShaderIncludeHandler() const; | 
|---|
| 113 |  | 
|---|
| 114 | private: | 
|---|
| 115 | /**	Called when the frame finishes rendering. */ | 
|---|
| 116 | void frameRenderingFinishedCallback(); | 
|---|
| 117 |  | 
|---|
| 118 | /**	Called by the core thread to begin profiling. */ | 
|---|
| 119 | void beginCoreProfiling(); | 
|---|
| 120 |  | 
|---|
| 121 | /**	Called by the core thread to end profiling. */ | 
|---|
| 122 | void endCoreProfiling(); | 
|---|
| 123 |  | 
|---|
| 124 | protected: | 
|---|
| 125 | typedef void(*UpdatePluginFunc)(); | 
|---|
| 126 |  | 
|---|
| 127 | SPtr<RenderWindow> mPrimaryWindow; | 
|---|
| 128 | START_UP_DESC mStartUpDesc; | 
|---|
| 129 |  | 
|---|
| 130 | // Frame limiting | 
|---|
| 131 | UINT64 mFrameStep = 16666; // 60 times a second in microseconds | 
|---|
| 132 | UINT64 mLastFrameTime = 0; // Microseconds | 
|---|
| 133 |  | 
|---|
| 134 | DynLib* mRendererPlugin; | 
|---|
| 135 |  | 
|---|
| 136 | Map<DynLib*, UpdatePluginFunc> mPluginUpdateFunctions; | 
|---|
| 137 |  | 
|---|
| 138 | bool mIsFrameRenderingFinished; | 
|---|
| 139 | Mutex mFrameRenderingFinishedMutex; | 
|---|
| 140 | Signal mFrameRenderingFinishedCondition; | 
|---|
| 141 | ThreadId mSimThreadId; | 
|---|
| 142 |  | 
|---|
| 143 | volatile bool mRunMainLoop; | 
|---|
| 144 |  | 
|---|
| 145 | }; | 
|---|
| 146 |  | 
|---|
| 147 | /**	Provides easy access to CoreApplication. */ | 
|---|
| 148 | BS_CORE_EXPORT CoreApplication& gCoreApplication(); | 
|---|
| 149 |  | 
|---|
| 150 | /** @} */ | 
|---|
| 151 | } | 
|---|
| 152 |  | 
|---|