Source/Game-Persistence.m
changeset 9 a59acc683080
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Source/Game-Persistence.m	Thu May 29 15:04:06 2008 -0700
     1.3 @@ -0,0 +1,115 @@
     1.4 +//
     1.5 +//  Game-Persistence.m
     1.6 +//  GeekGameBoard
     1.7 +//
     1.8 +//  Created by Jens Alfke on 3/16/08.
     1.9 +//  Copyright 2008 __MyCompanyName__. All rights reserved.
    1.10 +//
    1.11 +
    1.12 +#import "Game-Persistence.h"
    1.13 +
    1.14 +
    1.15 +static NSDictionary* parseURLFields( NSURL* url );
    1.16 +
    1.17 +
    1.18 +@implementation Game (Persistence)
    1.19 +
    1.20 +
    1.21 +static NSMutableDictionary *sPersistentGames;
    1.22 +
    1.23 +
    1.24 +- (id) initWithCoder: (NSCoder*)decoder
    1.25 +{
    1.26 +    self = [self init];
    1.27 +    if( self ) {
    1.28 +        _players = [[decoder decodeObjectForKey: @"players"] mutableCopy];
    1.29 +        _states  = [[decoder decodeObjectForKey: @"states"] mutableCopy];
    1.30 +        _moves   = [[decoder decodeObjectForKey: @"moves"] mutableCopy];
    1.31 +        self.currentTurn = self.maxTurn;
    1.32 +    }
    1.33 +    return self;
    1.34 +}
    1.35 +
    1.36 +
    1.37 +- (void) encodeWithCoder: (NSCoder*)coder
    1.38 +{
    1.39 +    [coder encodeObject: _players forKey: @"players"];
    1.40 +    [coder encodeObject: _states  forKey: @"states"];
    1.41 +    [coder encodeObject: _moves   forKey: @"moves"];
    1.42 +}
    1.43 +
    1.44 +
    1.45 +- (NSURL*) asURL
    1.46 +{
    1.47 +    return [NSURL URLWithString: 
    1.48 +            [NSString stringWithFormat: @"game:type=%@&id=%@&turn=%u&move=%@",
    1.49 +             [[self class] identifier], _uniqueID, self.currentTurn,_moves.lastObject]];
    1.50 +}
    1.51 +
    1.52 +
    1.53 ++ (Game*) gameWithURL: (NSURL*)url
    1.54 +{
    1.55 +    if( 0 != [@"game" caseInsensitiveCompare: url.scheme] )
    1.56 +        return nil;
    1.57 +    NSDictionary *fields = parseURLFields(url);
    1.58 +    NSString *type = [fields objectForKey: @"type"];
    1.59 +    NSString *uuid = [fields objectForKey: @"id"];
    1.60 +    int turn = [[fields objectForKey: @"turn"] intValue];
    1.61 +    if( !type || !uuid || turn<=0 )
    1.62 +        return nil;
    1.63 +    
    1.64 +    Game *game = [sPersistentGames objectForKey: uuid];
    1.65 +    if( game ) {
    1.66 +        if( ![type isEqualToString: [[game class] identifier]] )
    1.67 +            return nil;
    1.68 +    } else if( turn == 1 ) {
    1.69 +        Class gameClass = NSClassFromString( [type stringByAppendingString: @"Game"] );
    1.70 +        if( ! gameClass || ! [gameClass isSubclassOfClass: [Game class]] )
    1.71 +            return nil;
    1.72 +        game = [[gameClass alloc] initWithUniqueID: uuid];
    1.73 +        [game setNumberOfPlayers: 2];
    1.74 +        if( ! sPersistentGames )
    1.75 +            sPersistentGames = [[NSMutableDictionary alloc] init];
    1.76 +        [sPersistentGames setObject: game forKey: uuid];
    1.77 +        [game release];
    1.78 +    }
    1.79 +    return game;
    1.80 +}
    1.81 +
    1.82 +
    1.83 +- (BOOL) addMoveFromURL: (NSURL*)url
    1.84 +{
    1.85 +    NSDictionary *fields = parseURLFields(url);
    1.86 +    NSString *uuid = [fields objectForKey: @"id"];
    1.87 +    NSString *move = [fields objectForKey: @"move"];
    1.88 +    int turn = [[fields objectForKey: @"turn"] intValue];
    1.89 +    return [uuid isEqualToString: self.uniqueID]
    1.90 +        && turn==self.currentTurn
    1.91 +        && move.length > 0
    1.92 +        && [self applyMoveString: move];
    1.93 +}
    1.94 +
    1.95 +
    1.96 +
    1.97 +@end
    1.98 +
    1.99 +
   1.100 +
   1.101 +static NSDictionary* parseURLFields( NSURL* url )
   1.102 +{
   1.103 +    // Parse the URL into key-value pairs:
   1.104 +    NSMutableDictionary *fields = [NSMutableDictionary dictionary];
   1.105 +    for( NSString *field in [url.resourceSpecifier componentsSeparatedByString: @"&"] ) {
   1.106 +        NSRange e = [field rangeOfString: @"="];
   1.107 +        NSString *key, *value;
   1.108 +        if( e.length>0 ) {
   1.109 +            key = [field substringToIndex: e.location];
   1.110 +            value = [field substringFromIndex: NSMaxRange(e)];
   1.111 +        } else {
   1.112 +            key= field;
   1.113 +            value = @"";
   1.114 +        }
   1.115 +        [fields setObject: value forKey: key];
   1.116 +    }
   1.117 +    return fields;
   1.118 +}