Correct Message Loop

Started by
7 comments, last by marius1930 14 years, 10 months ago
Hi everyone, What is the correct way to write a message loop? Every tutorial or book that I have looked for has used:

MSG msg;

while (true)
{
	if (PeekMessage(...))
	{
		if (msg.message == WM_QUIT)
			break;
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	else
		render();
}

Even the DirectX SDK does it this way, but in a different post on these forums, I was told to use:

MSG msg;

while (true)
{
	while (PeekMessage(...))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

        if (msg.message == WM_QUIT)
	        break;

	render();
}


So, which way is the correct way and why?

Any help would be appreciated.
Advertisement
From what I was told if you just do if(peekmessage) it will only check for one message where as if your do while(peekmessage) it will eat all the messages in the queue, eventually you will get so many messages it will lock up your app...

now mind you this could be incorrect, but I have moved to the second one in my apps (I never did experience said lock ups though)
I used an if() in my last game, and while the game never froze, I did have a huge lag with input. The lower my FPS the bigger the lag. Took me forever to figure out why, and that's when I tried a while() loop. Apparently Windows was doing some input buffering for me, and each input command was only processed one at a time. The while() loop made it process them all before it continued and running at 10 FPS in debug still didn't lag the input.

If you're using DirectInput or SDL then it probably won't even matter. If you have an if() and don't notice any issues then I wouldn't worry about it.
The first version only processes one message and then processes the (time intensive) render function.

Try dragging your window around for a few seconds and you'll notice grand lag. This happens when there's more than one new message per frame in your queue.

Always go for the while version.


It'd be actually quite nice to play nice with other apps. Meaning, have a second loop if your game is not active (follow WM_ACTIVATE_APP). You don't need to gobble all the CPU if the user is not focussing on your window. It's probably enough to either enter a pause mode or only update the window if WM_PAINT is received.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Quote:Original post by Endurion
The first version only processes one message and then processes the (time intensive) render function.


Actually, they're both technically the same, except the first listing will break as soon as a WM_QUIT message is processed while the second will process all messages first.

The first listing reads While true, if there is a message to process, then process it, otherwise render one frame. Continue looping, which basically processes all the messages before rendering a frame.
The second reads While true, process all the messages, render one frame, and then continue looping. The second listing is a little more clearer than the first, though.

Holland, did you use an if ( message ) process(); else render();? Or did you if ( message ) process(); render();?
EDIT: Last poster beat me to it.
-- gekko
Duh, _fastcall is right of course. That's what you get from only skimming code.

Solidifies the point though, using while directly makes the intent clearer.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Ok, thanks guys!
Quote:Original post by yewbie
now mind you this could be incorrect, but I have moved to the second one in my apps (I never did experience said lock ups though)


If he were processing only one message per frame, then a lockup would in inevitable.

At least in any heavy input-dependent game, like an FPS.


of course no big deal, since he processes more message per frame either way.

This topic is closed to new replies.

Advertisement