Sign in to follow this  
nullsquared

[.net] C# and GUI threads

Recommended Posts

I'm confused about how to do a proper C# game loop. Once you create a Form, all the events are called automatically from a separate thread, as far as I can tell. So, where does my game loop go? If I put it in the main thread, then I might have issues when handling GUI events while my game loop is processing stuff. What is Application.DoEvents() used for considering it all happens automatically? (Just straight up C# and .NET stuff, no XNA or anything)

Share this post


Link to post
Share on other sites
Quote:
Original post by ragnarsun
Look at Tom Miller Loop


I've seen that. I'm just trying to find a cleaner, completely .NET based approach. I mean, come on, C# and .NET are so amazing that you can't do a proper game loop without invoking native win32 functions?

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
Quote:
Original post by ragnarsun
Look at Tom Miller Loop


I've seen that. I'm just trying to find a cleaner, completely .NET based approach. I mean, come on, C# and .NET are so amazing that you can't do a proper game loop without invoking native win32 functions?


Not really. All other approaches allocate memory, use up too much CPU time or are wildly inaccurate from a timing-perspective.

The only other approach is to spawn a different thread and do your work on that. Do note that you won't be able to access the main Form directly (you'll have to use BeginInvoke and the like), but this approach works and is "clean".

On the other hand, Tom Miller's loop is simpler. Don't let the p/invoke scare you off, I've been using this approach successfully for years on all all major operating systems (Windows, Linux, OSX, porting the loop is straightforward).

Share this post


Link to post
Share on other sites
Quote:
Original post by Fiddler
On the other hand, Tom Miller's loop is simpler. Don't let the p/invoke scare you off, I've been using this approach successfully for years on all all major operating systems (Windows, Linux, OSX, porting the loop is straightforward).


Okay, guess I'll just go with that then. It's not scary, I just thought that .NET would have something just as good built in [grin].

And out of curiousity, what do you mean you've been using this approach on several OS's? I thought the whole PeekMessage() idea would only work on Windows?

Share this post


Link to post
Share on other sites
I've done this. Don't use the Timer component. Instead use a Thread timer.

See usage for a .Net render surface here and create your own OnPaint event.

private System.Threading.Timer frameTimer;
private System.Threading.TimerCallback frameTimerCallback;
private int frameNumber = 0; //what number frame are we currently on? 0..60
private const int frameRate = 60;

public RenderSurface() //constructor
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
public void Begin()
{
this.frameTimerCallback = new System.Threading.TimerCallback(frameCallBack);
this.frameTimer = new System.Threading.Timer(this.frameTimerCallback);
this.frameTimer.Change(0, 1000 / frameRate); //start immediatly.
}
private void frameCallBack(object obj)
{
this.frameNumber++;
if (frameNumber >= frameRate)
this.frameNumber = 0;
this.Invalidate(); //calls Paint which triggers a render
}




Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
Quote:
Original post by Fiddler
On the other hand, Tom Miller's loop is simpler. Don't let the p/invoke scare you off, I've been using this approach successfully for years on all all major operating systems (Windows, Linux, OSX, porting the loop is straightforward).


Okay, guess I'll just go with that then. It's not scary, I just thought that .NET would have something just as good built in [grin].

And out of curiousity, what do you mean you've been using this approach on several OS's? I thought the whole PeekMessage() idea would only work on Windows?


Yes, but every OS provides a way to query for pending messages. For example, on Linux (and everything else that has an X server), you can use XPending. The implementation is slightly more complicated, because you need to gain access to the Form's private display connection but it's not too bad. For comparison: Windows implementation vs Linux implementation (you only need lines 35-36, 81-86 and 111-114 of the Linux one, the rest have to do with OpenGL initialization and are not relevant here).

Usage looks like this:

Application.Idle += (sender, e) =>
{
while (control.IsIdle)
{
// update and render
}
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Fiddler
Quote:
Original post by nullsquared
Quote:
Original post by Fiddler
On the other hand, Tom Miller's loop is simpler. Don't let the p/invoke scare you off, I've been using this approach successfully for years on all all major operating systems (Windows, Linux, OSX, porting the loop is straightforward).


Okay, guess I'll just go with that then. It's not scary, I just thought that .NET would have something just as good built in [grin].

And out of curiousity, what do you mean you've been using this approach on several OS's? I thought the whole PeekMessage() idea would only work on Windows?


Yes, but every OS provides a way to query for pending messages. For example, on Linux (and everything else that has an X server), you can use XPending. The implementation is slightly more complicated, because you need to gain access to the Form's private display connection but it's not too bad. For comparison: Windows implementation vs Linux implementation (you only need lines 35-36, 81-86 and 111-114 of the Linux one, the rest have to do with OpenGL initialization and are not relevant here).

Usage looks like this:
*** Source Snippet Removed ***


Very cool, thanks for the information!

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