From: Joe Wreschnig Date: Thu, 28 Feb 2013 13:44:41 +0000 (+0100) Subject: Replace hacky target stringification with structured serialization. X-Git-Tag: version-1.0~98 X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=commitdiff_plain;h=0a402879ee3beb79bb4d2270f909ad75eead0c96 Replace hacky target stringification with structured serialization. --- diff --git a/ConfigsController.m b/ConfigsController.m index 7db30bf..67033d3 100644 --- a/ConfigsController.m +++ b/ConfigsController.m @@ -94,10 +94,8 @@ 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]; @@ -127,7 +125,7 @@ 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]; @@ -151,7 +149,7 @@ 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]; } } diff --git a/KeyInputTextView.h b/KeyInputTextView.h index 0551509..a3cd4ff 100644 --- a/KeyInputTextView.h +++ b/KeyInputTextView.h @@ -18,6 +18,8 @@ @property (readonly) BOOL hasKey; @property (assign) BOOL enabled; ++ (NSString *)stringForKeyCode:(int)keycode; + - (void)clear; @end diff --git a/KeyInputTextView.m b/KeyInputTextView.m index cde2547..7bda696 100644 --- a/KeyInputTextView.m +++ b/KeyInputTextView.m @@ -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"; @@ -176,7 +176,7 @@ - (void)setVk:(int)key { vk = key; - descr = [self stringForKeyCode:key]; + descr = [KeyInputTextView stringForKeyCode:key]; [self setStringValue:descr]; if (self.hasKey) [targetController keyChanged]; diff --git a/Target.h b/Target.h index e1d1ff7..93b181f 100644 --- a/Target.h +++ b/Target.h @@ -17,7 +17,10 @@ - (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 diff --git a/Target.m b/Target.m index 6b208e8..35af184 100644 --- a/Target.m +++ b/Target.m @@ -20,31 +20,34 @@ @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 { diff --git a/TargetConfig.h b/TargetConfig.h index 0df0835..3f453ff 100644 --- a/TargetConfig.h +++ b/TargetConfig.h @@ -13,6 +13,5 @@ @interface TargetConfig : Target @property (weak) Config *config; -+ (TargetConfig *)unstringifyImpl:(NSArray *)comps withConfigList:(NSArray *)configs; @end diff --git a/TargetConfig.m b/TargetConfig.m index 763bbac..1fef7a9 100644 --- a/TargetConfig.m +++ b/TargetConfig.m @@ -13,12 +13,19 @@ @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; } diff --git a/TargetController.m b/TargetController.m index 3fc0f28..8afaaf2 100644 --- a/TargetController.m +++ b/TargetController.m @@ -55,7 +55,6 @@ if(keyInput.hasKey) { TargetKeyboard* k = [[TargetKeyboard alloc] init]; [k setVk: [keyInput vk]]; - [k setDescr: [keyInput descr]]; return k; } break; diff --git a/TargetKeyboard.h b/TargetKeyboard.h index 6ff088b..6599332 100644 --- a/TargetKeyboard.h +++ b/TargetKeyboard.h @@ -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 diff --git a/TargetKeyboard.m b/TargetKeyboard.m index e7bd8e7..d19c65f 100644 --- a/TargetKeyboard.m +++ b/TargetKeyboard.m @@ -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 diff --git a/TargetMouseBtn.h b/TargetMouseBtn.h index 29153d8..a0b8516 100644 --- a/TargetMouseBtn.h +++ b/TargetMouseBtn.h @@ -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 diff --git a/TargetMouseBtn.m b/TargetMouseBtn.m index e8d77e4..28fe536 100644 --- a/TargetMouseBtn.m +++ b/TargetMouseBtn.m @@ -12,14 +12,18 @@ @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; } diff --git a/TargetMouseMove.h b/TargetMouseMove.h index f486a96..24efa40 100644 --- a/TargetMouseMove.h +++ b/TargetMouseMove.h @@ -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 diff --git a/TargetMouseMove.m b/TargetMouseMove.m index 5f83dbf..8eeae88 100644 --- a/TargetMouseMove.m +++ b/TargetMouseMove.m @@ -18,14 +18,18 @@ @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; } diff --git a/TargetMouseScroll.h b/TargetMouseScroll.h index a53a02e..cdfe010 100644 --- a/TargetMouseScroll.h +++ b/TargetMouseScroll.h @@ -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 diff --git a/TargetMouseScroll.m b/TargetMouseScroll.m index 79bc542..3c417c1 100644 --- a/TargetMouseScroll.m +++ b/TargetMouseScroll.m @@ -12,22 +12,25 @@ @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); } diff --git a/TargetToggleMouseScope.h b/TargetToggleMouseScope.h index f167b5e..45c79ba 100644 --- a/TargetToggleMouseScope.h +++ b/TargetToggleMouseScope.h @@ -10,6 +10,4 @@ @interface TargetToggleMouseScope : Target -+(TargetToggleMouseScope*) unstringifyImpl: (NSArray*) comps; - @end diff --git a/TargetToggleMouseScope.m b/TargetToggleMouseScope.m index d6833fc..4f1d157 100644 --- a/TargetToggleMouseScope.m +++ b/TargetToggleMouseScope.m @@ -13,16 +13,19 @@ @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.