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