From e2a0bf60412ede6c4d449939e8c414f7104b0cd7 Mon Sep 17 00:00:00 2001 From: Matej Jan Date: Tue, 9 Oct 2012 15:26:47 +0000 Subject: [PATCH] CADisplayLink support for running the game loop git-svn-id: http://xni.googlecode.com/svn/XNI@118 ac433895-eea3-a490-d80a-17149a75e588 --- Classes/Retronator/Xni/Framework/Game.h | 7 ++++++ Classes/Retronator/Xni/Framework/Game.m | 24 +++++++++++++++++---- Classes/Retronator/Xni/Framework/GameHost.m | 20 ++++++++--------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Classes/Retronator/Xni/Framework/Game.h b/Classes/Retronator/Xni/Framework/Game.h index dafe858..237eb3a 100644 --- a/Classes/Retronator/Xni/Framework/Game.h +++ b/Classes/Retronator/Xni/Framework/Game.h @@ -37,6 +37,10 @@ GameTime *gameTime; NSDate *currentFrameTime; NSDate *lastFrameTime; + + BOOL usesDisplayLink; + int displayLinkFrameInterval; + CADisplayLink *displayLink; // Content manager ContentManager *content; @@ -63,6 +67,9 @@ @property (nonatomic) NSTimeInterval targetElapsedTime; @property (nonatomic) NSTimeInterval inactiveSleepTime; +@property (nonatomic) BOOL usesDisplayLink; +@property (nonatomic) int displayLinkFrameInterval; + @property (nonatomic, retain) ContentManager *content; @property (nonatomic, readonly) GameComponentCollection *components; @property (nonatomic, readonly) GameServiceContainer *services; diff --git a/Classes/Retronator/Xni/Framework/Game.m b/Classes/Retronator/Xni/Framework/Game.m index 2de124d..f4e9990 100644 --- a/Classes/Retronator/Xni/Framework/Game.m +++ b/Classes/Retronator/Xni/Framework/Game.m @@ -108,6 +108,13 @@ static NSArray *drawOrderSort; @synthesize targetElapsedTime; @synthesize inactiveSleepTime; +@synthesize usesDisplayLink, displayLinkFrameInterval; + +- (void)setDisplayLinkFrameInterval:(int)value { + displayLinkFrameInterval = value; + [displayLink setFrameInterval:displayLinkFrameInterval]; +} + @synthesize content; @synthesize components; @synthesize services; @@ -143,8 +150,14 @@ static NSArray *drawOrderSort; // Force redraw. [self.window.gameViewController.gameView layoutSubviews]; - // Run the game host with a delay event, so we don't block this method. - [gameHost performSelector:@selector(run) withObject:nil afterDelay:0]; + if (usesDisplayLink) { + displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(tick)] retain]; + [displayLink setFrameInterval:displayLinkFrameInterval]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + } else { + // Run the game host with a delay event, so we don't block this method. + [gameHost performSelector:@selector(run) withObject:nil afterDelay:0]; + } } - (void) tick { @@ -154,7 +167,9 @@ static NSArray *drawOrderSort; // Sleep if inactive. if (!isActive) { - CFRunLoopRunInMode(kCFRunLoopDefaultMode, inactiveSleepTime, NO); + if (!usesDisplayLink) { + CFRunLoopRunInMode(kCFRunLoopDefaultMode, inactiveSleepTime, NO); + } return; } @@ -163,7 +178,7 @@ static NSArray *drawOrderSort; NSTimeInterval elapsedRealTime = [currentFrameTime timeIntervalSinceDate:lastFrameTime]; // Sleep if we're ahead of the target elapsed time. - if (isFixedTimeStep) { + if (isFixedTimeStep && !usesDisplayLink) { if (elapsedRealTime < targetElapsedTime) { NSTimeInterval sleepTime = targetElapsedTime - elapsedRealTime; CFRunLoopRunInMode(kCFRunLoopDefaultMode, sleepTime, NO); @@ -420,6 +435,7 @@ static NSArray *drawOrderSort; [self unloadContent]; [gameTime release]; + [displayLink release]; [componentsList release]; [enabledComponents release]; diff --git a/Classes/Retronator/Xni/Framework/GameHost.m b/Classes/Retronator/Xni/Framework/GameHost.m index 2c06c37..31d1ba5 100644 --- a/Classes/Retronator/Xni/Framework/GameHost.m +++ b/Classes/Retronator/Xni/Framework/GameHost.m @@ -26,11 +26,15 @@ @synthesize window; - (void) run { - // Hijack the run loop. - NSLog(@"Starting the game loop."); game = [self delegate]; - + + // If game uses display link we don't need to run our own game loop. + if (game.usesDisplayLink) return; + + // Hijack the run loop. + NSLog(@"Starting the game loop."); + SInt32 runResult; isExiting = NO; @@ -48,16 +52,12 @@ // We release memory every frame. [pool release]; - } - - /* - CADisplayLink *aDisplayLink = [CADisplayLink displayLinkWithTarget:game selector:@selector(tick)]; - [aDisplayLink setFrameInterval:1]; - [aDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - */ + } } - (void) exit { + if (game.usesDisplayLink) return; + NSLog(@"Exiting the game loop."); isExiting = YES; }