aboutsummaryrefslogtreecommitdiffstats
path: root/misc/osxfe/ioquake3fe/Controller.m
blob: 2d2bf45907b3f922a4e42c1e995da10ad0d22326 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//
//  Controller.m
//  ioquake3fe
//
//  Created by Ben Wilber on 3/11/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "Controller.h"
#import "ErrorWindow.h"

#define IOQ3_BUNDLE @"/Applications/ioquake3/ioquake3.app"
#define IOQ3_BIN @"ioquake3.ub"

@implementation Controller

- (id)init {
	[super init];
	quakeData = [[NSMutableData alloc] initWithCapacity:1.0];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readPipe:) name:NSFileHandleReadCompletionNotification object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskNote:) name:NSTaskDidTerminateNotification object:nil];
	return self;
}

- (void)dealloc {
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	[super dealloc];
}

- (IBAction)launch:(id)sender {
	NSString *ioQuake3Path = [[NSBundle mainBundle] pathForAuxiliaryExecutable:IOQ3_BIN];
	if (!ioQuake3Path) 
		ioQuake3Path = [[NSBundle bundleWithPath:IOQ3_BUNDLE] pathForAuxiliaryExecutable:IOQ3_BIN];
		
	NSPipe *pipe = [NSPipe pipe];
	quakeOut = [pipe fileHandleForReading];
	[quakeOut readInBackgroundAndNotify];
	
	quakeTask = [NSTask new];
	[quakeTask setStandardOutput:pipe];
	[quakeTask setStandardError:pipe];

	NSString *args = [argsTextField stringValue];
	if ([args length])
		[quakeTask setArguments:[args componentsSeparatedByString:@" "]];
//		[quakeTask setArguments:[args componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]]; // tiger
			
	BOOL die = NO;
	
	@try {
		[quakeTask setLaunchPath:ioQuake3Path];
		[quakeTask launch];
	}
	@catch (NSException *e) {
		[[NSAlert
		  alertWithMessageText:NSLocalizedString(@"Launch Failed", @"launch failed")
		  defaultButton:NSLocalizedString(@"OK", @"OK")
		  alternateButton:nil
		  otherButton:nil
//		  informativeTextWithFormat:NSLocalizedString(@"Something is probably wrong with the actual ioquake3 binary.", @"launch failed text")]
//		  informativeTextWithFormat:NSLocalizedString([@"Unable to find the Quake binary at:\n" stringByAppendingString:ioQuake3Path], @"launch failed text")]
		  informativeTextWithFormat:NSLocalizedString([[[e reason] stringByAppendingString:@"\n\nExecutable path was:\n"] stringByAppendingString:ioQuake3Path], @"launch failed text")]
		  runModal];
		die = YES;
	}
	@finally {
		if (die)
			[NSApp terminate:self];
	}

	[[sender window] close];
	return;
}

- (void)readPipe:(NSNotification *)note {
	if ([note object] == quakeOut) {
		NSData *outputData = [[note userInfo] objectForKey:NSFileHandleNotificationDataItem];
		if ([outputData length])
			[quakeData appendData:outputData];
		if (quakeTask)
			[quakeOut readInBackgroundAndNotify];
	}
}

- (void)taskNote:(NSNotification *)note {
	if ([note object] == quakeTask) {
		if ([quakeTask isRunning] == NO) {
			if ([quakeTask terminationStatus] != 0) {
				ErrorWindow *ew = [[[ErrorWindow alloc] init] autorelease];
				[ew bitch:[[[NSString alloc] initWithData:quakeData encoding:NSUTF8StringEncoding] autorelease]];
			} 
			else
				[NSApp terminate:self];
		}
	}
}
@end