Source/Game-Persistence.m
author Jens Alfke <jens@mooseyard.com>
Wed May 28 12:47:10 2008 -0700 (2008-05-28)
changeset 8 45c82a071aca
permissions -rw-r--r--
* Got it working with latest iPhone SDK.
* Fixed some text alignment issues that showed up on PlayingCards.
* Working on persistence and move-tracking for Game.
     1 //
     2 //  Game-Persistence.m
     3 //  GeekGameBoard
     4 //
     5 //  Created by Jens Alfke on 3/16/08.
     6 //  Copyright 2008 __MyCompanyName__. All rights reserved.
     7 //
     8 
     9 #import "Game-Persistence.h"
    10 
    11 
    12 static NSDictionary* parseURLFields( NSURL* url );
    13 
    14 
    15 @implementation Game (Persistence)
    16 
    17 
    18 static NSMutableDictionary *sPersistentGames;
    19 
    20 
    21 - (id) initWithCoder: (NSCoder*)decoder
    22 {
    23     self = [self init];
    24     if( self ) {
    25         _players = [[decoder decodeObjectForKey: @"players"] mutableCopy];
    26         _states  = [[decoder decodeObjectForKey: @"states"] mutableCopy];
    27         _moves   = [[decoder decodeObjectForKey: @"moves"] mutableCopy];
    28         self.currentTurn = self.maxTurn;
    29     }
    30     return self;
    31 }
    32 
    33 
    34 - (void) encodeWithCoder: (NSCoder*)coder
    35 {
    36     [coder encodeObject: _players forKey: @"players"];
    37     [coder encodeObject: _states  forKey: @"states"];
    38     [coder encodeObject: _moves   forKey: @"moves"];
    39 }
    40 
    41 
    42 - (NSURL*) asURL
    43 {
    44     return [NSURL URLWithString: 
    45             [NSString stringWithFormat: @"game:type=%@&id=%@&turn=%u&move=%@",
    46              [[self class] identifier], _uniqueID, self.currentTurn,_moves.lastObject]];
    47 }
    48 
    49 
    50 + (Game*) gameWithURL: (NSURL*)url
    51 {
    52     if( 0 != [@"game" caseInsensitiveCompare: url.scheme] )
    53         return nil;
    54     NSDictionary *fields = parseURLFields(url);
    55     NSString *type = [fields objectForKey: @"type"];
    56     NSString *uuid = [fields objectForKey: @"id"];
    57     int turn = [[fields objectForKey: @"turn"] intValue];
    58     if( !type || !uuid || turn<=0 )
    59         return nil;
    60     
    61     Game *game = [sPersistentGames objectForKey: uuid];
    62     if( game ) {
    63         if( ![type isEqualToString: [[game class] identifier]] )
    64             return nil;
    65     } else if( turn == 1 ) {
    66         Class gameClass = NSClassFromString( [type stringByAppendingString: @"Game"] );
    67         if( ! gameClass || ! [gameClass isSubclassOfClass: [Game class]] )
    68             return nil;
    69         game = [[gameClass alloc] initWithUniqueID: uuid];
    70         [game setNumberOfPlayers: 2];
    71         if( ! sPersistentGames )
    72             sPersistentGames = [[NSMutableDictionary alloc] init];
    73         [sPersistentGames setObject: game forKey: uuid];
    74         [game release];
    75     }
    76     return game;
    77 }
    78 
    79 
    80 - (BOOL) addMoveFromURL: (NSURL*)url
    81 {
    82     NSDictionary *fields = parseURLFields(url);
    83     NSString *uuid = [fields objectForKey: @"id"];
    84     NSString *move = [fields objectForKey: @"move"];
    85     int turn = [[fields objectForKey: @"turn"] intValue];
    86     return [uuid isEqualToString: self.uniqueID]
    87         && turn==self.currentTurn
    88         && move.length > 0
    89         && [self applyMoveString: move];
    90 }
    91 
    92 
    93 
    94 @end
    95 
    96 
    97 
    98 static NSDictionary* parseURLFields( NSURL* url )
    99 {
   100     // Parse the URL into key-value pairs:
   101     NSMutableDictionary *fields = [NSMutableDictionary dictionary];
   102     for( NSString *field in [url.resourceSpecifier componentsSeparatedByString: @"&"] ) {
   103         NSRange e = [field rangeOfString: @"="];
   104         NSString *key, *value;
   105         if( e.length>0 ) {
   106             key = [field substringToIndex: e.location];
   107             value = [field substringFromIndex: NSMaxRange(e)];
   108         } else {
   109             key= field;
   110             value = @"";
   111         }
   112         [fields setObject: value forKey: key];
   113     }
   114     return fields;
   115 }