2024-10-08 18:33:13 +11:00

144 lines
7.3 KiB
Objective-C

//
// GCControllerProfile.h
// GameController
//
// Copyright (c) 2019 Apple Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <GameController/GCExtern.h>
@protocol GCDevice;
@class GCControllerElement;
@class GCControllerButtonInput;
@class GCControllerAxisInput;
@class GCControllerDirectionPad;
@class GCControllerTouchpad;
@compatibility_alias GCDeviceElement GCControllerElement;
@compatibility_alias GCDeviceButtonInput GCControllerButtonInput;
@compatibility_alias GCDeviceAxisInput GCControllerAxisInput;
@compatibility_alias GCDeviceDirectionPad GCControllerDirectionPad;
@compatibility_alias GCDeviceTouchpad GCControllerTouchpad;
NS_ASSUME_NONNULL_BEGIN
/**
A game controller profile representing physical buttons, thumbsticks, dpads, etc... on a controller.
All controller profiles provide a base level of information about the controller they belong to.
A profile maps the hardware notion of a controller into a logical controller. One that a developer can design for
and depend on, no matter the underlying hardware.
*/
API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
@interface GCPhysicalInputProfile : NSObject
/**
A profile keeps a reference to the device that this profile is mapping input from
*/
@property (nonatomic, readonly, weak) id<GCDevice> device API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
/**
The last time elements of this profile were updated.
*/
@property (atomic, readonly) NSTimeInterval lastEventTimestamp API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
/**
Whether the user has remapped their physical input controls for this profile at the system level.
@discussion On iOS and tvOS, users can remap their game controller inputs in Settings.
*/
@property (nonatomic, readonly) BOOL hasRemappedElements API_AVAILABLE(macos(12.0), ios(15.0), tvos(15.0));
/**
Set this block if you want to be notified when a value on a element changed. If multiple elements have changed this block will be called
for each element that changed.
@param profile this profile that is being used to map the raw input data into logical values on controller elements such as the dpad or the buttons.
@param element the element that has been modified.
*/
@property (nonatomic, copy, nullable) void (^valueDidChangeHandler)(__kindof GCPhysicalInputProfile *profile, GCControllerElement *element) API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0));
/**
The following properties allow for runtime lookup of any input element on a profile, when provided with a valid alias.
@example extendedGamepad.elements["Button A"] == extendedGamepad.buttonA // YES
@example extendedGamepad.dpads["Left Thumbstick"] == extendedGamepad.leftThumbstick // YES
@example extendedGamepad.dpads["Button B"] // returns nil, "Button B" is not a GCControllerDirectionPad
*/
@property (nonatomic, readonly, strong) NSDictionary<NSString *, GCDeviceElement *> *elements API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSDictionary<NSString *, GCDeviceButtonInput *> *buttons API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSDictionary<NSString *, GCDeviceAxisInput *> *axes API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSDictionary<NSString *, GCDeviceDirectionPad *> *dpads API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSDictionary<NSString *, GCDeviceTouchpad *> *touchpads API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
/**
The following properties allow for dynamic querying of the input elements available on a profile.
*/
@property (nonatomic, readonly, strong) NSSet<GCDeviceElement *> *allElements API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSSet<GCDeviceButtonInput *> *allButtons API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSSet<GCDeviceAxisInput *> *allAxes API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSSet<GCDeviceDirectionPad *> *allDpads API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
@property (nonatomic, readonly, strong) NSSet<GCDeviceTouchpad *> *allTouchpads API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
/**
Profile elements can be accessed using keyed subscript notation, with a valid alias of its inputs.
@example extendedGamepad["Button A"] == extendedGamepad.buttonA // YES
@example microGamepad["Button X"] == microGamepad.buttonX // YES
@note Equivalent to -elements
*/
- (__kindof GCDeviceElement * _Nullable)objectForKeyedSubscript:(NSString *)key API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
/**
Polls the state vector of the physical input input and saves it to a new and writable instance of GCPhysicalInputProfile.
If your application is heavily multithreaded this may also be useful to guarantee atomicity of input handling as
a snapshot will not change based on user input once it is taken.
@see snapshot
@return A new physical input profile with the duplicated state vector of the current physical input
*/
- (instancetype)capture API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
/**
Sets the state vector of the physical input profile to a copy of the passed in physical input profile's state vector.
@note If the controller's snapshot flag is set to NO, this method has no effect.
@see GCController.snapshot
*/
- (void)setStateFromPhysicalInput:(GCPhysicalInputProfile *)physicalInput API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0));
/**
Returns the primary alias of the GCControllerElement that a given physical input maps to.
@discussion If the user were to map a physical press of the A button of their game controller to the B button, then
-[GCPhysicalInputProfile mappedElementAliasForPhysicalInputName: GCInputButtonA] would return GCInputButtonB.
Note that mappings can change anytime your app is backgrounded, so make sure you update any relevant visuals when
returning to foreground.
@param inputName A GCInput string corresponding to the physical button you want the mapped element alias for.
@returns A GCInput string corresponding to the primary alias of the GCControllerElement that a given physical button maps to, or nil if there is no mapping.
*/
- (NSString *)mappedElementAliasForPhysicalInputName:(NSString *)inputName API_AVAILABLE(macos(12.0), ios(15.0), tvos(15.0));
/**
Returns a set of GCInput strings corresponding to physical inputs that are mapped to a given GCControllerElement.
@discussion If the user mapped the physical press of the A button, the B button, and the X button to the B button, then
-[GCPhysicalInputProfile mappedPhysicalInputNamesForElementAlias: GCInputButtonB] would return [GCInputButtonA, GCInputButtonB, GCInputButtonX].
Note that mappings can change anytime your app is backgrounded, so make sure you update any relevant visuals when
returning to foreground.
@param elementAlias A GCInput string corresponding to an alias of the GCControllerElement you want the physical buttons for.
@returns A set of GCInput strings corresponding to physical inputs that are mapped to a given GCControllerElement, or an empty set if there are no mappings.
*/
- (NSSet<NSString *> *)mappedPhysicalInputNamesForElementAlias:(NSString *)elementAlias API_AVAILABLE(macos(12.0), ios(15.0), tvos(15.0));
@end
NS_ASSUME_NONNULL_END