Re: Of input loops and games
Re: Of input loops and games
- Subject: Re: Of input loops and games
- From: Hari Seldon <email@hidden>
- Date: Wed, 21 Sep 2005 13:59:15 -0500
Thank you for an extremely helpful reply; the threading code seems to
be working nicely now, and I'm glad to be free of that hackish run
loop! With a working input loop implimented with threads, I believe
I've found the true cause of my memory leaks. My startGame() function
looks something like this:
- (void)startGame
{
NSAutoreleasePool * thePool = [[NSAutoreleasePool alloc] init];
start_move_loop();
[thePool release];
}
I spawn a new thread in calling startGame, which makes me responsible
for creating an NSAutoreleasePool. But I realized today while
deubugging that [thePool release] doesn't get called until the game
quits, which means that tons of "temporary" NSStrings are building up
in the pool, causing a big memory drain. Is there any way to
periodically "drain" the pool?
On 9/21/05, Jack Nutting <email@hidden> wrote:
> 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