+ return self;
+}
+
+- (void)dealloc {
+ [continuousTimer invalidate];
+ IOHIDManagerClose(hidManager, kIOHIDOptionsTypeNone);
+ CFRelease(hidManager);
+}
+
+- (void)expandRecursive:(id)handler {
+ if ([handler base])
+ [self expandRecursive:[handler base]];
+ [outlineView expandItem:handler];
+}
+
+- (void)addRunningTarget:(Target *)target {
+ if (![runningTargets containsObject:target]) {
+ [runningTargets addObject:target];
+ }
+ if (!continuousTimer) {
+ continuousTimer = [NSTimer scheduledTimerWithTimeInterval:1.f/60.f
+ target:self
+ selector:@selector(updateContinuousActions:)
+ userInfo:nil
+ repeats:YES];
+ NSLog(@"Scheduled continuous target timer.");
+ }
+}
+
+- (void)runTargetForDevice:(IOHIDDeviceRef)device value:(IOHIDValueRef)value {
+ Joystick *js = [self findJoystickByRef:device];
+ JSAction *mainAction = [js actionForEvent:value];
+ [mainAction notifyEvent:value];
+ NSArray *children = mainAction.children ? mainAction.children : mainAction ? @[mainAction] : @[];
+ for (JSAction *subaction in children) {
+ Target *target = configsController.currentConfig[subaction];
+ target.magnitude = mainAction.magnitude;
+ target.running = subaction.active;
+ if (target.running && target.isContinuous)
+ [self addRunningTarget:target];
+ }
+}
+
+- (void)showTargetForDevice:(IOHIDDeviceRef)device value:(IOHIDValueRef)value {
+ Joystick *js = [self findJoystickByRef:device];
+ JSAction *handler = [js handlerForEvent:value];
+ if (!handler)
+ return;
+
+ [self expandRecursive:handler];
+ [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[outlineView rowForItem:handler]] byExtendingSelection: NO];
+ [targetController focusKey];