Callbacks and the main game loop. Is it a good practice? - c++

I'm writting a game using C++. I wonder how can I optimize my game loop. For example, we have some game with the main loop looks like this:
while ( gameContinue ) {
if ( SCENE == HELP_SCENE ) {
renderHelpScene();
} else if ( SCENE == SCORE_SCENE ) {
renderScoreScene();
} else if ( SCENE == MAIN_GAME_SCENE ) {
renderMainGameScene();
} // .... and many others scenes
}
I'm thinking on how to make this code faster and lighter. I think about using callbacks so we will not need many if-cases. Something like this:
typedef void (*callback_function)(void);
callback_function renderFunc;
void renderMainGameScene() {
renderFunc = renderScoreScene(); // set to another scene if we need this
}
void renderScoreScene() {
renderFunc = renderAnyAnotherSceneWeNeedNow();
}
renderFunc = renderMainGameScene();
while ( gameContinue ) {
renderFunc();
}
What do you think about it? How do you organize your main loops?

I've personally started using multi-threading. I have a thread for object updates, a thread for objects collision and a thread for drawing. Each thread loops with a while (GetMessage()) and threads send messages from one to another.
At each cycle (frame), my main loop sends a message to each thread to:
Calculate collision for modified objects
Update objects (movement, state etc.)
Draw the updated objects
That's how I do it (at least on my GDI/GDI+ games). Not sure if the best way, but so far it works like a charm :).

Helpful patterns for this kind of problem are the State Pattern and the Strategy Pattern.
As you can see they are both similar. The Strategy pattern is a bit simpler than the State, but in exchange the State Pattern is more powerful and probably better fitted for a game engine like this. You can also easily create a stack with this for example: game start -> menu -> game run -> menu.
If the parent state of the last menu is game run, the menu would look different (e.g. "Return game" instead of "Start game" in the first menu). The states can be popped and you have a easy navigation.

Using call-backs should be fine. Just be careful not to have any cyclic dependencies in your headers. Notably it's a bad idea to include the header for your controller loop anywhere other than the .cpp for the controller loop.
As for the runtime benefits, they are very small. The if-else method will not noticeably slow down your game. Alternatively, there is also the switch statement, which is preferable to a series of if-else statements in terms of code readability.

Related

OpenGL multithreading

Ok I am trying to switch my Game Engine to multithreading. I have done the research on how to make it work to use OpenGL in multithreaded application. I have no problem with rendering or switching contexts. Let my piece of code explain the problem :) :
for (it = (*mIt).Renderables.begin(); it != (*mIt).Renderables.end(); it++)
{
//Set State Modeling matrix
CORE_RENDERER->state.ModelMatrix = (*it).matrix;
CORE_RENDERER->state.ActiveSubmesh = (*it).submesh;
//Internal Model Uniforms
THREAD_POOL->service.post([&]
{
for (unsigned int i = 0; i < CORE_RENDERER->state.ActiveShaderProgram->InternalModelUniforms.size(); i++)
{
CORE_RENDERER->state.ActiveShaderProgram->InternalModelUniforms[i]->Set( CORE_RENDERER->state.ModelMatrix);
}
CORE_RENDERER->state.ActiveSubmesh->_Render();
});
//Sleep(10);
}
I'll quickly explain what are the elements in the code to make my problem more clear. Renderables is a simple std::vector of elements with _Render() function which works perfectly. CORE_RENDERER->state is a struct holding information about current render state such as current material properties as well as current submesh ModelMatrix. So Matrix and Submesh are stored to state struct (I KNOW THIS IS SLOW, I'll probably change that in time :) ) The next piece of code is sent to THREAD_POOL->service which is actually boost::asio::io_service and has only one thread so it acts like a queue of rendering commands. The idea is that the main thread provides information about what to render and do frustum culling and other tests while an auxilary thread does actual rendering. This works fine, except there is a slight problem:
The code that is sent to thread pool starts to execute, but before all InternalModelUniforms are set and submesh is rendered the next iteration of Renderables is executed and both ModelMatrix and ActiveSubmesh are changed. The program doesn't crash but both informations change and some meshes are rendered some matrices are right others not which results in flickering image. Objects apear on frame and the next frame they are gone. The problem is only fixed if I enable that Sleep(10) function which makes sure that the code is executed before next iteration which obviously kills the idea of gaining preformance. What is the best possible solution for this? How can I send commands to the queue each with unique built in data? Maybe I need to implement my own queue for commands and a single thread without io_service?
I will continue my research as I know there is a way. The idea is right cause I get preformance boost as not a single if/else statement is processed by the rendering thread :) Any help or tips will really help!
Thanks!
Update:
After struggling for few nights I have created a very primitive model of communication between main thread and an Aux Thread. I created a class that represents a base command to be executed by aux thread:
class _ThreadCommand
{
public:
_ThreadCommand() {}
~_ThreadCommand() {}
virtual void _Execute() = 0;
virtual _ThreadCommand* Clone() = 0;
};
These commands that are childs of this class have _Execute() function to do whatever operation needs to be done. The main thread upon rendering fills a boost::ptr_vector of these commands While aux thread keeps on checking if there are any commands to process. When commands are found it copies entire vector to it's own vector inside _AuxThread and clears the original one. Commands are then executed by calling _Execute functions on each:
void _AuxThread()
{
//List of Thread commands
boost::ptr_vector<_ThreadCommand> _cmd;
//Infinitive loop
while(CORE_ENGINE->isRunning())
{
boost::lock_guard<boost::mutex> _lock(_auxMutex);
if (CORE_ENGINE->_ThreadCommands.size() > 0)
{
boost::lock_guard<boost::mutex> _auxLock(_cmdMutex);
for (unsigned int i = 0; i < CORE_ENGINE->_ThreadCommands.size(); i++)
{
_cmd.push_back(CORE_ENGINE->_ThreadCommands[i].Clone());
}
//Clear commands
CORE_ENGINE->_ThreadCommands.clear();
//Execute Commands
for (unsigned int i = 0; i < _cmd.size(); i++)
{
//Execute
_cmd[i]._Execute();
}
//Empty _cmd
_cmd.clear();
}
}
//Notify main thread that we have finished
CORE_ENGINE->_ShutdownCondition->notify_one();
}
I know that this is a really bad way to do it. Preformance is quite slower which I'm quite sure is because of all the copying and mutex locks. But at least the renderer works. You can get the idea of what I want to achieve but as I said I am very new to multithreading. What is the best solution for this scenario? Should I return back to ThreadPool system with asio::io_service? How can I feed commands to AuxThread with all values that must be sent to renderer to preform tasks in correct way?
First, a warning. Your "slight problem" is not slight at all. It is race condition, which is undefined behavior in C++, which, in turn, implies that anything could happen, including:
Everything renders fine
Image flickers
Nothing renders at all
It crashes on the last Saturday of every month. Or working fine on your computer and crashing on everyone's else.
Seriously, do not ever rely on UB, especially when writing library/framework/game engine.
Now about your question.
Lets leave aside any practical benefits of your approach and fix it first.
Actually, OpenGL implementation uses something very similar under the hood. Commands are executed asynchronously by the driver thread. I recommend you to read about their implementation to get some ideas on how to improve your design.
What you need to do, is to somehow "capture" the state at the time you post a rendering command. Simplest possible thing - copy the CORE_RENDERER->state into closure and use this copy to do the rendering. If state is large enough, it can be costly, though.
Alternative solution (and OpenGL goes that way) is to make every change in the state a command also, so
CORE_RENDERER->state.ModelMatrix = (*it).matrix;
CORE_RENDERER->state.ActiveSubmesh = (*it).submesh;
translates into
Matrix matrix = (*it).matrix;
Submesh submesh = (*it).submesh;
THREAD_POOL->service.post([&,matrix,submesh]{
CORE_RENDERER->state.ModelMatrix = matrix;
CORE_RENDERER->state.ActiveSubmesh = submesh;
});
Notice, however, that now you can't simply read CORE_RENDERER->state.ModelMatrix from your main thread, as it is changing in a different thread. You must first ensure that command queue is empty.

Qt - GUI freezing

I wrote in C++ a solver for the 8-puzzle game, and now I'm trying to use Qt to give it a GUI.
Basically I have an underlying object of type "Board" which represents the board of the puzzle, and I have organized the GUI as a grid of QPushButton. Then I have a method updateUI which associates to every button the correct text, based on the Board. Something like
for(int i=0; i<Board::MATRIX_DIM * Board::MATRIX_DIM; i++)
{
m_buttons[i]->setText(m_values[i]);
}
In another method (solveGUI) I have
void MainWindow::solveGUI()
{
m_game->solve();
int solutionDepth = m_game->getSolutionDepth();
Move *solutionMoves = m_game->getSolutionMoves();
for(int i=0; i<solutionDepth; i++)
{
Move m = solutionMoves[i];
m_board.performMove(m); /* perform the move on the Board object */
updateUI(); /* should update the GUI so that it represents the Board */
Sleep(1000);
}
}
where the first line (m_game->solve) takes some time. Then I obtain a list of the moves performed, in solutionMoves, and what I would like to do is showing this moves on the board, with some delay between a move and the next one. This method is called by my main, which looks like this:
QApplication app(argc, argv);
MainWindow w;
w.show();
w.solveGUI();
return app.exec();
The result is that the GUI hangs and, after some time, it displays only the solution, completely skipping the moves.
What am I missing? Thank you!
P.S. I don't think I need a different Thread for the solver because I want the solver to run before the solution is displayed. Is it right?
It's app.exec() that actually runs the main loop which handles all events, including displaying GUI. If you want to call solve() before that, it's OK, but if you want to actually display and update GUI before exec(), it's wrong. I'm not sure if it's totally impossible, but it's definitely not the right way to do it.
There are two ways around it. The more canonical way is to redesign a program using a QTimer. Then everything will be smooth and responsive. But that can be tedious sometimes. In your case it should be quite easy, though. Just save the results somewhere, and call a slot using a QTimer object every 1000 seconds - it will have the same effect as your Sleep(), but will keep everything responsive.
The other solution is to call your solveGUI() method after exec() starts its job. It can be done, for example, using QTimer::singleShot():
QTimer::singleShot(0, &w, SLOT(showGUI()));
return app.exec();
Then, before each Sleep(), you should call QApplication::processEvents(), which basically allows you to temporary yield control, processing all pending events, including GUI updates. This approach is somewhat easier, but it's inferior since the GUI still freezes at each Sleep(). For example, if the user wants to exit the application, or if the window is needed to be repainted, it will cause uncomfortable GUI lags.
You're stalling the main thread (which also does the event processing) and rendering it uncapable of responding to keyboard/mouse/window messages.
You should use an asynchronous timer operation instead of the sleep function: use a QTimer to delay showing the next solution and avoid messages being left unanswered for too long.
There is a nice article of methods to keep the GUI responsive during processing loops. if it's not a complicated case I think, just insert QCoreApplication::processEvents(); inside the long processing loops.
try the following:
void MainWindow::Wait(int interval ) {
QTime timer = new QTime;
timer.restart();
while(timer.elapsed() < interval) {
QApplication::processEvents();
}
}
...
for(...) {
//wait 1 second (1000 milliseconds) between each loop run at first
Wait(1000);
...
}
...
not tested yet - but should work (maybe there is some cpu load)!

C++ parallel loops

I'm making a console game called alien spaceships as a homework. It should look something like this http://img74.imageshack.us/img74/8362/alieninvadersfdcl192720mu1.jpg .
So far so good I ain't allowed to use classes nor objects => only functions and arrays.
I have one while loop that checks the buttons I press on the keyboard and according to the button applies some functions.
The problem comes when I try to shoot a missle because it's done with a "for" loop and when I shoot I can't move. Can someone give me an idea how the model is supposed to look like and how can I make something like this work. I don't think it's needed to post my code, but if you want I'll post it.
I assume that you're not willing to play with multiple threads. It is not mandatory for a simple game like this and would add a bit of complexity.
So generic loop for monothreaded game is:
state new_state = createInitialState();
do
{
input = readInput(); // non blocking !
new_state = modifyState(input, new_state);
updateScreen(new_state);
}
while (!exitCondition(input));
None of these functions should loop for long.
In your case, the missile position should be updated in modifyState taking into account the time since the last modifyState.
I assume you use a matrix to store all the data, and periodically you print the content of the matrix (that's how you create a console game).
So, your code should look something like this:
render()
{
update_position(x,y);
if(missile_fired)
update_missile_position();
}
main()
{
for(;;)
{
read_input(&x,&y);
render();
draw_image();
}
}

Is it bad practice to have nested render loops?

I'm porting a game from Ruby to C++. There is a main render loop that updates and draw the content. Now let's say that during the game, you want to select an item another screen. The way it's done in the original code is to do Item item = getItemFromMenu(); getItemFromMenu is a function that will open the menu and do have its own update/render loop, which mean that during the whole time the player has this other screen open, you are in a nested render loop. I feel like this is a bad method but I'm not sure why. On the other hand it's very handy because I can open the menu with just 1 function call and so the code is localized.
Any idea if this is a bad design or not?
I hesitated to post it on gamedev, but since this is mostly a design issue I posted it here
edit : some pseudo-code to give you an idea:
The usual loop in the main part of the code:
while(open) {
UpdateGame();
DrawGame();
}
now inside UpdateGame() i would do something like:
if(keyPressed == "I") {
Item& item = getItemFromInventory();
}
And getItemFromInventory():
while(true) {
UpdateInventory();
if(item_selected) return item;
DrawInventory();
}
A good way to handle something like this would be to replace the DrawInventory() call with something like InvalidateInventory(), which will mark the current graphical state of the inventory as outdated and request it to be redrawn during the next frame rendering (which'll happen pretty soon after when the main loop gets to DrawGame()).
This way, you can keep running through the main loop, but the only parts of the screen that get looked at for redrawing are the ones that have been invalidated, and during normal gameplay you can invalidate your (2/3)D environment as a normal part of processing, but then inside the inventory you can always mark only inventory assets as needing to be redrawn, which minimises overhead.
The other part of your inner loop, UpdateInventory(), can be a part of UpdateGame() if you use a flag to indicate the current game state, something like:
UpdateGame()
{
switch(gameState)
{
case INVENTORY:
UpdateInventory();
break;
case MAIN:
default:
UpdateMain();
break;
}
}
If you really wanted, you could also apply this to drawing:
DrawGame()
{
switch(gameState)
{
case INVENTORY:
DrawInventory();
break;
case MAIN:
default:
DrawMain();
break;
}
}
But I think drawing should be encapsulated and you should tell it which part of the screen, rather than which separate area of the game, needs to be drawn.
What you've created with your nested render loop is functionally a state machine (as most game render loops tend to be). The problem with the nested loop is that many times you'll want to do the same sorts of things in your nested loop as your outer loop (process input, handle IO, update debug info etc).
I've found that it's better to have one render loop and use a finite state machine (FSM) to represent your actual states. Your states might look like:
Main menu state
Options menu state
Inventory state
World view state
You hook up transitions between states to move between them. The player clicking a button might trigger the transition which could play an animation or otherwise, then move to the new state. With a FSM your loop might look like:
while (!LeaveGame()) {
input = GetInput();
timeInfo = GetTimeInfo();
StateMachine.UpdateCurrentState(input, timeInfo);
StateMachine.Draw();
}
A full FSM can be a bit heavyweight for a small game so you can try a simplified state machine using a stack of game states. Every time the user does an action to transition to a new state you push the state on a stack. Likewise when they leave a state you pop it off. Only the top of the stack typically receives input and the other items on the stack may/may not draw (depending on your preference). This is a common approach and has some upsides and downsides depending on who you talk to.
The simplest option of all is to just throw a switch statement in to pick which render function to use (similar to darvids0n's answer). If you're writing an arcade clone or a small puzzle game that would do just fine.

How to implement simple tick-based engine in c++?

I'm writing a text game and I need a simple combat system, like in MUDs, you issue commands, and once in a while "tick" happens, when all those commands execute, player and monsters deal damage, all kinds of different stuff happens. How do I implement that concept?
I thought about making a variable that holds last tick time, and a function that just puts events on stack and when that time is (time +x) executes them all simutaniously. Is there any easier or cleaner variant to do that?
What would be possible syntax for that?
double lastTickTime;
double currentTime;
void eventsPile(int event, int target)
{
// how do i implement stack of events? And send them to execute() when time is up?
}
void execute(int event, int target)
{
if ((currentTime - lastTickTime) == 2)
{
eventsHandler(event, target);
}
else
{ // How do I put events on stack?
}
}
The problem with simple action stack is that the order of actions will probably be time based - whoever types fastest will strike a first hit. You should probably introduce priorities in the stack, so that for instance all global events trigger first, then creatures' action events, but those action events are ordered by some attribute like agility, or level. If a creature has higher agility then that it gets the first hit.
From what I've seen, most such engines are event, rather than time, based. with a new tick being triggered some interval after the last tick ended. (thus mostly avoiding the issue of ticks taking longer than the interval)
This also simplifies implementation; you simply have a game loop that triggers a tick event, then sleeps/yields for the required interval. Which is trivial.
It can further be simplified by modeling the world as a tree, where each element manages propagating events (such as ticks) to their children. so long as you avoid / manage 'loops', this works well (I've done it).
This effectively reduces the tick system to something like this (psudocode):
while (isRunning) {
world->tick();
sleep(interval);
}
In most cases, theres little need to get much fancier than adjusting for the length of the previous duration.
Any individual entities actions would be part of their own action queue, and handled during their own "tick" events.
Usually user commands would be split into "ingame" and "meta" commands, anything ingame would merely amend their character's action queue, to be processed in their next tick, as per normal for any other entity.
Simple round-based combat follows naturally from this foundation. realtime can be modeled with a finer division of ticks, with optional 'time-pooling'.
Use a timer executing every x ms (whereas x is your ticktime), execute any actions put on the stack in that method.