project_files/HedgewarsMobile/Classes/MapConfigViewController.m
changeset 3910 dd47efbdec46
parent 3829 81db3c85784b
child 3911 46d7a5cf8ac6
--- a/project_files/HedgewarsMobile/Classes/MapConfigViewController.m	Sun Sep 26 16:28:04 2010 -0400
+++ b/project_files/HedgewarsMobile/Classes/MapConfigViewController.m	Sun Sep 26 23:48:03 2010 +0200
@@ -23,10 +23,7 @@
 #import "PascalImports.h"
 #import "CommodityFunctions.h"
 #import "UIImageExtra.h"
-#import "SDL_net.h"
-#import <pthread.h>
 
-#define INDICATOR_TAG 7654
 
 @implementation MapConfigViewController
 @synthesize previewButton, maxHogs, seedCommand, templateFilterCommand, mapGenCommand, mazeSizeCommand, themeCommand, staticMapCommand,
@@ -37,130 +34,6 @@
     return rotationManager(interfaceOrientation);
 }
 
-#pragma mark -
-#pragma mark Preview Handling
--(int) sendToEngine: (NSString *)string {
-    unsigned char length = [string length];
-
-    SDLNet_TCP_Send(csd, &length , 1);
-    return SDLNet_TCP_Send(csd, [string UTF8String], length);
-}
-
--(const uint8_t *)engineProtocol:(NSInteger) port {
-    IPaddress ip;
-    BOOL serverQuit = NO;
-    static uint8_t map[128*32];
-
-    if (SDLNet_Init() < 0) {
-        DLog(@"SDLNet_Init: %s", SDLNet_GetError());
-        serverQuit = YES;
-    }
-
-    // Resolving the host using NULL make network interface to listen
-    if (SDLNet_ResolveHost(&ip, NULL, port) < 0) {
-        DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
-        serverQuit = YES;
-    }
-
-    // Open a connection with the IP provided (listen on the host's port)
-    if (!(sd = SDLNet_TCP_Open(&ip))) {
-        DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), port);
-        serverQuit = YES;
-    }
-
-    // launch the preview here so that we're sure the tcp channel is open
-    pthread_t thread_id;
-    pthread_create(&thread_id, NULL, (void *)GenLandPreview, (void *)port);
-    pthread_detach(thread_id);
-
-    DLog(@"Waiting for a client on port %d", port);
-    while (!serverQuit) {
-        /* This check the sd if there is a pending connection.
-         * If there is one, accept that, and open a new socket for communicating */
-        csd = SDLNet_TCP_Accept(sd);
-        if (NULL != csd) {
-            DLog(@"Client found");
-
-            [self sendToEngine:self.seedCommand];
-            [self sendToEngine:self.templateFilterCommand];
-            [self sendToEngine:self.mapGenCommand];
-            [self sendToEngine:self.mazeSizeCommand];
-            [self sendToEngine:@"!"];
-
-            memset(map, 0, 128*32);
-            SDLNet_TCP_Recv(csd, map, 128*32);
-            SDLNet_TCP_Recv(csd, &maxHogs, sizeof(uint8_t));
-
-            SDLNet_TCP_Close(csd);
-            serverQuit = YES;
-        }
-    }
-
-    SDLNet_TCP_Close(sd);
-    SDLNet_Quit();
-    return map;
-}
-
--(void) drawingThread {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-    // select the port for IPC and launch the preview generation through engineProtocol:
-    int port = randomPort();
-    const uint8_t *map = [self engineProtocol:port];
-    uint8_t mapExp[128*32*8];
-
-    // draw the buffer (1 pixel per component, 0= transparent 1= color)
-    int k = 0;
-    for (int i = 0; i < 32*128; i++) {
-        unsigned char byte = map[i];
-        for (int j = 0; j < 8; j++) {
-            // select the color based on the leftmost bit
-            if ((byte & 0x80) != 0)
-                mapExp[k] = 100;
-            else
-                mapExp[k] = 255;
-            // shift to next bit
-            byte <<= 1;
-            k++;
-        }
-    }
-    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
-    CGContextRef bitmapImage = CGBitmapContextCreate(mapExp, 256, 128, 8, 256, colorspace, kCGImageAlphaNone);
-    CGColorSpaceRelease(colorspace);
-
-    CGImageRef previewCGImage = CGBitmapContextCreateImage(bitmapImage);
-    CGContextRelease(bitmapImage);
-    UIImage *previewImage = [[UIImage alloc] initWithCGImage:previewCGImage];
-    CGImageRelease(previewCGImage);
-    previewCGImage = nil;
-
-    // set the preview image (autoreleased) in the button and the maxhog label on the main thread to prevent a leak
-    [self performSelectorOnMainThread:@selector(setButtonImage:) withObject:[previewImage makeRoundCornersOfSize:CGSizeMake(12, 12)] waitUntilDone:NO];
-    [previewImage release];
-    [self performSelectorOnMainThread:@selector(setLabelText:) withObject:[NSString stringWithFormat:@"%d", maxHogs] waitUntilDone:NO];
-
-    // restore functionality of button and remove the spinning wheel on the main thread to prevent a leak
-    [self performSelectorOnMainThread:@selector(turnOnWidgets) withObject:nil waitUntilDone:NO];
-
-    [pool release];
-    //Invoking this method should be avoided as it does not give your thread a chance to clean up any resources it allocated during its execution.
-    //[NSThread exit];
-
-    /*
-    // http://developer.apple.com/mac/library/qa/qa2001/qa1037.html
-    UIGraphicsBeginImageContext(CGSizeMake(256,128));
-    CGContextRef context = UIGraphicsGetCurrentContext();
-    UIGraphicsPushContext(context);
-
-    CGContextSetRGBFillColor(context, 0.5, 0.5, 0.7, 1.0);
-    CGContextFillRect(context,CGRectMake(xc,yc,1,1));
-
-    UIGraphicsPopContext();
-    UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-    */
-}
-
 -(IBAction) mapButtonPressed {
     playSound(@"clickSound");
     [self updatePreview];
@@ -176,77 +49,26 @@
     NSString *seed = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);
     CFRelease(uuid);
     NSString *seedCmd = [[NSString alloc] initWithFormat:@"eseed {%@}", seed];
-    [seed release];
     self.seedCommand = seedCmd;
     [seedCmd release];
 
     NSIndexPath *theIndex;
     if (segmentedControl.selectedSegmentIndex != 1) {
-        // remove the current preview and title
-        [self.previewButton setImage:nil forState:UIControlStateNormal];
-        [self.previewButton setTitle:nil forState:UIControlStateNormal];
-
-        // don't display preview on slower device, too slow and memory hog
-        NSString *modelId = modelType();
-        if ([modelId hasPrefix:@"iPhone1"] || [modelId hasPrefix:@"iPod1,1"] || [modelId hasPrefix:@"iPod2,1"]) {
-            busy = NO;
-            [self.previewButton setTitle:NSLocalizedString(@"Preview not available",@"") forState:UIControlStateNormal];
-        } else {
-            // prevent other events and add an activity while the preview is beign generated
-            [self turnOffWidgets];
-
-            // add a very nice spinning wheel
-            UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]
-                                                  initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
-            indicator.center = CGPointMake(previewButton.bounds.size.width / 2, previewButton.bounds.size.height / 2);
-            indicator.tag = INDICATOR_TAG;
-            [indicator startAnimating];
-            [self.previewButton addSubview:indicator];
-            [indicator release];
-
-            // let's draw in a separate thread so the gui can work; at the end it restore other widgets
-            [NSThread detachNewThreadSelector:@selector(drawingThread) toTarget:self withObject:nil];
-        }
-
+        // prevent other events and add an activity while the preview is beign generated
+        [self turnOffWidgets];
+        [self.previewButton updatePreviewWithSeed:seed];
         theIndex = [NSIndexPath indexPathForRow:(random()%[self.themeArray count]) inSection:0];
     } else {
         theIndex = [NSIndexPath indexPathForRow:(random()%[self.mapArray count]) inSection:0];
+        // the preview for static maps is loaded in didSelectRowAtIndexPath
     }
-    [self.tableView reloadData];
+    [seed release];
+
+    // perform as if user clicked on an entry
     [self tableView:self.tableView didSelectRowAtIndexPath:theIndex];
     [self.tableView scrollToRowAtIndexPath:theIndex atScrollPosition:UITableViewScrollPositionNone animated:YES];
 }
 
-// instead of drawing a random map we load an image; this function is called by didSelectRowAtIndexPath only
--(void) updatePreviewWithMap:(NSInteger) index {
-    // change the preview button
-    NSString *fileImage = [[NSString alloc] initWithFormat:@"%@/%@/preview.png", MAPS_DIRECTORY(),[self.mapArray objectAtIndex:index]];
-    UIImage *image = [[UIImage alloc] initWithContentsOfFile:fileImage];
-    [fileImage release];
-    [self.previewButton setImage:[image makeRoundCornersOfSize:CGSizeMake(12, 12)] forState:UIControlStateNormal];
-    [image release];
-
-    // update label
-    maxHogs = 18;
-    NSString *fileCfg = [[NSString alloc] initWithFormat:@"%@/%@/map.cfg", MAPS_DIRECTORY(),[self.mapArray objectAtIndex:index]];
-    NSString *contents = [[NSString alloc] initWithContentsOfFile:fileCfg encoding:NSUTF8StringEncoding error:NULL];
-    [fileCfg release];
-    NSArray *split = [contents componentsSeparatedByString:@"\n"];
-    [contents release];
-
-    // set the theme and map here
-    self.themeCommand = [NSString stringWithFormat:@"etheme %@", [split objectAtIndex:0]];
-    self.staticMapCommand = [NSString stringWithFormat:@"emap %@", [self.mapArray objectAtIndex:index]];
-
-    // if the number is not set we keep 18 standard;
-    // sometimes it's not set but there are trailing characters, we get around them with the second equation
-    if ([split count] > 1 && [[split objectAtIndex:1] intValue] > 0)
-        maxHogs = [[split objectAtIndex:1] intValue];
-    NSString *max = [[NSString alloc] initWithFormat:@"%d",maxHogs];
-    self.maxLabel.text = max;
-    [max release];
-}
-
 -(void) turnOffWidgets {
     busy = YES;
     self.previewButton.alpha = 0.5f;
@@ -262,35 +84,21 @@
     self.segmentedControl.enabled = YES;
     self.slider.enabled = YES;
     busy = NO;
-
-    UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[self.previewButton viewWithTag:INDICATOR_TAG];
-    if (indicator) {
-        [indicator stopAnimating];
-        [indicator removeFromSuperview];
-    }
 }
 
 -(void) setLabelText:(NSString *)str {
+    self.maxHogs = [str intValue];
     self.maxLabel.text = str;
 }
 
--(void) setButtonImage:(UIImage *)img {
-    [self.previewButton setBackgroundImage:img forState:UIControlStateNormal];
-}
-
--(void) restoreBackgroundImage {
-    // white rounded rectangle as background image for previewButton
-    UIGraphicsBeginImageContext(CGSizeMake(256,128));
-    CGContextRef context = UIGraphicsGetCurrentContext();
-    UIGraphicsPushContext(context);
-
-    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
-    CGContextFillRect(context,CGRectMake(0,0,256,128));
-
-    UIGraphicsPopContext();
-    UIImage *bkgImg = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-    [self.previewButton setBackgroundImage:[bkgImg makeRoundCornersOfSize:CGSizeMake(12, 12)] forState:UIControlStateNormal];
+-(NSDictionary *)getDataForEngine {
+    NSDictionary *dictForEngine = [NSDictionary dictionaryWithObjectsAndKeys:
+                                   self.seedCommand,@"seedCommand",
+                                   self.templateFilterCommand,@"templateFilterCommand",
+                                   self.mapGenCommand,@"mapGenCommand",
+                                   self.mazeSizeCommand,@"mazeSizeCommand",
+                                   nil];
+    return dictForEngine;
 }
 
 #pragma mark -
@@ -340,6 +148,28 @@
     return cell;
 }
 
+// this set details for a static map (called by didSelectRowAtIndexPath)
+-(void) setDetailsForStaticMap:(NSInteger) index {
+    // update label
+    maxHogs = 18;
+    NSString *fileCfg = [[NSString alloc] initWithFormat:@"%@/%@/map.cfg", MAPS_DIRECTORY(),[self.mapArray objectAtIndex:index]];
+    NSString *contents = [[NSString alloc] initWithContentsOfFile:fileCfg encoding:NSUTF8StringEncoding error:NULL];
+    [fileCfg release];
+    NSArray *split = [contents componentsSeparatedByString:@"\n"];
+    [contents release];
+
+    // set the theme and map here
+    self.themeCommand = [NSString stringWithFormat:@"etheme %@", [split objectAtIndex:0]];
+    self.staticMapCommand = [NSString stringWithFormat:@"emap %@", [self.mapArray objectAtIndex:index]];
+
+    // if the number is not set we keep 18 standard;
+    // sometimes it's not set but there are trailing characters, we get around them with the second equation
+    if ([split count] > 1 && [[split objectAtIndex:1] intValue] > 0)
+        maxHogs = [[split objectAtIndex:1] intValue];
+    NSString *max = [[NSString alloc] initWithFormat:@"%d",maxHogs];
+    self.maxLabel.text = max;
+    [max release];
+}
 
 #pragma mark -
 #pragma mark Table view delegate
@@ -348,12 +178,14 @@
     int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
 
     if (newRow != oldRow) {
+        [self.tableView reloadData];
         if (self.segmentedControl.selectedSegmentIndex != 1) {
-            NSString *theme = [self.themeArray objectAtIndex:newRow];
-            self.themeCommand = [NSString stringWithFormat:@"etheme %@", theme];
+            // just change the theme, don't update preview
+            self.themeCommand = [NSString stringWithFormat:@"etheme %@", [self.themeArray objectAtIndex:newRow]];
         } else {
-            // theme and map are set in the function below
-            [self updatePreviewWithMap:newRow];
+            NSString *fileImage = [NSString stringWithFormat:@"%@/%@/preview.png",MAPS_DIRECTORY(),[self.mapArray objectAtIndex:newRow]];
+            [self.previewButton updatePreviewWithFile:fileImage];
+            [self setDetailsForStaticMap:newRow];
         }
 
         UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
@@ -456,7 +288,6 @@
 }
 
 // perform actions based on the activated section, then call updatePreview to visually update the selection
-// updatePreview will call didSelectRowAtIndexPath which will call the right update routine)
 // and if necessary update the table with a slide animation
 -(IBAction) segmentedControlChanged:(id) sender {
     NSString *mapgen, *staticmap;
@@ -477,7 +308,6 @@
             staticmap = @"map Bamboo";
             self.slider.enabled = NO;
             self.sizeLabel.text = NSLocalizedString(@"No filter",@"");
-            [self restoreBackgroundImage];
             break;
 
         case 2: // Maze
@@ -539,11 +369,6 @@
     [array release];
     self.mapArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:MAPS_DIRECTORY() error:NULL];
 
-    busy = NO;
-
-    // draw a white background
-    [self restoreBackgroundImage];
-
     // initialize some "default" values
     self.sizeLabel.text = NSLocalizedString(@"All",@"");
     self.slider.value = 0.05f;
@@ -564,7 +389,8 @@
 
     oldValue = 5;
     oldPage = 0;
-    
+    busy = NO;
+
     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
         [self.tableView setBackgroundView:nil];
         self.view.backgroundColor = [UIColor clearColor];
@@ -575,8 +401,8 @@
 }
 
 -(void) viewDidAppear:(BOOL) animated {
+    [self updatePreview];
     [super viewDidAppear:animated];
-    [self updatePreview];
 }
 
 #pragma mark -
@@ -589,7 +415,6 @@
 #pragma mark -
 -(void) didReceiveMemoryWarning {
     [super didReceiveMemoryWarning];
-    //[previewButton setImage:nil forState:UIControlStateNormal];
     MSG_MEMCLEAN();
 }
 
@@ -643,5 +468,4 @@
     [super dealloc];
 }
 
-
 @end