So I'm stuck with a little c++ program. I use "codeblocks" in a w7 environment.
I made a function which shows a ASCII map and a marker. A second function updates the markers position on that map.
I would like to know how I could make my main structure so that the marker gets updated and the map showed, and this repeated at a certain time rate. Which functions can I use to make this happen. What strategy should I follow?
every x times/second DO { showmap(); updatePosition();}
I am a c++ beginner and I hope you can help!
A loop with usleep
unsigned XtimesPerSecond = 5; // for example
unsigned long long microseconds = 1000000 / XtimesPerSecond;
do
{
showmap();
updatePosition();
usleep(microseconds);
} while(true);
Depending on what else your program needs to be doing, you may need to employ event driven programming. If updating that marker is the only thing it will be doing, a simple while loop with a sleep will suffice, as demonstrated in other answers.
In order to do event driven programming you generally need an event loop - which is a function that you call in main, which waits for events and dispatches them. Most event loops will provide timer events - where, basically, you ask the event loop to call function X after a given time interval elapses.
You most likely don't want to write your own event loop. There are many choices for an event loop, depending on many things like programming language and required portability.
Some examples of event loops:
the Qt event loop,
the GLib event loop,
the Windows event loop, and many more...
Seems that you want to implement an infinite loop like games engine does.
Try to do this:
while (true)
{
showmap();
updatePosition();
sleep(1);
}
Related
In my little project, I've decided to create a game that updates a counter of the user's experience points every second, as well as printing a menu and allowing the user to navigate said menu simultaneously. The code to update the user's experience is as follows, and it works perfectly fine standalone.
double timerX = GetTickCount();
double timerY = GetTickCount();
while(true)
{
double timerZ = GetTickCount() - timerX;
double timerA = GetTickCount() - timerY;
if(timerZ >= 1000) {
userExperience = userExperience + 1;
timerX = GetTickCount();
}
if(timerA >= 1100) {
system("CLS");
refreshExperience();
timerY = GetTickCount();
}
The function 'refreshExperience()' simply prints the 'userExperience' variable onto the screen using 'cout'.
At the same time as this, my program should be able to display the main menu GUI and ask for input from the user. However, I do not want the asking of input to halt the program, especially the money updater, as it is paramount that that is updated constantly. I have attempted to use multithreading by creating a thread for the 'refreshExperience' function, and also creating a thread for asking for input, but the problem still remained - the money would only update if the user was continually inputting (pressing keys). If he was not, the money would stay the same.
Any help would be very much appreciated.
Getting input from the user with no discernible break in program execution is only possible in GUI programming. When working in the console, every request for user input will block for the obvious reason that the program has to wait to actually have the necessary data before proceeding.
This is also why you should initialize variables before declaring them; if you don't, stack-allocated variables will contain random (to you) data and the program will not function as intended. Conceptually, this is the same problem the console has, except it doesn't have the luxury of free will and can't simply choose to skip the wait.
Conceptually, programs that have a user interface work by operating with a loop. Every event that occurs, from a mouse movement to a button click, triggers an event in the Window procedure. In the Win32 API, it's just a switch statement that checks for each possible event against what actually happened. When there's a match, the system triggers that event handler.
It should be noted that it only seems like there is no lag, because usually graphical window procedures are fast enough to seem to respond instantaneously. In reality, any action on the window triggers a calculation by the computer to determine what part of the window was blocked and must be redrawn, as it is now called "invalid."
Lastly, I would highly recommend a different method for the scoreboard update. I know it's just a contrived example for you to experiment with, but that means it's just as good if not better for trying out some design patterns, namely the observer pattern. Rather than the program checking for input every possible clock cycle it can is just a waste. When you have a situation like this, it's common to use callback functions, which in C are just function pointers that you pass along. That way you don't have to check to find out when the event is triggered, you can just have the event invoke the function that you passed in as a parameter. This is how Node.js works, by the way, and how it seems to do so much at once despite being single-threaded.
If you've heard anything about Reactive programming lately -it's been getting talked about just about everywhere in the C# community these past few months- this is what it's talking about, and the reason I bring it up is because this is one of the more common, though trivial, examples of a textbook reactive programming scenario.
If you've ever used XNA game studio 4 you are familiar with the update method. By default the code within is processed at 60 times per second. I have been struggling to recreate such an effect in c++.
I would like to create a method where it will only process the code x amount of times per second. Every way I've tried it processes all at once, as loops do. I've tried for loops, while, goto, and everything processes all at once.
If anyone could please tell me how and if I can achieve such a thing in c++ it would be much appreciated.
With your current level of knowledge this is as specific as I can get:
You can't do what you want with loops, fors, ifs and gotos, because we are no longer in the MS-DOS era.
You also can't have code running at precisely 60 frames per second.
On Windows a system application runs within something called an "event loop".
Typically, from within the event loop, most GUI frameworks call the "onIdle" event, which happens when an application is doing nothing.
You call update from within the onIdle event.
Your onIdle() function will look like this:
void onIdle(){
currentFrameTime = getCurrentFrameTime();
if ((currentFrameTime - lastFrameTime) < minUpdateDelay){
sleepForSmallAmountOfTime();//using Sleep or anything.
//Delay should be much smaller than minUPdateDelay.
//Doing this will reduce CPU load.
return;
}
update(currentFrameTime - lastFrameTime);
lastFrameTime = currentFrameTime;
}
You will need to write your own update function, your update function should take amount of time passed since last frame, and you need to write a getFrameTime() function using either GetTickCount, QueryPerformanceCounter, or some similar function.
Alternatively you could use system timers, but that is a bad idea compared to onIdle() event - if your app runs too slowly.
In short, there's a long road ahead of you.
You need to learn some (preferably cross-platform) GUI framework, learn how to create a window, the concept of an event loop (can't do anything without it today), and then write your own "update()" and get a basic idea of multithreading programming and system events.
Good luck.
As you are familiar with XNA then i assume you also are familiar with "input" and "draw". What you could do is assign independant threads to these 3 functions and have a timer to see if its time to run a thread.
Eg the input would probably trigger draw, and both draw and input would trigger the update method.
-Another way to handle this is my messages events. If youre using Windows then look into Windows messages loop. This will make your input, update and draw event easier by executing on events triggered by the OS.
I'm writing a check point. I'm checking every time I run a loop. I think this will waste a lot of CPU time. I wonder how to check with the system time every 10 seconds?
time_t start = clock();
while(forever)
{
if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit)
{
break;
}
}
The very short answer is that this is very difficult, if you're a novice programmer.
Now a few possiblilites:
Sleep for ten seconds. That means your program is basically pointless.
Use alarm() and signal handlers. This is difficult to get right, because you mustn't do anything fancy inside the signal handler.
Use a timerfd and integrate timing logic into your I/O loop.
Set up a dedicated thread for the timer (which can then sleep); this is exceedingly difficult because you need to think about synchronising all shared data access.
The point to take home here is that your problem doesn't have a simple solution. You need to integrate the timing logic deeply into your already existing program flow. This flow should be some sort of "main loop" (e.g. an I/O multiplexing loop like epoll_wait or select), possibly multi-threaded, and that loop should pick up the fact that the timer has fired.
It's not that easy.
Here's a tangent, possibly instructive. There are basically two kinds of computer program (apart from all the other kinds):
One kind is programs that perform one specific task, as efficiently as possible, and are then done. This is for example something like "generate an SSL key pair", or "find all lines in a file that match X". Those are the sort of programs that are easy to write and understand as far as the program flow is concerned.
The other kind is programs that interact with the user. Those programs stay up indefinitely and respond to user input. (Basically any kind of UI or game, but also a web server.) From a control flow perspective, these programs spend the vast majority of their time doing... nothing. They're just idle waiting for user input. So when you think about how to program this, how do you make a program do nothing? This is the heart of the "main loop": It's a loop that tells the OS to keep the process asleep until something interesting happens, then processes the interesting event, and then goes back to sleep.
It isn't until you understand how to do nothing that you'll be able to design programs of the second kind.
If you need precision, you can place a call to select() with null parameters but with a delay. This is accurate to the millisecond.
struct timeval timeout= {10, 0};
select(1,NULL,NULL,NULL, &timeout);
If you don't, just use sleep():
sleep(10);
Just add a call to sleep to yield CPU time to the system:
time_t start = clock();
while(forever)
{
if(difftime(clock(),start)/CLOCKS_PER_SEC >=timeLimit)
{
break;
}
sleep(1); // <<< put process to sleep for 1s
}
You can use a event loop in your program and schedule timer to do a callback. For example you can use libev to make an event loop and add timer.
ev_timer_init (timer, callback, 0., 5.);
ev_timer_again (loop, timer);
...
timer->again = 17.;
ev_timer_again (loop, timer);
...
timer->again = 10.;
ev_timer_again (loop, timer);
If you code in a specific toolkit you can use other event loops, gtk, qt, glib has own event loops so you can use them.
The simplest approach (in a single threaded environment), would be to sleep for some time and repeatedly check if the total waiting time has expired.
int sleepPeriodMs = 500;
time_t start = clock();
while(forever)
{
while(difftime(clock(),start)/CLOCKS_PER_SEC <timeLimit) // NOTE: Change of logic here!
{
sleep(sleepPeriod);
}
}
Please note, that sleep() is not very accurate. If you need higher accuracy timing (i.e. better than 10ms of resolution) you might need to dig deeper. Also, with C++11 there is the <chrono> header that offers a lot more of functionality.
using namespace std::chrono;
int sleepPeriodMs = 500;
time_t start = clock();
while(forever)
{
auto start = system_clock()::now()
// do some stuff that takes between [0..10[ seconds
std::this_thread::sleep_until(start+seconds(10));
}
I am currently working on writing a simple game in order to learn how to use SFML in C++. So far things have been going smoothly and I have a basic understanding of most things to do with SFML. The problem I have run into is finding an efficient way to and time based events.
The game I'm working on is a very simple space invaders esque game that has waves of enemies come in at predefined times during the level. As of now I have an event class that holds and controls what is supposed to happen with each called event in order to allow me to reuse simple events multiple times. As of now I trigger these events by looping utilizing an SFML cloock and with each iteration of the game loop running through a vector of all of the events for the current level and comparing the elapsed time on the clock with the specified time for the event to be called. The problem is that I have to check an entire vector of events every game loop iteration and if the event list get long enough I am worried it will begin to have an impact on the performance of the game.
I had an idea to give each event a simple numerical Id for its position in the timeline and simply store which event is supposed to run next that way I would only have to check the time of one event per loop iteration, and while this will work fairly well I think, I was curious if a more efficient method that didn't require a check every loop iteration was possible? I looked a bit into event driven programming but could not find much specifically related to time based events.
Thus I was wondering if anyone has had any experience with timelines or time based event triggering and would have any tips or resources that I could look at to figure out a more efficient idea? Any help would be great, thanks!
The method you suggest is just one comparison each time through the game loop. It doesn't get any faster than that.
To allow multiple events to fire at the same instant, use a multimap, where keys are event times, and values are the events themselves. The multimap will then be sorted by time.
Each time through the game loop, do something like this (pseudocode):
now = getCurrentTime()
while not events.isEmpty() and events.firstElement().key() < now:
e = events.firstElement().value
e.execute()
events.removeFirst()
Sort your vector based on the events' times and then just store how far you've gotten through the vector so far. Each loop then you'll advance that position until the next event shouldn't occur yet, and fire off the events you just iterated over.
std::vector<Event> time_line;
size_t time_line_position;
void fire_new_events(Time t) {
size_t new_time_line_position = time_line_position;
while(new_time_line_position < time_line.size()
&& time_line[new_time_line_position].time <= t)
++new_time_line_position;
fire_events(time_line.begin() + time_line_position,
time_line.begin() + new_time_line_position);
time_line_position = new_time_line_position;
}
I'm using the GCC compiler and C++ and I want to make a timer that triggers an interruption when the countdown is 0.
Any Ideas? Thanks in advance.
EDIT
Thanks to Adam, I know how to do it.
Now. What about multiple timers running in parallel?
Actually, these timers are for something very basic. In NCURSES, I have a list of things. When I press a key, one of the things will change colors for 5 seconds. If I press another key, another thing in the list will do the same. It's like emphasize strings depending on the user input. Is there a simpler way to do that?
An easy, portable way to implement an interrupt timer is using Boost.ASIO. Specifically, the boost::asio::deadline_timer class allows you to specify a time duration and an interrupt handler which will be executed asynchronously when the timer runs out.
See here for a quick tutorial and demonstration.
One way to do it is to use the alarm(2) system call to send a SIGALRM to your process when the timer runs out:
void sigalrm_handler(int sig)
{
// This gets called when the timer runs out. Try not to do too much here;
// the recommended practice is to set a flag (of type sig_atomic_t), and have
// code elsewhere check that flag (e.g. in the main loop of your program)
}
...
signal(SIGALRM, &sigalrm_handler); // set a signal handler
alarm(10); // set an alarm for 10 seconds from now
Take careful note of the cautions in the man page of alarm:
alarm() and setitimer() share the same timer; calls to one will interfere with use of the other.
sleep() may be implemented using SIGALRM; mixing calls to alarm() and sleep() is a bad idea.
Scheduling delays can, as ever, cause the execution of the process to be delayed by an arbitrary amount of time.