2023-01-14 16:28:08 +00:00
|
|
|
#import "GBHapticManager.h"
|
2023-01-14 19:15:25 +00:00
|
|
|
#import "GBHapticManagerLegacy.h"
|
2023-01-14 16:28:08 +00:00
|
|
|
#import <CoreHaptics/CoreHaptics.h>
|
|
|
|
|
|
|
|
@implementation GBHapticManager
|
|
|
|
{
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wpartial-availability"
|
|
|
|
CHHapticEngine *_engine;
|
|
|
|
id<CHHapticPatternPlayer> _rumblePlayer;
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
double _rumble;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (instancetype)sharedManager
|
|
|
|
{
|
|
|
|
static dispatch_once_t onceToken;
|
|
|
|
static GBHapticManager *manager;
|
|
|
|
dispatch_once(&onceToken, ^{
|
|
|
|
manager = [[self alloc] init];
|
|
|
|
});
|
|
|
|
return manager;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)init
|
|
|
|
{
|
|
|
|
self = [super init];
|
|
|
|
if (!self) return nil;
|
2023-01-14 19:15:25 +00:00
|
|
|
if (self.class != [GBHapticManager class]) return self;
|
|
|
|
|
2023-01-14 16:28:08 +00:00
|
|
|
if (@available(iOS 13.0, *)) {
|
2023-01-14 19:15:25 +00:00
|
|
|
_engine = [[CHHapticEngine alloc] initAndReturnError:nil];
|
|
|
|
_engine.playsHapticsOnly = true;
|
|
|
|
_engine.autoShutdownEnabled = true;
|
2023-01-14 16:28:08 +00:00
|
|
|
}
|
2023-01-14 19:15:25 +00:00
|
|
|
if (!_engine) return [[GBHapticManagerLegacy alloc] init];
|
2023-01-14 16:28:08 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma clang diagnostic ignored "-Wpartial-availability"
|
|
|
|
|
|
|
|
- (CHHapticEvent *) eventWithType:(CHHapticEventType)type
|
|
|
|
sharpness:(double)sharpness
|
|
|
|
intensity:(double)intensity
|
|
|
|
duration:(NSTimeInterval)duration
|
|
|
|
{
|
2023-01-15 20:07:28 +00:00
|
|
|
return [[CHHapticEvent alloc] initWithEventType:type
|
2023-01-14 16:28:08 +00:00
|
|
|
parameters:@[[[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticSharpness
|
|
|
|
value:sharpness],
|
|
|
|
[[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity
|
|
|
|
value:intensity]]
|
|
|
|
relativeTime:CHHapticTimeImmediate
|
|
|
|
duration:duration];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)doTapHaptic
|
|
|
|
{
|
|
|
|
if (_rumble) return;
|
|
|
|
|
|
|
|
CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:@[[self eventWithType:CHHapticEventTypeHapticTransient
|
|
|
|
sharpness:0.25
|
|
|
|
intensity:0.75
|
|
|
|
duration:1.0]]
|
|
|
|
parameters:nil
|
|
|
|
error:nil];
|
|
|
|
id<CHHapticPatternPlayer> player = [_engine createPlayerWithPattern:pattern error:nil];
|
|
|
|
|
|
|
|
[player startAtTime:0 error:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setRumbleStrength:(double)rumble
|
|
|
|
{
|
|
|
|
if (rumble == 0) {
|
|
|
|
[_rumblePlayer stopAtTime:0 error:nil];
|
|
|
|
_rumblePlayer = nil;
|
|
|
|
_rumble = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_rumble = rumble;
|
|
|
|
CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:@[[self eventWithType:CHHapticEventTypeHapticContinuous
|
|
|
|
sharpness:0.75
|
|
|
|
intensity:rumble
|
|
|
|
duration:1.0]]
|
|
|
|
parameters:nil
|
|
|
|
error:nil];
|
|
|
|
id<CHHapticPatternPlayer> newPlayer = [_engine createPlayerWithPattern:pattern error:nil];
|
|
|
|
|
|
|
|
[newPlayer startAtTime:0 error:nil];
|
|
|
|
[_rumblePlayer stopAtTime:0 error:nil];
|
|
|
|
_rumblePlayer = newPlayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|