Reputation: 5597
I'm trying to implement an update thread for my small game with C++11 threads. I've got the update cycle going on "as fast as possible", but I'd like to limit it to say, 60 times per second. How do I get the remaining time left?
Core::Core()
{
std::thread updateThread(update); // Start update thread
}
void Core::update()
{
// TODO Get start time
// Here happens the actual update stuff
// TODO Get end time
// double duration = ...; // Get the duration
// Sleep if necessary
if(duration < 1.0 / 60.0)
{
_sleep(1.0 / 60.0 - duration);
}
}
Upvotes: 4
Views: 7389
Reputation: 219395
Here is Pete's correct answer (which I up-voted) but with some code thrown in to show how much easier it is done than the other answers:
// desired frame rate
typedef std::chrono::duration<int, std::ratio<1, 60>> frame_duration;
void Core::update()
{
// Get start time
auto start_time = std::chrono::steady_clock::now();
// Get end time
auto end_time = start_time + frame_duration(1);
// Here happens the actual update stuff
// Sleep if necessary
std::this_thread::sleep_until(end_time);
}
Any time you're using <chrono>
, and you see you're manually converting units, you're opening yourself up to bugs, either immediately, or in future maintenance. Let <chrono>
do the conversions for you.
Upvotes: 14
Reputation: 4850
Have a look at the functions and clocks provided in the chrono header.
For example:
using double_milliseconds = std::chrono::duration<double, std::chrono::milliseconds::period>;
auto t0 = std::chrono::high_resolution_clock::now();
/* do work here */
auto t1 = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<double_milliseconds>(t1 - t0).count();
Upvotes: 4
Reputation: 76498
If you're using C++11 threads, you're not limited to whatever that _sleep
function does. C++11 threads have sleep_for
, which takes a duration (i.e., sleep for 10 seconds), and sleep_until
, which takes a time point (i.e., sleep until next Thursday). For a thread that has to wake up at fixed intervals, sleep_until
is the way to go. Just sleep until the next wakeup time.
Upvotes: 5
Reputation: 6515
The easiest way to limit the framerate is to keep track of how long it takes your entire update function. After that you need to sleep the remaining time:
In this example i used timeGetTime to measure time but you can use any other function that has high precision
void Core::Update()
{
unsigned int start_time = timeGetTime();
ActualUpdate();
unsigned int end_time = timeGetTime();
unsigned int frame_time = end_time - start_time;
const unsigned int miliseconds_per_frame = 1000 / 60;
if(frame_time < miliseconds_per_frame)
{
Sleep(miliseconds_per_frame - frame_time);
}
}
Upvotes: 1