1// 2// KTMutableMatrixImp 3// KTMatrix 4// 5// Implements a mutable KTMutableMatrix subclass 6// 7// Copyright (c) 2002 Chris Purcell. All rights reserved. 8// 9// You may use this code for whatever purposes you wish. 10// This code comes with no warranties, implied or otherwise. 11// Using it may damage your data. It shouldn't, but save a copy first. 12// That's a good idea anyway, actually. 13// 14 15#import "KTMutableMatrixImp.h" 16 17@implementation KTMutableMatrixImp 18 19+ (id)matrixWithMatrix:(KTMatrix *)other 20{ 21 return [[[self alloc] initWithMatrix:other] autorelease]; 22} 23+ (id)matrixWithLocationHash:(id<KTLocationHash>)locationHash 24 objects:(NSArray *)objects 25 atLocations:(NSArray *)loc1s 26 byLocations:(NSArray *)loc2s 27{ 28 return [[[self alloc] initWithLocationHash:locationHash 29 objects:objects 30 atLocations:loc1s 31 byLocations:loc2s] autorelease]; 32} 33+ (id)matrixWithCapacity:(unsigned)numItems 34 locationHash:(id<KTLocationHash>)_hs 35{ 36 return [[KTMutableMatrixImp alloc] initWithCapacity:numItems 37 locationHash:_hs]; 38} 39- (id)initWithMatrix:(KTMatrix *)other 40{ 41 if ((self = [super init])) 42 { 43 matrix = [[other matrixData] mutableCopyWithZone:[self zone]]; 44 if ([[other locationHash] zone] == [self zone]) 45 hash = [[other locationHash] retain]; 46 else 47 hash = [[other locationHash] copyWithZone:[self zone]]; 48 } 49 return self; 50} 51- (id)initWithMatrixData:(NSDictionary *)matrixData 52 locationHash:(id<KTLocationHash>)locationHash 53{ 54 if ((self = [super init])) 55 { 56 matrix = [matrixData mutableCopyWithZone:[self zone]]; 57 if ([locationHash zone] == [self zone]) 58 hash = [locationHash retain]; 59 else 60 hash = [locationHash copyWithZone:[self zone]]; 61 } 62 return self; 63} 64- (id)initWithLocationHash:(id<KTLocationHash>)locationHash 65{ 66 if ((self = [super init])) 67 { 68 matrix = [[NSMutableDictionary allocWithZone:[self zone]] init]; 69 if ([locationHash zone] == [self zone]) 70 hash = [locationHash retain]; 71 else 72 hash = [locationHash copyWithZone:[self zone]]; 73 } 74 return self; 75} 76- (id)initWithLocationHash:(id<KTLocationHash>)locationHash 77 objects:(NSArray *)objects 78 atLocations:(NSArray *)loc1s 79 byLocations:(NSArray *)loc2s 80{ 81 if ((self = [super init])) 82 { 83 NSMutableArray *indices = [[NSMutableArray alloc] initWithCapacity: 84 [loc1s count]]; 85 unsigned i; 86 87 if ([locationHash zone] == [self zone]) 88 hash = [locationHash retain]; 89 else 90 hash = [locationHash copyWithZone:[self zone]]; 91 92 NSAssert([objects count] == [loc1s count], 93 @"Objects and locations arrays not of equal length"); 94 NSAssert([loc1s count] == [loc2s count], 95 @"Locations arrays not of equal length"); 96 for (i = 0; i < [loc1s count]; i++) 97 { 98 [indices addObject:[NSNumber numberWithInt: 99 [hash hashForLocation:[loc1s objectAtIndex:i] 100 byLocation:[loc2s objectAtIndex:i]]]]; 101 } 102 matrix = [[NSMutableDictionary allocWithZone:[self zone]] 103 initWithObjects:objects 104 forKeys:indices]; 105 106 [indices release]; 107 } 108 return self; 109} 110- (id)initWithCapacity:(unsigned)numItems 111 locationHash:(id<KTLocationHash>)locationHash 112{ 113 if ((self = [super init])) 114 { 115 matrix = [[NSMutableDictionary allocWithZone:[self zone]] 116 initWithCapacity:numItems]; 117 if ([locationHash zone] == [self zone]) 118 hash = [locationHash retain]; 119 else 120 hash = [locationHash copyWithZone:[self zone]]; 121 } 122 return self; 123} 124 125 126// Accessor methods 127- (id)objectAtLocation:(NSDictionary *)loc 128 byLocation:(NSDictionary *)loc2; 129{ 130 return [matrix objectForKey:[NSNumber numberWithInt:[hash 131 hashForLocation:loc byLocation:loc2]]]; 132} 133 134- (id<KTLocationHash>)locationHash 135{ return hash; } 136- (NSDictionary *)matrixData 137{ return matrix; } 138 139- (NSEnumerator *)objectEnumerator 140{ return [matrix objectEnumerator]; } 141- (unsigned)count 142{ return [matrix count]; } 143 144 145//// Mutator methods 146- (void)setMatrix:(KTMatrix *)other 147{ 148 [matrix release]; 149 [hash release]; 150 matrix = [[other matrixData] mutableCopyWithZone:[self zone]]; 151 if ([[other locationHash] zone] == [self zone]) 152 hash = [[other locationHash] retain]; 153 else 154 hash = [[other locationHash] copyWithZone:[self zone]]; 155} 156- (void)setObject:(id)object 157 atLocation:(NSDictionary *)loc1 158 byLocation:(NSDictionary *)loc2 159{ 160 [matrix setObject:object 161 forKey:[NSNumber numberWithInt:[hash 162 hashForLocation:loc1 163 byLocation:loc2]]]; 164} 165- (void)removeObjectAtLocation:(NSDictionary *)loc1 166 byLocation:(NSDictionary *)loc2; 167{ 168 [matrix removeObjectForKey:[NSNumber numberWithInt:[hash 169 hashForLocation:loc1 170 byLocation:loc2]]]; 171} 172- (void)removeAllObjects 173{ 174 [matrix removeAllObjects]; 175} 176 177- (void)dealloc 178{ 179 [matrix release]; 180 [hash release]; 181} 182@end 183