Automatically trigger/untrigger targets based on setting the 'running' property;...
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 27 Feb 2013 17:28:05 +0000 (18:28 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 27 Feb 2013 17:28:05 +0000 (18:28 +0100)
15 files changed:
JSAction.h
JSAction.m
JSActionAnalog.h
JSActionAnalog.m
JoystickController.h
JoystickController.m
SubAction.h
SubAction.m
Target.h
Target.m
TargetKeyboard.m
TargetMouseBtn.m
TargetMouseMove.m
TargetMouseScroll.m
TargetToggleMouseScope.m

index 30e99b9cd71e68a4a649a9d170589d7742a5f0ae..8e52e9c4594b6fc1849e652c8d786d0c3ed0e3df 100644 (file)
@@ -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;
index 84d1ea84c395d40587dd3bd04879fc74247fa51c..8576b2fdc6af36e4a95dfc55db90f762957dc960 100644 (file)
@@ -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
index f351a4ab06bba9280b19412f39f01440ea7b4a4b..cc13d1e05029f80074aaeb68114c7c33132ececd 100644 (file)
@@ -16,6 +16,5 @@
 @property (assign) float scale;
 
 - (id)initWithIndex:(int)newIndex offset:(float)offset scale:(float)scale;
-- (float)getRealValue:(int)value;
 
 @end
index 5aded63d3ad01e51dc8da6d926d2e4f8c26cd655..06552a967509f721cd0228fc6f977fd189c36ff1 100644 (file)
@@ -10,7 +10,9 @@
 
 #import "JSActionAnalog.h"
 
-@implementation JSActionAnalog
+@implementation JSActionAnalog {
+    float magnitude;
+}
 
 @synthesize offset, scale;
 
 
 - (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;
 
 - (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
index 9cebde246714a4d1a29904e9d6e05ff27b2597c1..2306ea1c9c8fb3c929200a46e86a286eb4d8a299 100644 (file)
@@ -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;
index c5ddcdc0cbe217b6f8d3b6655ceebc3e032d4e1a..dfa246f6f622b909407153c735f00225d5bdd34a 100644 (file)
@@ -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;
index 51a85098a4da667099669faba5c77fab6dc83194..7b297d85dbef4d209f4b1fcd92de24e0a4090f19 100644 (file)
@@ -14,6 +14,4 @@
 
 - (id)initWithIndex:(int)newIndex name:(NSString *)newName  base:(JSAction *)newBase;
 
-@property (assign) BOOL active;
-
 @end
index 07011ca90427f6ac09a877ee728ba42611c2a2ba..501d457b4c8fa2a238fcf1252881c4daaab3e154 100644 (file)
@@ -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])) {
index 51470bfcd7f089f18945725f0c6cc2b7315e041b..f7d4ec119320ce19737d0eef2bcf0ecabbfee9cf 100644 (file)
--- a/Target.h
+++ b/Target.h
@@ -8,19 +8,16 @@
 
 #import <Cocoa/Cocoa.h>
 
-@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
index e7ea673885798d5461d4c1acffc4ae13e15678d2..9666c8a80f27280f02d1d3219e45dd3180ccfd5b 100644 (file)
--- 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"])
         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
index f171a50976a50624ca6cb49b54dbe66ee33270a2..eb1f4d780ca48674f33acd267f48a4257b590e22 100644 (file)
        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);
index 172f7406f1a1d0d3c1a56d53b2a37d2fed5b9f6c..e8d77e42f6c67364557d835ef860a0e00d4383bd 100644 (file)
@@ -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];
index 78d9c93198d75d684a13845f3264ce3b9ddc7a2c..aa503069441645295ebe4bf9551a485eaa646735 100644 (file)
        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;
index be64f7a2986c4e9824a0534ccd4d7dea6dec744f..79bc5421f371bfe97e6aecd24882e183247a810d 100644 (file)
@@ -23,7 +23,7 @@
        return target;
 }
 
--(void) trigger: (JoystickController *)jc {
+-(void) trigger {
     CGEventRef scroll = CGEventCreateScrollWheelEvent(NULL,
                                                       kCGScrollEventUnitLine,
                                                       1,
index 55357e5f6a38da52068e26ffb61d456f934a4aca..9e986df79d8af98dffc1682a1374b811659869fe 100644 (file)
        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]);
 }