engine interaction class refactoring, round 4 or 5, can't remember: this time use the class methods to create an instance object and operates on that, reducing the number of arguments between methods and simplifying memory management
--- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Sun Nov 06 16:41:14 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Sun Nov 06 17:43:57 2011 +0100
@@ -54,6 +54,7 @@
#pragma mark -
#pragma mark Spawner functions
-(NSInteger) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary {
+ [self retain];
self.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil;
[self.stream open];
--- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Sun Nov 06 16:41:14 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Sun Nov 06 17:43:57 2011 +0100
@@ -23,8 +23,12 @@
@interface GameInterfaceBridge : NSObject {
+ NSInteger ipcPort;
+ UIView *blackView;
+}
-}
+@property (assign) NSInteger ipcPort;
+@property (nonatomic,retain) UIView *blackView;
+(void) startLocalGame:(NSDictionary *)withOptions;
+(void) startSaveGame:(NSString *)atPath;
--- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Sun Nov 06 16:41:14 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Sun Nov 06 17:43:57 2011 +0100
@@ -27,14 +27,72 @@
#import "ObjcExports.h"
@implementation GameInterfaceBridge
+@synthesize ipcPort, blackView;
+
+#pragma mark -
+#pragma mark Instance methods for engine interaction
+// prepares the controllers for hosting a game
+-(void) earlyEngineLaunch:(NSString *)pathOrNil withOptions:(NSDictionary *)optionsOrNil {
+ [self retain];
+ [AudioManagerController stopBackgroundMusic];
+
+ EngineProtocolNetwork *proto = [[EngineProtocolNetwork alloc] init];
+ self.ipcPort = [proto spawnThread:pathOrNil withOptions:optionsOrNil];
+ [proto release];
+
+ // add a black view hiding the background
+ CGRect theFrame = [[UIScreen mainScreen] bounds];
+ UIWindow *thisWindow = [[HedgewarsAppDelegate sharedAppDelegate] uiwindow];
+ self.blackView = [[UIView alloc] initWithFrame:theFrame];
+ self.blackView.opaque = YES;
+ self.blackView.backgroundColor = [UIColor blackColor];
+ self.blackView.alpha = 0;
+ [UIView beginAnimations:@"fade out" context:NULL];
+ [UIView setAnimationDuration:1];
+ self.blackView.alpha = 1;
+ [UIView commitAnimations];
+ [thisWindow addSubview:self.blackView];
+ [self.blackView release];
+
+ // keep track of uncompleted games
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:pathOrNil forKey:@"savedGamePath"];
+ [userDefaults synchronize];
+
+ // let's launch the engine using this -perfomSelector so that the runloop can deal with queued messages first
+ [self performSelector:@selector(engineLaunch:) withObject:pathOrNil afterDelay:0.1f];
+}
+
+// cleans up everything
+-(void) lateEngineLaunch {
+ // remove completed games notification
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:@"" forKey:@"savedGamePath"];
+ [userDefaults synchronize];
+
+ // remove the cover view with a transition
+ self.blackView.alpha = 1;
+ [UIView beginAnimations:@"fade in" context:NULL];
+ [UIView setAnimationDuration:1];
+ self.blackView.alpha = 0;
+ [UIView commitAnimations];
+ [self.blackView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
+
+ // the overlay is not needed any more and can be removed
+ [[OverlayViewController mainOverlay] removeOverlay];
+
+ // restart music and we're done
+ [AudioManagerController playBackgroundMusic];
+ [self release];
+}
// main routine for calling the actual game engine
-+(void) engineLaunchOn:(NSInteger) ipcPort withArgument:(NSString *)path {
+-(void) engineLaunch:(NSString *)pathOrNil {
const char *gameArgs[11];
CGFloat width, height;
CGFloat screenScale = [[UIScreen mainScreen] safeScale];
- NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",ipcPort];
- NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
+ NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",self.ipcPort];
+ NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt",[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
if (IS_DUALHEAD()) {
@@ -83,7 +141,7 @@
gameArgs[ 7] = [[[settings objectForKey:@"music"] stringValue] UTF8String]; //isMusicEnabled
gameArgs[ 8] = [[[settings objectForKey:@"alternate"] stringValue] UTF8String]; //cAltDamage
gameArgs[ 9] = [rotation UTF8String]; //rotateQt
- gameArgs[10] = ([HWUtils gameType] == gtSave) ? [path UTF8String] : NULL; //recordFileName
+ gameArgs[10] = ([HWUtils gameType] == gtSave) ? [pathOrNil UTF8String] : NULL; //recordFileName
[verticalSize release];
[horizontalSize release];
@@ -95,61 +153,11 @@
// this is the pascal function that starts the game
Game(gameArgs);
+ [self lateEngineLaunch];
}
-// prepares the controllers for hosting a game
-+(void) prepareEngineOn:(NSString *)pathOrNil withOptions:(NSDictionary *)optionsOrNil {
- EngineProtocolNetwork *proto = [[EngineProtocolNetwork alloc] init];
- NSInteger ipcPort = [proto spawnThread:pathOrNil withOptions:optionsOrNil];
-
- CGRect theFrame = [[UIScreen mainScreen] bounds];
- UIWindow *thisWindow = [[HedgewarsAppDelegate sharedAppDelegate] uiwindow];
- // we add a black view hiding the background
- UIView *blackView = [[UIView alloc] initWithFrame:theFrame];
- [thisWindow addSubview:blackView];
- blackView.opaque = YES;
- blackView.backgroundColor = [UIColor blackColor];
- blackView.alpha = 0;
-
- // when dual screen we apply a little transition
- if (IS_DUALHEAD()) {
- [UIView beginAnimations:@"fade out" context:NULL];
- [UIView setAnimationDuration:1];
- blackView.alpha = 1;
- [UIView commitAnimations];
- } else
- blackView.alpha = 1;
-
- // keep track of uncompleted games
- NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
- [userDefaults setObject:pathOrNil forKey:@"savedGamePath"];
- [userDefaults synchronize];
-
- [AudioManagerController pauseBackgroundMusic];
-
- // SYSTEMS ARE GO!!
- [self engineLaunchOn:ipcPort withArgument:pathOrNil];
-
- // remove completed games notification
- [userDefaults setObject:@"" forKey:@"savedGamePath"];
- [userDefaults synchronize];
-
- // now we can remove the cover with a transition
- blackView.frame = theFrame;
- blackView.alpha = 1;
- [UIView beginAnimations:@"fade in" context:NULL];
- [UIView setAnimationDuration:1];
- blackView.alpha = 0;
- [UIView commitAnimations];
- [blackView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
- [blackView release];
-
- // the overlay is not needed any more and can be removed
- [[OverlayViewController mainOverlay] removeOverlay];
-
- [AudioManagerController playBackgroundMusic];
-}
-
+#pragma mark -
+#pragma mark Class methods for setting up the engine from outsite
// set up variables for a local game
+(void) startLocalGame:(NSDictionary *)withOptions {
[HWUtils setGameType:gtLocal];
@@ -159,18 +167,22 @@
NSString *savePath = [[NSString alloc] initWithFormat:@"%@%@.hws",SAVES_DIRECTORY(),[outputFormatter stringFromDate:[NSDate date]]];
[outputFormatter release];
- // in the rare case in which a savefile with the same name exists the older one must be removed (or it gets corrupted)
+ // in the rare case in which a savefile with the same name exists the older one must be removed (otherwise it gets corrupted)
if ([[NSFileManager defaultManager] fileExistsAtPath:savePath])
[[NSFileManager defaultManager] removeItemAtPath:savePath error:nil];
- [GameInterfaceBridge prepareEngineOn:savePath withOptions:withOptions];
+ GameInterfaceBridge *bridge = [[GameInterfaceBridge alloc] init];
+ [bridge earlyEngineLaunch:savePath withOptions:withOptions];
+ [bridge release];
[savePath release];
}
// set up variables for a save game
+(void) startSaveGame:(NSString *)atPath {
[HWUtils setGameType:gtSave];
- [GameInterfaceBridge prepareEngineOn:atPath withOptions:nil];
+ GameInterfaceBridge *bridge = [[GameInterfaceBridge alloc] init];
+ [bridge earlyEngineLaunch:atPath withOptions:nil];
+ [bridge release];
}
+(void) startMissionGame:(NSString *)withScript {
@@ -180,7 +192,9 @@
NSDictionary *missionLine = [[NSDictionary alloc] initWithObjectsAndKeys:missionPath,@"mission_command",nil];
[missionPath release];
- [GameInterfaceBridge prepareEngineOn:nil withOptions:missionLine];
+ GameInterfaceBridge *bridge = [[GameInterfaceBridge alloc] init];
+ [bridge earlyEngineLaunch:nil withOptions:missionLine];
+ [bridge release];
[missionLine release];
}