Re: Of input loops and games
Re: Of input loops and games
- Subject: Re: Of input loops and games
- From: Jack Nutting <email@hidden>
- Date: Wed, 21 Sep 2005 09:51:54 +0200
Hi Hari,
On 9/20/05, Hari Seldon <email@hidden> wrote:
> The function that's got me perplexed
> is the one that processes a user's input. It expects an int of the key
> the user pressed to be returned. The game processes the keystroke,
> updates itself, then immediately calls the "get_key_from_user"
> function again, ad infinitum.
I can see why that function gets you into trouble... It looks like
what you're doing in get_key_from_user is sort of implementing your
own little run loop. Your implementation looks OK, but I think the
problem is that your own "little run loop" is being looped through
during a single iteration of the app's "real run loop", which leads to
unknown stuff happening. This is happening because somewhere, at some
point, a method triggered by the real run loop is kicking off your
game; Your game then runs forever, and never returns to the real run
loop.
I'm not sure what's the best way around this. One idea is to run your
game in a background thread using NSThread, and use NSLocks to
synchronize with the main thread. So, for instance,
get_key_from_user, in the background thread, would simply wait on a
lock; The main run loop would continue to run as normal, and in
keyDown would make note of the key and then unlock the lock, allowing
get_key_from_user to grab the key value and return.
For starters, somewhere you'll need to start your background thread,
with something like:
[NSThread detachNewThreadSelector:@selector(startGame)
toTarget:theController withObject:nil];
Then, the other code should look something like this:
<TheView.m>
- init
{
...
// assuming NSLock *keyLock is an ivar
keyLock = [[NSLock alloc] init];
[keyLock lock];
...
}
// this is called in the main thread
- (void)keyDown:(NSEvent*)event
{
// get pressed key
NSString * keyString = [event charactersIgnoringModifiers];
[theController processKey:keyString];
[keyLock unlock];
}
<Controller.m>
// assuming we have a pointer to keyLock from the TheView instance (perhaps
// passed in when Controller is initialized) as well as a -keyLock
accessor method
// this is called in the background thread
int get_key_from_user()
{
// this blocks the thread until the main thread unlocks it
[[c_controller keyLock] lock];
return [c_controller getCurrentKeyAndClear];
}
You'd need to do something conceptually similar for drawing, since
Cocoa only allows drawing in the main thread. From your background
thread, in "draw_frame" or whatever, you'd tell your view to update in
the main thread. Fortunately NSObject provides a method that lets us
do this without the need to explicitly create a lock and wait on it:
[theView performSelectorOnMainThread:@selector(redrawGameView)
withObject:nil waitUntilDone:YES];
--
// jack
// http://www.nuthole.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden