From 51d43664909060e85c943c4d63cc3cff307ceb1d Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Wed, 27 Feb 2013 18:28:05 +0100 Subject: [PATCH] Automatically trigger/untrigger targets based on setting the 'running' property; set it directly from action activity state. Add action/target magnitudes, usually zero, except for analog sticks. --- JSAction.h | 3 ++- JSAction.m | 6 ++--- JSActionAnalog.h | 1 - JSActionAnalog.m | 22 +++++++-------- JoystickController.h | 2 ++ JoystickController.m | 34 ++++++++--------------- SubAction.h | 2 -- SubAction.m | 6 +---- Target.h | 21 +++++++-------- Target.m | 58 +++++++++++++++++++++++++--------------- TargetKeyboard.m | 4 +-- TargetMouseBtn.m | 4 +-- TargetMouseMove.m | 18 ++++--------- TargetMouseScroll.m | 2 +- TargetToggleMouseScope.m | 6 ++++- 15 files changed, 91 insertions(+), 98 deletions(-) diff --git a/JSAction.h b/JSAction.h index 30e99b9..8e52e9c 100644 --- a/JSAction.h +++ b/JSAction.h @@ -19,7 +19,8 @@ @property (copy) NSArray *children; @property (strong) id base; @property (copy) NSString *name; -@property (readonly) BOOL active; +@property (assign) BOOL active; +@property (readonly) float magnitude; - (void)notifyEvent:(IOHIDValueRef)value; - (NSString *)stringify; diff --git a/JSAction.m b/JSAction.m index 84d1ea8..8576b2f 100644 --- a/JSAction.m +++ b/JSAction.m @@ -14,6 +14,7 @@ @synthesize children; @synthesize base; @synthesize name; +@synthesize active; - (id)findSubActionForValue:(IOHIDValueRef)value { return NULL; @@ -27,9 +28,8 @@ [self doesNotRecognizeSelector:_cmd]; } -- (BOOL)active { - [self doesNotRecognizeSelector:_cmd]; - return NO; +- (float)magnitude { + return 0.f; } @end diff --git a/JSActionAnalog.h b/JSActionAnalog.h index f351a4a..cc13d1e 100644 --- a/JSActionAnalog.h +++ b/JSActionAnalog.h @@ -16,6 +16,5 @@ @property (assign) float scale; - (id)initWithIndex:(int)newIndex offset:(float)offset scale:(float)scale; -- (float)getRealValue:(int)value; @end diff --git a/JSActionAnalog.m b/JSActionAnalog.m index 5aded63..06552a9 100644 --- a/JSActionAnalog.m +++ b/JSActionAnalog.m @@ -10,7 +10,9 @@ #import "JSActionAnalog.h" -@implementation JSActionAnalog +@implementation JSActionAnalog { + float magnitude; +} @synthesize offset, scale; @@ -28,11 +30,10 @@ - (id)findSubActionForValue:(IOHIDValueRef)value { int raw = IOHIDValueGetIntegerValue(value); - float parsed = [self getRealValue:raw]; - - if (parsed < -DEAD_ZONE) + float mag = offset + scale * raw; + if (mag < -DEAD_ZONE) return self.children[0]; - else if (parsed > DEAD_ZONE) + else if (mag > DEAD_ZONE) return self.children[1]; else return nil; @@ -40,14 +41,13 @@ - (void)notifyEvent:(IOHIDValueRef)value { int raw = IOHIDValueGetIntegerValue(value); - float parsed = [self getRealValue:raw]; - [self.children[0] setActive:parsed < -DEAD_ZONE]; - [self.children[1] setActive:parsed > DEAD_ZONE]; + magnitude = offset + scale * raw; + [self.children[0] setActive:magnitude < -DEAD_ZONE]; + [self.children[1] setActive:magnitude > DEAD_ZONE]; } -- (float)getRealValue:(int)value { - return offset + scale * value; +- (float)magnitude { + return magnitude; } - @end diff --git a/JoystickController.h b/JoystickController.h index 9cebde2..2306ea1 100644 --- a/JoystickController.h +++ b/JoystickController.h @@ -13,6 +13,7 @@ @class JSAction; @class ConfigsController; @class TargetController; +@class Config; @interface JoystickController : NSObject { IBOutlet NSOutlineView *outlineView; @@ -23,6 +24,7 @@ - (void)setup; - (Joystick *)findJoystickByRef:(IOHIDDeviceRef)device; +@property (readonly) Config *currentConfig; @property (readonly) JSAction *selectedAction; @property (readonly) NSMutableArray *joysticks; @property (readonly) NSMutableArray *runningTargets; diff --git a/JoystickController.m b/JoystickController.m index c5ddcdc..dfa246f 100644 --- a/JoystickController.m +++ b/JoystickController.m @@ -59,33 +59,17 @@ static void input_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDVa Joystick *js = [controller findJoystickByRef:device]; if (((ApplicationController *)[NSApplication sharedApplication].delegate).active) { JSAction *mainAction = [js actionForEvent:value]; - if (!mainAction) - return; - [mainAction notifyEvent:value]; NSArray *children = mainAction.children ? mainAction.children : @[mainAction]; for (JSAction *subaction in children) { - Target *target = [[controller->configsController currentConfig] getTargetForAction:subaction]; - if (!target) - continue; - // TODO: Can we just trigger based on setRunning:? - if (target.running != subaction.active) { - if (subaction.active) - [target trigger:controller]; - else - [target untrigger:controller]; - target.running = subaction.active; - } - - // FIXME: Hack, should just expose analog info properly in continuous target. - if ([mainAction isKindOfClass:[JSActionAnalog class]]) { - double realValue = [(JSActionAnalog *)mainAction getRealValue:IOHIDValueGetIntegerValue(value)]; - [target setInputValue:realValue]; - if (target.isContinuous && target.running) - [controller addRunningTarget:target]; - } + Target *target = [controller.currentConfig getTargetForAction:subaction]; + target.magnitude = mainAction.magnitude; + target.running = subaction.active; + if (target.running && target.isContinuous) + [controller addRunningTarget:target]; } - } else if ([NSApplication sharedApplication].isActive && [NSApplication sharedApplication].mainWindow.isVisible) { + } else if ([NSApplication sharedApplication].isActive + && [NSApplication sharedApplication].mainWindow.isVisible) { // joysticks not active, use it to select stuff JSAction *handler = [js handlerForEvent:value]; if (!handler) @@ -170,6 +154,10 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void *)self); } +- (Config *)currentConfig { + return configsController.currentConfig; +} + - (JSAction *)selectedAction { id item = [outlineView itemAtRow:outlineView.selectedRow]; return [item children] ? nil : item; diff --git a/SubAction.h b/SubAction.h index 51a8509..7b297d8 100644 --- a/SubAction.h +++ b/SubAction.h @@ -14,6 +14,4 @@ - (id)initWithIndex:(int)newIndex name:(NSString *)newName base:(JSAction *)newBase; -@property (assign) BOOL active; - @end diff --git a/SubAction.m b/SubAction.m index 07011ca..501d457 100644 --- a/SubAction.m +++ b/SubAction.m @@ -9,11 +9,7 @@ #import "SubAction.h" -@implementation SubAction { - BOOL active; -} - -@synthesize active; +@implementation SubAction - (id)initWithIndex:(int)newIndex name:(NSString *)newName base:(JSAction *)newBase { if ((self = [super init])) { diff --git a/Target.h b/Target.h index 51470bf..f7d4ec1 100644 --- a/Target.h +++ b/Target.h @@ -8,19 +8,16 @@ #import -@interface Target : NSObject { - BOOL running; - BOOL isContinuous; - double inputValue; -} +@interface Target : NSObject -@property(readwrite) BOOL running; -@property(readonly) BOOL isContinuous; -@property(readwrite) double inputValue; --(void) trigger: (JoystickController *)jc; --(void) untrigger: (JoystickController *)jc; +@property (assign) float magnitude; +@property (assign) BOOL running; +@property (readonly) BOOL isContinuous; + +- (void)trigger; +- (void)untrigger; - (BOOL)update:(JoystickController *)jc; --(NSString*) stringify; -+(Target*) unstringify: (NSString*) str withConfigList: (NSArray*) configs; +- (NSString*) stringify; ++ (Target *)unstringify:(NSString*)str withConfigList:(NSArray*)configs; @end diff --git a/Target.m b/Target.m index e7ea673..9666c8a 100644 --- a/Target.m +++ b/Target.m @@ -5,16 +5,21 @@ // Created by Sam McCall on 5/05/09. // -@implementation Target +@implementation Target { + BOOL running; +} + +@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]; + 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"]) @@ -23,32 +28,43 @@ return [TargetMouseScroll unstringifyImpl:components]; if([typeTag isEqualToString:@"mtoggle"]) return [TargetToggleMouseScope unstringifyImpl:components]; - - NSParameterAssert(NO); - return NULL; + + NSParameterAssert(NO); + return NULL; } --(NSString*) stringify { - [self doesNotRecognizeSelector:_cmd]; - return NULL; +- (NSString *)stringify { + [self doesNotRecognizeSelector:_cmd]; + return NULL; } --(void) trigger: (JoystickController *)jc { - [self doesNotRecognizeSelector:_cmd]; +- (void)trigger { } --(void) untrigger: (JoystickController *)jc { - // no-op by default +- (void)untrigger { } - (BOOL)update:(JoystickController *)jc { return NO; } --(BOOL) isContinuous { - return false; +- (BOOL)isContinuous { + return NO; +} + +- (BOOL)running { + return running; +} + +- (void)setRunning:(BOOL)newRunning { + if (running != newRunning) { + running = newRunning; + if (running) + [self trigger]; + else + [self untrigger]; + } } -@synthesize inputValue, running; @end diff --git a/TargetKeyboard.m b/TargetKeyboard.m index f171a50..eb1f4d7 100644 --- a/TargetKeyboard.m +++ b/TargetKeyboard.m @@ -21,13 +21,13 @@ return target; } --(void) trigger: (JoystickController *)jc { +-(void) trigger { CGEventRef keyDown = CGEventCreateKeyboardEvent(NULL, vk, true); CGEventPost(kCGHIDEventTap, keyDown); CFRelease(keyDown); } --(void) untrigger: (JoystickController *)jc { +-(void) untrigger { CGEventRef keyUp = CGEventCreateKeyboardEvent(NULL, vk, false); CGEventPost(kCGHIDEventTap, keyUp); CFRelease(keyUp); diff --git a/TargetMouseBtn.m b/TargetMouseBtn.m index 172f740..e8d77e4 100644 --- a/TargetMouseBtn.m +++ b/TargetMouseBtn.m @@ -23,7 +23,7 @@ return target; } --(void) trigger: (JoystickController *)jc { +-(void) trigger { NSRect screenRect = [[NSScreen mainScreen] frame]; NSInteger height = screenRect.size.height; NSPoint mouseLoc = [NSEvent mouseLocation]; @@ -36,7 +36,7 @@ CFRelease(click); } --(void) untrigger: (JoystickController *)jc { +-(void) untrigger { NSRect screenRect = [[NSScreen mainScreen] frame]; NSInteger height = screenRect.size.height; NSPoint mouseLoc = [NSEvent mouseLocation]; diff --git a/TargetMouseMove.m b/TargetMouseMove.m index 78d9c93..aa50306 100644 --- a/TargetMouseMove.m +++ b/TargetMouseMove.m @@ -27,31 +27,23 @@ return target; } --(void) trigger: (JoystickController *)jc { - return; -} - --(void) untrigger: (JoystickController *)jc { - return; -} - - (BOOL)update:(JoystickController *)jc { //printf("Dir %d inputValue %f\n", [self dir], [self inputValue]); - if (fabs([self inputValue]) < 0.01) + if (fabs(self.magnitude) < 0.01) return NO; // dead zone NSRect screenRect = [[NSScreen mainScreen] frame]; NSInteger height = screenRect.size.height; // TODO - double speed = 4.0; + float speed = 4.0; if ([jc frontWindowOnly]) speed = 12.0; - double dx = 0.0, dy = 0.0; + float dx = 0.0, dy = 0.0; if ([self dir] == 0) - dx = [self inputValue] * speed; + dx = self.magnitude * speed; else - dy = [self inputValue] * speed; + dy = self.magnitude * speed; NSPoint mouseLoc = jc.mouseLoc; mouseLoc.x += dx; mouseLoc.y -= dy; diff --git a/TargetMouseScroll.m b/TargetMouseScroll.m index be64f7a..79bc542 100644 --- a/TargetMouseScroll.m +++ b/TargetMouseScroll.m @@ -23,7 +23,7 @@ return target; } --(void) trigger: (JoystickController *)jc { +-(void) trigger { CGEventRef scroll = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, 1, diff --git a/TargetToggleMouseScope.m b/TargetToggleMouseScope.m index 55357e5..9e986df 100644 --- a/TargetToggleMouseScope.m +++ b/TargetToggleMouseScope.m @@ -20,7 +20,11 @@ return target; } --(void) trigger: (JoystickController *)jc { +- (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. + ApplicationController *ac = [NSApplication sharedApplication].delegate; + JoystickController *jc = ac.jsController; [jc setFrontWindowOnly: ![jc frontWindowOnly]]; printf("Front window only: %d\n", [jc frontWindowOnly]); } -- 2.20.1