Replace hacky target stringification with structured serialization.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Thu, 28 Feb 2013 13:44:41 +0000 (14:44 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Thu, 28 Feb 2013 13:44:41 +0000 (14:44 +0100)
18 files changed:
ConfigsController.m
KeyInputTextView.h
KeyInputTextView.m
Target.h
Target.m
TargetConfig.h
TargetConfig.m
TargetController.m
TargetKeyboard.h
TargetKeyboard.m
TargetMouseBtn.h
TargetMouseBtn.m
TargetMouseMove.h
TargetMouseMove.m
TargetMouseScroll.h
TargetMouseScroll.m
TargetToggleMouseScope.h
TargetToggleMouseScope.m

index 7db30bf9318d3a6c8bb7d6ddb48bdb75c034fa65..67033d3bc4a22470e267c55164279ba5cea4c2c7 100644 (file)
        return [configs[index] name];
 }
 
-- (void)tableView:(NSTableView *)view setObjectValue:obj forTableColumn:(NSTableColumn *)col row:(int)index {
-       /* ugly hack so stringification doesn't fail */
-       NSString* newName = [(NSString*)obj stringByReplacingOccurrencesOfString: @"~" withString: @""];
-       [(Config *)configs[index] setName:newName];
+- (void)tableView:(NSTableView *)view setObjectValue:(NSString *)obj forTableColumn:(NSTableColumn *)col row:(int)index {
+       [(Config *)configs[index] setName:obj];
        [targetController refreshConfigsPreservingSelection:YES];
        [tableView reloadData];
        [(ApplicationController *)[[NSApplication sharedApplication] delegate] configsChanged];
                cfgInfo[@"name"] = [config name];
                NSMutableDictionary* cfgEntries = [[NSMutableDictionary alloc] init];
                for(id key in [config entries]) {
-                       cfgEntries[key] = [[config entries][key]stringify];
+                       cfgEntries[key] = [[config entries][key] serialize];
                }
                cfgInfo[@"entries"] = cfgEntries;
                [ary addObject: cfgInfo];
        for(int i=0; i<[ary count]; i++) {
                NSDictionary* dict = ary[i][@"entries"];
                for(id key in dict) {
-                       [newConfigs[i] entries][key] = [Target unstringify: dict[key] withConfigList: newConfigs];
+                       [newConfigs[i] entries][key] = [Target targetDeserialize:dict[key] withConfigs:newConfigs];
                }
        }
        
index 05515097c4c55f6fce5d00d64edbd3656556ceca..a3cd4ff00c501c1e6f05243dfc6891cb90ff397e 100644 (file)
@@ -18,6 +18,8 @@
 @property (readonly) BOOL hasKey;
 @property (assign) BOOL enabled;
 
++ (NSString *)stringForKeyCode:(int)keycode;
+
 - (void)clear;
 
 @end
index cde2547d8c8ac455db7e9e2f4741627e919f73c6..7bda696fa07dea90139d3a0be7990729796b051c 100644 (file)
@@ -33,7 +33,7 @@
     return self.vk >= 0;
 }
 
-- (NSString *)stringForKeyCode:(int)keycode {
++ (NSString *)stringForKeyCode:(int)keycode {
     switch(keycode) {
         case   -1: return @"";
         case 0x7a: return @"F1";
 
 - (void)setVk:(int)key {
     vk = key;
-    descr = [self stringForKeyCode:key];
+    descr = [KeyInputTextView stringForKeyCode:key];
     [self setStringValue:descr];
     if (self.hasKey)
         [targetController keyChanged];
index e1d1ff7b3d15c4d6896d4c3a039b0a631119f008..93b181f083acbc820e1496d0d4955485b2190057 100644 (file)
--- a/Target.h
+++ b/Target.h
 - (void)trigger;
 - (void)untrigger;
 - (BOOL)update:(JoystickController *)jc;
-- (NSString*) stringify;
-+ (Target *)unstringify:(NSString*)str withConfigList:(NSArray*)configs;
+
+- (NSDictionary *)serialize;
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs;
++ (NSString *)serializationCode;
 
 @end
index 6b208e8785626f9d4f27614b36a709f7b3baaa2c..35af1844ba195cb9a86f195589b0e8a03966a2e1 100644 (file)
--- a/Target.m
+++ b/Target.m
 
 @synthesize magnitude;
 
-// TODO: Should just be NSCoding? Or like a dictionary?
-+(Target*) unstringify: (NSString*) str withConfigList: (NSArray*) configs {
-    NSArray* components = [str componentsSeparatedByString:@"~"];
-    NSParameterAssert([components count]);
-    NSString* typeTag = components[0];
-    if([typeTag isEqualToString:@"key"])
-        return [TargetKeyboard unstringifyImpl:components];
-    if([typeTag isEqualToString:@"cfg"])
-        return [TargetConfig unstringifyImpl:components withConfigList:configs];
-    if([typeTag isEqualToString:@"mmove"])
-        return [TargetMouseMove unstringifyImpl:components];
-    if([typeTag isEqualToString:@"mbtn"])
-        return [TargetMouseBtn unstringifyImpl:components];
-    if([typeTag isEqualToString:@"mscroll"])
-        return [TargetMouseScroll unstringifyImpl:components];
-    if([typeTag isEqualToString:@"mtoggle"])
-        return [TargetToggleMouseScope unstringifyImpl:components];
-    
-    NSParameterAssert(NO);
-    return NULL;
++ (NSString *)serializationCode {
+    [self doesNotRecognizeSelector:_cmd];
+    return nil;
 }
 
-- (NSString *)stringify {
+- (NSDictionary *)serialize {
     [self doesNotRecognizeSelector:_cmd];
-    return NULL;
+    return nil;    
+}
+
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs {
+    // Don't crash loading old configs (but don't load them either).
+    if (![serialization isKindOfClass:[NSDictionary class]])
+        return nil;
+    NSString *type = serialization[@"type"];
+    for (Class cls in @[[TargetKeyboard class],
+                        [TargetConfig class],
+                        [TargetMouseMove class],
+                        [TargetMouseBtn class],
+                        [TargetMouseScroll class],
+                        [TargetToggleMouseScope class]
+         ]) {
+        if ([type isEqualToString:[cls serializationCode]])
+            return [cls targetDeserialize:serialization withConfigs:configs];
+    }
+    
+    return nil;
 }
 
 - (void)trigger {
index 0df08352b7d207acee6f1743c49049899b7f0e49..3f453ff73d6065a1aec3c4ac8837a0eddb36ae3f 100644 (file)
@@ -13,6 +13,5 @@
 @interface TargetConfig : Target
 
 @property (weak) Config *config;
-+ (TargetConfig *)unstringifyImpl:(NSArray *)comps withConfigList:(NSArray *)configs;
 
 @end
index 763bbac7157001ff217aad3fc06f07da458a57f3..1fef7a9231d1274a3f1977536a2a8ecbe3132de3 100644 (file)
 
 @implementation TargetConfig
 
-- (NSString *)stringify {
-    return [[NSString alloc] initWithFormat: @"cfg~%@", self.config.name];
++ (NSString *)serializationCode {
+    return @"cfg";
 }
 
-+ (TargetConfig *)unstringifyImpl:(NSArray *)comps withConfigList:(NSArray *)configs {
-    NSString *name = comps[1];
+- (NSDictionary *)serialize {
+    return self.config
+        ? @{ @"type": @"cfg", @"name": self.config.name }
+        : @{};
+}
+
++ (TargetConfig *)targetDeserialize:(NSDictionary *)serialization
+                        withConfigs:(NSArray *)configs {
+    NSString *name = serialization[@"name"];
     TargetConfig *target = [[TargetConfig alloc] init];
     for (Config *config in configs) {
         if ([config.name isEqualToString:name]) {
@@ -26,7 +33,6 @@
             return target;
         }
     }
-    NSLog(@"Warning: couldn't find matching config to restore from: %@", name);
     return nil;
 }
 
index 3fc0f288ad9ce7033e17e70732e0cf5028a316b9..8afaaf2fc6056d2f79140875fde15dff400f767d 100644 (file)
@@ -55,7 +55,6 @@
                        if(keyInput.hasKey) {
                                TargetKeyboard* k = [[TargetKeyboard alloc] init];
                                [k setVk: [keyInput vk]];
-                               [k setDescr: [keyInput descr]];
                                return k;
                        }
                        break;
index 6ff088b78412e28f2097069fe89b23622501a3fa..65993320a1acb0bafcf94283fc8359d51248b794 100644 (file)
@@ -8,14 +8,9 @@
 
 #import "Target.h"
 
-@interface TargetKeyboard : Target {
-       CGKeyCode vk;
-       NSString* descr;
-}
+@interface TargetKeyboard : Target
 
-@property (readwrite) CGKeyCode vk;
-@property (readwrite, copy) NSString* descr;
-
-+(TargetKeyboard*) unstringifyImpl: (NSArray*) comps;
+@property (assign) CGKeyCode vk;
+@property (readonly) NSString* descr;
 
 @end
index e7bd8e761694dc0459f17ea10c472d37464beb3a..d19c65f039df547d4818d34c7e8f6349a70832eb 100644 (file)
@@ -7,19 +7,24 @@
 
 #import "TargetKeyboard.h"
 
+#import "KeyInputTextView.h"
+
 @implementation TargetKeyboard
 
-@synthesize vk, descr;
+@synthesize vk;
+
++ (NSString *)serializationCode {
+    return @"key";
+}
 
--(NSString*) stringify {
-       return [[NSString alloc] initWithFormat: @"key~%d~%@", vk, descr];
+- (NSDictionary *)serialize {
+    return @{ @"type": @"key", @"key": @(self.vk) };
 }
 
-+(TargetKeyboard*) unstringifyImpl: (NSArray*) comps {
-       NSParameterAssert([comps count] == 3);
-       TargetKeyboard* target = [[TargetKeyboard alloc] init];
-       [target setVk: [comps[1] integerValue]];
-       [target setDescr: comps[2]];
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs {
+       TargetKeyboard *target = [[TargetKeyboard alloc] init];
+    target.vk = [serialization[@"key"] intValue];
        return target;
 }
 
@@ -35,4 +40,8 @@
        CFRelease(keyUp);
 }
 
+- (NSString *)descr {
+    return [KeyInputTextView stringForKeyCode:self.vk];
+}
+
 @end
index 29153d8ceddaf57a7cc0409c27beda15a7776f0e..a0b85166526544a45531e96f96655a62b09b7131 100644 (file)
@@ -8,12 +8,8 @@
 
 #import "Target.h"
 
-@interface TargetMouseBtn : Target {
-    CGMouseButton which;
-}
+@interface TargetMouseBtn : Target
 
-@property(readwrite) CGMouseButton which;
-
-+(TargetMouseBtn*) unstringifyImpl: (NSArray*) comps;
+@property (assign) CGMouseButton which;
 
 @end
index e8d77e42f6c67364557d835ef860a0e00d4383bd..28fe536345c24fa88f3e490e320b688da0504fa1 100644 (file)
 
 @synthesize which;
 
--(NSString*) stringify {
-       return [[NSString alloc] initWithFormat: @"mbtn~%u", which];
++ (NSString *)serializationCode {
+    return @"mbtn";
 }
 
-+(TargetMouseBtn*) unstringifyImpl: (NSArray*) comps {
-       NSParameterAssert([comps count] == 2);
-       TargetMouseBtn* target = [[TargetMouseBtn alloc] init];
-       [target setWhich: [comps[1] integerValue]];
+- (NSDictionary *)serialize {
+    return @{ @"type": @"mbtn", @"which": @(self.which) };
+}
+
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs {
+       TargetMouseBtn *target = [[TargetMouseBtn alloc] init];
+    target.which = [serialization[@"which"] intValue];
        return target;
 }
 
index f486a96f53c45b4b2cbe9bdd13bca57207f424d8..24efa406fa8b30b93c36e0c4b29689ef72017b2c 100644 (file)
@@ -8,12 +8,8 @@
 
 #import "Target.h"
 
-@interface TargetMouseMove : Target {
-    int dir;
-}
+@interface TargetMouseMove : Target
 
-@property(readwrite) int dir;
-
-+(TargetMouseMove*) unstringifyImpl: (NSArray*) comps;
+@property (assign) int dir;
 
 @end
index 5f83dbfdc9cc167b69d2360a678fb6da4f6b7437..8eeae88d3dfae9b3e2a240bc85f908ecafaddf3d 100644 (file)
 
 @synthesize dir;
 
--(NSString*) stringify {
-       return [[NSString alloc] initWithFormat: @"mmove~%d", dir];
++ (NSString *)serializationCode {
+    return @"mmove";
 }
 
-+(TargetMouseMove*) unstringifyImpl: (NSArray*) comps {
-       NSParameterAssert([comps count] == 2);
-       TargetMouseMove* target = [[TargetMouseMove alloc] init];
-       [target setDir: [comps[1] integerValue]];
+- (NSDictionary *)serialize {
+    return @{ @"type": @"mmove", @"dir": @(self.dir) };
+}
+
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs {
+       TargetMouseMove *target = [[TargetMouseMove alloc] init];
+    target.dir = [serialization[@"dir"] intValue];
        return target;
 }
 
index a53a02e79a2660331227a758ec41e8cd6aeef85f..cdfe010157a674096e6ce5ced8d4f2433cb449d5 100644 (file)
@@ -8,12 +8,8 @@
 
 #import "Target.h"
 
-@interface TargetMouseScroll : Target {
-    int howMuch;
-}
+@interface TargetMouseScroll : Target
 
-@property(readwrite) int howMuch;
-
-+(TargetMouseScroll*) unstringifyImpl: (NSArray*) comps;
+@property (assign) int howMuch;
 
 @end
index 79bc5421f371bfe97e6aecd24882e183247a810d..3c417c1264a56576d0d4d2870af97d219acfdbb3 100644 (file)
 
 @synthesize howMuch;
 
--(NSString*) stringify {
-       return [[NSString alloc] initWithFormat: @"mscroll~%d", howMuch];
++ (NSString *)serializationCode {
+    return @"mscroll";
 }
 
-+(TargetMouseScroll*) unstringifyImpl: (NSArray*) comps {
-       NSParameterAssert([comps count] == 2);
-       TargetMouseScroll* target = [[TargetMouseScroll alloc] init];
-       [target setHowMuch: [comps[1] integerValue]];
-       return target;
+- (NSDictionary *)serialize {
+    return @{ @"type": @"mscroll", @"howMuch": @(self.howMuch) };
 }
 
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs {
+       TargetMouseScroll *target = [[TargetMouseScroll alloc] init];
+    target.howMuch = [serialization[@"howMuch"] intValue];
+       return target;
+}
 -(void) trigger {
     CGEventRef scroll = CGEventCreateScrollWheelEvent(NULL,
                                                       kCGScrollEventUnitLine,
                                                       1,
-                                                      [self howMuch]);
+                                                      self.howMuch);
     CGEventPost(kCGHIDEventTap, scroll);
     CFRelease(scroll);
 }
index f167b5e788804f379f82bf192862ac566657ef04..45c79ba0f00cfe727178a967cb01b6d17618234e 100644 (file)
@@ -10,6 +10,4 @@
 
 @interface TargetToggleMouseScope : Target
 
-+(TargetToggleMouseScope*) unstringifyImpl: (NSArray*) comps;
-
 @end
index d6833fcd1888e08f2733731b171313c22d465417..4f1d157aeac9a9f09afead7536b1f7a7bbb763fd 100644 (file)
 
 @implementation TargetToggleMouseScope
 
--(NSString*) stringify {
-       return [[NSString alloc] initWithFormat: @"mtoggle"];
++ (NSString *)serializationCode {
+    return @"mtoggle";
 }
 
-+(TargetToggleMouseScope*) unstringifyImpl: (NSArray*) comps {
-       NSParameterAssert([comps count] == 1);
-       TargetToggleMouseScope* target = [[TargetToggleMouseScope alloc] init];
-       return target;
+- (NSDictionary *)serialize {
+    return @{ @"type": @"mtoggle" };
 }
 
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs {
+       TargetToggleMouseScope *target = [[TargetToggleMouseScope alloc] init];
+       return target;
+}
 - (void)trigger {
     // FIXME: It's hacky to get at the controller this way, but it's
     // also hacky to pass it. Shouldn't need to do either.