Skip to content

Commit 85586c4

Browse files
committed
perf: running both android and ios modules on the main thread
1 parent 03e2788 commit 85586c4

2 files changed

Lines changed: 60 additions & 46 deletions

File tree

android/src/main/java/com/haptics/HapticsModule.kt

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,57 +28,60 @@ class HapticsModule(reactContext: ReactApplicationContext) :
2828
return NAME
2929
}
3030

31-
override fun impact(style: String, promise: Promise) {
31+
private fun runOnUiQueueThread(block: () -> Unit) {
32+
reactApplicationContext.runOnUiQueueThread(block)
33+
}
34+
35+
private fun executeSafely(promise: Promise, errorCode: String, action: () -> Unit) {
3236
try {
33-
val vibrationType = HapticsUtils.getImpactType(style)
34-
vibrate(vibrationType)
35-
promise.resolve(null)
37+
action()
3638
} catch (e: IllegalArgumentException) {
37-
promise.reject("E_INVALID_STYLE", e.message)
39+
promise.reject(errorCode, e.message, e)
3840
} catch (e: Exception) {
3941
promise.reject("E_UNEXPECTED", "An unexpected error occurred: ${e.message}", e)
4042
}
4143
}
4244

45+
override fun impact(style: String, promise: Promise) {
46+
executeSafely(promise, "E_INVALID_STYLE") {
47+
val vibrationType = HapticsUtils.getImpactType(style)
48+
runOnUiQueueThread {
49+
vibrate(vibrationType)
50+
}
51+
promise.resolve(null)
52+
}
53+
}
54+
4355
override fun notification(type: String, promise: Promise) {
44-
try {
56+
executeSafely(promise, "E_INVALID_TYPE") {
4557
val vibrationType = HapticsUtils.getNotificationType(type)
46-
vibrate(vibrationType)
58+
runOnUiQueueThread {
59+
vibrate(vibrationType)
60+
}
4761
promise.resolve(null)
48-
} catch (e: IllegalArgumentException) {
49-
promise.reject("E_INVALID_TYPE", e.message)
50-
} catch (e: Exception) {
51-
promise.reject("E_UNEXPECTED", "An unexpected error occurred: ${e.message}", e)
5262
}
5363
}
5464

5565
override fun selection(promise: Promise) {
56-
try {
57-
vibrate(HapticsUtils.getSelectionType())
58-
promise.resolve(null)
59-
} catch (e: Exception) {
60-
promise.reject("E_UNEXPECTED", "An unexpected error occurred: ${e.message}", e)
66+
val vibrationType = HapticsUtils.getSelectionType()
67+
runOnUiQueueThread {
68+
vibrate(vibrationType)
6169
}
70+
promise.resolve(null)
6271
}
6372

6473
override fun androidHaptics(type: String, promise: Promise) {
65-
try {
66-
val view = currentActivity?.window?.decorView
67-
68-
if (view == null) {
69-
promise.reject("E_NO_VIEW", "Could not get the current view.")
70-
return
71-
}
74+
val view = currentActivity?.window?.decorView
75+
if (view == null) {
76+
promise.reject("E_NO_VIEW", "Could not get the current view.")
77+
return
78+
}
79+
executeSafely(promise, "E_INVALID_TYPE") {
7280
val feedbackConstant = HapticsUtils.getAndroidHapticsType(type)
73-
74-
reactApplicationContext.runOnUiQueueThread {
81+
runOnUiQueueThread {
7582
view.performHapticFeedback(feedbackConstant)
7683
}
7784
promise.resolve(null)
78-
} catch (e: IllegalArgumentException) {
79-
promise.reject("E_INVALID_TYPE", e.message)
80-
} catch (e: Exception) {
81-
promise.reject("E_HAPTIC_FEEDBACK", "An unexpected error occurred: ${e.message}", e)
8285
}
8386
}
8487

@@ -87,13 +90,12 @@ class HapticsModule(reactContext: ReactApplicationContext) :
8790
return
8891
}
8992
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
90-
if (vibrator?.hasAmplitudeControl() == true) {
91-
val effect = VibrationEffect.createWaveform(type.timings, type.amplitudes, -1)
92-
vibrator?.vibrate(effect)
93+
val effect = if (vibrator?.hasAmplitudeControl() == true) {
94+
VibrationEffect.createWaveform(type.timings, type.amplitudes, -1)
9395
} else {
94-
val effect = VibrationEffect.createWaveform(type.timings, -1)
95-
vibrator?.vibrate(effect)
96+
VibrationEffect.createWaveform(type.timings, -1)
9697
}
98+
vibrator?.vibrate(effect)
9799
} else {
98100
@Suppress("DEPRECATION")
99101
vibrator?.vibrate(type.oldFallback, -1)

ios/Haptics.mm

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
#import "Haptics.h"
2-
#import <React/RCTLog.h>
2+
3+
static inline void runOnMainThread(dispatch_block_t block) {
4+
if ([NSThread isMainThread]) {
5+
block();
6+
} else {
7+
dispatch_async(dispatch_get_main_queue(), block);
8+
}
9+
}
310

411
@implementation Haptics
512

@@ -45,20 +52,21 @@ - (void)impact:(NSString *)style
4552
reject:(nonnull RCTPromiseRejectBlock)reject
4653
{
4754
NSNumber *styleValue = self.impactStyles[style];
48-
55+
4956
if (!styleValue) {
5057
reject(@"E_INVALID_STYLE", [NSString stringWithFormat:@"Invalid impact style '%@'", style], nil);
5158
return;
5259
}
53-
UIImpactFeedbackGenerator *generator = self.impactGenerators[style];
60+
runOnMainThread(^{
61+
UIImpactFeedbackGenerator *generator = self.impactGenerators[style];
5462

55-
if (!generator) {
56-
generator = [[UIImpactFeedbackGenerator alloc]
57-
initWithStyle:(UIImpactFeedbackStyle)styleValue.integerValue];
58-
[generator prepare];
59-
self.impactGenerators[style] = generator;
60-
}
61-
[generator impactOccurred];
63+
if (!generator) {
64+
generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:(UIImpactFeedbackStyle)styleValue.integerValue];
65+
[generator prepare];
66+
self.impactGenerators[style] = generator;
67+
}
68+
[generator impactOccurred];
69+
});
6270
resolve(nil);
6371
}
6472

@@ -72,13 +80,17 @@ - (void)notification:(NSString *)type
7280
reject(@"E_INVALID_TYPE", [NSString stringWithFormat:@"Invalid notification type '%@'", type], nil);
7381
return;
7482
}
75-
[self.notificationGenerator notificationOccurred:(UINotificationFeedbackType)typeValue.integerValue];
83+
runOnMainThread(^{
84+
[self.notificationGenerator notificationOccurred:(UINotificationFeedbackType)typeValue.integerValue];
85+
});
7686
resolve(nil);
7787
}
7888

7989
- (void)selection:(nonnull RCTPromiseResolveBlock)resolve
8090
reject:(nonnull RCTPromiseRejectBlock)reject {
81-
[self.selectionGenerator selectionChanged];
91+
runOnMainThread(^{
92+
[self.selectionGenerator selectionChanged];
93+
});
8294
resolve(nil);
8395
}
8496

0 commit comments

Comments
 (0)