Sign in to follow this  
Dasil

Correct Message Loop

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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();?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this