diff --git a/include/SFML/System/Clock.hpp b/include/SFML/System/Clock.hpp index 5c66ab10..a4527dc5 100644 --- a/include/SFML/System/Clock.hpp +++ b/include/SFML/System/Clock.hpp @@ -103,22 +103,62 @@ public: //////////////////////////////////////////////////////////// Time getElapsedTime() const; + //////////////////////////////////////////////////////////// + /// \brief Check whether the clock is running + /// + /// \return True if the clock is running, false otherwise + /// + //////////////////////////////////////////////////////////// + bool isRunning() const; + + //////////////////////////////////////////////////////////// + /// \brief Start the clock + /// + /// \see stop + /// + //////////////////////////////////////////////////////////// + void start(); + + //////////////////////////////////////////////////////////// + /// \brief Stop the clock + /// + /// \see start + /// + //////////////////////////////////////////////////////////// + void stop(); + //////////////////////////////////////////////////////////// /// \brief Restart the clock /// - /// This function puts the time counter back to zero. - /// It also returns the time elapsed since the clock was started. + /// This function puts the time counter back to zero, returns + /// the elapsed time, and leaves the clock in a running state. /// /// \return Time elapsed /// + /// \see reset + /// //////////////////////////////////////////////////////////// Time restart(); + //////////////////////////////////////////////////////////// + /// \brief Reset the clock + /// + /// This function puts the time counter back to zero, returns + /// the elapsed time, and leaves the clock in a paused state. + /// + /// \return Time elapsed + /// + /// \see restart + /// + //////////////////////////////////////////////////////////// + Time reset(); + private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - priv::ClockImpl::time_point m_startTime{priv::ClockImpl::now()}; //!< Time of last reset + priv::ClockImpl::time_point m_refPoint{priv::ClockImpl::now()}; //!< Time of last reset + priv::ClockImpl::time_point m_stopPoint; //!< Time of last stop }; } // namespace sf @@ -130,7 +170,7 @@ private: /// /// sf::Clock is a lightweight class for measuring time. /// -/// Its provides the most precise time that the underlying +/// It provides the most precise time that the underlying /// OS can achieve (generally microseconds or nanoseconds). /// It also ensures monotonicity, which means that the returned /// time can never go backward, even if the system time is @@ -143,6 +183,8 @@ private: /// Time time1 = clock.getElapsedTime(); /// ... /// Time time2 = clock.restart(); +/// ... +/// Time time3 = clock.reset(); /// \endcode /// /// The sf::Time value returned by the clock can then be diff --git a/src/SFML/System/Clock.cpp b/src/SFML/System/Clock.cpp index e73fbafa..1898e15b 100644 --- a/src/SFML/System/Clock.cpp +++ b/src/SFML/System/Clock.cpp @@ -34,17 +34,54 @@ namespace sf //////////////////////////////////////////////////////////// Time Clock::getElapsedTime() const { - return std::chrono::duration_cast(priv::ClockImpl::now() - m_startTime); + if (isRunning()) + return std::chrono::duration_cast(priv::ClockImpl::now() - m_refPoint); + return std::chrono::duration_cast(m_stopPoint - m_refPoint); +} + + +//////////////////////////////////////////////////////////// +bool Clock::isRunning() const +{ + return m_stopPoint == priv::ClockImpl::time_point(); +} + + +//////////////////////////////////////////////////////////// +void Clock::start() +{ + if (!isRunning()) + { + m_refPoint += priv::ClockImpl::now() - m_stopPoint; + m_stopPoint = {}; + } +} + + +//////////////////////////////////////////////////////////// +void Clock::stop() +{ + if (isRunning()) + m_stopPoint = priv::ClockImpl::now(); } //////////////////////////////////////////////////////////// Time Clock::restart() { - const auto now = priv::ClockImpl::now(); - const auto elapsed = std::chrono::duration_cast(now - m_startTime); - m_startTime = now; + const Time elapsed = getElapsedTime(); + m_refPoint = priv::ClockImpl::now(); + m_stopPoint = {}; + return elapsed; +} + +//////////////////////////////////////////////////////////// +Time Clock::reset() +{ + const Time elapsed = getElapsedTime(); + m_refPoint = priv::ClockImpl::now(); + m_stopPoint = m_refPoint; return elapsed; } diff --git a/test/System/Clock.test.cpp b/test/System/Clock.test.cpp index 67c0d208..4eb0ba2d 100644 --- a/test/System/Clock.test.cpp +++ b/test/System/Clock.test.cpp @@ -9,6 +9,8 @@ TEST_CASE("[System] sf::Clock") { + using namespace std::chrono_literals; + SECTION("Type traits") { STATIC_CHECK(std::is_copy_constructible_v); @@ -17,21 +19,50 @@ TEST_CASE("[System] sf::Clock") STATIC_CHECK(std::is_nothrow_move_assignable_v); } + SECTION("Construction") + { + const sf::Clock clock; + CHECK(clock.isRunning()); + CHECK(clock.getElapsedTime() >= sf::microseconds(0)); + } + SECTION("getElapsedTime()") { const sf::Clock clock; CHECK(clock.getElapsedTime() >= sf::microseconds(0)); const auto elapsed = clock.getElapsedTime(); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); CHECK(clock.getElapsedTime() > elapsed); } + SECTION("start/stop") + { + sf::Clock clock; + clock.stop(); + CHECK(!clock.isRunning()); + const auto elapsed = clock.getElapsedTime(); + std::this_thread::sleep_for(1ms); + CHECK(elapsed == clock.getElapsedTime()); + + clock.start(); + CHECK(clock.isRunning()); + CHECK(clock.getElapsedTime() >= elapsed); + } + SECTION("restart()") { sf::Clock clock; CHECK(clock.restart() >= sf::microseconds(0)); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + CHECK(clock.isRunning()); + std::this_thread::sleep_for(1ms); const auto elapsed = clock.restart(); CHECK(clock.restart() < elapsed); } + + SECTION("reset()") + { + sf::Clock clock; + CHECK(clock.reset() >= sf::microseconds(0)); + CHECK(!clock.isRunning()); + } }