X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=Classes%2FNJMapping.m;h=1b05c424bfe708ab23698b07448ffea79c368eec;hp=8cc572407945ac02b21a1171123e94e884a16995;hb=HEAD;hpb=0064c1fbff36795885a9724081af2a17d83c20a3 diff --git a/Classes/NJMapping.m b/Classes/NJMapping.m index 8cc5724..1b05c42 100644 --- a/Classes/NJMapping.m +++ b/Classes/NJMapping.m @@ -10,16 +10,45 @@ #import "NJInput.h" #import "NJOutput.h" -@implementation NJMapping +@implementation NJMapping { + NSMutableDictionary *_entries; +} -- (id)initWithName:(NSString *)name { +// Extra checks during initialization because the data is often loaded +// from untrusted serializations. + +- (id)init { if ((self = [super init])) { - self.name = name ? name : @"Untitled"; + self.name = NSLocalizedString(@"Untitled", @"name for new mappings"); _entries = [[NSMutableDictionary alloc] init]; } return self; } +- (id)initWithName:(NSString *)name { + if ((self = [self init])) { + if ([name isKindOfClass:NSString.class]) + self.name = name; + } + return self; +} + +- (id)initWithSerialization:(NSDictionary *)serialization { + if ((self = [self initWithName:serialization[@"name"]])) { + NSDictionary *entries = serialization[@"entries"]; + if ([entries isKindOfClass:NSDictionary.class]) { + for (id key in entries) { + if ([key isKindOfClass:NSString.class]) { + NJOutput *output = [NJOutput outputWithSerialization:entries[key]]; + if (output) + _entries[key] = output; + } + } + } + } + return self; +} + - (NJOutput *)objectForKeyedSubscript:(NJInput *)input { return input ? _entries[input.uid] : nil; } @@ -54,11 +83,28 @@ return success; } -+ (id)mappingWithContentsOfURL:(NSURL *)url mappings:(NSArray *)mappings error:(NSError **)error { +- (NSUInteger)count { + return _entries.count; +} + +- (BOOL)hasConflictWith:(NJMapping *)other { + if (other.count < self.count) + return [other hasConflictWith:self]; + for (NSString *uid in _entries) { + NJOutput *output = other->_entries[uid]; + if (output && ![output isEqual:_entries[uid]]) + return YES; + } + return NO; +} + ++ (id)mappingWithContentsOfURL:(NSURL *)url error:(NSError **)error { NSInputStream *stream = [NSInputStream inputStreamWithURL:url]; [stream open]; NSDictionary *serialization = stream && !*error - ? [NSJSONSerialization JSONObjectWithStream:stream options:0 error:error] + ? [NSJSONSerialization JSONObjectWithStream:stream + options:(NSJSONReadingOptions)0 + error:error] : nil; [stream close]; @@ -70,22 +116,23 @@ && [serialization[@"entries"] isKindOfClass:NSDictionary.class])) { *error = [NSError errorWithDomain:@"Enjoyable" code:0 - description:@"This isn't a valid mapping file."]; + description:NSLocalizedString(@"invalid mapping file", + @"error when imported file was JSON but not a mapping")]; return nil; } - NSDictionary *entries = serialization[@"entries"]; - NJMapping *mapping = [[NJMapping alloc] initWithName:serialization[@"name"]]; - for (id key in entries) { - NSDictionary *value = entries[key]; - if ([key isKindOfClass:NSString.class]) { - NJOutput *output = [NJOutput outputDeserialize:value - withMappings:mappings]; - if (output) - mapping.entries[key] = output; - } - } - return mapping; + return [[NJMapping alloc] initWithSerialization:serialization]; +} + +- (void)mergeEntriesFrom:(NJMapping *)other { + if (other) + [_entries addEntriesFromDictionary:other->_entries]; } +- (void)postLoadProcess:(id )allMappings { + for (NJOutput *o in _entries.allValues) + [o postLoadProcess:allMappings]; +} + + @end