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];
}
}
@property (readonly) BOOL hasKey;
@property (assign) BOOL enabled;
++ (NSString *)stringForKeyCode:(int)keycode;
+
- (void)clear;
@end
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];
- (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
@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 {
@interface TargetConfig : Target
@property (weak) Config *config;
-+ (TargetConfig *)unstringifyImpl:(NSArray *)comps withConfigList:(NSArray *)configs;
@end
@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]) {
return target;
}
}
- NSLog(@"Warning: couldn't find matching config to restore from: %@", name);
return nil;
}
if(keyInput.hasKey) {
TargetKeyboard* k = [[TargetKeyboard alloc] init];
[k setVk: [keyInput vk]];
- [k setDescr: [keyInput descr]];
return k;
}
break;
#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
#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;
}
CFRelease(keyUp);
}
+- (NSString *)descr {
+ return [KeyInputTextView stringForKeyCode:self.vk];
+}
+
@end
#import "Target.h"
-@interface TargetMouseBtn : Target {
- CGMouseButton which;
-}
+@interface TargetMouseBtn : Target
-@property(readwrite) CGMouseButton which;
-
-+(TargetMouseBtn*) unstringifyImpl: (NSArray*) comps;
+@property (assign) CGMouseButton which;
@end
@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;
}
#import "Target.h"
-@interface TargetMouseMove : Target {
- int dir;
-}
+@interface TargetMouseMove : Target
-@property(readwrite) int dir;
-
-+(TargetMouseMove*) unstringifyImpl: (NSArray*) comps;
+@property (assign) int dir;
@end
@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;
}
#import "Target.h"
-@interface TargetMouseScroll : Target {
- int howMuch;
-}
+@interface TargetMouseScroll : Target
-@property(readwrite) int howMuch;
-
-+(TargetMouseScroll*) unstringifyImpl: (NSArray*) comps;
+@property (assign) int howMuch;
@end
@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);
}
@interface TargetToggleMouseScope : Target
-+(TargetToggleMouseScope*) unstringifyImpl: (NSArray*) comps;
-
@end
@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.