diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 390eeb583..ade850775 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,7 @@ set(Magnum_SRCS Renderbuffer.cpp Shader.cpp SizeTraits.cpp + Timeline.cpp TypeTraits.cpp Trade/AbstractImporter.cpp @@ -60,6 +61,7 @@ set(Magnum_HEADERS SizeTraits.h Swizzle.h Texture.h + Timeline.h TypeTraits.h magnumVisibility.h) diff --git a/src/Timeline.cpp b/src/Timeline.cpp new file mode 100644 index 000000000..306ce4ac7 --- /dev/null +++ b/src/Timeline.cpp @@ -0,0 +1,53 @@ +#include "Timeline.h" +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include +#include + +using namespace std::chrono; +using namespace Corrade::Utility; + +namespace Magnum { + +void Timeline::start() { + running = true; + previousFrameTime = high_resolution_clock::now(); + _previousFrameDuration = 0; +} + +void Timeline::stop() { + running = false; + previousFrameTime = high_resolution_clock::time_point(); + _previousFrameDuration = 0; +} + +void Timeline::nextFrame() { + if(!running) return; + + auto now = high_resolution_clock::now(); + unsigned int duration = duration_cast(now-previousFrameTime).count(); + _previousFrameDuration = duration/1e6f; + + if(_previousFrameDuration < _minimalFrameTime) { + sleep(duration/1000); + now = high_resolution_clock::now(); + _previousFrameDuration = duration_cast(now-previousFrameTime).count()/1e6f; + } + + previousFrameTime = now; +} + +} diff --git a/src/Timeline.h b/src/Timeline.h new file mode 100644 index 000000000..093191677 --- /dev/null +++ b/src/Timeline.h @@ -0,0 +1,91 @@ +#ifndef Magnum_Timeline_h +#define Magnum_Timeline_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +#include "Magnum.h" + +#include "magnumVisibility.h" + +/** @file + * @brief Class Magnum::Timeline + */ + +namespace Magnum { + +/** @brief %Timeline */ +class MAGNUM_EXPORT Timeline { + public: + /** + * @brief Constructor + * + * Constructs stopped timeline. + * @see start() + */ + inline constexpr Timeline(): _minimalFrameTime(0), _previousFrameDuration(0), running(false) {} + + /** @brief Minimal frame time (in seconds) */ + GLfloat minimalFrameTime() const { return _minimalFrameTime; } + + /** + * @brief Set minimal frame time + * + * @see nextFrame() + */ + void setMinimalFrameTime(GLfloat seconds) { + _minimalFrameTime = seconds; + } + + /** + * @brief Start timeline + * + * Sets previous frame duration to `0`. + * @see stop(), previousFrameDuration() + */ + void start(); + + /** + * @brief Stop timeline + */ + void stop(); + + /** + * @brief Advance to next frame + * + * If current frame time is smaller than minimal frame time, pauses + * the execution for remaining time. + * @note This function does nothing if the timeline is stopped. + * @see setMinimalFrameTime() + */ + void nextFrame(); + + /** @brief Duration of previous frame */ + inline constexpr GLfloat previousFrameDuration() const { + return _previousFrameDuration; + } + + private: + std::chrono::high_resolution_clock::time_point previousFrameTime; + GLfloat _minimalFrameTime; + GLfloat _previousFrameDuration; + + bool running; +}; + +} + +#endif