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 30e99b9..8e52e9c 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 84d1ea8..8576b2f 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 f351a4a..cc13d1e 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 5aded63..06552a9 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 9cebde2..2306ea1 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 c5ddcdc..dfa246f 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 51a8509..7b297d8 100644 (file)
@@ -14,6 +14,4 @@
 
 - (id)initWithIndex:(int)newIndex name:(NSString *)newName  base:(JSAction *)newBase;
 
-@property (assign) BOOL active;
-
 @end
index 07011ca..501d457 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 51470bf..f7d4ec1 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 e7ea673..9666c8a 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 f171a50..eb1f4d7 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 172f740..e8d77e4 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 78d9c93..aa50306 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 be64f7a..79bc542 100644 (file)
@@ -23,7 +23,7 @@
        return target;
 }
 
--(void) trigger: (JoystickController *)jc {
+-(void) trigger {
     CGEventRef scroll = CGEventCreateScrollWheelEvent(NULL,
                                                       kCGScrollEventUnitLine,
                                                       1,
index 55357e5..9e986df 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]);
 }