Update SFML Time classes to C++17
Ensure Clock uses a monotonic clock Statically assert against low precision clocks Allow suspend-aware clock for Android Add descriptive documentation to sf::Clock
This commit is contained in:
parent
e9e353a7b2
commit
dfff93fe04
@ -105,6 +105,11 @@ endif()
|
|||||||
|
|
||||||
# Android options
|
# Android options
|
||||||
if(SFML_OS_ANDROID)
|
if(SFML_OS_ANDROID)
|
||||||
|
sfml_set_option(SFML_ANDROID_USE_SUSPEND_AWARE_CLOCK FALSE BOOL "TRUE to use an sf::Clock implementation which takes system sleep time into account (keeps advancing during suspension), FALSE to default to another available monotonic clock")
|
||||||
|
if (SFML_ANDROID_USE_SUSPEND_AWARE_CLOCK)
|
||||||
|
add_definitions(-DSFML_ANDROID_USE_SUSPEND_AWARE_CLOCK)
|
||||||
|
endif()
|
||||||
|
|
||||||
# avoid missing libraries when building SFML for Android with NDK r19c and later
|
# avoid missing libraries when building SFML for Android with NDK r19c and later
|
||||||
set(CMAKE_FIND_ROOT_PATH "${PROJECT_SOURCE_DIR};${CMAKE_FIND_ROOT_PATH}")
|
set(CMAKE_FIND_ROOT_PATH "${PROJECT_SOURCE_DIR};${CMAKE_FIND_ROOT_PATH}")
|
||||||
|
|
||||||
|
@ -30,10 +30,56 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/Export.hpp>
|
#include <SFML/System/Export.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
#include <chrono>
|
||||||
|
#include <ratio>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
|
#include <SFML/System/SuspendAwareClock.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Chooses a monotonic clock of highest resolution
|
||||||
|
///
|
||||||
|
/// The high_resolution_clock is usually an alias for other
|
||||||
|
/// clocks: steady_clock or system_clock, whichever has a
|
||||||
|
/// higher precision.
|
||||||
|
///
|
||||||
|
/// sf::Clock, however, is aimed towards monotonic time
|
||||||
|
/// measurements and so system_clock could never be a choice
|
||||||
|
/// as its subject to discontinuous jumps in the system time
|
||||||
|
/// (e.g., if the system administrator manually changes
|
||||||
|
/// the clock), and by the incremental adjustments performed
|
||||||
|
/// by `adjtime` and Network Time Protocol. On the other
|
||||||
|
/// hand, monotonic clocks are unaffected by this behavior.
|
||||||
|
///
|
||||||
|
/// Note: Linux implementation of a monotonic clock that
|
||||||
|
/// takes sleep time into account is represented by
|
||||||
|
/// CLOCK_BOOTTIME. Android devices can define the macro:
|
||||||
|
/// SFML_ANDROID_USE_SUSPEND_AWARE_CLOCK to use a separate
|
||||||
|
/// implementation of that clock, instead.
|
||||||
|
///
|
||||||
|
/// For more information on Linux clocks visit:
|
||||||
|
/// https://linux.die.net/man/2/clock_gettime
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#if defined(SFML_SYSTEM_ANDROID) && defined(SFML_ANDROID_USE_SUSPEND_AWARE_CLOCK)
|
||||||
|
using MostSuitableClock = SuspendAwareClock;
|
||||||
|
#else
|
||||||
|
using MostSuitableClock = std::conditional_t<
|
||||||
|
std::chrono::high_resolution_clock::is_steady,
|
||||||
|
std::chrono::high_resolution_clock,
|
||||||
|
std::chrono::steady_clock>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Utility class that measures the elapsed time
|
/// \brief Utility class that measures the elapsed time
|
||||||
///
|
///
|
||||||
@ -74,11 +120,28 @@ public:
|
|||||||
Time restart();
|
Time restart();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using ClockImpl = priv::MostSuitableClock;
|
||||||
|
|
||||||
|
static_assert(ClockImpl::is_steady,
|
||||||
|
"Provided implementation is not a monotonic clock");
|
||||||
|
static_assert(std::ratio_less_equal<ClockImpl::period, std::micro>::value,
|
||||||
|
"Clock resolution is too low. Expecting at least a microsecond precision");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Convert clock duration to Time
|
||||||
|
///
|
||||||
|
/// This function acts as a utility for converting clock
|
||||||
|
/// duration type instance into sf::Time
|
||||||
|
///
|
||||||
|
/// \return Time instance
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static Time durationToTime(ClockImpl::duration duration);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Time m_startTime; //!< Time of last reset, in microseconds
|
ClockImpl::time_point m_startTime; //!< Time of last reset
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -22,40 +22,59 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef SFML_CLOCKIMPLWIN32_HPP
|
|
||||||
#define SFML_CLOCKIMPLWIN32_HPP
|
#ifndef SFML_SUSPENDAWARECLOCK_HPP
|
||||||
|
#define SFML_SUSPENDAWARECLOCK_HPP
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Config.hpp>
|
#include <SFML/System/Export.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <chrono>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Windows implementation of sf::Clock
|
/// \brief Android, chrono-compatible, suspend-aware clock
|
||||||
|
///
|
||||||
|
/// Linux steady clock is represented by CLOCK_MONOTONIC.
|
||||||
|
/// However, this implementation does not work properly for
|
||||||
|
/// long-running clocks that work in the background when the
|
||||||
|
/// system is suspended.
|
||||||
|
///
|
||||||
|
/// SuspendAwareClock uses CLOCK_BOOTTIME which is identical
|
||||||
|
/// to CLOCK_MONOTONIC, except that it also includes any time
|
||||||
|
/// that the system is suspended.
|
||||||
|
///
|
||||||
|
/// Note: In most cases, CLOCK_MONOTONIC is a better choice.
|
||||||
|
/// Make sure this implementation is required for your use case.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
class ClockImpl
|
class SFML_SYSTEM_API SuspendAwareClock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Type traits and static members
|
||||||
|
///
|
||||||
|
/// These type traits and static members meet the requirements
|
||||||
|
/// of a Clock concept in the C++ Standard. More specifically,
|
||||||
|
/// TrivialClock requirements are met. Thus, naming convention
|
||||||
|
/// has been kept consistent to allow for extended use e.g.
|
||||||
|
/// https://en.cppreference.com/w/cpp/chrono/is_clock
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
using duration = std::chrono::nanoseconds;
|
||||||
|
using rep = duration::rep;
|
||||||
|
using period = duration::period;
|
||||||
|
using time_point = std::chrono::time_point<SuspendAwareClock, duration>;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
static constexpr bool is_steady = true;
|
||||||
/// \brief Get the current time
|
|
||||||
///
|
static time_point now() noexcept;
|
||||||
/// \return Current time
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
static Time getCurrentTime();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
||||||
|
#endif // SFML_SUSPENDAWARECLOCK_HPP
|
||||||
#endif // SFML_CLOCKIMPLWIN32_HPP
|
|
@ -22,31 +22,24 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef SFML_SLEEPIMPLUNIX_HPP
|
|
||||||
#define SFML_SLEEPIMPLUNIX_HPP
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Config.hpp>
|
#include <SFML/System/SuspendAwareClock.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Unix implementation of sf::Sleep
|
|
||||||
///
|
|
||||||
/// \param time Time to sleep
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void sleepImpl(Time time);
|
|
||||||
|
|
||||||
} // namespace priv
|
SuspendAwareClock::time_point SuspendAwareClock::now() noexcept
|
||||||
|
{
|
||||||
|
::timespec ts;
|
||||||
|
#ifdef CLOCK_BOOTTIME
|
||||||
|
clock_gettime(CLOCK_BOOTTIME, &ts);
|
||||||
|
#else
|
||||||
|
#error "CLOCK_BOOTTIME is essential for SuspendAwareClock to work"
|
||||||
|
#endif // CLOCK_BOOTTIME
|
||||||
|
return time_point(std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
||||||
|
|
||||||
#endif // SFML_SLEEPIMPLUNIX_HPP
|
|
@ -29,38 +29,22 @@ set(SRC
|
|||||||
${INCROOT}/FileInputStream.hpp
|
${INCROOT}/FileInputStream.hpp
|
||||||
${SRCROOT}/MemoryInputStream.cpp
|
${SRCROOT}/MemoryInputStream.cpp
|
||||||
${INCROOT}/MemoryInputStream.hpp
|
${INCROOT}/MemoryInputStream.hpp
|
||||||
|
${INCROOT}/SuspendAwareClock.hpp
|
||||||
)
|
)
|
||||||
source_group("" FILES ${SRC})
|
source_group("" FILES ${SRC})
|
||||||
|
|
||||||
# add platform specific sources
|
# add platform specific sources
|
||||||
if(SFML_OS_WINDOWS)
|
if(SFML_OS_ANDROID)
|
||||||
set(PLATFORM_SRC
|
set(PLATFORM_SRC ${PLATFORM_SRC}
|
||||||
${SRCROOT}/Win32/ClockImpl.cpp
|
${SRCROOT}/Android/Activity.hpp
|
||||||
${SRCROOT}/Win32/ClockImpl.hpp
|
${SRCROOT}/Android/Activity.cpp
|
||||||
${SRCROOT}/Win32/SleepImpl.cpp
|
${SRCROOT}/Android/NativeActivity.cpp
|
||||||
${SRCROOT}/Win32/SleepImpl.hpp
|
${SRCROOT}/Android/ResourceStream.cpp
|
||||||
|
${SRCROOT}/Android/ResourceStream.cpp
|
||||||
|
${SRCROOT}/Android/SuspendAwareClock.cpp
|
||||||
)
|
)
|
||||||
source_group("windows" FILES ${PLATFORM_SRC})
|
|
||||||
else()
|
|
||||||
set(PLATFORM_SRC
|
|
||||||
${SRCROOT}/Unix/ClockImpl.cpp
|
|
||||||
${SRCROOT}/Unix/ClockImpl.hpp
|
|
||||||
${SRCROOT}/Unix/SleepImpl.cpp
|
|
||||||
${SRCROOT}/Unix/SleepImpl.hpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if(SFML_OS_ANDROID)
|
|
||||||
set(PLATFORM_SRC ${PLATFORM_SRC}
|
|
||||||
${SRCROOT}/Android/Activity.hpp
|
|
||||||
${SRCROOT}/Android/Activity.cpp
|
|
||||||
${SRCROOT}/Android/NativeActivity.cpp
|
|
||||||
${SRCROOT}/Android/ResourceStream.cpp
|
|
||||||
${SRCROOT}/Android/ResourceStream.cpp
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
source_group("unix" FILES ${PLATFORM_SRC})
|
|
||||||
endif()
|
endif()
|
||||||
|
source_group("unix" FILES ${PLATFORM_SRC})
|
||||||
|
|
||||||
# define the sfml-system target
|
# define the sfml-system target
|
||||||
sfml_add_library(sfml-system
|
sfml_add_library(sfml-system
|
||||||
|
@ -27,18 +27,12 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/Clock.hpp>
|
#include <SFML/System/Clock.hpp>
|
||||||
|
|
||||||
#if defined(SFML_SYSTEM_WINDOWS)
|
|
||||||
#include <SFML/System/Win32/ClockImpl.hpp>
|
|
||||||
#else
|
|
||||||
#include <SFML/System/Unix/ClockImpl.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Clock::Clock() :
|
Clock::Clock() :
|
||||||
m_startTime(priv::ClockImpl::getCurrentTime())
|
m_startTime(ClockImpl::now())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,18 +40,27 @@ m_startTime(priv::ClockImpl::getCurrentTime())
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Time Clock::getElapsedTime() const
|
Time Clock::getElapsedTime() const
|
||||||
{
|
{
|
||||||
return priv::ClockImpl::getCurrentTime() - m_startTime;
|
return durationToTime(ClockImpl::now() - m_startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Time Clock::restart()
|
Time Clock::restart()
|
||||||
{
|
{
|
||||||
Time now = priv::ClockImpl::getCurrentTime();
|
const ClockImpl::time_point now = ClockImpl::now();
|
||||||
Time elapsed = now - m_startTime;
|
Time elapsed = durationToTime(now - m_startTime);
|
||||||
m_startTime = now;
|
m_startTime = now;
|
||||||
|
|
||||||
return elapsed;
|
return elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
Time Clock::durationToTime(Clock::ClockImpl::duration duration)
|
||||||
|
{
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
using std::chrono::microseconds;
|
||||||
|
return sf::microseconds(duration_cast<microseconds>(duration).count());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -26,12 +26,8 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/Sleep.hpp>
|
#include <SFML/System/Sleep.hpp>
|
||||||
|
#include <chrono>
|
||||||
#if defined(SFML_SYSTEM_WINDOWS)
|
#include <thread>
|
||||||
#include <SFML/System/Win32/SleepImpl.hpp>
|
|
||||||
#else
|
|
||||||
#include <SFML/System/Unix/SleepImpl.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
@ -39,8 +35,8 @@ namespace sf
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void sleep(Time duration)
|
void sleep(Time duration)
|
||||||
{
|
{
|
||||||
if (duration >= Time::Zero)
|
const auto time = std::chrono::duration<Int64, std::micro>(duration.asMicroseconds());
|
||||||
priv::sleepImpl(duration);
|
std::this_thread::sleep_for(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/System/Unix/ClockImpl.hpp>
|
|
||||||
#if defined(SFML_SYSTEM_MACOS) || defined(SFML_SYSTEM_IOS)
|
|
||||||
#include <mach/mach_time.h>
|
|
||||||
#else
|
|
||||||
#include <ctime>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Time ClockImpl::getCurrentTime()
|
|
||||||
{
|
|
||||||
#if defined(SFML_SYSTEM_MACOS) || defined(SFML_SYSTEM_IOS)
|
|
||||||
|
|
||||||
// Mac OS X specific implementation (it doesn't support clock_gettime)
|
|
||||||
static mach_timebase_info_data_t frequency = {0, 0};
|
|
||||||
if (frequency.denom == 0)
|
|
||||||
mach_timebase_info(&frequency);
|
|
||||||
Uint64 nanoseconds = mach_absolute_time() * frequency.numer / frequency.denom;
|
|
||||||
return sf::microseconds(nanoseconds / 1000);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// POSIX implementation
|
|
||||||
timespec time;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
|
||||||
return sf::microseconds(time.tv_sec * 1000000 + time.tv_nsec / 1000);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
@ -1,61 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef SFML_CLOCKIMPLUNIX_HPP
|
|
||||||
#define SFML_CLOCKIMPLUNIX_HPP
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/Config.hpp>
|
|
||||||
#include <SFML/System/Time.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Unix implementation of sf::Clock
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
class ClockImpl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Get the current time
|
|
||||||
///
|
|
||||||
/// \return Current time
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
static Time getCurrentTime();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SFML_CLOCKIMPLUNIX_HPP
|
|
@ -1,59 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/System/Unix/SleepImpl.hpp>
|
|
||||||
#include <cerrno>
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void sleepImpl(Time time)
|
|
||||||
{
|
|
||||||
Int64 usecs = time.asMicroseconds();
|
|
||||||
|
|
||||||
// Construct the time to wait
|
|
||||||
timespec ti;
|
|
||||||
ti.tv_nsec = static_cast<long>((usecs % 1000000) * 1000);
|
|
||||||
ti.tv_sec = static_cast<time_t>(usecs / 1000000);
|
|
||||||
|
|
||||||
// Wait...
|
|
||||||
// If nanosleep returns -1, we check errno. If it is EINTR
|
|
||||||
// nanosleep was interrupted and has set ti to the remaining
|
|
||||||
// duration. We continue sleeping until the complete duration
|
|
||||||
// has passed. We stop sleeping if it was due to an error.
|
|
||||||
while ((nanosleep(&ti, &ti) == -1) && (errno == EINTR))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
@ -1,87 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/System/Win32/ClockImpl.hpp>
|
|
||||||
#include <mutex>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
LARGE_INTEGER getFrequency()
|
|
||||||
{
|
|
||||||
LARGE_INTEGER frequency;
|
|
||||||
QueryPerformanceFrequency(&frequency);
|
|
||||||
return frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isWindowsXpOrOlder()
|
|
||||||
{
|
|
||||||
// Windows XP was the last 5.x version of Windows
|
|
||||||
return static_cast<DWORD>(LOBYTE(LOWORD(GetVersion()))) < 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Time ClockImpl::getCurrentTime()
|
|
||||||
{
|
|
||||||
// Calculate inverse of frequency multiplied by 1000000 to prevent overflow in final calculation
|
|
||||||
// Frequency is constant across the program lifetime
|
|
||||||
static double inverse = 1000000.0 / static_cast<double>(getFrequency().QuadPart);
|
|
||||||
|
|
||||||
// Detect if we are on Windows XP or older
|
|
||||||
static bool oldWindows = isWindowsXpOrOlder();
|
|
||||||
|
|
||||||
LARGE_INTEGER time;
|
|
||||||
|
|
||||||
if (oldWindows)
|
|
||||||
{
|
|
||||||
static std::recursive_mutex oldWindowsMutex;
|
|
||||||
|
|
||||||
// Acquire a lock (CRITICAL_SECTION) to prevent travelling back in time
|
|
||||||
std::scoped_lock lock(oldWindowsMutex);
|
|
||||||
|
|
||||||
// Get the current time
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get the current time
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the current time as microseconds
|
|
||||||
return sf::microseconds(static_cast<sf::Int64>(static_cast<double>(time.QuadPart) * inverse));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
@ -1,55 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/System/Win32/SleepImpl.hpp>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void sleepImpl(Time time)
|
|
||||||
{
|
|
||||||
// Get the supported timer resolutions on this system
|
|
||||||
TIMECAPS tc;
|
|
||||||
timeGetDevCaps(&tc, sizeof(TIMECAPS));
|
|
||||||
|
|
||||||
// Set the timer resolution to the minimum for the Sleep call
|
|
||||||
timeBeginPeriod(tc.wPeriodMin);
|
|
||||||
|
|
||||||
// Wait...
|
|
||||||
::Sleep(static_cast<DWORD>(time.asMilliseconds()));
|
|
||||||
|
|
||||||
// Reset the timer resolution back to the system default
|
|
||||||
timeEndPeriod(tc.wPeriodMin);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
@ -1,52 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef SFML_SLEEPIMPLWIN32_HPP
|
|
||||||
#define SFML_SLEEPIMPLWIN32_HPP
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/Config.hpp>
|
|
||||||
#include <SFML/System/Time.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Windows implementation of sf::Sleep
|
|
||||||
///
|
|
||||||
/// \param time Time to sleep
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void sleepImpl(Time time);
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SFML_SLEEPIMPLWIN32_HPP
|
|
Loading…
Reference in New Issue
Block a user