# HG changeset patch # User koda # Date 1333939410 -7200 # Node ID f72cac290325eb86f3b4c531e58bb9b0bfb22a9e # Parent a187c280dd3dd5c0a5087a78819c72e1dad41915 ios: refactor the code of the after-game statistics display using delegates diff -r a187c280dd3d -r f72cac290325 project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h --- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h Mon Apr 09 03:25:17 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h Mon Apr 09 04:43:30 2012 +0200 @@ -21,19 +21,27 @@ #import "SDL_net.h" +@protocol EngineProtocolDelegate + +-(void) gameEndedWithStatistics:(NSArray *)stats; + +@end + + @interface EngineProtocolNetwork : NSObject { - NSMutableArray *statsArray; + id delegate; NSOutputStream *stream; TCPsocket csd; NSInteger enginePort; } -@property (nonatomic,assign) NSMutableArray *statsArray; +@property (nonatomic,assign) id delegate; @property (nonatomic,retain) NSOutputStream *stream; @property (assign) TCPsocket csd; @property (assign) NSInteger enginePort; -(id) init; +-(id) initWithPort:(NSInteger) port; -(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary; -(void) engineProtocol:(id) object; diff -r a187c280dd3d -r f72cac290325 project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m --- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Mon Apr 09 03:25:17 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Mon Apr 09 04:43:30 2012 +0200 @@ -23,20 +23,24 @@ #define BUFFER_SIZE 255 // like in original frontend @implementation EngineProtocolNetwork -@synthesize statsArray, stream, csd, enginePort; +@synthesize delegate, stream, csd, enginePort; --(id) init { +-(id) initWithPort:(NSInteger) port { if (self = [super init]) { - self.statsArray = nil; + self.delegate = nil; self.csd = NULL; self.stream = nil; - self.enginePort = [HWUtils randomPort]; + self.enginePort = port; } return self; } +-(id) init { + return [self initWithPort:[HWUtils randomPort]]; +} + -(void) dealloc { - releaseAndNil(statsArray); + self.delegate = nil; releaseAndNil(stream); [super dealloc]; } @@ -212,6 +216,7 @@ -(void) engineProtocol:(id) object { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSDictionary *gameConfig = (NSDictionary *)object; + NSMutableArray *statsArray = nil; TCPsocket sd; IPaddress ip; int eProto; @@ -326,10 +331,10 @@ } break; case 'i': - if (self.statsArray == nil) { - self.statsArray = [[NSMutableArray alloc] initWithCapacity:10 - 2]; + if (statsArray == nil) { + statsArray = [[NSMutableArray alloc] initWithCapacity:10 - 2]; NSMutableArray *ranking = [[NSMutableArray alloc] initWithCapacity:4]; - [self.statsArray insertObject:ranking atIndex:0]; + [statsArray insertObject:ranking atIndex:0]; [ranking release]; } NSString *tempStr = [NSString stringWithUTF8String:&buffer[2]]; @@ -338,16 +343,16 @@ int index = [arg length] + 3; switch (buffer[1]) { case 'r': // winning team - [self.statsArray insertObject:[NSString stringWithUTF8String:&buffer[2]] atIndex:1]; + [statsArray insertObject:[NSString stringWithUTF8String:&buffer[2]] atIndex:1]; break; case 'D': // best shot - [self.statsArray addObject:[NSString stringWithFormat:@"The best shot award won by %s (with %@ points)", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"The best shot award won by %s (with %@ points)", &buffer[index], arg]]; break; case 'k': // best hedgehog - [self.statsArray addObject:[NSString stringWithFormat:@"The best killer is %s with %@ kill(s) in a turn", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"The best killer is %s with %@ kill(s) in a turn", &buffer[index], arg]]; break; case 'K': // number of hogs killed - [self.statsArray addObject:[NSString stringWithFormat:@"%@ hedgehog(s) were killed during this round", arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%@ hedgehog(s) were killed during this round", arg]]; break; case 'H': // team health/graph break; @@ -355,16 +360,16 @@ // still WIP in statsPage.cpp break; case 'P': // teams ranking - [[self.statsArray objectAtIndex:0] addObject:tempStr]; + [[statsArray objectAtIndex:0] addObject:tempStr]; break; case 's': // self damage - [self.statsArray addObject:[NSString stringWithFormat:@"%s thought it's good to shoot his own hedgehogs with %@ points", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%s thought it's good to shoot his own hedgehogs with %@ points", &buffer[index], arg]]; break; case 'S': // friendly fire - [self.statsArray addObject:[NSString stringWithFormat:@"%s killed %@ of his own hedgehogs", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%s killed %@ of his own hedgehogs", &buffer[index], arg]]; break; case 'B': // turn skipped - [self.statsArray addObject:[NSString stringWithFormat:@"%s was scared and skipped turn %@ times", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%s was scared and skipped turn %@ times", &buffer[index], arg]]; break; default: DLog(@"Unhandled stat message, see statsPage.cpp"); @@ -373,6 +378,9 @@ break; case 'q': // game ended and match finished, statsArray is full of delicious statistics + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(gameEndedWithStatistics:)]) + [self.delegate gameEndedWithStatistics:statsArray]; + [statsArray release]; [HWUtils setGameStatus:gsEnded]; // closing connection here would trigger a "IPC connection lost" error, so we have to wait until recv fails break; diff -r a187c280dd3d -r f72cac290325 project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h --- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Mon Apr 09 03:25:17 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Mon Apr 09 04:43:30 2012 +0200 @@ -18,19 +18,18 @@ #import +#import "EngineProtocolNetwork.h" -@class EngineProtocolNetwork; - -@interface GameInterfaceBridge : NSObject { +@interface GameInterfaceBridge : NSObject { UIView *blackView; NSString *savePath; - EngineProtocolNetwork *proto; + NSInteger port; } @property (nonatomic,retain) UIView *blackView; @property (nonatomic,retain) NSString *savePath; -@property (nonatomic,retain) EngineProtocolNetwork *proto; +@property (assign) NSInteger port; +(void) startLocalGame:(NSDictionary *)withOptions; +(void) startSaveGame:(NSString *)atPath; diff -r a187c280dd3d -r f72cac290325 project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m --- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Mon Apr 09 03:25:17 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Mon Apr 09 04:43:30 2012 +0200 @@ -25,7 +25,7 @@ static UIViewController *callingController; @implementation GameInterfaceBridge -@synthesize blackView, savePath, proto; +@synthesize blackView, savePath, port; #pragma mark - #pragma mark Instance methods for engine interaction @@ -35,9 +35,10 @@ [[AudioManagerController mainManager] fadeOutBackgroundMusic]; EngineProtocolNetwork *engineProtocol = [[EngineProtocolNetwork alloc] init]; - self.proto = engineProtocol; + self.port = engineProtocol.enginePort; + engineProtocol.delegate = self; + [engineProtocol spawnThread:self.savePath withOptions:optionsOrNil]; [engineProtocol release]; - [self.proto spawnThread:self.savePath withOptions:optionsOrNil]; // add a black view hiding the background UIWindow *thisWindow = [[HedgewarsAppDelegate sharedAppDelegate] uiwindow]; @@ -82,20 +83,6 @@ [UIView commitAnimations]; [self.blackView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1]; - // engine thread *should* be done by now - NSArray *stats = [[NSArray alloc] initWithArray:self.proto.statsArray copyItems:YES]; - if ([HWUtils gameStatus] == gsEnded && stats != nil) { - StatsPageViewController *statsPage = [[StatsPageViewController alloc] init]; - statsPage.statsArray = stats; - statsPage.modalTransitionStyle = UIModalTransitionStyleCoverVertical; - if ([statsPage respondsToSelector:@selector(setModalPresentationStyle:)]) - statsPage.modalPresentationStyle = UIModalPresentationPageSheet; - - [callingController presentModalViewController:statsPage animated:YES]; - [statsPage release]; - } - [stats release]; - // can remove the savefile if the replay has ended if ([HWUtils gameType] == gtSave) [[NSFileManager defaultManager] removeItemAtPath:self.savePath error:nil]; @@ -111,9 +98,8 @@ -(void) engineLaunch { const char *gameArgs[11]; CGFloat width, height; - NSInteger enginePort = self.proto.enginePort; CGFloat screenScale = [[UIScreen mainScreen] safeScale]; - NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",enginePort]; + NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",self.port]; NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt",[[NSLocale preferredLanguages] objectAtIndex:0]]; NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; @@ -175,11 +161,23 @@ -(void) dealloc { releaseAndNil(blackView); releaseAndNil(savePath); - releaseAndNil(proto); [super dealloc]; } #pragma mark - +#pragma mark EngineProtocolDelegate methods +-(void) gameEndedWithStatistics:(NSArray *)stats { + if (stats != nil) { + StatsPageViewController *statsPage = [[StatsPageViewController alloc] init]; + statsPage.statsArray = stats; + statsPage.modalTransitionStyle = UIModalTransitionStyleCoverVertical; + + [callingController presentModalViewController:statsPage animated:YES]; + [statsPage release]; + } +} + +#pragma mark - #pragma mark Class methods for setting up the engine from outsite +(void) registerCallingController:(UIViewController *)controller { callingController = controller;