Have device controller setup itself rather than relying on the application delegate...
[enjoyable.git] / Classes / NJMapping.m
1 //
2 // NJMapping.m
3 // Enjoy
4 //
5 // Created by Sam McCall on 4/05/09.
6 //
7
8 #import "NJMapping.h"
9
10 #import "NJInput.h"
11 #import "NJOutput.h"
12
13 @implementation NJMapping
14
15 - (id)initWithName:(NSString *)name {
16 if ((self = [super init])) {
17 self.name = name ? name : @"Untitled";
18 _entries = [[NSMutableDictionary alloc] init];
19 }
20 return self;
21 }
22
23 - (NJOutput *)objectForKeyedSubscript:(NJInput *)input {
24 return input ? _entries[input.uid] : nil;
25 }
26
27 - (void)setObject:(NJOutput *)output forKeyedSubscript:(NJInput *)input {
28 if (input) {
29 if (output)
30 _entries[input.uid] = output;
31 else
32 [_entries removeObjectForKey:input.uid];
33 }
34 }
35
36 - (NSDictionary *)serialize {
37 NSMutableDictionary *entries = [[NSMutableDictionary alloc] initWithCapacity:_entries.count];
38 for (id key in _entries) {
39 id serialized = [_entries[key] serialize];
40 if (serialized)
41 entries[key] = serialized;
42 }
43 return @{ @"name": _name, @"entries": entries };
44 }
45
46 - (BOOL)writeToURL:(NSURL *)url error:(NSError **)error {
47 [NSProcessInfo.processInfo disableSuddenTermination];
48 NSDictionary *serialization = [self serialize];
49 NSData *json = [NSJSONSerialization dataWithJSONObject:serialization
50 options:NSJSONWritingPrettyPrinted
51 error:error];
52 BOOL success = json && [json writeToURL:url options:NSDataWritingAtomic error:error];
53 [NSProcessInfo.processInfo enableSuddenTermination];
54 return success;
55 }
56
57 + (id)mappingWithContentsOfURL:(NSURL *)url mappings:(NSArray *)mappings error:(NSError **)error {
58 NSInputStream *stream = [NSInputStream inputStreamWithURL:url];
59 [stream open];
60 NSDictionary *serialization = stream && !*error
61 ? [NSJSONSerialization JSONObjectWithStream:stream options:0 error:error]
62 : nil;
63 [stream close];
64
65 if (!serialization && error)
66 return nil;
67
68 if (!([serialization isKindOfClass:NSDictionary.class]
69 && [serialization[@"name"] isKindOfClass:NSString.class]
70 && [serialization[@"entries"] isKindOfClass:NSDictionary.class])) {
71 *error = [NSError errorWithDomain:@"Enjoyable"
72 code:0
73 description:@"This isn't a valid mapping file."];
74 return nil;
75 }
76
77 NSDictionary *entries = serialization[@"entries"];
78 NJMapping *mapping = [[NJMapping alloc] initWithName:serialization[@"name"]];
79 for (id key in entries) {
80 NSDictionary *value = entries[key];
81 if ([key isKindOfClass:NSString.class]) {
82 NJOutput *output = [NJOutput outputDeserialize:value
83 withMappings:mappings];
84 if (output)
85 mapping.entries[key] = output;
86 }
87 }
88 return mapping;
89 }
90
91 @end