// // GCControllerProfile.h // GameController // // Copyright (c) 2019 Apple Inc. All rights reserved. // #import #import @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 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 *elements API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSDictionary *buttons API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSDictionary *axes API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSDictionary *dpads API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSDictionary *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 *allElements API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSSet *allButtons API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSSet *allAxes API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSSet *allDpads API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)); @property (nonatomic, readonly, strong) NSSet *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 *)mappedPhysicalInputNamesForElementAlias:(NSString *)elementAlias API_AVAILABLE(macos(12.0), ios(15.0), tvos(15.0)); @end NS_ASSUME_NONNULL_END