• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Of input loops and games
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

  • Follow-Ups:
    • Re: Of input loops and games
      • From: Hari Seldon <email@hidden>
References: 
 >Of input loops and games (From: Hari Seldon <email@hidden>)

  • Prev by Date: NSPanel, DO & applications vs. bundles
  • Next by Date: Re: [NSUndoManager undoMenuItemTitle]
  • Previous by thread: Of input loops and games
  • Next by thread: Re: Of input loops and games
  • Index(es):
    • Date
    • Thread