Switch controller/HID bridging to non-retained since the controller lives as long...
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Tue, 26 Feb 2013 21:05:34 +0000 (22:05 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Tue, 26 Feb 2013 21:05:34 +0000 (22:05 +0100)
Joystick.h
Joystick.m
JoystickController.m

index 587ad3f..99587a7 100644 (file)
@@ -9,26 +9,17 @@
 #import <Cocoa/Cocoa.h>
 @class JSAction;
 
-@interface Joystick : NSObject {
-       int vendorId;
-       int productId;
-       int index;
-       NSString* productName;
-       IOHIDDeviceRef device;
-       NSMutableArray* children;
-       NSString* name;
-}
+@interface Joystick : NSObject
 
-@property(readwrite) int vendorId;
-@property(readwrite) int productId;
-@property(readwrite) int index;
-@property(readwrite, copy) NSString* productName;
-@property(readwrite) IOHIDDeviceRef device;
-@property(readonly) NSArray* children;
-@property(readonly) NSString* name;
+@property (assign) int vendorId;
+@property (assign) int productId;
+@property (assign) int index;
+@property (copy) NSString *productName;
+@property (assign) IOHIDDeviceRef device;
+@property (readonly) NSArray *children;
+@property (readonly) NSString *name;
 
 -(void) populateActions;
--(void) invalidate;
 -(id) handlerForEvent: (IOHIDValueRef) value;
 -(id)initWithDevice: (IOHIDDeviceRef) newDevice;
 -(JSAction*) actionForEvent: (IOHIDValueRef) value;
index d6c4362..2d50fa4 100644 (file)
@@ -5,36 +5,26 @@
 //  Created by Sam McCall on 4/05/09.
 //
 
-@implementation Joystick
-
+@implementation Joystick {
+       NSMutableArray *children;
+}
 
-@synthesize    vendorId, productId, productName, name, index, device, children;
+@synthesize    vendorId, productId, productName, index, device, children;
 
--(id)initWithDevice: (IOHIDDeviceRef) newDevice {
-       if(self=[super init]) {
-               children = [[NSMutableArray alloc]init];
-               
-               device = newDevice;
-               productName = (__bridge NSString*)IOHIDDeviceGetProperty( device, CFSTR(kIOHIDProductKey) );
-               vendorId = [(__bridge NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
-               productId = [(__bridge NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
+- (id)initWithDevice: (IOHIDDeviceRef) newDevice {
+       if ((self = [super init])) {
+               children = [[NSMutableArray alloc] init];
                
-               name = productName;
+               self.device = newDevice;
+               self.productName = (__bridge NSString *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
+               self.vendorId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
+               self.productId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
        }
        return self;
 }
 
--(void) setIndex: (int) newIndex {
-       index = newIndex;
-       name = [[NSString alloc] initWithFormat: @"%@ #%d", productName, (index+1)];
-}
--(int) index {
-       return index;
-}
-
--(void) invalidate {
-       IOHIDDeviceClose(device, kIOHIDOptionsTypeNone);
-       NSLog(@"Removed a device: %@", [self name]);
+- (NSString *)name {
+       return [[NSString alloc] initWithFormat: @"%@ #%d", productName, index + 1];
 }
 
 -(id) base {
index 5056b0e..51c2a37 100644 (file)
@@ -43,15 +43,7 @@ static NSMutableDictionary* create_criterion( UInt32 inUsagePage, UInt32 inUsage
        [outlineView expandItem: handler];
 }
 
-BOOL objInArray(NSMutableArray *array, id object) {
-    for (id o in array) {
-        if (o == object)
-            return true;
-    }
-    return false;
-}
-
-void timer_callback(CFRunLoopTimerRef timer, void *ctx) {
+static void timer_callback(CFRunLoopTimerRef timer, void *ctx) {
     JoystickController *jc = (__bridge JoystickController *)ctx;
     jc->mouseLoc = [NSEvent mouseLocation];
     for (Target *target in [jc runningTargets]) {
@@ -59,13 +51,12 @@ void timer_callback(CFRunLoopTimerRef timer, void *ctx) {
     }
 }
 
-void input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef value) {
-       JoystickController* self = (__bridge JoystickController*)inContext;
-       IOHIDDeviceRef device = IOHIDQueueGetDevice((IOHIDQueueRef) inSender);
+static void input_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDValueRef value) {
+       JoystickController *controller = (__bridge JoystickController *)ctx;
+       IOHIDDeviceRef device = IOHIDQueueGetDevice(inSender);
        
-       Joystick* js = [self findJoystickByRef: device];
+       Joystick *js = [controller findJoystickByRef:device];
        if([(ApplicationController *)[[NSApplication sharedApplication] delegate] active]) {
-               // for reals
                JSAction* mainAction = [js actionForEvent: value];
                if(!mainAction)
                        return;
@@ -75,17 +66,17 @@ void input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDVal
                if(!subactions)
                        subactions = @[mainAction];
                for(id subaction in subactions) {
-                       Target* target = [[self->configsController currentConfig] getTargetForAction:subaction];
+                       Target* target = [[controller->configsController currentConfig] getTargetForAction:subaction];
                        if(!target)
                                continue;
                        /* target application? doesn't seem to be any need since we are only active when it's in front */
                        /* might be required for some strange actions */
             if ([target running] != [subaction active]) {
                 if ([subaction active]) {
-                    [target trigger: self];
+                    [target trigger: controller];
                 }
                 else {
-                    [target untrigger: self];
+                    [target untrigger: controller];
                 }
                 [target setRunning: [subaction active]];
             }
@@ -96,8 +87,8 @@ void input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDVal
             
                 // Add to list of running targets
                 if ([target isContinuous] && [target running]) {
-                    if (!objInArray([self runningTargets], target)) {
-                        [[self runningTargets] addObject: target];
+                    if (![controller.runningTargets containsObject:target]) {
+                        [[controller runningTargets] addObject: target];
                     }
                 }
             }
@@ -108,13 +99,13 @@ void input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDVal
                if(!handler)
                        return;
        
-               [self expandRecursive: handler];
-               self->programmaticallySelecting = YES;
-               [self->outlineView selectRowIndexes: [NSIndexSet indexSetWithIndex: [self->outlineView rowForItem: handler]] byExtendingSelection: NO];
+               [controller expandRecursive: handler];
+               controller->programmaticallySelecting = YES;
+               [controller->outlineView selectRowIndexes: [NSIndexSet indexSetWithIndex: [controller->outlineView rowForItem: handler]] byExtendingSelection: NO];
        }
 }
 
-int findAvailableIndex(id list, Joystick* js) {
+static int findAvailableIndex(id list, Joystick* js) {
        BOOL available;
        Joystick* js2;
        for(int index=0;;index++) {
@@ -131,46 +122,39 @@ int findAvailableIndex(id list, Joystick* js) {
        }
 }
 
-void add_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) {
-       JoystickController* self = (__bridge JoystickController*)inContext;
-       
-       IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
-       IOHIDDeviceRegisterInputValueCallback(device, input_callback, (void*) CFBridgingRetain(self));
-       
-       Joystick *js = [[Joystick alloc] initWithDevice: device];
-       [js setIndex: findAvailableIndex([self joysticks], js)];
-       
+static void add_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
+       JoystickController *controller = (__bridge JoystickController *)ctx;
+    IOHIDDeviceRegisterInputValueCallback(device, input_callback, (__bridge void*)controller);
+       Joystick *js = [[Joystick alloc] initWithDevice:device];
+    js.index = findAvailableIndex(controller.joysticks, js);
        [js populateActions];
-
-       [[self joysticks] addObject: js];
-       [self->outlineView reloadData];
+       [[controller joysticks] addObject:js];
+       [controller->outlineView reloadData];
 }
        
--(Joystick*) findJoystickByRef: (IOHIDDeviceRef) device {
+- (Joystick *)findJoystickByRef:(IOHIDDeviceRef)device {
     for (Joystick *js in joysticks)
         if (js.device == device)
             return js;
        return nil;
 }      
 
-void remove_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) {
-       JoystickController* self = CFBridgingRelease(inContext);
-       
-       Joystick* match = [self findJoystickByRef: device];
-       if(!match)
-               return;
-                               
-       [[self joysticks] removeObject: match];
-
-       [match invalidate];
-       [self->outlineView reloadData];
+static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
+       JoystickController *controller = (__bridge JoystickController *)ctx;
+       Joystick *match = [controller findJoystickByRef:device];
+    IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
+       if (match) {
+        [controller.joysticks removeObject:match];
+        [controller->outlineView reloadData];
+    }
 }
 
--(void) setup {
+- (void)setup {
     hidManager = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-       NSArray *criteria = @[create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick),
-                create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad),
-         create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController)];
+       NSArray *criteria = @[
+        create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick),
+        create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad),
+        create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController)];
        
        IOHIDManagerSetDeviceMatchingMultiple(hidManager, (CFArrayRef)CFBridgingRetain(criteria));
     
@@ -178,13 +162,9 @@ void remove_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDDe
        IOReturn tIOReturn = IOHIDManagerOpen( hidManager, kIOHIDOptionsTypeNone );
        (void)tIOReturn;
        
-       IOHIDManagerRegisterDeviceMatchingCallback( hidManager, add_callback, (__bridge void*)self );
-       IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void*) self);
-//     IOHIDManagerRegisterInputValueCallback(hidManager, input_callback, (void*)self);
-// register individually so we can find the device more easily
-    
-    
-       
+       IOHIDManagerRegisterDeviceMatchingCallback(hidManager, add_callback, (__bridge void *)self );
+       IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void *)self);
+
     // Setup timer for continuous targets
     CFRunLoopTimerContext ctx = {
         0, (__bridge void*)self, NULL, NULL, NULL