23 #import "OverlayViewController.h" |
23 #import "OverlayViewController.h" |
24 |
24 |
25 |
25 |
26 #define BUFFER_SIZE 255 // like in original frontend |
26 #define BUFFER_SIZE 255 // like in original frontend |
27 |
27 |
|
28 static NSInteger activeEnginePort; |
|
29 |
28 @implementation EngineProtocolNetwork |
30 @implementation EngineProtocolNetwork |
29 @synthesize delegate, stream, csd; |
31 @synthesize delegate, stream, csd, enginePort; |
30 |
32 |
31 -(id) init { |
33 -(id) init { |
32 if (self = [super init]) { |
34 if (self = [super init]) { |
33 self.delegate = nil; |
35 self.delegate = nil; |
34 |
36 |
35 self.csd = NULL; |
37 self.csd = NULL; |
36 self.stream = nil; |
38 self.stream = nil; |
37 } |
39 self.enginePort = [HWUtils randomPort]; |
|
40 } |
|
41 activeEnginePort = self.enginePort; |
38 return self; |
42 return self; |
39 } |
43 } |
40 |
44 |
41 -(void) gameHasEndedWithStats:(NSArray *)stats { |
45 -(void) gameHasEndedWithStats:(NSArray *)stats { |
42 if (self.delegate != nil && [self.delegate respondsToSelector:@selector(gameHasEndedWithStats:)]) |
46 if (self.delegate != nil && [self.delegate respondsToSelector:@selector(gameHasEndedWithStats:)]) |
51 [super dealloc]; |
55 [super dealloc]; |
52 } |
56 } |
53 |
57 |
54 #pragma mark - |
58 #pragma mark - |
55 #pragma mark Spawner functions |
59 #pragma mark Spawner functions |
56 -(NSInteger) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary { |
60 +(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary { |
57 [self retain]; |
61 EngineProtocolNetwork *proto = [[EngineProtocolNetwork alloc] init]; |
58 self.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil; |
62 proto.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil; |
59 [self.stream open]; |
63 [proto.stream open]; |
60 |
64 |
61 NSInteger ipcPort = [HWUtils randomPort]; |
65 // +detachNewThreadSelector retain/release self automatically |
62 NSDictionary *config = [[NSDictionary alloc] initWithObjectsAndKeys: |
|
63 [NSNumber numberWithInt:ipcPort],@"port", |
|
64 dictionary,@"config", nil]; |
|
65 [NSThread detachNewThreadSelector:@selector(engineProtocol:) |
66 [NSThread detachNewThreadSelector:@selector(engineProtocol:) |
66 toTarget:self |
67 toTarget:proto |
67 withObject:config]; |
68 withObject:dictionary]; |
68 [config release]; |
69 [proto release]; |
69 |
70 } |
70 return ipcPort; |
71 |
|
72 +(NSInteger) activeEnginePort { |
|
73 return activeEnginePort; |
71 } |
74 } |
72 |
75 |
73 #pragma mark - |
76 #pragma mark - |
74 #pragma mark Provider functions |
77 #pragma mark Provider functions |
75 // unpacks team data from the selected team.plist to a sequence of engine commands |
78 // unpacks team data from the selected team.plist to a sequence of engine commands |
226 } |
229 } |
227 |
230 |
228 // this is launched as thread and handles all IPC with engine |
231 // this is launched as thread and handles all IPC with engine |
229 -(void) engineProtocol:(id) object { |
232 -(void) engineProtocol:(id) object { |
230 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
233 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
231 NSDictionary *gameConfig = [(NSDictionary *)object objectForKey:@"config"]; |
234 NSDictionary *gameConfig = (NSDictionary *)object; |
232 NSInteger port = [[(NSDictionary *)object objectForKey:@"port"] intValue]; |
|
233 NSMutableArray *statsArray = nil; |
235 NSMutableArray *statsArray = nil; |
234 TCPsocket sd; |
236 TCPsocket sd; |
235 IPaddress ip; |
237 IPaddress ip; |
236 int eProto; |
238 int eProto; |
237 BOOL clientQuit; |
239 BOOL clientQuit; |
245 DLog(@"SDLNet_Init: %s", SDLNet_GetError()); |
247 DLog(@"SDLNet_Init: %s", SDLNet_GetError()); |
246 clientQuit = YES; |
248 clientQuit = YES; |
247 } |
249 } |
248 |
250 |
249 // Resolving the host using NULL make network interface to listen |
251 // Resolving the host using NULL make network interface to listen |
250 if (SDLNet_ResolveHost(&ip, NULL, port) < 0 && !clientQuit) { |
252 if (SDLNet_ResolveHost(&ip, NULL, self.enginePort) < 0 && !clientQuit) { |
251 DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError()); |
253 DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError()); |
252 clientQuit = YES; |
254 clientQuit = YES; |
253 } |
255 } |
254 |
256 |
255 // Open a connection with the IP provided (listen on the host's port) |
257 // Open a connection with the IP provided (listen on the host's port) |
256 if (!(sd = SDLNet_TCP_Open(&ip)) && !clientQuit) { |
258 if (!(sd = SDLNet_TCP_Open(&ip)) && !clientQuit) { |
257 DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), port); |
259 DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), self.enginePort); |
258 clientQuit = YES; |
260 clientQuit = YES; |
259 } |
261 } |
260 |
262 |
261 DLog(@"Waiting for a client on port %d", port); |
263 DLog(@"Waiting for a client on port %d", self.enginePort); |
262 while (csd == NULL) |
264 while (csd == NULL) |
263 csd = SDLNet_TCP_Accept(sd); |
265 csd = SDLNet_TCP_Accept(sd); |
264 SDLNet_TCP_Close(sd); |
266 SDLNet_TCP_Close(sd); |
265 |
267 |
266 while (!clientQuit) { |
268 while (!clientQuit) { |
411 // Close the client socket |
413 // Close the client socket |
412 SDLNet_TCP_Close(csd); |
414 SDLNet_TCP_Close(csd); |
413 SDLNet_Quit(); |
415 SDLNet_Quit(); |
414 |
416 |
415 [pool release]; |
417 [pool release]; |
416 |
|
417 [self performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:YES]; |
|
418 // Invoking this method should be avoided as it does not give your thread a chance |
418 // Invoking this method should be avoided as it does not give your thread a chance |
419 // to clean up any resources it allocated during its execution. |
419 // to clean up any resources it allocated during its execution. |
420 //[NSThread exit]; |
420 //[NSThread exit]; |
421 } |
421 } |
422 |
422 |