Skip to content

Instantly share code, notes, and snippets.

@bigdavedev
Created October 22, 2019 13:33
Show Gist options
  • Save bigdavedev/ad0c6c7324ee60d8e30640031abc005b to your computer and use it in GitHub Desktop.
Save bigdavedev/ad0c6c7324ee60d8e30640031abc005b to your computer and use it in GitHub Desktop.
Patch to add `std::chrono` to SFML
diff --git a/examples/island/Island.cpp b/examples/island/Island.cpp
index 50a8f1ea..846930fa 100644
--- a/examples/island/Island.cpp
+++ b/examples/island/Island.cpp
@@ -226,7 +226,7 @@ int main()
// Update and draw the HUD text
osstr.str("");
- osstr << "Frame: " << clock.restart().asMilliseconds() << "ms\n"
+ osstr << "Frame: " << clock.restart().asMilliseconds().count() << "ms\n"
<< "perlinOctaves: " << perlinOctaves << "\n\n"
<< "Use the arrow keys to change the values.\nUse the return key to regenerate the terrain.\n\n";
diff --git a/examples/opengl/OpenGL.cpp b/examples/opengl/OpenGL.cpp
index f2260d6b..d1c8823b 100644
--- a/examples/opengl/OpenGL.cpp
+++ b/examples/opengl/OpenGL.cpp
@@ -232,9 +232,9 @@ int main()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x, y, -100.f);
- glRotatef(clock.getElapsedTime().asSeconds() * 50.f, 1.f, 0.f, 0.f);
- glRotatef(clock.getElapsedTime().asSeconds() * 30.f, 0.f, 1.f, 0.f);
- glRotatef(clock.getElapsedTime().asSeconds() * 90.f, 0.f, 0.f, 1.f);
+ glRotatef(clock.getElapsedTime().asSeconds().count() * 50.f, 1.f, 0.f, 0.f);
+ glRotatef(clock.getElapsedTime().asSeconds().count() * 30.f, 0.f, 1.f, 0.f);
+ glRotatef(clock.getElapsedTime().asSeconds().count() * 90.f, 0.f, 0.f, 1.f);
// Draw the cube
glDrawArrays(GL_TRIANGLES, 0, 36);
diff --git a/include/SFML/System/Time.hpp b/include/SFML/System/Time.hpp
index 43d7548b..036bfcb0 100644
--- a/include/SFML/System/Time.hpp
+++ b/include/SFML/System/Time.hpp
@@ -30,9 +30,12 @@
////////////////////////////////////////////////////////////
#include <SFML/System/Export.hpp>
+#include <chrono>
namespace sf
{
+using Seconds = std::chrono::duration<float>;
+
////////////////////////////////////////////////////////////
/// \brief Represents a time value
///
@@ -57,7 +60,7 @@ public:
/// \see asMilliseconds, asMicroseconds
///
////////////////////////////////////////////////////////////
- float asSeconds() const;
+ Seconds asSeconds() const;
////////////////////////////////////////////////////////////
/// \brief Return the time value as a number of milliseconds
@@ -67,7 +70,7 @@ public:
/// \see asSeconds, asMicroseconds
///
////////////////////////////////////////////////////////////
- Int32 asMilliseconds() const;
+ std::chrono::milliseconds asMilliseconds() const;
////////////////////////////////////////////////////////////
/// \brief Return the time value as a number of microseconds
@@ -77,7 +80,7 @@ public:
/// \see asSeconds, asMilliseconds
///
////////////////////////////////////////////////////////////
- Int64 asMicroseconds() const;
+ std::chrono::microseconds asMicroseconds() const;
////////////////////////////////////////////////////////////
// Static member data
@@ -90,6 +93,10 @@ private:
friend SFML_SYSTEM_API Time milliseconds(Int32);
friend SFML_SYSTEM_API Time microseconds(Int64);
+ friend SFML_SYSTEM_API Time seconds(Seconds);
+ friend SFML_SYSTEM_API Time milliseconds(std::chrono::milliseconds);
+ friend SFML_SYSTEM_API Time microseconds(std::chrono::microseconds);
+
////////////////////////////////////////////////////////////
/// \brief Construct from a number of microseconds
///
@@ -99,14 +106,14 @@ private:
/// \param microseconds Number of microseconds
///
////////////////////////////////////////////////////////////
- explicit Time(Int64 microseconds);
+ explicit Time(std::chrono::microseconds microseconds);
private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
- Int64 m_microseconds; ///< Time value stored as microseconds
+ std::chrono::microseconds m_microseconds; ///< Time value stored as microseconds
};
////////////////////////////////////////////////////////////
@@ -121,6 +128,7 @@ private:
///
////////////////////////////////////////////////////////////
SFML_SYSTEM_API Time seconds(float amount);
+SFML_SYSTEM_API Time seconds(Seconds amount);
////////////////////////////////////////////////////////////
/// \relates Time
@@ -134,6 +142,7 @@ SFML_SYSTEM_API Time seconds(float amount);
///
////////////////////////////////////////////////////////////
SFML_SYSTEM_API Time milliseconds(Int32 amount);
+SFML_SYSTEM_API Time milliseconds(std::chrono::milliseconds amount);
////////////////////////////////////////////////////////////
/// \relates Time
@@ -147,6 +156,7 @@ SFML_SYSTEM_API Time milliseconds(Int32 amount);
///
////////////////////////////////////////////////////////////
SFML_SYSTEM_API Time microseconds(Int64 amount);
+SFML_SYSTEM_API Time microseconds(std::chrono::microseconds amount);
////////////////////////////////////////////////////////////
/// \relates Time
diff --git a/src/SFML/Audio/InputSoundFile.cpp b/src/SFML/Audio/InputSoundFile.cpp
index 9cc781ff..00504c0b 100644
--- a/src/SFML/Audio/InputSoundFile.cpp
+++ b/src/SFML/Audio/InputSoundFile.cpp
@@ -238,7 +238,7 @@ void InputSoundFile::seek(Uint64 sampleOffset)
////////////////////////////////////////////////////////////
void InputSoundFile::seek(Time timeOffset)
{
- seek(static_cast<Uint64>(timeOffset.asSeconds() * m_sampleRate * m_channelCount));
+ seek(static_cast<Uint64>(timeOffset.asSeconds().count() * m_sampleRate * m_channelCount));
}
diff --git a/src/SFML/Audio/Music.cpp b/src/SFML/Audio/Music.cpp
index 141d6903..ad8931c8 100644
--- a/src/SFML/Audio/Music.cpp
+++ b/src/SFML/Audio/Music.cpp
@@ -252,7 +252,7 @@ Uint64 Music::timeToSamples(Time position) const
// This avoids most precision errors arising from "samples => Time => samples" conversions
// Original rounding calculation is ((Micros * Freq * Channels) / 1000000) + 0.5
// We refactor it to keep Int64 as the data type throughout the whole operation.
- return ((position.asMicroseconds() * getSampleRate() * getChannelCount()) + 500000) / 1000000;
+ return ((position.asMicroseconds().count() * getSampleRate() * getChannelCount()) + 500000) / 1000000;
}
diff --git a/src/SFML/Audio/Sound.cpp b/src/SFML/Audio/Sound.cpp
index b7a0b130..04e99ba7 100644
--- a/src/SFML/Audio/Sound.cpp
+++ b/src/SFML/Audio/Sound.cpp
@@ -115,7 +115,7 @@ void Sound::setLoop(bool loop)
////////////////////////////////////////////////////////////
void Sound::setPlayingOffset(Time timeOffset)
{
- alCheck(alSourcef(m_source, AL_SEC_OFFSET, timeOffset.asSeconds()));
+ alCheck(alSourcef(m_source, AL_SEC_OFFSET, timeOffset.asSeconds().count()));
}
diff --git a/src/SFML/Audio/SoundStream.cpp b/src/SFML/Audio/SoundStream.cpp
index 0e405482..5841733b 100644
--- a/src/SFML/Audio/SoundStream.cpp
+++ b/src/SFML/Audio/SoundStream.cpp
@@ -215,7 +215,7 @@ void SoundStream::setPlayingOffset(Time timeOffset)
onSeek(timeOffset);
// Restart streaming
- m_samplesProcessed = static_cast<Uint64>(timeOffset.asSeconds() * m_sampleRate * m_channelCount);
+ m_samplesProcessed = static_cast<Uint64>(timeOffset.asSeconds().count() * m_sampleRate * m_channelCount);
if (oldStatus == Stopped)
return;
diff --git a/src/SFML/Network/SocketSelector.cpp b/src/SFML/Network/SocketSelector.cpp
index fa00c63d..e207c1d4 100644
--- a/src/SFML/Network/SocketSelector.cpp
+++ b/src/SFML/Network/SocketSelector.cpp
@@ -155,10 +155,11 @@ void SocketSelector::clear()
////////////////////////////////////////////////////////////
bool SocketSelector::wait(Time timeout)
{
+ auto seconds = std::chrono::duration_cast<std::chrono::seconds>(timeout.asMicroseconds());
// Setup the timeout
timeval time;
- time.tv_sec = static_cast<long>(timeout.asMicroseconds() / 1000000);
- time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);
+ time.tv_sec = seconds.count();
+ time.tv_usec = (timeout.asMicroseconds() - seconds).count();
// Initialize the set that will contain the sockets that are ready
m_impl->socketsReady = m_impl->allSockets;
diff --git a/src/SFML/Network/TcpSocket.cpp b/src/SFML/Network/TcpSocket.cpp
index d8effa1c..b5a8a818 100644
--- a/src/SFML/Network/TcpSocket.cpp
+++ b/src/SFML/Network/TcpSocket.cpp
@@ -172,10 +172,11 @@ Socket::Status TcpSocket::connect(const IpAddress& remoteAddress, unsigned short
FD_ZERO(&selector);
FD_SET(getHandle(), &selector);
+ auto seconds = std::chrono::duration_cast<std::chrono::seconds>(timeout.asMicroseconds());
// Setup the timeout
timeval time;
- time.tv_sec = static_cast<long>(timeout.asMicroseconds() / 1000000);
- time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);
+ time.tv_sec = seconds.count();
+ time.tv_usec = (timeout.asMicroseconds() - seconds).count();
// Wait for something to write on our socket (which means that the connection request has returned)
if (select(static_cast<int>(getHandle() + 1), NULL, &selector, NULL, &time) > 0)
diff --git a/src/SFML/System/Time.cpp b/src/SFML/System/Time.cpp
index 681c9a9d..26a76a07 100644
--- a/src/SFML/System/Time.cpp
+++ b/src/SFML/System/Time.cpp
@@ -42,28 +42,28 @@ m_microseconds(0)
////////////////////////////////////////////////////////////
-float Time::asSeconds() const
+Seconds Time::asSeconds() const
{
- return m_microseconds / 1000000.f;
+ return std::chrono::duration_cast<Seconds>(m_microseconds);
}
////////////////////////////////////////////////////////////
-Int32 Time::asMilliseconds() const
+std::chrono::milliseconds Time::asMilliseconds() const
{
- return static_cast<Int32>(m_microseconds / 1000);
+ return std::chrono::duration_cast<std::chrono::milliseconds>(m_microseconds);
}
////////////////////////////////////////////////////////////
-Int64 Time::asMicroseconds() const
+std::chrono::microseconds Time::asMicroseconds() const
{
return m_microseconds;
}
////////////////////////////////////////////////////////////
-Time::Time(Int64 microseconds) :
+Time::Time(std::chrono::microseconds microseconds) :
m_microseconds(microseconds)
{
}
@@ -72,19 +72,34 @@ m_microseconds(microseconds)
////////////////////////////////////////////////////////////
Time seconds(float amount)
{
- return Time(static_cast<Int64>(amount * 1000000));
+ return seconds(Seconds{amount});
+}
+
+Time seconds(Seconds amount)
+{
+ return Time(std::chrono::duration_cast<std::chrono::microseconds>(amount));
}
////////////////////////////////////////////////////////////
Time milliseconds(Int32 amount)
{
- return Time(static_cast<Int64>(amount) * 1000);
+ return milliseconds(std::chrono::milliseconds{amount});
+}
+
+Time milliseconds(std::chrono::milliseconds amount)
+{
+ return Time(amount);
}
////////////////////////////////////////////////////////////
Time microseconds(Int64 amount)
+{
+ return microseconds(std::chrono::microseconds{amount});
+}
+
+Time microseconds(std::chrono::microseconds amount)
{
return Time(amount);
}
diff --git a/src/SFML/System/Win32/SleepImpl.cpp b/src/SFML/System/Win32/SleepImpl.cpp
index 41c10188..74e1cc90 100644
--- a/src/SFML/System/Win32/SleepImpl.cpp
+++ b/src/SFML/System/Win32/SleepImpl.cpp
@@ -44,7 +44,7 @@ void sleepImpl(Time time)
timeBeginPeriod(tc.wPeriodMin);
// Wait...
- ::Sleep(time.asMilliseconds());
+ ::Sleep(time.asMilliseconds().count());
// Reset the timer resolution back to the system default
timeEndPeriod(tc.wPeriodMin);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment