mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Rewrote the implementation of sf::Clock, it now ensures microseconds resolution and monotonicity
This commit is contained in:
parent
5b2648fd8b
commit
3e89dd652f
@ -62,7 +62,7 @@ public :
|
||||
Uint32 GetElapsedTime() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Restart the timer
|
||||
/// \brief Restart the clock
|
||||
///
|
||||
/// This function puts the time counter back to zero.
|
||||
///
|
||||
@ -74,7 +74,7 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
Uint64 myStartTime; ///< Time of last reset
|
||||
Uint64 myStartTime; ///< Time of last reset, in nanoseconds
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -13,7 +13,6 @@ set(SRC
|
||||
${SRCROOT}/Mutex.cpp
|
||||
${INCROOT}/Mutex.hpp
|
||||
${INCROOT}/NonCopyable.hpp
|
||||
${SRCROOT}/Platform.hpp
|
||||
${SRCROOT}/Sleep.cpp
|
||||
${INCROOT}/Sleep.hpp
|
||||
${SRCROOT}/String.cpp
|
||||
@ -37,10 +36,12 @@ set(SRC
|
||||
if(WINDOWS)
|
||||
set(SRC
|
||||
${SRC}
|
||||
${SRCROOT}/Win32/ClockImpl.cpp
|
||||
${SRCROOT}/Win32/ClockImpl.hpp
|
||||
${SRCROOT}/Win32/MutexImpl.cpp
|
||||
${SRCROOT}/Win32/MutexImpl.hpp
|
||||
${SRCROOT}/Win32/Platform.cpp
|
||||
${SRCROOT}/Win32/Platform.hpp
|
||||
${SRCROOT}/Win32/SleepImpl.cpp
|
||||
${SRCROOT}/Win32/SleepImpl.hpp
|
||||
${SRCROOT}/Win32/ThreadImpl.cpp
|
||||
${SRCROOT}/Win32/ThreadImpl.hpp
|
||||
${SRCROOT}/Win32/ThreadLocalImpl.cpp
|
||||
@ -49,10 +50,12 @@ if(WINDOWS)
|
||||
else()
|
||||
set(SRC
|
||||
${SRC}
|
||||
${SRCROOT}/Unix/ClockImpl.cpp
|
||||
${SRCROOT}/Unix/ClockImpl.hpp
|
||||
${SRCROOT}/Unix/MutexImpl.cpp
|
||||
${SRCROOT}/Unix/MutexImpl.hpp
|
||||
${SRCROOT}/Unix/Platform.cpp
|
||||
${SRCROOT}/Unix/Platform.hpp
|
||||
${SRCROOT}/Unix/SleepImpl.cpp
|
||||
${SRCROOT}/Unix/SleepImpl.hpp
|
||||
${SRCROOT}/Unix/ThreadImpl.cpp
|
||||
${SRCROOT}/Unix/ThreadImpl.hpp
|
||||
${SRCROOT}/Unix/ThreadLocalImpl.cpp
|
||||
|
@ -26,7 +26,12 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Clock.hpp>
|
||||
#include <SFML/System/Platform.hpp>
|
||||
|
||||
#if defined(SFML_SYSTEM_WINDOWS)
|
||||
#include <SFML/System/Win32/ClockImpl.hpp>
|
||||
#else
|
||||
#include <SFML/System/Unix/ClockImpl.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -41,14 +46,15 @@ Clock::Clock()
|
||||
////////////////////////////////////////////////////////////
|
||||
Uint32 Clock::GetElapsedTime() const
|
||||
{
|
||||
return static_cast<Uint32>(priv::Platform::GetSystemTime() - myStartTime);
|
||||
Uint64 microseconds = priv::ClockImpl::GetMicroSeconds() - myStartTime;
|
||||
return static_cast<Uint32>(microseconds / 1000);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Clock::Reset()
|
||||
{
|
||||
myStartTime = priv::Platform::GetSystemTime();
|
||||
myStartTime = priv::ClockImpl::GetMicroSeconds();
|
||||
}
|
||||
|
||||
} // namespace sf
|
||||
|
@ -26,7 +26,12 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Sleep.hpp>
|
||||
#include <SFML/System/Platform.hpp>
|
||||
|
||||
#if defined(SFML_SYSTEM_WINDOWS)
|
||||
#include <SFML/System/Win32/SleepImpl.hpp>
|
||||
#else
|
||||
#include <SFML/System/Unix/SleepImpl.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -34,7 +39,7 @@ namespace sf
|
||||
////////////////////////////////////////////////////////////
|
||||
void Sleep(Uint32 duration)
|
||||
{
|
||||
priv::Platform::Sleep(duration);
|
||||
priv::SleepImpl(duration);
|
||||
}
|
||||
|
||||
} // namespace sf
|
||||
|
64
src/SFML/System/Unix/ClockImpl.cpp
Normal file
64
src/SFML/System/Unix/ClockImpl.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// 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>
|
||||
#ifdef SFML_SYSTEM_MACOS
|
||||
#include <mach/mach_time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Uint64 ClockImpl::GetMicroSeconds()
|
||||
{
|
||||
#ifdef SFML_SYSTEM_MACOS
|
||||
|
||||
// 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 nanoseconds / 1000;
|
||||
|
||||
#else
|
||||
|
||||
// POSIX implementation
|
||||
timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return time.tv_sec * 1000000 + time.tv_nsec / 1000;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
@ -22,14 +22,13 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_PLATFORMWIN32_HPP
|
||||
#define SFML_PLATFORMWIN32_HPP
|
||||
#ifndef SFML_CLOCKIMPLUNIX_HPP
|
||||
#define SFML_CLOCKIMPLUNIX_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Config.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -37,28 +36,20 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Gives access to some system-specific low-level functions
|
||||
/// \brief Unix implementaton of sf::Clock
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class Platform
|
||||
class ClockImpl
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the current system time
|
||||
/// \brief Get the current time
|
||||
///
|
||||
/// \return System time, in milliseconds
|
||||
/// \return Current time, in microseconds
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Uint64 GetSystemTime();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Suspend the execution of the current thread for a specified duration
|
||||
///
|
||||
/// \param time Time to sleep, in milliseconds
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void Sleep(Uint32 time);
|
||||
static Uint64 GetMicroSeconds();
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
@ -66,4 +57,4 @@ public :
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_PLATFORMWIN32_HPP
|
||||
#endif // SFML_CLOCKIMPLUNIX_HPP
|
@ -1,7 +1,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// 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.
|
||||
@ -25,7 +25,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Unix/Platform.hpp>
|
||||
#include <SFML/System/Unix/SleepImpl.hpp>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
@ -36,21 +36,12 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Uint64 Platform::GetSystemTime()
|
||||
{
|
||||
timeval time = {0, 0};
|
||||
gettimeofday(&time, NULL);
|
||||
|
||||
return time.tv_sec * 1000 + time.tv_usec / 1000;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Platform::Sleep(Uint32 time)
|
||||
void SleepImpl(Uint32 time)
|
||||
{
|
||||
// usleep is not reliable enough (it might block the
|
||||
// whole process instead of just the current thread)
|
||||
// so we must use pthread_cond_timedwait instead
|
||||
|
||||
// this implementation is inspired from Qt
|
||||
|
||||
// first get the current time
|
@ -22,11 +22,13 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_SLEEPIMPLUNIX_HPP
|
||||
#define SFML_SLEEPIMPLUNIX_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Win32/Platform.hpp>
|
||||
#include <windows.h>
|
||||
#include <SFML/Config.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -34,33 +36,16 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Uint64 Platform::GetSystemTime()
|
||||
{
|
||||
static LARGE_INTEGER frequency;
|
||||
static BOOL useHighPerformanceTimer = QueryPerformanceFrequency(&frequency);
|
||||
|
||||
if (useHighPerformanceTimer)
|
||||
{
|
||||
// High performance counter available : use it
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
|
||||
return currentTime.QuadPart * 1000 / frequency.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
// High performance counter not available: use GetTickCount (less accurate)
|
||||
return GetTickCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// \brief Unix implementation of sf::Sleep
|
||||
///
|
||||
/// \param time Time to sleep, in milliseconds
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Platform::Sleep(Uint32 time)
|
||||
{
|
||||
::Sleep(time);
|
||||
}
|
||||
void SleepImpl(Uint32 time);
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_SLEEPIMPLUNIX_HPP
|
74
src/SFML/System/Win32/ClockImpl.cpp
Normal file
74
src/SFML/System/Win32/ClockImpl.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// 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 <windows.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Private data
|
||||
////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
LARGE_INTEGER GetFrequency()
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
return frequency;
|
||||
}
|
||||
}
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Uint64 ClockImpl::GetMicroSeconds()
|
||||
{
|
||||
// Force the following code to run on first core
|
||||
// (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx)
|
||||
HANDLE currentThread = GetCurrentThread();
|
||||
DWORD_PTR previousMask = SetThreadAffinityMask(currentThread, 1);
|
||||
|
||||
// Get the frequency of the performance counter
|
||||
// (it is constant across the program lifetime)
|
||||
static LARGE_INTEGER frequency = GetFrequency();
|
||||
|
||||
// Get the current time
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
|
||||
// Restore the thread affinity
|
||||
SetThreadAffinityMask(currentThread, previousMask);
|
||||
|
||||
// Return the current time as microseconds
|
||||
return 1000000 * time.QuadPart / frequency.QuadPart;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
@ -1,7 +1,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// 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.
|
||||
@ -22,8 +22,8 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_PLATFORMUNIX_HPP
|
||||
#define SFML_PLATFORMUNIX_HPP
|
||||
#ifndef SFML_CLOCKIMPLWIN32_HPP
|
||||
#define SFML_CLOCKIMPLWIN32_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
@ -36,28 +36,20 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Give access to some system-specific low-level functions
|
||||
/// \brief Windows implementaton of sf::Clock
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class Platform
|
||||
class ClockImpl
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the current system time
|
||||
/// \brief Get the current time
|
||||
///
|
||||
/// \return System time, in milliseconds
|
||||
/// \return Current time, in microseconds
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Uint64 GetSystemTime();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Suspend the execution of the current thread for a specified duration
|
||||
///
|
||||
/// \param time Time to sleep, in milliseconds
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void Sleep(Uint32 time);
|
||||
static Uint64 GetMicroSeconds();
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
@ -65,4 +57,4 @@ public :
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_PLATFORMUNIX_HPP
|
||||
#endif // SFML_CLOCKIMPLWIN32_HPP
|
@ -22,24 +22,23 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_PLATFORM_HPP
|
||||
#define SFML_PLATFORM_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Config.hpp>
|
||||
#include <SFML/System/Win32/SleepImpl.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
#if defined(SFML_SYSTEM_WINDOWS)
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
void SleepImpl(Uint32 time)
|
||||
{
|
||||
::Sleep(time);
|
||||
}
|
||||
|
||||
#include <SFML/System/Win32/Platform.hpp>
|
||||
} // namespace priv
|
||||
|
||||
#else
|
||||
|
||||
#include <SFML/System/Unix/Platform.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // SFML_PLATFORM_HPP
|
||||
} // namespace sf
|
51
src/SFML/System/Win32/SleepImpl.hpp
Normal file
51
src/SFML/System/Win32/SleepImpl.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// 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>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Windows implementation of sf::Sleep
|
||||
///
|
||||
/// \param time Time to sleep, in milliseconds
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SleepImpl(Uint32 time);
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_SLEEPIMPLWIN32_HPP
|
Loading…
Reference in New Issue
Block a user