X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=Classes%2FNJInputController.m;h=ed0d72d8208c14ef0f771bff4bb7ec66bc7be188;hp=9ff9d2679cdce9c2dca18934d680213d1e08edb7;hb=dc526070b502b03b2c98c679bbbde371b21eeb9a;hpb=1d10a45acf54217e765614cd2b4667297c1f7083 diff --git a/Classes/NJInputController.m b/Classes/NJInputController.m index 9ff9d26..ed0d72d 100644 --- a/Classes/NJInputController.m +++ b/Classes/NJInputController.m @@ -11,14 +11,34 @@ #import "NJOutput.h" #import "NJEvents.h" +#import + +@interface NJInputController () + +- (void)updateContinuousOutputs; + +@end + +static CVReturn _updateDL(CVDisplayLinkRef displayLink, + const CVTimeStamp *inNow, + const CVTimeStamp *inOutputTime, + CVOptionFlags flagsIn, + CVOptionFlags *flagsOut, + void *ctxManager) { + NJInputController *manager = (__bridge NJInputController *)ctxManager; + [manager performSelectorOnMainThread:@selector(updateContinuousOutputs) + withObject:nil + waitUntilDone:NO]; + return kCVReturnSuccess; +} + @implementation NJInputController { - NJHIDManager *_hidManager; - NSTimer *_continuousOutputsTick; + NJHIDManager *_HIDManager; NSMutableArray *_continousOutputs; NSMutableArray *_devices; NSMutableArray *_mappings; NJMapping *_manualMapping; - + CVDisplayLinkRef _displayLink; } #define NSSTR(e) ((NSString *)CFSTR(e)) @@ -27,8 +47,19 @@ if ((self = [super init])) { _devices = [[NSMutableArray alloc] initWithCapacity:16]; _continousOutputs = [[NSMutableArray alloc] initWithCapacity:32]; + + CVReturn cvErr = CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink); + if (cvErr) { + NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain + code:cvErr + userInfo:nil]; + [self.delegate inputController:self didError:error]; + NSLog(@"DisplayLink failed creation with error: %@", error); + _displayLink = NULL; + } + CVDisplayLinkSetOutputCallback(_displayLink, _updateDL, (__bridge void *)self); - _hidManager = [[NJHIDManager alloc] initWithCriteria:@[ + _HIDManager = [[NJHIDManager alloc] initWithCriteria:@[ @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop), NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_Joystick) }, @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop), @@ -69,7 +100,10 @@ - (void)dealloc { [NSNotificationCenter.defaultCenter removeObserver:self]; - [_continuousOutputsTick invalidate]; + if (_displayLink) { + CVDisplayLinkStop(_displayLink); + CVDisplayLinkRelease(_displayLink); + } } - (void)addRunningOutput:(NJOutput *)output { @@ -77,13 +111,8 @@ // re-adding them or they trigger multiple times each time. if (![_continousOutputs containsObject:output]) [_continousOutputs addObject:output]; - if (!_continuousOutputsTick) { - _continuousOutputsTick = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 - target:self - selector:@selector(updateContinuousOutputs:) - userInfo:nil - repeats:YES]; - } + if (_displayLink && !CVDisplayLinkIsRunning(_displayLink)) + CVDisplayLinkStart(_displayLink); } - (void)runOutputForDevice:(IOHIDDeviceRef)device value:(IOHIDValueRef)value { @@ -109,7 +138,7 @@ [self.delegate inputController:self didInput:handler]; } -- (void)hidManager:(NJHIDManager *)manager +- (void)HIDManager:(NJHIDManager *)manager valueChanged:(IOHIDValueRef)value fromDevice:(IOHIDDeviceRef)device { if (self.simulatingEvents @@ -135,7 +164,7 @@ [_devices addObject:device]; } -- (void)hidManager:(NJHIDManager *)manager deviceAdded:(IOHIDDeviceRef)device { +- (void)HIDManager:(NJHIDManager *)manager deviceAdded:(IOHIDDeviceRef)device { NJDevice *match = [[NJDevice alloc] initWithDevice:device]; [self addDevice:match]; [self.delegate inputController:self didAddDevice:match]; @@ -148,7 +177,7 @@ return nil; } -- (void)hidManager:(NJHIDManager *)manager deviceRemoved:(IOHIDDeviceRef)device { +- (void)HIDManager:(NJHIDManager *)manager deviceRemoved:(IOHIDDeviceRef)device { NJDevice *match = [self findDeviceByRef:device]; if (match) { NSInteger idx = [_devices indexOfObjectIdenticalTo:match]; @@ -157,39 +186,42 @@ } } -- (void)updateContinuousOutputs:(NSTimer *)timer { +- (void)updateContinuousOutputs { self.mouseLoc = [NSEvent mouseLocation]; for (NJOutput *output in [_continousOutputs copy]) { if (![output update:self]) { [_continousOutputs removeObject:output]; } } - if (!_continousOutputs.count) { - [_continuousOutputsTick invalidate]; - _continuousOutputsTick = nil; + if (!_continousOutputs.count && _displayLink) { + CVDisplayLinkStop(_displayLink); } } -- (void)hidManager:(NJHIDManager *)manager didError:(NSError *)error { +- (void)HIDManager:(NJHIDManager *)manager didError:(NSError *)error { [self.delegate inputController:self didError:error]; self.simulatingEvents = NO; + if (_displayLink) + CVDisplayLinkStop(_displayLink); } -- (void)hidManagerDidStart:(NJHIDManager *)manager { +- (void)HIDManagerDidStart:(NJHIDManager *)manager { [self.delegate inputControllerDidStartHID:self]; } -- (void)hidManagerDidStop:(NJHIDManager *)manager { +- (void)HIDManagerDidStop:(NJHIDManager *)manager { [_devices removeAllObjects]; + if (_displayLink) + CVDisplayLinkStop(_displayLink); [self.delegate inputControllerDidStopHID:self]; } - (void)startHid { - [_hidManager start]; + [_HIDManager start]; } - (void)stopHid { - [_hidManager stop]; + [_HIDManager stop]; } - (void)setSimulatingEvents:(BOOL)simulatingEvents { @@ -232,10 +264,10 @@ - (void)mappingsSet { [self postLoadProcess]; [NSNotificationCenter.defaultCenter - postNotificationName:NJEventMappingListChanged - object:self - userInfo:@{ NJMappingListKey: _mappings, - NJMappingKey: _currentMapping }]; + postNotificationName:NJEventMappingListChanged + object:self + userInfo:@{ NJMappingListKey: _mappings, + NJMappingKey: _currentMapping }]; } - (void)mappingsChanged { @@ -261,8 +293,7 @@ if ([oldMapping.name.lowercaseString isEqualToString:@"@application"] || [oldMapping.name.lowercaseString isEqualToString: NSLocalizedString(@"@Application", nil).lowercaseString]) { - oldMapping.name = app.bestMappingName; - [self mappingsChanged]; + [self renameMapping:oldMapping to:app.bestMappingName]; } } _manualMapping = oldMapping; @@ -273,10 +304,10 @@ _currentMapping = mapping; NSUInteger idx = [self indexOfMapping:_currentMapping]; [NSNotificationCenter.defaultCenter - postNotificationName:NJEventMappingChanged - object:self - userInfo:@{ NJMappingKey : _currentMapping, - NJMappingIndexKey: @(idx) }]; + postNotificationName:NJEventMappingChanged + object:self + userInfo:@{ NJMappingKey : _currentMapping, + NJMappingIndexKey: @(idx) }]; } - (void)activateMapping:(NJMapping *)mapping {