Skip to main content
GameDev.net gamedev.net
🔒 Locked

[MDX] Game Loops

Started by campbellec Apr 12, 2006 at 12:11 AM 2 replies 2.2k views
Original Post
campbellec
campbellec
Can anyone offer an explanation on the difference between the different game loops such as OnPaint vs OnIdle, or link to an article that does? Thanks.
remigius
remigius
The OnPaint/Invalidate one is a bit of a dirty way to do this, since you're stuck with the dreaded DoEvents() call that reportedly isn't too efficient, both in terms of performance as well as memory allocation. The recommended render loop can be found in the MDX SampleFramework and this is indeed the OnIdle/AppStillIdle loop.

In Tom Miller's blog you'll find a better explaination with code, but I'll try to explain the basic steps here.


  1. 'Import' the PeekMessage function using PInvoke. This will allow you to check if there are Windows messages waiting to be processed by your application. If there aren't any, your application is being idle and you can just continue rendering. This makes for the AppStillIdle bool in Tom's code.

  2. Hook the OnIdle event of your application. When the application is done handling messages, it will fire this event once (and only once, until new messages have been handled). You can use this to start your rendering loop.

  3. Keep running your rendering loop for as long as the application remains idle, which can be checked using the AppStillIdle bool. When the app needs to process user input, it will break out of this loop, handle the messages and fire the OnIdle event, which will start rendering again.


To quote Tom:
Quote:
Simple, elegant, effective. No extra allocations, no extra collections, it just works
Armadon
Armadon
Fantastic reply remigus,
Let me extend the thread by adding the message loop implementation that i've been using

In a NativeMethods class
internal sealed class NativeMethods{	[StructLayout(LayoutKind.Sequential)]	public struct Message	{		public IntPtr hWnd;		public IntPtr msg;		public IntPtr wParam;		public IntPtr lParam;		public uint time;		public System.Drawing.Point p;	}	[System.Security.SuppressUnmanagedCodeSecurity]	[DllImport("User32.dll", CharSet = CharSet.Auto)]	public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);}

This class exposes the PeekMessage method which you can use to check whether the app is idle or not and as long as it is, you can do your rendering and updating.

After creating a new class and inheriting from System.Windows.Form, You can create a property that basically states whether the app is idle or not and then you can hook the Application's Idle event to this run method you will create

public sealed class Window: Form{	#region members	private Game game;	#endregion	#region properties	public bool AppStillIdle	{		get		{			NativeMethods.Message msg;			return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);		}	}	#endregion	#region methods	public Window(DeviceSettings settings)	{		game= new game(settings, this);		Application.Idle += new EventHandler(OnApplicationIdle);	}	public void OnApplicationIdle(object sender, EventArgs e)	{		while (AppStillIdle)		{		}	}	internal void Run()	{		Application.Run(this);	}	#endregion}


Then in some other class you can just create a new window object and off you go.


I hope this helps.
Take care.
campbellec
campbellec
Thanks for both of your replies, this is exactly what I was looking for.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.