jens@8: // jens@8: // Game-Persistence.m jens@8: // GeekGameBoard jens@8: // jens@8: // Created by Jens Alfke on 3/16/08. jens@8: // Copyright 2008 __MyCompanyName__. All rights reserved. jens@8: // jens@8: jens@8: #import "Game-Persistence.h" jens@8: jens@8: jens@8: static NSDictionary* parseURLFields( NSURL* url ); jens@8: jens@8: jens@8: @implementation Game (Persistence) jens@8: jens@8: jens@8: static NSMutableDictionary *sPersistentGames; jens@8: jens@8: jens@8: - (id) initWithCoder: (NSCoder*)decoder jens@8: { jens@8: self = [self init]; jens@8: if( self ) { jens@8: _players = [[decoder decodeObjectForKey: @"players"] mutableCopy]; jens@8: _states = [[decoder decodeObjectForKey: @"states"] mutableCopy]; jens@8: _moves = [[decoder decodeObjectForKey: @"moves"] mutableCopy]; jens@8: self.currentTurn = self.maxTurn; jens@8: } jens@8: return self; jens@8: } jens@8: jens@8: jens@8: - (void) encodeWithCoder: (NSCoder*)coder jens@8: { jens@8: [coder encodeObject: _players forKey: @"players"]; jens@8: [coder encodeObject: _states forKey: @"states"]; jens@8: [coder encodeObject: _moves forKey: @"moves"]; jens@8: } jens@8: jens@8: jens@8: - (NSURL*) asURL jens@8: { jens@8: return [NSURL URLWithString: jens@8: [NSString stringWithFormat: @"game:type=%@&id=%@&turn=%u&move=%@", jens@8: [[self class] identifier], _uniqueID, self.currentTurn,_moves.lastObject]]; jens@8: } jens@8: jens@8: jens@8: + (Game*) gameWithURL: (NSURL*)url jens@8: { jens@8: if( 0 != [@"game" caseInsensitiveCompare: url.scheme] ) jens@8: return nil; jens@8: NSDictionary *fields = parseURLFields(url); jens@8: NSString *type = [fields objectForKey: @"type"]; jens@8: NSString *uuid = [fields objectForKey: @"id"]; jens@8: int turn = [[fields objectForKey: @"turn"] intValue]; jens@8: if( !type || !uuid || turn<=0 ) jens@8: return nil; jens@8: jens@8: Game *game = [sPersistentGames objectForKey: uuid]; jens@8: if( game ) { jens@8: if( ![type isEqualToString: [[game class] identifier]] ) jens@8: return nil; jens@8: } else if( turn == 1 ) { jens@8: Class gameClass = NSClassFromString( [type stringByAppendingString: @"Game"] ); jens@8: if( ! gameClass || ! [gameClass isSubclassOfClass: [Game class]] ) jens@8: return nil; jens@8: game = [[gameClass alloc] initWithUniqueID: uuid]; jens@8: [game setNumberOfPlayers: 2]; jens@8: if( ! sPersistentGames ) jens@8: sPersistentGames = [[NSMutableDictionary alloc] init]; jens@8: [sPersistentGames setObject: game forKey: uuid]; jens@8: [game release]; jens@8: } jens@8: return game; jens@8: } jens@8: jens@8: jens@8: - (BOOL) addMoveFromURL: (NSURL*)url jens@8: { jens@8: NSDictionary *fields = parseURLFields(url); jens@8: NSString *uuid = [fields objectForKey: @"id"]; jens@8: NSString *move = [fields objectForKey: @"move"]; jens@8: int turn = [[fields objectForKey: @"turn"] intValue]; jens@8: return [uuid isEqualToString: self.uniqueID] jens@8: && turn==self.currentTurn jens@8: && move.length > 0 jens@8: && [self applyMoveString: move]; jens@8: } jens@8: jens@8: jens@8: jens@8: @end jens@8: jens@8: jens@8: jens@8: static NSDictionary* parseURLFields( NSURL* url ) jens@8: { jens@8: // Parse the URL into key-value pairs: jens@8: NSMutableDictionary *fields = [NSMutableDictionary dictionary]; jens@8: for( NSString *field in [url.resourceSpecifier componentsSeparatedByString: @"&"] ) { jens@8: NSRange e = [field rangeOfString: @"="]; jens@8: NSString *key, *value; jens@8: if( e.length>0 ) { jens@8: key = [field substringToIndex: e.location]; jens@8: value = [field substringFromIndex: NSMaxRange(e)]; jens@8: } else { jens@8: key= field; jens@8: value = @""; jens@8: } jens@8: [fields setObject: value forKey: key]; jens@8: } jens@8: return fields; jens@8: }