Fix uniqueIDs not being unique in combined controllers

This commit is contained in:
Lior Halphon 2022-10-28 20:15:24 +03:00
parent 6547137389
commit 354f68a861
15 changed files with 80 additions and 27 deletions

View File

@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>
#import "JOYInput.h"
typedef enum {
JOYAxes2DUsageNone,
@ -11,10 +12,8 @@ typedef enum {
JOYAxes2DUsageGeneric0 = 0x10000,
} JOYAxes2DUsage;
@interface JOYAxes2D : NSObject
- (NSString *)usageString;
@interface JOYAxes2D : JOYInput
+ (NSString *)usageToString: (JOYAxes2DUsage) usage;
- (uint64_t)uniqueID;
- (double)distance;
- (double)angle;
- (NSPoint)value;

View File

@ -8,7 +8,6 @@
int32_t initialX, initialY;
int32_t minX, minY;
int32_t maxX, maxY;
}
+ (NSString *)usageToString: (JOYAxes2DUsage) usage
@ -36,12 +35,12 @@
- (uint64_t)uniqueID
{
return _element1.uniqueID;
return _element1.uniqueID | (uint64_t)self.combinedIndex << 32;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p, %@ (%llu); State: %.2f%%, %.2f degrees>", self.className, self, self.usageString, self.uniqueID, self.distance * 100, self.angle];
return [NSString stringWithFormat:@"<%@: %p, %@ (%llx); State: %.2f%%, %.2f degrees>", self.className, self, self.usageString, self.uniqueID, self.distance * 100, self.angle];
}
- (instancetype)initWithFirstElement:(JOYElement *)element1 secondElement:(JOYElement *)element2

View File

@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>
#import "JOYInput.h"
typedef enum {
JOYAxes3DUsageNone,
@ -14,10 +15,8 @@ typedef struct {
double x, y, z;
} JOYPoint3D;
@interface JOYAxes3D : NSObject
- (NSString *)usageString;
@interface JOYAxes3D : JOYInput
+ (NSString *)usageToString: (JOYAxes3DUsage) usage;
- (uint64_t)uniqueID;
- (JOYPoint3D)rawValue;
- (JOYPoint3D)normalizedValue; // For orientation
- (JOYPoint3D)gUnitsValue; // For acceleration

View File

@ -34,12 +34,12 @@
- (uint64_t)uniqueID
{
return _element1.uniqueID;
return _element1.uniqueID | (uint64_t)self.combinedIndex << 32;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p, %@ (%llu); State: (%.2f, %.2f, %.2f)>", self.className, self, self.usageString, self.uniqueID, _state1, _state2, _state3];
return [NSString stringWithFormat:@"<%@: %p, %@ (%llx); State: (%.2f, %.2f, %.2f)>", self.className, self, self.usageString, self.uniqueID, _state1, _state2, _state3];
}
- (instancetype)initWithFirstElement:(JOYElement *)element1 secondElement:(JOYElement *)element2 thirdElement:(JOYElement *)element3

View File

@ -1,5 +1,6 @@
#import <Foundation/Foundation.h>
#import "JOYButton.h"
#import "JOYInput.h"
typedef enum {
JOYAxisUsageNone,
@ -24,10 +25,8 @@ typedef enum {
JOYAxisUsageGeneric0 = 0x10000,
} JOYAxisUsage;
@interface JOYAxis : NSObject
- (NSString *)usageString;
@interface JOYAxis : JOYInput
+ (NSString *)usageToString: (JOYAxisUsage) usage;
- (uint64_t)uniqueID;
- (double)value;
- (JOYButtonUsage)equivalentButtonUsage;
@property JOYAxisUsage usage;

View File

@ -42,12 +42,12 @@
- (uint64_t)uniqueID
{
return _element.uniqueID;
return _element.uniqueID | (uint64_t)self.combinedIndex << 32;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p, %@ (%llu); State: %f%%>", self.className, self, self.usageString, self.uniqueID, _state * 100];
return [NSString stringWithFormat:@"<%@: %p, %@ (%llx); State: %f%%>", self.className, self, self.usageString, self.uniqueID, _state * 100];
}
- (instancetype)initWithElement:(JOYElement *)element

View File

@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>
#import "JOYInput.h"
typedef enum {
JOYButtonUsageNone,
@ -46,10 +47,8 @@ typedef enum {
JOYButtonTypeHatEmulated,
} JOYButtonType;
@interface JOYButton : NSObject
- (NSString *)usageString;
@interface JOYButton : JOYInput
+ (NSString *)usageToString: (JOYButtonUsage) usage;
- (uint64_t)uniqueID;
- (bool) isPressed;
@property JOYButtonUsage usage;
@property (readonly) JOYButtonType type;

View File

@ -51,12 +51,12 @@
- (uint64_t)uniqueID
{
return _element.uniqueID;
return _element.uniqueID | (uint64_t)self.combinedIndex << 32;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p, %@ (%llu); State: %s>", self.className, self, self.usageString, self.uniqueID, _state? "Presssed" : "Released"];
return [NSString stringWithFormat:@"<%@: %p, %@ (%llx); State: %s>", self.className, self, self.usageString, self.uniqueID, _state? "Presssed" : "Released"];
}
- (instancetype)initWithElement:(JOYElement *)element

View File

@ -42,6 +42,7 @@ typedef enum {
- (NSArray<JOYAxes2D *> *) axes2D;
- (NSArray<JOYAxes3D *> *) axes3D;
- (NSArray<JOYHat *> *) hats;
- (NSArray<JOYInput *> *) allInputs;
- (void)setRumbleAmplitude:(double)amp;
- (void)setPlayerLEDs:(uint8_t)mask;
- (uint8_t)LEDMaskForPlayer:(unsigned)player;

View File

@ -87,6 +87,10 @@ static bool hatsEmulateButtons = false;
- (bool)updateState;
@end
@interface JOYInput ()
@property unsigned combinedIndex;
@end
static NSDictionary *CreateHIDDeviceMatchDictionary(const UInt32 page, const UInt32 usage)
{
return @{
@ -1099,6 +1103,17 @@ typedef union {
return _logicallyConnected && _physicallyConnected;
}
- (NSArray<JOYInput *> *)allInputs
{
NSMutableArray<JOYInput *> *ret = [NSMutableArray array];
[ret addObjectsFromArray:self.buttons];
[ret addObjectsFromArray:self.axes];
[ret addObjectsFromArray:self.axes2D];
[ret addObjectsFromArray:self.axes3D];
[ret addObjectsFromArray:self.hats];
return ret;
}
+ (void)controllerAdded:(IOHIDDeviceRef) device
{
NSString *name = (__bridge NSString *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
@ -1213,6 +1228,7 @@ typedef union {
}
}
unsigned index = 0;
for (JOYController *child in _chidlren) {
for (id<JOYListener> listener in listeners) {
if ([listener respondsToSelector:@selector(controllerDisconnected:)]) {
@ -1220,6 +1236,10 @@ typedef union {
}
}
child->_parent = self;
for (JOYInput *input in child.allInputs) {
input.combinedIndex = index;
}
index++;
[exposedControllers removeObject:child];
}
@ -1249,6 +1269,9 @@ typedef union {
for (JOYController *child in _chidlren) {
child->_parent = nil;
for (JOYInput *input in child.allInputs) {
input.combinedIndex = 0;
}
[exposedControllers addObject:child];
for (id<JOYListener> listener in listeners) {
if ([listener respondsToSelector:@selector(controllerConnected:)]) {

View File

@ -25,7 +25,7 @@
- (uint64_t)uniqueID
{
return _uniqueID;
return _uniqueID | (uint64_t)self.combinedIndex << 32;
}
- (bool)updateStateFromAxis:(JOYAxis *)axis

View File

@ -1,7 +1,7 @@
#import <Foundation/Foundation.h>
#import "JOYInput.h"
@interface JOYHat : NSObject
- (uint64_t)uniqueID;
@interface JOYHat : JOYInput
- (double)angle;
- (unsigned)resolution;
@property (readonly, getter=isPressed) bool pressed;

View File

@ -10,15 +10,15 @@
- (uint64_t)uniqueID
{
return _element.uniqueID;
return _element.uniqueID | (uint64_t)self.combinedIndex << 32;
}
- (NSString *)description
{
if (self.isPressed) {
return [NSString stringWithFormat:@"<%@: %p (%llu); State: %f degrees>", self.className, self, self.uniqueID, self.angle];
return [NSString stringWithFormat:@"<%@: %p (%llx); State: %f degrees>", self.className, self, self.uniqueID, self.angle];
}
return [NSString stringWithFormat:@"<%@: %p (%llu); State: released>", self.className, self, self.uniqueID];
return [NSString stringWithFormat:@"<%@: %p (%llx); State: released>", self.className, self, self.uniqueID];
}
@ -59,4 +59,9 @@
return false;
}
- (NSString *)usageString
{
return @"Hat switch";
}
@end

8
JoyKit/JOYInput.h Normal file
View File

@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>
@interface JOYInput : NSObject
@property (readonly) unsigned combinedIndex;
- (NSString *)usageString;
- (uint64_t)uniqueID;
@end

21
JoyKit/JOYInput.m Normal file
View File

@ -0,0 +1,21 @@
#import "JOYInput.h"
@interface JOYInput ()
@property unsigned combinedIndex;
@end
@implementation JOYInput
- (uint64_t)uniqueID
{
[self doesNotRecognizeSelector:_cmd];
__builtin_unreachable();
}
- (NSString *)usageString
{
[self doesNotRecognizeSelector:_cmd];
__builtin_unreachable();
}
@end