C++ Timer for my C++ Game - c++

I've encountered a huge problem! I'm making a C++ Zombie game and it works perfectly besides the barrier part. I want the zombies to come to the barrier, then have them wait around 5 seconds, and then break through the barrier. Now I don't think you need my whole code for this since it's just a timer, but if you do let me know! Basically, I tried many timers AND the Sleep command, but when I use them it makes the zombies stay at the barrier, but then everything else freezes until the timers. For exmaple if the zombies at the barrier and I use a timer for 5 seconds, the zombie stays at the barrier for 5 seconds! but so does everything else, nothing else can move for 5 seconds! Is their any way I could use a sleep command only for a CERTAIN part of my code? Here is one of the few timers I used.
int Timer()
{
int s = 0;
int m = 0;
int h = 0;
while (true)
{
CPos(12,58);
cout << "Timer: ";
cout << h/3600 << ":" << m/60 << ":" << s;
if (s == 59) s = -1;
if (m == 3599) m = -1; //3599 = 60*60 -1
s++;
m++;
h++;
Sleep(1000);
cout<<"\b\b\b";
}
}
This one involves a sleep command, I also used a timer where while(number > 0) --number, but it works! but it still freezes everything else in my program!
If you need anything, Let me know!

Unless you have EACH zombie and everything else running on different threads, calling Sleep will pause the entire application for x milliseconds... You need to stop the zombie a different way, namely by just not moving him until the time has passed, while still updating the other entities as normal (don't use sleep).
EDIT:
You can't just create a timer and then wait until that timer is done. At the time when the zombie needs to stop moving, you have to 'remember' the current time, but continue on. Then each time you get back to that zombie again to update its position, you check to see if he has a pause timer. If he does, then you have to compare the elapsed time between what you 'remembered' against the current time and check whether he has paused long enough... here is some psuedo code:
#include <time>
class Zombie {
private:
int m_xPos;
time_t m_rememberedTime;
public:
Zombie() {
this->m_xPos = 0;
this->m_rememberedTime = 0;
}
void Update() {
if (CheckPaused()) {
// bail out before we move this zombie if he is paused at a barrier.
return;
}
// If it's not paused, then move him as normal.
this->m_xPos += 1; // or whatever.
if (ZombieHitBarrier()) {
PauseZombieAtBarrier();
}
}
bool CheckPaused() {
if (this.m_rememberedTime > 0) {
// If we have a remembered time, calculate the elapsed time.
time_t currentTime;
time(&currentTime);
time_t elapsed = currentTime - this.m_rememberedTime;
if (elapsed > 5.0f) {
// 5 seconds has gone by, so clear the remembered time and continue on to return false.
this.m_rememberedTime = 0;
} else {
// 5 seconds has not gone by yet, so return true that we are still paused.
return true;
}
}
// Either no timer exists, or the timer has just finished, return false that we are not paused.
return false;
}
// Call this when the zombie hits a wall.
void PauseZombieAtBarrier() {
// Store the current time in a variable for later use.
time(&this->m_rememberedTime);
}
};

Related

Best approach to Independently Timing each Tick of a For Loop in another Thread

Suppose I have a client thread and a server thread. The client thread must perform an expensive for loop operation which is prone to hanging. Thus, the server has independently determine whether each tick of the for loop has exceeded the max time. The context behind this is that the server will timeout the client if it takes too long to complete a tick.
My initial idea below is to have two for loops in the client and server thread. The server thread will have a condition variable that waits for 1 second. If the client does not notify the condition variable in 1 second every tick, the server will time it out:
Server
bool success;
for (int i = 0; i < 10; i++) {
std::unique_lock<std::mutex> lock(CLIENT_MUTEX);
success = CLIENT_CV.wait_for(lock, std::chrono::seconds(1));
if (!success) {
std::cout << "timed out during tick " << i << std::endl;
break;
}
}
Client
for (int i = 0; i < 10; i++) {
std::unique_lock<std::mutex> lock(CLIENT_MUTEX);
//do work
CLIENT_CV.notify_one();
}
However my implementation attempt is unreliable and times out at random times given the same work for the client. How can I improve the design to make it more reliable?
Side Note:
A simple solution to this would be for the server to time the entire for loop as opposed to each tick. However if the for loop fails on tick 1 out of 10, and the timer is waiting for 10 seconds, then the client will be informed after 10 seconds. However if the server was to impose a 1 second timeout for each tick (10x1sec = 10secs) then the client will be informed of timeout without having to wait the full 10 seconds.
Edit.
This whole client/server/timeout analogy is simply to put the question into context. I'm purely interested in the best way to time the for loop from a different thread.
One way of doing this might be:
Shared vars:
std::vector<std::chrono::time_point<std::chrono::high_resolution_clock>> ledger;
std::mutex ledger_mtx;
Client:
for (int i = 0; i < 10; i++) {
{
std::scoped_lock lock(ledger_mtx);
ledger.push_back(std::chrono::high_resolution_clock::now());
}
// Do work
}
{
std::scoped_lock lock(ledger_mtx);
ledger.push_back(std::chrono::high_resolution_clock::now());
}
Server:
size_t id = 0;
std::this_thread::wait_for(1s); // Some time so that initial write to ledger is made
while(true) {
{
std::scoped_lock lock(ledger_mtx);
if(ledger.size()==id) { /* Do something if the thread hangs */ }
id = ledger.size();
std::chrono::time_point<std::chrono::high_resolution_clock> last_tick = ledger.back();
}
if(id == 11) break;
std::this_thread::sleep_for(1s - (std::chrono::high_resolution_clock::now() - last_tick));
}
This way you can time the thread, while monitoring it from the outside. Is it the best way? probably not, but it does give you the times you need.

Increasing a value every 5 seconds

I'm making a simple meteor and rocket game in the console. And I want to increase the spawnrate of the meteors every five seconds. I have already tried the Sleep() function but that will of course not work and sleep the whole application. So does a while loop.
I will only post the Logic() function where it must increase because it's a program
of like 100 lines and I didn't feel like posting it all in here. If you do need context just ask me and I will post everything.
void Logic() {
Sleep(5000); // TODO Increase meteors every Five seconds
nMeteors++;
}
I'm pretty stuck on this so it would be nice if someone could help me :)
There are mainly two ways to approach this problem. One would be to spawn a new thread and put the loop there. You can use C++11's standard libraries <thread> and <chrono. Putting the thread to sleep for 5 seconds is as simple as std::this_thread::sleep_for(std::chrono::seconds{5});
But dedicating an entire thread to such a trivial task is unnecessary. In a videogame you usually have some sort of time keeping variable.
What you'd want to do is probably have a variable like std::chrono::time_point<std::chrono::steady_clock> previous_time = std::chrono::steady_clock::now(); (or simply auto previous_time = std::chrono::steady_clock::now()) outside of your loop. Now you have a reference point you can use to know where you are in time while running your loop. Inside of your loop you create another variable like auto current_time = std::chrono::steady_clock::now();, this is your current time. Now it's a simple matter of calculating the difference between current_time and previous_time and check if 5 seconds have passed. If they have, increase your variable and don't forget to set previous_time = current_time; to update the time, if not then just skip and keep doing whatever else you need to do in your main game loop.
To check if 5 seconds have passed, you do if (std::chrono::duration_cast<std::chrono::seconds>(current_time - previous_time).count() >= 5) { ... }.
You can find a lot more info here for the chrono library and here for the thread library. Plus, Google is your friend.
The typical way to write a game is to have an event loop.
The event loop polls various inputs for status, updates the state of the game, and then repeats. Some clever event loops even sleep for short periods and get notifications when inputs change or state has to be updated.
In your meteor spawning code, keep track of a timestamp when the last increase in spawnrate occurred. When you check if a meteor should spawn or spawn meteors 5 seconds after that point, update the spawn rate and record a new timestamp (possibly retroactively, and possibly in a loop to handle more than 10 seconds passing between checks for whatever reason).
An alternative solution involving an extra thread of execution is possible, but not a good idea.
As an aside, most games want to support pausing; so you want to distinguish between wall-clock time and nominal game-play time.
One way you can do this is by making your value a function of elapsed time. For example:
// somewhere to store the beginning of the
// time period.
inline std::time_t& get_start_timer()
{
static std::time_t t{};
return t;
}
// Start a time period (resets meteors to zero)
inline void start_timer()
{
get_start_timer() = std::time(nullptr); // current time in seconds
}
// retrieve the current number of meteors
// as a function of time.
inline int nMeteors()
{
return int(std::difftime(std::time(nullptr), get_start_timer())) / 5;
}
int main()
{
start_timer();
for(;;)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "meteors: " << nMeteors() << '\n';
}
}
Here is a similar version using C++11 <chrono> library:
// somewhere to store the beginning of the
// time period.
inline auto& get_time_point()
{
static std::chrono::steady_clock::time_point tp{};
return tp;
}
// Start a time period (resets meteors to zero)
inline void start_timing()
{
get_time_point() = std::chrono::steady_clock::now(); // current time in seconds
}
// retrieve the current number of meteors
// as a function of time.
inline auto nMeteors()
{
return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - get_time_point()).count() / 5;
}
int main()
{
start_timing();
for(;;)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "meteors: " << nMeteors() << '\n';
}
}
I found this easier than using chrono
Open to feedbacks:
Code:-
include "time.h"
main(){
int d;
time_t s,e;
time(&s);
time(&e);
d=e-s;
while(d<5){
cout<<d;
time(&e);
d=e-s;
}
}

Using sleep() in game loop makes delta time unstable

I'm writing a game loop with sfml. When I don't make it sleep, time elapsed for each loop iteration is ~1ms. But when I add sleep(sleepTime) suddenly dt is high. I restart dt at the beginning of the loop but it seems that it adds last sleep time to it. What causes it?
sf::Clock clock;
float dt;
sf::Time sleepTime = sf::milliseconds(0);
while(m_Window.isOpen())
{
sf::Time elapsed = clock.restart();
dt = elapsed.asMilliseconds();
cout << "Elapsed: " << dt;
sf::Event event;
while(m_Window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
m_Window.close();
break;
}
}
sleepTime = sf::milliseconds(16 - dt);
float time = sleepTime.asMilliseconds();
cout << "\tSleep time: " << time << endl;
if(sleepTime >= sf::Time::Zero)
{
sf::sleep(sleepTime);
}
else
{
cout << "Shit." << endl;
}
Without sleep: https://aww.moe/sn1z0a.png
With sleep: https://aww.moe/7seof1.png
What you're trying to do – limiting the game to a specific framerate – is already built into SFML. Just call sf::Window::setFrameRateLimit() with your intended framerate as parameter and you're set. It's also possible to use vertical synchronization (by using sf::Window::setVerticalSyncEnabled()) to limit the number of frames/updates, although it's often considered a bad idea, since the game would also slow down if the target machine can't render at the desired framerate (or speed up for high end screens running at 120 or 140Hz).
However, you'll typically want to disconnect your game updates from your frame rate so the game doesn't slow down, even if the current machine can't update the screen fast enough.
The basic approach using SFML will typically look like this (this is from memory, so might include bugs or typos):
sf::Clock updateTimer; // Clock to monitor the time passed
sf::Time passedTime; // Accumulated game time
const sf::Time frameTime(sf::milliseconds(10)); // intended time per frame; here: 10ms
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
// Event handling
}
// First add the time passed
passedTime += updateClock.restart();
unsigned int numUpdates = 0; // Count the updates done
// As long as enough time passed, do an update
// Up to a specific maximum to avoid problems, e.g.
// the main thread was blocked or can't catch up
while (passedTime >= frameTime) {
if (numUpdates++ < 10) {
// Do your game update here
}
// Subtract the time we've "handled"
passedTime -= frameTime;
}
window.clear();
// Draw your game here
window.display();
}
The usage of numUpdates might not be clear at first, but just imagine a situation where the machine is barely able to run the desired 100 updates per second. If you're 20 updates behind (some hick-up or whatever) the machine will never be able to catch up again properly, causing heavy stuttering or the game becoming unresponsive.

How to stop a function from running from outside in c++

I want to run a function and tell if the function didn't finish after n milliseconds, stop that function and start another one. something like this code:
void run()
{
//do something that doesn't have while(1)
}
void main()
{
run();
if(runFunctionDidntFinishInSeconds(10)
{
endPrintFunction();
backupPlan();
}
return 0;
}
I searched out and found boost::timed_join function. here's my code:
void run()
{
int a;
for (int i = 0; i < 2000; i++)
cout << i << endl;
}
int main()
{
boost::thread t = new boost::thread(&run);
if (t.timed_join(boost::posix_time::microseconds(10000))){
cout << "done" << endl;
}
else{
cout << endl << "not done" << endl;
}
system("pause");
return 0;
}
but it doesn't stop thread 't' from running. I went to terminate the thread, but it's not a good option.
I want the 'a' function to finish the exact time I'm telling it to.
The system gets input every 16ms and I want to do a processing on it and say if the processing took more than about 13ms leave it and go do a backup plan. and I want it to be abstracted from the ones who write the processing method. So putting a while loop on the top of it brings me delay.
What should i do?
The least I think I need is to be abled to reset the processing thread to do what it had needed to do again!
I think your are looking for something like std::future.
http://en.cppreference.com/w/cpp/thread/future/wait_for
You can start the function in another thread and wait until the function returns or has a timeout.
For your example:
std::future< void > future = std::async( std::launch::async, print );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferred\n";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeout\n";
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!\n";
}
However this doesn't cause the detached thread to end. For this it is necessary to include a flag on startup, so the detached thread can cleanup and exit savely on its own.
void run(const std::atomic_bool& cancelled)
{
int a;
for (int i = 0; i < 2000; i++)
{
cout << i << endl;
if (cancelled)
return;
}
}
std::atomic_bool cancellation_token = false;
std::future< void > future = std::async( std::launch::async,
run,
std::ref(cancellation_token) );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferred\n";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeout\n";
cancellation_token = true;
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!\n";
}
I want it to be abstracted from the ones who write the processing method.
Standard C++ does not have a way to forcibly interrupt the control flow of a function from outside of that function's call graph (a function it calls can throw, but someone can't throw for them).
OS-specific thread systems have ways to terminate a thread. However, this leaves the program potentially in an undefined state, as the destructors for any stack variables have not been called. And since you didn't know where it was in that processing when you killed it, you can't effectively clean up after it. Even a C program cannot guarantee that an arbitrary function can be terminated; it would have to be one which did not dynamically allocate memory or other resources that have to be cleaned up.
You can compensate for this by coding your function very carefully. But that requires that the person who wrote that function to code it very carefully. And thus, there isn't an abstraction, since the person writing the function has to know what the rules are and is required to follow them.
So the only solution that works requires cooperation. The function must either be written in such a way that it can safely be stopped via those OS-dependent features, or it must be written to periodically check some value and stop itself.
Here are two and 3/4 approaches.
The first requires that the code you want to halt cooperates. It either polls some variable while it runs, or it calls a function periodically that could throw an exception to halt execution. boost interruptable threads follow the second model.
The second requires you to launch a new process, marshall your data over to the function, and use IPC to get the information back. If the function doesn't return in time, you kill the child process.
The third "half" involves rewriting the code in a different language, or using C++ as a scripting language. You run the code in an interpreter that does the first or second solution for you.
Now, a practical alternative (a 1/4 solution) is to make sure the function is purely functional, run it in a separate thread with a semi-reliable abort message (like the first one), and discard its return value if it takes too long. This doesn't do what you want, but is far easier.
There's a way with atomics used as semaphores but this will emit full blown memory barriers and thus decrease the performance because of the load every iteration :
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
std::atomic<bool> printFinished { false };
std::atomic<bool> shouldPrintRun { true };
void print()
{
while (shouldPrintRun.load() /* && your normal stop condition*/)
{
//work..
}
printFinished.store(true);
}
int main()
{
std::thread t(print);
std::this_thread::sleep_for(std::chrono::seconds(10));
if (!printFinished.load())
{
shouldPrintRun.store(false);
t.join();
std::cout << "help!";
}
return 0;
}
If you don't want your function that's ran on another thread to check back if it needs to stop then terminating that thread is the only option.
A possible solution is that you have to make that the lengthy function into small & short incremental function which will continue the task still every time it is call from the last time it left of. The code below which can be run in a thread will do similar job of a time slicer and can be terminated at will.
void Process()
{
bool flag = true;
while (running)
{
std::chrono::high_resolution_clock::time_point time1 = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds span(16);
while ( (std::chrono::high_resolution_clock::now() - time1 ) < span)
{
flag ? incremental_function1() : incremental_function2();
if (!running) return;
}
flag = (!flag);
}
}

Delay execution 1 second

So I am trying to program a simple tick-based game. I write in C++ on a linux machine. The code below illustrates what I'm trying to accomplish.
for (unsigned int i = 0; i < 40; ++i)
{
functioncall();
sleep(1000); // wait 1 second for the next function call
}
Well, this doesn't work. It seems that it sleeps for 40 seconds, then prints out whatever the result is from the function call.
I also tried creating a new function called delay, and it looked like this:
void delay(int seconds)
{
time_t start, current;
time(&start);
do
{
time(&current);
}
while ((current - start) < seconds);
}
Same result here. Anybody?
To reiterate on what has already been stated by others with a concrete example:
Assuming you're using std::cout for output, you should call std::cout.flush(); right before the sleep command. See this MS knowledgebase article.
sleep(n) waits for n seconds, not n microseconds.
Also, as mentioned by Bart, if you're writing to stdout, you should flush the stream after each write - otherwise, you won't see anything until the buffer is flushed.
So I am trying to program a simple tick-based game. I write in C++ on a linux machine.
if functioncall() may take a considerable time then your ticks won't be equal if you sleep the same amount of time.
You might be trying to do this:
while 1: // mainloop
functioncall()
tick() # wait for the next tick
Here tick() sleeps approximately delay - time_it_takes_for(functioncall) i.e., the longer functioncall() takes the less time tick() sleeps.
sleep() sleeps an integer number of seconds. You might need a finer time resolution. You could use clock_nanosleep() for that.
Example Clock::tick() implementation
// $ g++ *.cpp -lrt && time ./a.out
#include <iostream>
#include <stdio.h> // perror()
#include <stdlib.h> // ldiv()
#include <time.h> // clock_nanosleep()
namespace {
class Clock {
const long delay_nanoseconds;
bool running;
struct timespec time;
const clockid_t clock_id;
public:
explicit Clock(unsigned fps) : // specify frames per second
delay_nanoseconds(1e9/fps), running(false), time(),
clock_id(CLOCK_MONOTONIC) {}
void tick() {
if (clock_nanosleep(clock_id, TIMER_ABSTIME, nexttick(), 0)) {
// interrupted by a signal handler or an error
perror("clock_nanosleep");
exit(EXIT_FAILURE);
}
}
private:
struct timespec* nexttick() {
if (not running) { // initialize `time`
running = true;
if (clock_gettime(clock_id, &time)) {
//process errors
perror("clock_gettime");
exit(EXIT_FAILURE);
}
}
// increment `time`
// time += delay_nanoseconds
ldiv_t q = ldiv(time.tv_nsec + delay_nanoseconds, 1000000000);
time.tv_sec += q.quot;
time.tv_nsec = q.rem;
return &time;
}
};
}
int main() {
Clock clock(20);
char arrows[] = "\\|/-";
for (int nframe = 0; nframe < 100; ++nframe) { // mainloop
// process a single frame
std::cout << arrows[nframe % (sizeof(arrows)-1)] << '\r' << std::flush;
clock.tick(); // wait for the next tick
}
}
Note: I've used std::flush() to update the output immediately.
If you run the program it should take about 5 seconds (100 frames, 20 frames per second).
I guess on linux u have to use usleep() and it must be found in ctime
And in windows you can use delay(), sleep(), msleep()