mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-06-17 14:11:35 +00:00
Dynamically update haptic effects instead of creating new players all the time
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
GCControllerPlayerIndex _playerIndex;
|
GCControllerPlayerIndex _playerIndex;
|
||||||
CHHapticEngine* _hapticEngine API_AVAILABLE(ios(13.0), tvos(14.0));
|
CHHapticEngine* _hapticEngine API_AVAILABLE(ios(13.0), tvos(14.0));
|
||||||
id<CHHapticPatternPlayer> _hapticPlayer API_AVAILABLE(ios(13.0), tvos(14.0));
|
id<CHHapticPatternPlayer> _hapticPlayer API_AVAILABLE(ios(13.0), tvos(14.0));
|
||||||
|
BOOL _playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)cleanup API_AVAILABLE(ios(14.0), tvos(14.0)) {
|
-(void)cleanup API_AVAILABLE(ios(14.0), tvos(14.0)) {
|
||||||
@@ -31,41 +32,54 @@
|
|||||||
-(void)setMotorAmplitude:(unsigned short)amplitude API_AVAILABLE(ios(14.0), tvos(14.0)) {
|
-(void)setMotorAmplitude:(unsigned short)amplitude API_AVAILABLE(ios(14.0), tvos(14.0)) {
|
||||||
NSError* error;
|
NSError* error;
|
||||||
|
|
||||||
// Cancel the last haptic effect
|
|
||||||
if (_hapticPlayer != nil) {
|
|
||||||
[_hapticPlayer stopAtTime:0 error:&error];
|
|
||||||
_hapticPlayer = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the haptic engine died
|
// Check if the haptic engine died
|
||||||
if (_hapticEngine == nil) {
|
if (_hapticEngine == nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't bother queuing a 0 amplitude haptic event
|
// Stop the effect entirely if the amplitude is 0
|
||||||
if (amplitude == 0) {
|
if (amplitude == 0) {
|
||||||
|
if (_playing) {
|
||||||
|
[_hapticPlayer stopAtTime:0 error:&error];
|
||||||
|
_playing = NO;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHHapticEventParameter* intensityParameter = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:amplitude / 65536.0f];
|
if (_hapticPlayer == nil) {
|
||||||
CHHapticEvent* hapticEvent = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:intensityParameter, nil] relativeTime:0 duration:GCHapticDurationInfinite];
|
// We must initialize the intensity to 1.0f because the dynamic parameters are multiplied by this value before being applied
|
||||||
CHHapticPattern* hapticPattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:hapticEvent] parameters:[[NSArray alloc] init] error:&error];
|
CHHapticEventParameter* intensityParameter = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f];
|
||||||
|
CHHapticEvent* hapticEvent = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObject:intensityParameter] relativeTime:0 duration:GCHapticDurationInfinite];
|
||||||
|
CHHapticPattern* hapticPattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:hapticEvent] parameters:[[NSArray alloc] init] error:&error];
|
||||||
|
if (error != nil) {
|
||||||
|
Log(LOG_W, @"Controller %d: Haptic pattern creation failed: %@", _playerIndex, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hapticPlayer = [_hapticEngine createPlayerWithPattern:hapticPattern error:&error];
|
||||||
|
if (error != nil) {
|
||||||
|
Log(LOG_W, @"Controller %d: Haptic player creation failed: %@", _playerIndex, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHHapticDynamicParameter* intensityParameter = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:amplitude / 65536.0f relativeTime:0];
|
||||||
|
[_hapticPlayer sendParameters:[NSArray arrayWithObject:intensityParameter] atTime:CHHapticTimeImmediate error:&error];
|
||||||
if (error != nil) {
|
if (error != nil) {
|
||||||
Log(LOG_W, @"Controller %d: Haptic pattern creation failed: %@", _playerIndex, error);
|
Log(LOG_W, @"Controller %d: Haptic player parameter update failed: %@", _playerIndex, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hapticPlayer = [_hapticEngine createPlayerWithPattern:hapticPattern error:&error];
|
if (!_playing) {
|
||||||
if (error != nil) {
|
[_hapticPlayer startAtTime:0 error:&error];
|
||||||
Log(LOG_W, @"Controller %d: Haptic player creation failed: %@", _playerIndex, error);
|
if (error != nil) {
|
||||||
return;
|
_hapticPlayer = nil;
|
||||||
}
|
Log(LOG_W, @"Controller %d: Haptic playback start failed: %@", _playerIndex, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
[_hapticPlayer startAtTime:0 error:&error];
|
_playing = YES;
|
||||||
if (error != nil) {
|
|
||||||
_hapticPlayer = nil;
|
|
||||||
Log(LOG_W, @"Controller %d: Haptic playback start failed: %@", _playerIndex, error);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +109,7 @@
|
|||||||
Log(LOG_W, @"Controller %d: Haptic engine stopped: %p", me->_playerIndex, stoppedReason);
|
Log(LOG_W, @"Controller %d: Haptic engine stopped: %p", me->_playerIndex, stoppedReason);
|
||||||
me->_hapticPlayer = nil;
|
me->_hapticPlayer = nil;
|
||||||
me->_hapticEngine = nil;
|
me->_hapticEngine = nil;
|
||||||
|
me->_playing = NO;
|
||||||
};
|
};
|
||||||
_hapticEngine.resetHandler = ^{
|
_hapticEngine.resetHandler = ^{
|
||||||
HapticContext* me = weakSelf;
|
HapticContext* me = weakSelf;
|
||||||
@@ -104,6 +119,7 @@
|
|||||||
|
|
||||||
Log(LOG_W, @"Controller %d: Haptic engine reset", me->_playerIndex);
|
Log(LOG_W, @"Controller %d: Haptic engine reset", me->_playerIndex);
|
||||||
me->_hapticPlayer = nil;
|
me->_hapticPlayer = nil;
|
||||||
|
me->_playing = NO;
|
||||||
[me->_hapticEngine startAndReturnError:nil];
|
[me->_hapticEngine startAndReturnError:nil];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user