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 +}