PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: Timing.h * 00003 * 00004 * Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLCORE_TIMING_H__ 00024 #define __PLCORE_TIMING_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include "PLCore/Core/Singleton.h" 00032 00033 00034 //[-------------------------------------------------------] 00035 //[ Namespace ] 00036 //[-------------------------------------------------------] 00037 namespace PLCore { 00038 00039 00040 //[-------------------------------------------------------] 00041 //[ Classes ] 00042 //[-------------------------------------------------------] 00043 /** 00044 * @brief 00045 * Timing stuff 00046 * 00047 * @remarks 00048 * This timing class offers a lot of timing tool functions you can for 00049 * instance use to create timed movement. Have a look at the 'System'-singleton 00050 * for the basic timing functions. 00051 */ 00052 class Timing : public Singleton<Timing> { 00053 00054 00055 //[-------------------------------------------------------] 00056 //[ Friends ] 00057 //[-------------------------------------------------------] 00058 friend class Singleton<Timing>; 00059 00060 00061 //[-------------------------------------------------------] 00062 //[ Public static PLCore::Singleton functions ] 00063 //[-------------------------------------------------------] 00064 // This solution enhances the compatibility with legacy compilers like GCC 4.2.1 used on Mac OS X 10.6 00065 // -> The C++11 feature "extern template" (C++11, see e.g. http://www2.research.att.com/~bs/C++0xFAQ.html#extern-templates) can only be used on modern compilers like GCC 4.6 00066 // -> We can't break legacy compiler support, especially when only the singletons are responsible for the break 00067 // -> See PLCore::Singleton for more details about singletons 00068 public: 00069 static PLCORE_API Timing *GetInstance(); 00070 static PLCORE_API bool HasInstance(); 00071 00072 00073 //[-------------------------------------------------------] 00074 //[ Public functions ] 00075 //[-------------------------------------------------------] 00076 public: 00077 //[-------------------------------------------------------] 00078 //[ General ] 00079 //[-------------------------------------------------------] 00080 /** 00081 * @brief 00082 * Returns whether the timing is active or not 00083 * 00084 * @return 00085 * 'true' if the timing is active, else 'false' 00086 */ 00087 inline bool IsActive() const; 00088 00089 /** 00090 * @brief 00091 * Sets whether the timing is active or not 00092 * 00093 * @param[in] bActive 00094 * Should the timing be active? 00095 * 00096 * @note 00097 * - If the timing is disabled the time difference between 00098 * two frames will be always the maximum time difference 00099 * - Use it only for testing 00100 */ 00101 inline void SetActive(bool bActive = true); 00102 00103 /** 00104 * @brief 00105 * Resets the timing 00106 */ 00107 PLCORE_API void Reset(); 00108 00109 /** 00110 * @brief 00111 * Checks whether the timing has to be updated or not 00112 * 00113 * @param[in] pnTimeToWait 00114 * If not a null pointer, if there's a FPS limit and it's not time for an update -> receives the time in 00115 * milliseconds we need to wait until it's time for the next update, receives '0' in all other cases 00116 * 00117 * @return 00118 * 'true' if the timing has to be updated, else 'false' 00119 * 00120 * @remarks 00121 * Normally the timing must be updated every frame. But if theres a frame 00122 * rate limitation it's not allowed to update the timing every frame! 00123 */ 00124 PLCORE_API bool CheckUpdate(uint64 *pnTimeToWait = nullptr) const; 00125 00126 /** 00127 * @brief 00128 * Updates all time relevant stuff 00129 * 00130 * @param[in] pnTimeToWait 00131 * If not a null pointer, if there's a FPS limit and it's not time for an update -> receives the time in 00132 * milliseconds we need to wait until it's time for the next update, receives '0' in all other cases 00133 * 00134 * @return 00135 * 'true' if all went fine, else 'false' (maybe there's a frame rate limitation) 00136 * 00137 * @see 00138 * - CheckUpdate() 00139 */ 00140 PLCORE_API bool Update(uint64 *pnTimeToWait = nullptr); 00141 00142 //[-------------------------------------------------------] 00143 //[ Past time ] 00144 //[-------------------------------------------------------] 00145 /** 00146 * @brief 00147 * Returns the past time since last frame (seconds) 00148 * 00149 * @return 00150 * Past time since last frame 00151 * 00152 * @remarks 00153 * The timing class tries to compensate irregularities in timing automatically to 00154 * avoid for instance sudden jumps through half of the universe. Further a maximum 00155 * time difference is applied to avoid any totally undesired results. 00156 */ 00157 inline float GetTimeDifference() const; 00158 00159 /** 00160 * @brief 00161 * Returns the past time since last frame without any compensating (seconds) 00162 * 00163 * @return 00164 * Past time since last frame without any compensating 00165 * 00166 * @note 00167 * - Use GetTimeDifference() instead this function whenever you can 00168 */ 00169 inline float GetTimeDifferenceNoCompensating() const; 00170 00171 /** 00172 * @brief 00173 * Returns the maximum time difference 00174 * 00175 * @return 00176 * The maximum time difference since the last frame in seconds 00177 * 00178 * @note 00179 * - The maximum time difference will avoid a too hight time difference 00180 * value which would probably end in undefined problems. 00181 * - A maximum time difference of 0.15 is a good value 00182 */ 00183 inline float GetMaxTimeDifference() const; 00184 00185 /** 00186 * @brief 00187 * Sets the maximum time difference 00188 * 00189 * @param[in] fMaxTimeDifference 00190 * The maximum time difference since the last frame in seconds (> 0) 00191 * 00192 * @see 00193 * - GetMaxTimeDifference() 00194 */ 00195 inline void SetMaxTimeDifference(float fMaxTimeDifference = 0.15f); 00196 00197 /** 00198 * @brief 00199 * Returns the past time in milliseconds since the application start 00200 * 00201 * @return 00202 * Past time in milliseconds since the application start 00203 */ 00204 PLCORE_API uint64 GetPastTime() const; 00205 00206 /** 00207 * @brief 00208 * Returns a general timing 00209 * 00210 * @return 00211 * General timing 00212 * 00213 * @remarks 00214 * On each timing update, the current time difference is added to this general timing. 00215 */ 00216 inline float GetTimer() const; 00217 00218 //[-------------------------------------------------------] 00219 //[ Frames ] 00220 //[-------------------------------------------------------] 00221 /** 00222 * @brief 00223 * Returns the current frames per second (FPS) 00224 * 00225 * @return 00226 * Current frames per second 00227 */ 00228 inline float GetFramesPerSecond() const; 00229 00230 /** 00231 * @brief 00232 * Returns the number of past frames since timing start 00233 * 00234 * @return 00235 * Current frames per second (FPS) 00236 */ 00237 inline uint32 GetPastFrames() const; 00238 00239 /** 00240 * @brief 00241 * Returns the FPS limit 00242 * 00243 * @return 00244 * FPS limit, 0 if there's no FPS limitation 00245 * 00246 * @note 00247 * - FPS limitation could be used to avoid that the application 00248 * uses to much system resources. (normally 30 FPS are enough) 00249 * - Use a FPS limitation only in special situations! 00250 * (users love FPS over 100 even if its more or less senseless ;-) 00251 */ 00252 inline float GetFPSLimit() const; 00253 00254 /** 00255 * @brief 00256 * Sets the FPS limit 00257 * 00258 * @param[in] fFPSLimit 00259 * FPS limit, 0 if there should be no limitation (>= 0) 00260 * 00261 * @see 00262 * - GetFPSLimit() 00263 */ 00264 inline void SetFPSLimit(float fFPSLimit = 0.0f); 00265 00266 //[-------------------------------------------------------] 00267 //[ Time scale ] 00268 //[-------------------------------------------------------] 00269 /** 00270 * @brief 00271 * Returns if the timing is currently freezed or not 00272 * 00273 * @return 00274 * 'true' if the timing is freezed at the moment, else 'false' 00275 */ 00276 inline bool IsFreezed() const; 00277 00278 /** 00279 * @brief 00280 * Set freezed mode 00281 * 00282 * @param[in] bFreeze 00283 * Should the timing be freezed or not? 00284 * 00285 * @note 00286 * - Freeze your application if you are not in rendering mode 00287 * (e.g. you load something) 00288 */ 00289 PLCORE_API void Freeze(bool bFreeze = true); 00290 00291 /** 00292 * @brief 00293 * Returns whether the timing is paused of not 00294 * 00295 * @return 00296 * 'true' if the timing is paused, else 'false' 00297 * 00298 * @note 00299 * - If the timing is paused scene nodes, particles etc. are not updated 00300 * - The timing will still be updated 00301 */ 00302 inline bool IsPaused() const; 00303 00304 /** 00305 * @brief 00306 * Set pause mode 00307 * 00308 * @param[in] bPause 00309 * Should the timing be paused or not? 00310 */ 00311 inline void Pause(bool bPause = true); 00312 00313 /** 00314 * @brief 00315 * Returns the time scale factor 00316 * 00317 * @return 00318 * Time scale factor 00319 * 00320 * @note 00321 * - The global time scale factor should only be manipulated for debugging 00322 * - For 'slow motion' effects use the slow motion functions instead! 00323 * - A factor of <= 0 is NOT allowed because this may cause problems in certain 00324 * situations, pause the timer instead by hand! 00325 * - Do NOT make the factor 'too' (for example > 4) extreme, this may cause 00326 * problems in certain situations! 00327 */ 00328 inline float GetTimeScaleFactor() const; 00329 00330 /** 00331 * @brief 00332 * Sets the time scale factor 00333 * 00334 * @param[in] fFactor 00335 * Time scale, a factor of <= 0 is NOT allowed! 00336 * 00337 * @return 00338 * 'true' if all went fine, else 'false' (maybe the given factor is <= 0?) 00339 * 00340 * @see 00341 * - GetTimeScaleFactor() 00342 */ 00343 inline bool SetTimeScaleFactor(float fFactor = 1.0f); 00344 00345 /** 00346 * @brief 00347 * Returns if the slow motion is activated or not 00348 * 00349 * @return 00350 * 'true' is the slow motion mode is activated, else 'false' 00351 */ 00352 inline bool IsSlowMotion() const; 00353 00354 /** 00355 * @brief 00356 * Activates/deactivates the slow motion mode 00357 * 00358 * @param[in] bSlowMotion 00359 * Should the slow motion mode be activated? 00360 */ 00361 inline void SetSlowMotion(bool bSlowMotion = false); 00362 00363 /** 00364 * @brief 00365 * Returns the slow motion factor 00366 * 00367 * @param[in] bRealUsed 00368 * The real used slow motion factor will be returned. If the slow motion mode 00369 * is deactivated this will be 1! 00370 * 00371 * @return 00372 * The current slow motion factor 00373 * 00374 * @note 00375 * - The slow motion mode must be activated that this factor 00376 * changes the game speed 00377 * - Use this function to change the speed in general 00378 * - A factor of <= 0 is NOT allowed because this may cause problems in certain 00379 * situations, pause the timer instead by hand! 00380 * - Do NOT make the factor 'too' (for example > 4) extreme, this may cause 00381 * problems in certain situations! 00382 */ 00383 inline float GetSlowMotionFactor(bool bRealUsed = true) const; 00384 00385 /** 00386 * @brief 00387 * Sets the slow motion factor 00388 * 00389 * @param[in] fSlowMotionFactor 00390 * The slow motion factor, a factor of <= 0 is NOT allowed! 00391 * 00392 * @return 00393 * 'true' if all went fine, else 'false' (maybe the given factor is <= 0?) 00394 * 00395 * @see 00396 * - GetSlowMotionFactor() 00397 */ 00398 inline bool SetSlowMotionFactor(float fSlowMotionFactor = 1.0f); 00399 00400 /** 00401 * @brief 00402 * Returns the custom slow motion factor 00403 * 00404 * @param[in] bRealUsed 00405 * The real used slow motion factor will be returned. If the slow motion mode 00406 * is deactivated this will be 1! 00407 * 00408 * @return 00409 * The current slow motion factor 00410 * 00411 * @note 00412 * - The slow motion mode must be activated that this 00413 * factor changes the game speed 00414 * - Use this factor to temporal slow motion effects 00415 */ 00416 inline float GetCustomSlowMotionFactor(bool bRealUsed = true) const; 00417 00418 /** 00419 * @brief 00420 * Sets the custom slow motion factor 00421 * 00422 * @param[in] fSlowMotionFactor 00423 * The slow motion factor, a factor of <= 0 is NOT allowed! 00424 * 00425 * @return 00426 * 'true' if all went fine, else 'false' (maybe the given factor is <= 0?) 00427 * 00428 * @see 00429 * - GetCustomSlowMotionFactor() 00430 */ 00431 inline bool SetCustomSlowMotionFactor(float fSlowMotionFactor = 1.0f); 00432 00433 00434 //[-------------------------------------------------------] 00435 //[ Private functions ] 00436 //[-------------------------------------------------------] 00437 private: 00438 /** 00439 * @brief 00440 * Constructor 00441 */ 00442 Timing(); 00443 00444 /** 00445 * @brief 00446 * Copy constructor 00447 * 00448 * @param[in] cSource 00449 * Source to copy from 00450 */ 00451 Timing(const Timing &cSource); 00452 00453 /** 00454 * @brief 00455 * Destructor 00456 */ 00457 virtual ~Timing(); 00458 00459 /** 00460 * @brief 00461 * Copy operator 00462 * 00463 * @param[in] cSource 00464 * Source to copy from 00465 * 00466 * @return 00467 * Reference to this instance 00468 */ 00469 Timing &operator =(const Timing &cSource); 00470 00471 00472 //[-------------------------------------------------------] 00473 //[ Private data ] 00474 //[-------------------------------------------------------] 00475 private: 00476 bool m_bActive; /**< Is the timing active? */ 00477 uint64 m_nTimeStart; /**< The start system time */ 00478 uint64 m_nTimeNow; /**< Current system time */ 00479 uint64 m_nTimeLast; /**< System time of the last frame */ 00480 float m_fTimeDifference; /**< The past time since last frame (seconds) */ 00481 float m_fTimeDifferenceNoCompensating; /**< The past time since last frame without any compensating (seconds) */ 00482 float m_fMaxTimeDifference; /**< The maximum possible time difference (seconds) */ 00483 float m_fFramesPerSecond; /**< Current frames per second (FPS... hopefully not SPS... Seconds Per Frame ;) */ 00484 int m_nFramesSinceCheck; /**< Number of frames since last FPS update */ 00485 uint32 m_nPastFrames; /**< Number of past frames since timing start */ 00486 uint64 m_nLastFPSUpdateTime; /**< The time were the last FPS update was done */ 00487 float m_fFPSUpdateTimer; /**< Timing for updating FPS (only each second) */ 00488 bool m_bFreezed; /**< Is the application currently freezed? */ 00489 uint64 m_nFreezeTime; /**< The time were the application was frozen */ 00490 bool m_bPause; /**< Is the timing paused? */ 00491 float m_fTimeScaleFactor; /**< Time scale factor */ 00492 bool m_bSlowMotion; /**< Is the slow motion modus activated? */ 00493 float m_fSlowMotionFactor; /**< The slow motion factor */ 00494 float m_fCustomSlowMotionFactor; /**< The custom slow motion factor */ 00495 uint64 m_nFPSLimitLastTime; /**< Time were the last update was done */ 00496 float m_fFPSLimit; /**< FPS limitation */ 00497 float m_fTimer; /**< General timing */ 00498 00499 00500 }; 00501 00502 00503 //[-------------------------------------------------------] 00504 //[ Namespace ] 00505 //[-------------------------------------------------------] 00506 } // PLCore 00507 00508 00509 //[-------------------------------------------------------] 00510 //[ Implementation ] 00511 //[-------------------------------------------------------] 00512 #include "PLCore/Tools/Timing.inl" 00513 00514 00515 #endif // __PLCORE_TIMING_H__
|