project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m
changeset 6321 5a0416e5a6de
parent 6301 1259736c0134
child 6337 84e7d1a5e3df
equal deleted inserted replaced
6320:238a6dc0e7ad 6321:5a0416e5a6de
    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