react-native-reanimated 2.3.3 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/Common/cpp/AnimatedSensor/AnimatedSensorModule.cpp +72 -0
  2. package/Common/cpp/NativeModules/NativeReanimatedModule.cpp +30 -1
  3. package/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp +64 -39
  4. package/Common/cpp/Tools/RuntimeDecorator.cpp +2 -0
  5. package/Common/cpp/headers/AnimatedSensor/AnimatedSensorModule.h +41 -0
  6. package/Common/cpp/headers/NativeModules/NativeReanimatedModule.h +14 -0
  7. package/Common/cpp/headers/NativeModules/NativeReanimatedModuleSpec.h +14 -0
  8. package/Common/cpp/headers/SharedItems/MutableValue.h +4 -1
  9. package/Common/cpp/headers/SharedItems/ShareableValue.h +3 -0
  10. package/Common/cpp/headers/SharedItems/ValueWrapper.h +3 -0
  11. package/Common/cpp/headers/Tools/PlatformDepMethodsHolder.h +11 -0
  12. package/Common/cpp/headers/Tools/RuntimeDecorator.h +2 -0
  13. package/LICENSE +1 -1
  14. package/README.md +2 -2
  15. package/android/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  16. package/android/.gradle/7.2/dependencies-accessors/gc.properties +0 -0
  17. package/android/.gradle/7.2/executionHistory/executionHistory.bin +0 -0
  18. package/android/.gradle/7.2/executionHistory/executionHistory.lock +0 -0
  19. package/android/.gradle/7.2/fileChanges/last-build.bin +0 -0
  20. package/android/.gradle/7.2/fileHashes/fileHashes.bin +0 -0
  21. package/android/.gradle/7.2/fileHashes/fileHashes.lock +0 -0
  22. package/android/.gradle/7.2/fileHashes/resourceHashesCache.bin +0 -0
  23. package/android/.gradle/7.2/gc.properties +0 -0
  24. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  25. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  26. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  27. package/android/.gradle/checksums/checksums.lock +0 -0
  28. package/android/.gradle/checksums/md5-checksums.bin +0 -0
  29. package/android/.gradle/checksums/sha1-checksums.bin +0 -0
  30. package/android/.gradle/vcs-1/gc.properties +0 -0
  31. package/android/CMakeLists.txt +198 -0
  32. package/android/README.md +15 -0
  33. package/android/build.gradle +686 -73
  34. package/android/empty.cpp +1 -0
  35. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  36. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  37. package/android/gradle.properties +25 -0
  38. package/android/gradlew +234 -0
  39. package/android/gradlew.bat +89 -0
  40. package/android/react-native-reanimated-64-hermes.aar +0 -0
  41. package/android/react-native-reanimated-64-jsc.aar +0 -0
  42. package/android/react-native-reanimated-65-hermes.aar +0 -0
  43. package/android/react-native-reanimated-65-jsc.aar +0 -0
  44. package/android/react-native-reanimated-66-hermes.aar +0 -0
  45. package/android/react-native-reanimated-66-jsc.aar +0 -0
  46. package/android/react-native-reanimated-67-hermes.aar +0 -0
  47. package/android/react-native-reanimated-67-jsc.aar +0 -0
  48. package/android/react-native-reanimated-68-hermes.aar +0 -0
  49. package/android/react-native-reanimated-68-jsc.aar +0 -0
  50. package/android/rnVersionPatch/62/layoutReanimation/ReanimatedNativeHierarchyManager.java +412 -0
  51. package/android/rnVersionPatch/62/layoutReanimation/ReanimatedUIImplementation.java +68 -0
  52. package/android/rnVersionPatch/63/layoutReanimation/ReanimatedUIImplementation.java +68 -0
  53. package/android/rnVersionPatch/64/layoutReanimation/ReanimatedUIImplementation.java +68 -0
  54. package/android/rnVersionPatch/65/.gitkeep +0 -0
  55. package/android/rnVersionPatch/66/.gitkeep +0 -0
  56. package/android/rnVersionPatch/67/.gitkeep +0 -0
  57. package/android/rnVersionPatch/68/.gitkeep +0 -0
  58. package/android/rnVersionPatch/backup/.gitkeep +0 -0
  59. package/android/settings.gradle +1 -0
  60. package/android/spotless.gradle +9 -0
  61. package/android/src/{AndroidManifest.xml → main/AndroidManifest.xml} +0 -0
  62. package/android/src/main/cpp/AndroidErrorHandler.cpp +42 -0
  63. package/android/src/main/cpp/AndroidLogger.cpp +27 -0
  64. package/android/src/main/cpp/AndroidScheduler.cpp +59 -0
  65. package/android/src/main/cpp/JNIHelper.cpp +59 -0
  66. package/android/src/main/cpp/LayoutAnimations.cpp +103 -0
  67. package/android/src/main/cpp/NativeProxy.cpp +327 -0
  68. package/android/src/main/cpp/OnLoad.cpp +17 -0
  69. package/android/src/main/cpp/TurboModule.cpp +44 -0
  70. package/android/src/main/cpp/headers/AndroidErrorHandler.h +30 -0
  71. package/android/src/main/cpp/headers/AndroidLogger.h +16 -0
  72. package/android/src/main/cpp/headers/AndroidScheduler.h +41 -0
  73. package/android/src/main/cpp/headers/JNIHelper.h +30 -0
  74. package/android/src/main/cpp/headers/LayoutAnimations.h +42 -0
  75. package/android/src/main/cpp/headers/NativeProxy.h +170 -0
  76. package/android/src/main/cpp/headers/TurboModule.h +70 -0
  77. package/android/src/main/java/com/facebook/react/uimanager/UIManagerReanimatedHelper.java +15 -0
  78. package/android/src/main/java/com/swmansion/common/GestureHandlerStateManager.java +5 -0
  79. package/android/src/main/java/com/swmansion/reanimated/AndroidErrorHandler.java +8 -0
  80. package/android/src/main/java/com/swmansion/reanimated/CopiedEvent.java +43 -0
  81. package/android/src/main/java/com/swmansion/reanimated/MapUtils.java +26 -0
  82. package/android/src/main/java/com/swmansion/reanimated/NativeMethodsHelper.java +117 -0
  83. package/android/src/main/java/com/swmansion/reanimated/NativeProxy.java +285 -0
  84. package/android/src/main/java/com/swmansion/reanimated/NodesManager.java +682 -0
  85. package/android/src/main/java/com/swmansion/reanimated/ReanimatedJSIModulePackage.java +29 -0
  86. package/android/src/main/java/com/swmansion/reanimated/ReanimatedModule.java +251 -0
  87. package/android/src/main/java/com/swmansion/reanimated/ReanimatedPackage.java +96 -0
  88. package/android/src/main/java/com/swmansion/reanimated/Scheduler.java +51 -0
  89. package/android/src/main/java/com/swmansion/reanimated/UpdateContext.java +11 -0
  90. package/android/src/main/java/com/swmansion/reanimated/Utils.java +32 -0
  91. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/AnimationsManager.java +517 -0
  92. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/LayoutAnimations.java +56 -0
  93. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/NativeMethodsHolder.java +11 -0
  94. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ReanimatedNativeHierarchyManager.java +410 -0
  95. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ReanimatedUIImplementation.java +68 -0
  96. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ReanimatedUIManager.java +292 -0
  97. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/Snapshot.java +121 -0
  98. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ViewHierarchyObserver.java +12 -0
  99. package/android/src/main/java/com/swmansion/reanimated/nodes/AlwaysNode.java +29 -0
  100. package/android/src/main/java/com/swmansion/reanimated/nodes/BezierNode.java +87 -0
  101. package/android/src/main/java/com/swmansion/reanimated/nodes/BlockNode.java +24 -0
  102. package/android/src/main/java/com/swmansion/reanimated/nodes/CallFuncNode.java +49 -0
  103. package/android/src/main/java/com/swmansion/reanimated/nodes/ClockNode.java +38 -0
  104. package/android/src/main/java/com/swmansion/reanimated/nodes/ClockOpNode.java +73 -0
  105. package/android/src/main/java/com/swmansion/reanimated/nodes/ConcatNode.java +36 -0
  106. package/android/src/main/java/com/swmansion/reanimated/nodes/CondNode.java +41 -0
  107. package/android/src/main/java/com/swmansion/reanimated/nodes/DebugNode.java +33 -0
  108. package/android/src/main/java/com/swmansion/reanimated/nodes/EventNode.java +83 -0
  109. package/android/src/main/java/com/swmansion/reanimated/nodes/FinalNode.java +5 -0
  110. package/android/src/main/java/com/swmansion/reanimated/nodes/FunctionNode.java +20 -0
  111. package/android/src/main/java/com/swmansion/reanimated/nodes/JSCallNode.java +41 -0
  112. package/android/src/main/java/com/swmansion/reanimated/nodes/Node.java +139 -0
  113. package/android/src/main/java/com/swmansion/reanimated/nodes/NoopNode.java +37 -0
  114. package/android/src/main/java/com/swmansion/reanimated/nodes/OperatorNode.java +377 -0
  115. package/android/src/main/java/com/swmansion/reanimated/nodes/ParamNode.java +71 -0
  116. package/android/src/main/java/com/swmansion/reanimated/nodes/PropsNode.java +153 -0
  117. package/android/src/main/java/com/swmansion/reanimated/nodes/SetNode.java +32 -0
  118. package/android/src/main/java/com/swmansion/reanimated/nodes/StyleNode.java +40 -0
  119. package/android/src/main/java/com/swmansion/reanimated/nodes/TransformNode.java +84 -0
  120. package/android/src/main/java/com/swmansion/reanimated/nodes/ValueNode.java +40 -0
  121. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensor.java +41 -0
  122. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorContainer.java +40 -0
  123. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorListener.java +31 -0
  124. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorType.java +35 -0
  125. package/android/src/main/java/com/swmansion/reanimated/transitions/ChangeTransition.java +84 -0
  126. package/android/src/main/java/com/swmansion/reanimated/transitions/SaneSidePropagation.java +25 -0
  127. package/android/src/main/java/com/swmansion/reanimated/transitions/Scale.java +86 -0
  128. package/android/src/main/java/com/swmansion/reanimated/transitions/TransitionModule.java +41 -0
  129. package/android/src/main/java/com/swmansion/reanimated/transitions/TransitionUtils.java +161 -0
  130. package/ios/LayoutReanimation/REAAnimationsManager.h +1 -1
  131. package/ios/LayoutReanimation/REAAnimationsManager.m +18 -4
  132. package/ios/REAModule.m +8 -9
  133. package/ios/REANodesManager.h +4 -1
  134. package/ios/REANodesManager.m +75 -3
  135. package/ios/native/NativeMethods.h +1 -1
  136. package/ios/native/NativeProxy.mm +85 -5
  137. package/ios/sensor/ReanimatedSensor.h +21 -0
  138. package/ios/sensor/ReanimatedSensor.m +169 -0
  139. package/ios/sensor/ReanimatedSensorContainer.h +13 -0
  140. package/ios/sensor/ReanimatedSensorContainer.m +41 -0
  141. package/ios/sensor/ReanimatedSensorType.h +7 -0
  142. package/lib/ConfigHelper.js +2 -2
  143. package/lib/createAnimatedComponent.js +3 -4
  144. package/lib/reanimated1/core/AnimatedFunction.js +1 -1
  145. package/lib/reanimated1/derived/interpolate.js +2 -4
  146. package/lib/reanimated2/Colors.js +3 -98
  147. package/lib/reanimated2/Easing.js +5 -0
  148. package/lib/reanimated2/NativeMethods.js +15 -5
  149. package/lib/reanimated2/NativeReanimated/NativeReanimated.js +25 -12
  150. package/lib/reanimated2/NativeReanimated/index.js +2 -6
  151. package/lib/reanimated2/ViewDescriptorsSet.js +2 -2
  152. package/lib/reanimated2/animation/styleAnimation.js +2 -1
  153. package/lib/reanimated2/core.js +30 -24
  154. package/lib/reanimated2/globals.d.ts +6 -0
  155. package/lib/reanimated2/hook/index.js +1 -0
  156. package/lib/reanimated2/hook/useAnimatedGestureHandler.js +1 -2
  157. package/lib/reanimated2/hook/useAnimatedSensor.js +66 -0
  158. package/lib/reanimated2/hook/useAnimatedStyle.js +31 -14
  159. package/lib/reanimated2/hook/utils.js +14 -11
  160. package/lib/reanimated2/index.js +2 -0
  161. package/lib/reanimated2/interpolateColor.js +98 -0
  162. package/lib/reanimated2/interpolation.js +1 -1
  163. package/lib/reanimated2/jestUtils.js +9 -4
  164. package/lib/reanimated2/js-reanimated/JSReanimated.js +24 -3
  165. package/lib/reanimated2/js-reanimated/commonTypes.js +1 -0
  166. package/lib/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.js +8 -0
  167. package/lib/reanimated2/layoutReanimation/animationBuilder/Keyframe.js +2 -1
  168. package/lib/reanimated2/layoutReanimation/defaultAnimations/Bounce.js +32 -42
  169. package/lib/reanimated2/layoutReanimation/defaultAnimations/Fade.js +20 -38
  170. package/lib/reanimated2/layoutReanimation/defaultAnimations/Flip.js +32 -44
  171. package/lib/reanimated2/layoutReanimation/defaultAnimations/Lightspeed.js +8 -16
  172. package/lib/reanimated2/layoutReanimation/defaultAnimations/Pinwheel.js +6 -10
  173. package/lib/reanimated2/layoutReanimation/defaultAnimations/Roll.js +8 -12
  174. package/lib/reanimated2/layoutReanimation/defaultAnimations/Rotate.js +20 -36
  175. package/lib/reanimated2/layoutReanimation/defaultAnimations/Slide.js +16 -20
  176. package/lib/reanimated2/layoutReanimation/defaultAnimations/Stretch.js +8 -12
  177. package/lib/reanimated2/layoutReanimation/defaultAnimations/Zoom.js +32 -48
  178. package/lib/reanimated2/layoutReanimation/defaultTransitions/EntryExitTransition.js +22 -18
  179. package/lib/reanimated2/mock.js +3 -2
  180. package/mock.js +6 -4
  181. package/package.json +44 -36
  182. package/plugin.js +3 -0
  183. package/react-native-reanimated.d.ts +102 -15
  184. package/src/ConfigHelper.ts +4 -4
  185. package/src/createAnimatedComponent.tsx +3 -3
  186. package/src/reanimated1/core/AnimatedFunction.js +1 -1
  187. package/src/reanimated1/derived/interpolate.js +2 -4
  188. package/src/reanimated2/Colors.ts +8 -151
  189. package/src/reanimated2/Easing.ts +11 -0
  190. package/src/reanimated2/NativeMethods.ts +19 -6
  191. package/src/reanimated2/NativeReanimated/NativeReanimated.ts +42 -14
  192. package/src/reanimated2/NativeReanimated/index.ts +2 -8
  193. package/src/reanimated2/ViewDescriptorsSet.ts +2 -3
  194. package/src/reanimated2/animation/commonTypes.ts +44 -40
  195. package/src/reanimated2/animation/decay.ts +1 -1
  196. package/src/reanimated2/animation/delay.ts +2 -16
  197. package/src/reanimated2/animation/index.ts +8 -8
  198. package/src/reanimated2/animation/repeat.ts +2 -12
  199. package/src/reanimated2/animation/sequence.ts +3 -10
  200. package/src/reanimated2/animation/spring.ts +1 -1
  201. package/src/reanimated2/animation/styleAnimation.ts +11 -25
  202. package/src/reanimated2/animation/timing.ts +4 -2
  203. package/src/reanimated2/animation/util.ts +22 -20
  204. package/src/reanimated2/commonTypes.ts +68 -1
  205. package/src/reanimated2/component/FlatList.tsx +2 -1
  206. package/src/reanimated2/core.ts +35 -29
  207. package/src/reanimated2/globals.d.ts +6 -0
  208. package/src/reanimated2/hook/commonTypes.ts +5 -0
  209. package/src/reanimated2/hook/index.ts +1 -0
  210. package/src/reanimated2/hook/useAnimatedGestureHandler.ts +1 -2
  211. package/src/reanimated2/hook/useAnimatedRef.ts +1 -5
  212. package/src/reanimated2/hook/useAnimatedSensor.ts +91 -0
  213. package/src/reanimated2/hook/useAnimatedStyle.ts +35 -16
  214. package/src/reanimated2/hook/utils.ts +20 -18
  215. package/src/reanimated2/index.ts +2 -0
  216. package/src/reanimated2/interpolateColor.ts +178 -0
  217. package/src/reanimated2/interpolation.ts +2 -6
  218. package/src/reanimated2/jestUtils.ts +9 -4
  219. package/src/reanimated2/js-reanimated/JSReanimated.ts +28 -6
  220. package/src/reanimated2/js-reanimated/Mapper.ts +1 -1
  221. package/src/reanimated2/js-reanimated/MapperRegistry.ts +1 -1
  222. package/src/reanimated2/js-reanimated/commonTypes.ts +51 -0
  223. package/src/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.ts +13 -0
  224. package/src/reanimated2/layoutReanimation/animationBuilder/Keyframe.ts +2 -3
  225. package/src/reanimated2/layoutReanimation/defaultAnimations/Bounce.ts +51 -21
  226. package/src/reanimated2/layoutReanimation/defaultAnimations/Fade.ts +40 -10
  227. package/src/reanimated2/layoutReanimation/defaultAnimations/Flip.ts +48 -12
  228. package/src/reanimated2/layoutReanimation/defaultAnimations/Lightspeed.ts +16 -4
  229. package/src/reanimated2/layoutReanimation/defaultAnimations/Pinwheel.ts +8 -2
  230. package/src/reanimated2/layoutReanimation/defaultAnimations/Roll.ts +16 -4
  231. package/src/reanimated2/layoutReanimation/defaultAnimations/Rotate.ts +32 -8
  232. package/src/reanimated2/layoutReanimation/defaultAnimations/Slide.ts +32 -10
  233. package/src/reanimated2/layoutReanimation/defaultAnimations/Stretch.ts +16 -4
  234. package/src/reanimated2/layoutReanimation/defaultAnimations/Zoom.ts +64 -16
  235. package/src/reanimated2/layoutReanimation/defaultTransitions/CurvedTransition.ts +2 -1
  236. package/src/reanimated2/layoutReanimation/defaultTransitions/EntryExitTransition.ts +32 -21
  237. package/src/reanimated2/layoutReanimation/defaultTransitions/FadingTransition.ts +2 -1
  238. package/src/reanimated2/layoutReanimation/defaultTransitions/JumpingTransition.ts +2 -1
  239. package/src/reanimated2/layoutReanimation/defaultTransitions/LinearTransition.ts +2 -1
  240. package/src/reanimated2/layoutReanimation/defaultTransitions/SequencedTransition.ts +2 -1
  241. package/src/reanimated2/mock.ts +3 -2
  242. package/src/reanimated2/utils.ts +1 -1
  243. package/android/react-native-reanimated-63-hermes.aar +0 -0
  244. package/android/react-native-reanimated-63-jsc.aar +0 -0
  245. package/android/src/main/java/com/swmansion/reanimated/ReanimatedProxyPackage.java +0 -15
  246. package/libSo/fbjni/jni/arm64-v8a/libfbjni.so +0 -0
  247. package/libSo/fbjni/jni/armeabi-v7a/libfbjni.so +0 -0
  248. package/libSo/fbjni/jni/x86/libfbjni.so +0 -0
  249. package/libSo/fbjni/jni/x86_64/libfbjni.so +0 -0
@@ -14,6 +14,7 @@ typedef NS_ENUM(NSInteger, FrameConfigType) { EnteringFrame, ExitingFrame };
14
14
 
15
15
  - (void)removeLeftovers;
16
16
  - (void)scheduleCleaning;
17
+ - (double)getDoubleOrZero:(NSNumber *)number;
17
18
 
18
19
  @end
19
20
 
@@ -150,6 +151,10 @@ typedef NS_ENUM(NSInteger, FrameConfigType) { EnteringFrame, ExitingFrame };
150
151
  NSMutableSet<NSNumber *> *roots = [NSMutableSet new];
151
152
  for (NSNumber *viewTag in _toRemove) {
152
153
  UIView *view = _viewForTag[viewTag];
154
+ if (view == nil) {
155
+ view = [_reaUiManager viewForReactTag:viewTag];
156
+ _viewForTag[viewTag] = view;
157
+ }
153
158
  [self findRoot:view roots:roots];
154
159
  }
155
160
  for (NSNumber *viewTag in roots) {
@@ -190,31 +195,40 @@ typedef NS_ENUM(NSInteger, FrameConfigType) { EnteringFrame, ExitingFrame };
190
195
  [self setNewProps:[newStyle mutableCopy] forView:_viewForTag[tag] withComponentData:componentData];
191
196
  }
192
197
 
198
+ - (double)getDoubleOrZero:(NSNumber *)number
199
+ {
200
+ double doubleValue = [number doubleValue];
201
+ if (doubleValue != doubleValue) { // NaN != NaN
202
+ return 0;
203
+ }
204
+ return doubleValue;
205
+ }
206
+
193
207
  - (void)setNewProps:(NSMutableDictionary *)newProps
194
208
  forView:(UIView *)view
195
209
  withComponentData:(RCTComponentData *)componentData
196
210
  {
197
211
  if (newProps[@"height"]) {
198
- double height = [newProps[@"height"] doubleValue];
212
+ double height = [self getDoubleOrZero:newProps[@"height"]];
199
213
  double oldHeight = view.bounds.size.height;
200
214
  view.bounds = CGRectMake(0, 0, view.bounds.size.width, height);
201
215
  view.center = CGPointMake(view.center.x, view.center.y - oldHeight / 2.0 + view.bounds.size.height / 2.0);
202
216
  [newProps removeObjectForKey:@"height"];
203
217
  }
204
218
  if (newProps[@"width"]) {
205
- double width = [newProps[@"width"] doubleValue];
219
+ double width = [self getDoubleOrZero:newProps[@"width"]];
206
220
  double oldWidth = view.bounds.size.width;
207
221
  view.bounds = CGRectMake(0, 0, width, view.bounds.size.height);
208
222
  view.center = CGPointMake(view.center.x + view.bounds.size.width / 2.0 - oldWidth / 2.0, view.center.y);
209
223
  [newProps removeObjectForKey:@"width"];
210
224
  }
211
225
  if (newProps[@"originX"]) {
212
- double originX = [newProps[@"originX"] doubleValue];
226
+ double originX = [self getDoubleOrZero:newProps[@"originX"]];
213
227
  view.center = CGPointMake(originX + view.bounds.size.width / 2.0, view.center.y);
214
228
  [newProps removeObjectForKey:@"originX"];
215
229
  }
216
230
  if (newProps[@"originY"]) {
217
- double originY = [newProps[@"originY"] doubleValue];
231
+ double originY = [self getDoubleOrZero:newProps[@"originY"]];
218
232
  view.center = CGPointMake(view.center.x, originY + view.bounds.size.height / 2.0);
219
233
  [newProps removeObjectForKey:@"originY"];
220
234
  }
package/ios/REAModule.m CHANGED
@@ -28,6 +28,8 @@ RCT_EXPORT_MODULE(ReanimatedModule);
28
28
  return RCTGetUIManagerQueue();
29
29
  }
30
30
 
31
+ #pragma mark-- Initialize
32
+
31
33
  - (void)setBridge:(RCTBridge *)bridge
32
34
  {
33
35
  [super setBridge:bridge];
@@ -40,6 +42,11 @@ RCT_EXPORT_MODULE(ReanimatedModule);
40
42
  [bridge.uiManager.observerCoordinator addObserver:self];
41
43
  }
42
44
 
45
+ RCT_EXPORT_METHOD(installTurboModule)
46
+ {
47
+ // TODO: Move initialization from UIResponder+Reanimated to here
48
+ }
49
+
43
50
  #pragma mark-- Transitioning API
44
51
 
45
52
  RCT_EXPORT_METHOD(animateNextTransition : (nonnull NSNumber *)rootTag config : (NSDictionary *)config)
@@ -119,15 +126,6 @@ RCT_EXPORT_METHOD(detachEvent
119
126
  }];
120
127
  }
121
128
 
122
- RCT_EXPORT_METHOD(configureProps
123
- : (nonnull NSArray<NSString *> *)nativeProps uiProps
124
- : (nonnull NSArray<NSString *> *)uiProps)
125
- {
126
- [self addOperationBlock:^(REANodesManager *nodesManager) {
127
- [nodesManager configureProps:[NSSet setWithArray:nativeProps] uiProps:[NSSet setWithArray:uiProps]];
128
- }];
129
- }
130
-
131
129
  RCT_EXPORT_METHOD(setValue : (nonnull NSNumber *)nodeID newValue : (nonnull NSNumber *)newValue)
132
130
  {
133
131
  [self addOperationBlock:^(REANodesManager *nodesManager) {
@@ -153,6 +151,7 @@ RCT_EXPORT_METHOD(triggerRender)
153
151
 
154
152
  - (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager
155
153
  {
154
+ [_nodesManager maybeFlushUpdateBuffer];
156
155
  if (_operations.count == 0) {
157
156
  return;
158
157
  }
@@ -64,7 +64,8 @@ typedef void (^REAEventHandler)(NSString *eventName, id<RCTEvent> event);
64
64
 
65
65
  // configuration
66
66
 
67
- - (void)configureProps:(nonnull NSSet<NSString *> *)nativeProps uiProps:(nonnull NSSet<NSString *> *)uiProps;
67
+ - (void)configureUiProps:(nonnull NSSet<NSString *> *)uiPropsSet
68
+ andNativeProps:(nonnull NSSet<NSString *> *)nativePropsSet;
68
69
 
69
70
  - (void)updateProps:(nonnull NSDictionary *)props
70
71
  ofViewWithTag:(nonnull NSNumber *)viewTag
@@ -78,4 +79,6 @@ typedef void (^REAEventHandler)(NSString *eventName, id<RCTEvent> event);
78
79
 
79
80
  - (void)setValueForNodeID:(nonnull NSNumber *)nodeID value:(nonnull NSNumber *)newValue;
80
81
 
82
+ - (void)maybeFlushUpdateBuffer;
83
+
81
84
  @end
@@ -3,6 +3,7 @@
3
3
  #import <React/RCTConvert.h>
4
4
 
5
5
  #import <React/RCTShadowView.h>
6
+ #import <stdatomic.h>
6
7
  #import "Nodes/REAAlwaysNode.h"
7
8
  #import "Nodes/REABezierNode.h"
8
9
  #import "Nodes/REABlockNode.h"
@@ -46,6 +47,17 @@
46
47
 
47
48
  @end
48
49
 
50
+ @interface ComponentUpdate : NSObject
51
+
52
+ @property (nonnull) NSMutableDictionary *props;
53
+ @property (nonnull) NSNumber *viewTag;
54
+ @property (nonnull) NSString *viewName;
55
+
56
+ @end
57
+
58
+ @implementation ComponentUpdate
59
+ @end
60
+
49
61
  @implementation RCTUIManager (SyncUpdates)
50
62
 
51
63
  - (BOOL)hasEnqueuedUICommands
@@ -99,6 +111,9 @@
99
111
  BOOL _tryRunBatchUpdatesSynchronously;
100
112
  REAEventHandler _eventHandler;
101
113
  volatile void (^_mounting)(void);
114
+ NSMutableDictionary<NSNumber *, ComponentUpdate *> *_componentUpdateBuffer;
115
+ volatile atomic_bool _shouldFlushUpdateBuffer;
116
+ NSMutableDictionary<NSNumber *, UIView *> *_viewRegistry;
102
117
  }
103
118
 
104
119
  - (instancetype)initWithModule:(REAModule *)reanimatedModule uiManager:(RCTUIManager *)uiManager
@@ -113,6 +128,9 @@
113
128
  _wantRunUpdates = NO;
114
129
  _onAnimationCallbacks = [NSMutableArray new];
115
130
  _operationsInBatch = [NSMutableArray new];
131
+ _componentUpdateBuffer = [NSMutableDictionary new];
132
+ _viewRegistry = [_uiManager valueForKey:@"_viewRegistry"];
133
+ _shouldFlushUpdateBuffer = false;
116
134
  }
117
135
 
118
136
  _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onAnimationFrame:)];
@@ -486,10 +504,16 @@
486
504
  }
487
505
  }
488
506
 
489
- - (void)configureProps:(NSSet<NSString *> *)nativeProps uiProps:(NSSet<NSString *> *)uiProps
507
+ - (void)configureUiProps:(nonnull NSSet<NSString *> *)uiPropsSet
508
+ andNativeProps:(nonnull NSSet<NSString *> *)nativePropsSet
490
509
  {
491
- _uiProps = uiProps;
492
- _nativeProps = nativeProps;
510
+ _uiProps = uiPropsSet;
511
+ _nativeProps = nativePropsSet;
512
+ }
513
+
514
+ - (BOOL)isNotNativeViewFullyMounted:(NSNumber *)viewTag
515
+ {
516
+ return _viewRegistry[viewTag].superview == nil;
493
517
  }
494
518
 
495
519
  - (void)setValueForNodeID:(nonnull NSNumber *)nodeID value:(nonnull NSNumber *)newValue
@@ -506,6 +530,24 @@
506
530
  ofViewWithTag:(nonnull NSNumber *)viewTag
507
531
  withName:(nonnull NSString *)viewName
508
532
  {
533
+ ComponentUpdate *lastSnapshot = _componentUpdateBuffer[viewTag];
534
+ if ([self isNotNativeViewFullyMounted:viewTag] || lastSnapshot != nil) {
535
+ if (lastSnapshot == nil) {
536
+ ComponentUpdate *propsSnapshot = [ComponentUpdate new];
537
+ propsSnapshot.props = [props mutableCopy];
538
+ propsSnapshot.viewTag = viewTag;
539
+ propsSnapshot.viewName = viewName;
540
+ _componentUpdateBuffer[viewTag] = propsSnapshot;
541
+ atomic_store(&_shouldFlushUpdateBuffer, true);
542
+ } else {
543
+ NSMutableDictionary *lastProps = lastSnapshot.props;
544
+ for (NSString *key in props) {
545
+ [lastProps setValue:props[key] forKey:key];
546
+ }
547
+ }
548
+ return;
549
+ }
550
+
509
551
  // TODO: refactor PropsNode to also use this function
510
552
  NSMutableDictionary *uiProps = [NSMutableDictionary new];
511
553
  NSMutableDictionary *nativeProps = [NSMutableDictionary new];
@@ -553,4 +595,34 @@
553
595
  return result;
554
596
  }
555
597
 
598
+ - (void)maybeFlushUpdateBuffer
599
+ {
600
+ RCTAssertUIManagerQueue();
601
+ bool shouldFlushUpdateBuffer = atomic_load(&_shouldFlushUpdateBuffer);
602
+ if (!shouldFlushUpdateBuffer) {
603
+ return;
604
+ }
605
+
606
+ __weak typeof(self) weakSelf = self;
607
+ [_uiManager addUIBlock:^(__unused RCTUIManager *manager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
608
+ __typeof__(self) strongSelf = weakSelf;
609
+ if (strongSelf == nil) {
610
+ return;
611
+ }
612
+ atomic_store(&strongSelf->_shouldFlushUpdateBuffer, false);
613
+ NSMutableDictionary *componentUpdateBuffer = [strongSelf->_componentUpdateBuffer copy];
614
+ strongSelf->_componentUpdateBuffer = [NSMutableDictionary new];
615
+ for (NSNumber *tag in componentUpdateBuffer) {
616
+ ComponentUpdate *componentUpdate = componentUpdateBuffer[tag];
617
+ if (componentUpdate == Nil) {
618
+ continue;
619
+ }
620
+ [strongSelf updateProps:componentUpdate.props
621
+ ofViewWithTag:componentUpdate.viewTag
622
+ withName:componentUpdate.viewName];
623
+ }
624
+ [strongSelf performOperations];
625
+ }];
626
+ }
627
+
556
628
  @end
@@ -1,11 +1,11 @@
1
1
  #import <Foundation/Foundation.h>
2
+ #import <RNGestureHandlerStateManager.h>
2
3
  #import <React/RCTUIManager.h>
3
4
  #include <string>
4
5
  #import <string>
5
6
  #include <utility>
6
7
  #include <vector>
7
8
  #import <vector>
8
- #import "RNGestureHandlerStateManager.h"
9
9
 
10
10
  namespace reanimated {
11
11
 
@@ -1,8 +1,12 @@
1
+ #if TARGET_IPHONE_SIMULATOR
2
+ #import <dlfcn.h>
3
+ #endif
1
4
 
2
5
  #import <React/RCTFollyConvert.h>
3
6
  #import <React/RCTUIManager.h>
4
7
  #import <folly/json.h>
5
8
 
9
+ #import <RNGestureHandlerStateManager.h>
6
10
  #import "LayoutAnimationsProxy.h"
7
11
  #import "NativeMethods.h"
8
12
  #import "NativeProxy.h"
@@ -12,7 +16,7 @@
12
16
  #import "REAModule.h"
13
17
  #import "REANodesManager.h"
14
18
  #import "REAUIManager.h"
15
- #import "RNGestureHandlerStateManager.h"
19
+ #import "ReanimatedSensorContainer.h"
16
20
 
17
21
  #if __has_include(<reacthermes/HermesExecutorFactory.h>)
18
22
  #import <reacthermes/HermesExecutorFactory.h>
@@ -27,6 +31,41 @@ namespace reanimated {
27
31
  using namespace facebook;
28
32
  using namespace react;
29
33
 
34
+ static CGFloat SimAnimationDragCoefficient(void)
35
+ {
36
+ static float (*UIAnimationDragCoefficient)(void) = NULL;
37
+ #if TARGET_IPHONE_SIMULATOR
38
+ static dispatch_once_t onceToken;
39
+ dispatch_once(&onceToken, ^{
40
+ UIAnimationDragCoefficient = (float (*)(void))dlsym(RTLD_DEFAULT, "UIAnimationDragCoefficient");
41
+ });
42
+ #endif
43
+ return UIAnimationDragCoefficient ? UIAnimationDragCoefficient() : 1.f;
44
+ }
45
+
46
+ static CFTimeInterval calculateTimestampWithSlowAnimations(CFTimeInterval currentTimestamp)
47
+ {
48
+ #if TARGET_IPHONE_SIMULATOR
49
+ static CFTimeInterval dragCoefChangedTimestamp = CACurrentMediaTime();
50
+ static CGFloat previousDragCoef = SimAnimationDragCoefficient();
51
+
52
+ const CGFloat dragCoef = SimAnimationDragCoefficient();
53
+ if (previousDragCoef != dragCoef) {
54
+ previousDragCoef = dragCoef;
55
+ dragCoefChangedTimestamp = CACurrentMediaTime();
56
+ }
57
+
58
+ const bool areSlowAnimationsEnabled = dragCoef != 1.f;
59
+ if (areSlowAnimationsEnabled) {
60
+ return (dragCoefChangedTimestamp + (currentTimestamp - dragCoefChangedTimestamp) / dragCoef);
61
+ } else {
62
+ return currentTimestamp;
63
+ }
64
+ #else
65
+ return currentTimestamp;
66
+ #endif
67
+ }
68
+
30
69
  // COPIED FROM RCTTurboModule.mm
31
70
  static id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value);
32
71
 
@@ -87,6 +126,17 @@ static id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &v
87
126
  throw std::runtime_error("Unsupported jsi::jsi::Value kind");
88
127
  }
89
128
 
129
+ static NSSet *convertProps(jsi::Runtime &rt, const jsi::Value &props)
130
+ {
131
+ NSMutableSet *propsSet = [[NSMutableSet alloc] init];
132
+ jsi::Array propsNames = props.asObject(rt).asArray(rt);
133
+ for (int i = 0; i < propsNames.size(rt); i++) {
134
+ NSString *propName = @(propsNames.getValueAtIndex(rt, i).asString(rt).utf8(rt).c_str());
135
+ [propsSet addObject:propName];
136
+ }
137
+ return propsSet;
138
+ }
139
+
90
140
  std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
91
141
  RCTBridge *bridge,
92
142
  std::shared_ptr<CallInvoker> jsInvoker)
@@ -149,7 +199,7 @@ std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
149
199
 
150
200
  auto requestRender = [reanimatedModule, &module](std::function<void(double)> onRender, jsi::Runtime &rt) {
151
201
  [reanimatedModule.nodesManager postOnAnimation:^(CADisplayLink *displayLink) {
152
- double frameTimestamp = displayLink.targetTimestamp * 1000;
202
+ double frameTimestamp = calculateTimestampWithSlowAnimations(displayLink.targetTimestamp) * 1000;
153
203
  jsi::Object global = rt.global();
154
204
  jsi::String frameTimestampName = jsi::String::createFromAscii(rt, "_frameTimestamp");
155
205
  global.setProperty(rt, frameTimestampName, frameTimestamp);
@@ -158,7 +208,7 @@ std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
158
208
  }];
159
209
  };
160
210
 
161
- auto getCurrentTime = []() { return CACurrentMediaTime() * 1000; };
211
+ auto getCurrentTime = []() { return calculateTimestampWithSlowAnimations(CACurrentMediaTime()) * 1000; };
162
212
 
163
213
  // Layout Animations start
164
214
  REAUIManager *reaUiManagerNoCast = [bridge moduleForClass:[REAUIManager class]];
@@ -179,6 +229,13 @@ std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
179
229
  }
180
230
  };
181
231
 
232
+ auto configurePropsFunction = [reanimatedModule](
233
+ jsi::Runtime &rt, const jsi::Value &uiProps, const jsi::Value &nativeProps) {
234
+ NSSet *uiPropsSet = convertProps(rt, uiProps);
235
+ NSSet *nativePropsSet = convertProps(rt, nativeProps);
236
+ [reanimatedModule.nodesManager configureUiProps:uiPropsSet andNativeProps:nativePropsSet];
237
+ };
238
+
182
239
  std::shared_ptr<LayoutAnimationsProxy> layoutAnimationsProxy =
183
240
  std::make_shared<LayoutAnimationsProxy>(notifyAboutProgress, notifyAboutEnd);
184
241
  std::weak_ptr<jsi::Runtime> wrt = animatedRuntime;
@@ -224,14 +281,29 @@ std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
224
281
 
225
282
  // Layout Animations end
226
283
 
284
+ // sensors
285
+ ReanimatedSensorContainer *reanimatedSensorContainer = [[ReanimatedSensorContainer alloc] init];
286
+ auto registerSensorFunction = [=](int sensorType, int interval, std::function<void(double[])> setter) -> int {
287
+ return [reanimatedSensorContainer registerSensor:(ReanimatedSensorType)sensorType
288
+ interval:interval
289
+ setter:^(double *data) {
290
+ setter(data);
291
+ }];
292
+ };
293
+
294
+ auto unregisterSensorFunction = [=](int sensorId) { [reanimatedSensorContainer unregisterSensor:sensorId]; };
295
+ // end sensors
296
+
227
297
  PlatformDepMethodsHolder platformDepMethodsHolder = {
228
298
  requestRender,
229
299
  propUpdater,
230
300
  scrollToFunction,
231
301
  measuringFunction,
232
302
  getCurrentTime,
303
+ registerSensorFunction,
304
+ unregisterSensorFunction,
233
305
  setGestureStateFunction,
234
- };
306
+ configurePropsFunction};
235
307
 
236
308
  module = std::make_shared<NativeReanimatedModule>(
237
309
  jsInvoker,
@@ -246,7 +318,15 @@ std::shared_ptr<NativeReanimatedModule> createReanimatedModule(
246
318
 
247
319
  [reanimatedModule.nodesManager registerEventHandler:^(NSString *eventName, id<RCTEvent> event) {
248
320
  std::string eventNameString([eventName UTF8String]);
249
- std::string eventAsString = folly::toJson(convertIdToFollyDynamic([event arguments][2]));
321
+
322
+ std::string eventAsString;
323
+ try {
324
+ eventAsString = folly::toJson(convertIdToFollyDynamic([event arguments][2]));
325
+ } catch (std::exception &) {
326
+ // Events from other libraries may contain NaN or INF values which cannot be represented in JSON.
327
+ // See https://github.com/software-mansion/react-native-reanimated/issues/1776 for details.
328
+ return;
329
+ }
250
330
 
251
331
  eventAsString = "{ NativeMap:" + eventAsString + "}";
252
332
  jsi::Object global = module->runtime->global();
@@ -0,0 +1,21 @@
1
+ #import <CoreMotion/CoreMotion.h>
2
+ #import "ReanimatedSensorType.h"
3
+
4
+ @interface ReanimatedSensor : NSObject {
5
+ ReanimatedSensorType _sensorType;
6
+ double _interval;
7
+ double _lastTimestamp;
8
+ CMMotionManager *_motionManager;
9
+ void (^_setter)(double[]);
10
+ }
11
+
12
+ - (instancetype)init:(ReanimatedSensorType)sensorType interval:(int)interval setter:(void (^)(double[]))setter;
13
+ - (bool)initialize;
14
+ - (bool)initializeGyroscope;
15
+ - (bool)initializeAccelerometer;
16
+ - (bool)initializeGravity;
17
+ - (bool)initializeMagnetometer;
18
+ - (bool)initializeOrientation;
19
+ - (void)cancel;
20
+
21
+ @end
@@ -0,0 +1,169 @@
1
+ #import "ReanimatedSensor.h"
2
+
3
+ @implementation ReanimatedSensor
4
+
5
+ - (instancetype)init:(ReanimatedSensorType)sensorType interval:(int)interval setter:(void (^)(double[]))setter
6
+ {
7
+ self = [super init];
8
+ _sensorType = sensorType;
9
+ _interval = interval / 1000; // in seconds
10
+ _setter = setter;
11
+ _motionManager = [[CMMotionManager alloc] init];
12
+ return self;
13
+ }
14
+
15
+ - (bool)initialize
16
+ {
17
+ if (_sensorType == ACCELEROMETER) {
18
+ return [self initializeAccelerometer];
19
+ } else if (_sensorType == GYROSCOPE) {
20
+ return [self initializeGyroscope];
21
+ } else if (_sensorType == GRAVITY) {
22
+ return [self initializeGravity];
23
+ } else if (_sensorType == MAGNETIC_FIELD) {
24
+ return [self initializeMagnetometer];
25
+ } else if (_sensorType == ROTATION_VECTOR) {
26
+ return [self initializeOrientation];
27
+ }
28
+
29
+ return false;
30
+ }
31
+
32
+ - (bool)initializeGyroscope
33
+ {
34
+ if (![_motionManager isGyroAvailable]) {
35
+ return false;
36
+ }
37
+ [_motionManager setGyroUpdateInterval:_interval];
38
+ [_motionManager startGyroUpdates];
39
+ [_motionManager
40
+ startGyroUpdatesToQueue:[NSOperationQueue mainQueue]
41
+ withHandler:^(CMGyroData *sensorData, NSError *error) {
42
+ double currentTime = [[NSProcessInfo processInfo] systemUptime];
43
+ if (currentTime - self->_lastTimestamp < self->_interval) {
44
+ return;
45
+ }
46
+ double data[] = {sensorData.rotationRate.x, sensorData.rotationRate.y, sensorData.rotationRate.z};
47
+ self->_setter(data);
48
+ self->_lastTimestamp = currentTime;
49
+ }];
50
+
51
+ return true;
52
+ }
53
+
54
+ - (bool)initializeAccelerometer
55
+ {
56
+ if (![_motionManager isAccelerometerAvailable]) {
57
+ return false;
58
+ }
59
+ [_motionManager setAccelerometerUpdateInterval:_interval];
60
+ [_motionManager startAccelerometerUpdates];
61
+ [_motionManager
62
+ startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue]
63
+ withHandler:^(CMAccelerometerData *sensorData, NSError *error) {
64
+ double currentTime = [[NSProcessInfo processInfo] systemUptime];
65
+ if (currentTime - self->_lastTimestamp < self->_interval) {
66
+ return;
67
+ }
68
+ double data[] = {
69
+ sensorData.acceleration.x, sensorData.acceleration.y, sensorData.acceleration.z};
70
+ self->_setter(data);
71
+ self->_lastTimestamp = currentTime;
72
+ }];
73
+
74
+ return true;
75
+ }
76
+
77
+ - (bool)initializeGravity
78
+ {
79
+ if (![_motionManager isDeviceMotionAvailable]) {
80
+ return false;
81
+ }
82
+ [_motionManager setDeviceMotionUpdateInterval:_interval];
83
+ [_motionManager setShowsDeviceMovementDisplay:YES];
84
+ [_motionManager
85
+ startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
86
+ withHandler:^(CMDeviceMotion *sensorData, NSError *error) {
87
+ double currentTime = [[NSProcessInfo processInfo] systemUptime];
88
+ if (currentTime - self->_lastTimestamp < self->_interval) {
89
+ return;
90
+ }
91
+ double data[] = {sensorData.gravity.x, sensorData.gravity.y, sensorData.gravity.z};
92
+ self->_setter(data);
93
+ self->_lastTimestamp = currentTime;
94
+ }];
95
+
96
+ return true;
97
+ }
98
+
99
+ - (bool)initializeMagnetometer
100
+ {
101
+ if (![_motionManager isMagnetometerAvailable]) {
102
+ return false;
103
+ }
104
+ [_motionManager setMagnetometerUpdateInterval:_interval];
105
+ [_motionManager startMagnetometerUpdates];
106
+ [_motionManager
107
+ startMagnetometerUpdatesToQueue:[NSOperationQueue mainQueue]
108
+ withHandler:^(CMMagnetometerData *sensorData, NSError *error) {
109
+ double currentTime = [[NSProcessInfo processInfo] systemUptime];
110
+ if (currentTime - self->_lastTimestamp < self->_interval) {
111
+ return;
112
+ }
113
+ double data[] = {
114
+ sensorData.magneticField.x, sensorData.magneticField.y, sensorData.magneticField.z};
115
+ self->_setter(data);
116
+ self->_lastTimestamp = currentTime;
117
+ }];
118
+
119
+ return true;
120
+ }
121
+
122
+ - (bool)initializeOrientation
123
+ {
124
+ if (![_motionManager isDeviceMotionAvailable]) {
125
+ return false;
126
+ }
127
+ [_motionManager setDeviceMotionUpdateInterval:_interval];
128
+
129
+ [_motionManager setShowsDeviceMovementDisplay:YES];
130
+ [_motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical
131
+ toQueue:[NSOperationQueue mainQueue]
132
+ withHandler:^(CMDeviceMotion *sensorData, NSError *error) {
133
+ double currentTime = [[NSProcessInfo processInfo] systemUptime];
134
+ if (currentTime - self->_lastTimestamp < self->_interval) {
135
+ return;
136
+ }
137
+ CMAttitude *attitude = sensorData.attitude;
138
+ double data[] = {
139
+ attitude.quaternion.x,
140
+ attitude.quaternion.y,
141
+ attitude.quaternion.z,
142
+ attitude.quaternion.w,
143
+ attitude.pitch,
144
+ attitude.roll,
145
+ attitude.yaw,
146
+ };
147
+ self->_setter(data);
148
+ self->_lastTimestamp = currentTime;
149
+ }];
150
+
151
+ return true;
152
+ }
153
+
154
+ - (void)cancel
155
+ {
156
+ if (_sensorType == ACCELEROMETER) {
157
+ [_motionManager stopAccelerometerUpdates];
158
+ } else if (_sensorType == GYROSCOPE) {
159
+ [_motionManager stopGyroUpdates];
160
+ } else if (_sensorType == GRAVITY) {
161
+ [_motionManager stopDeviceMotionUpdates];
162
+ } else if (_sensorType == MAGNETIC_FIELD) {
163
+ [_motionManager stopMagnetometerUpdates];
164
+ } else if (_sensorType == ROTATION_VECTOR) {
165
+ [_motionManager stopDeviceMotionUpdates];
166
+ }
167
+ }
168
+
169
+ @end
@@ -0,0 +1,13 @@
1
+ #import <CoreMotion/CoreMotion.h>
2
+ #import "ReanimatedSensorType.h"
3
+
4
+ @interface ReanimatedSensorContainer : NSObject {
5
+ NSNumber *_nextSensorId;
6
+ NSMutableDictionary *_sensors;
7
+ }
8
+
9
+ - (instancetype)init;
10
+ - (int)registerSensor:(ReanimatedSensorType)sensorType interval:(int)interval setter:(void (^)(double[]))setter;
11
+ - (void)unregisterSensor:(int)sensorId;
12
+
13
+ @end
@@ -0,0 +1,41 @@
1
+ #import "ReanimatedSensorContainer.h"
2
+ #import <CoreMotion/CoreMotion.h>
3
+ #import <Foundation/Foundation.h>
4
+ #import "ReanimatedSensor.h"
5
+
6
+ static NSNumber *_nextSensorId = nil;
7
+
8
+ @implementation ReanimatedSensorContainer
9
+
10
+ - (instancetype)init
11
+ {
12
+ self = [super init];
13
+ _sensors = [[NSMutableDictionary alloc] init];
14
+ _nextSensorId = @0;
15
+ return self;
16
+ }
17
+
18
+ - (int)registerSensor:(ReanimatedSensorType)sensorType interval:(int)interval setter:(void (^)(double[]))setter
19
+ {
20
+ ReanimatedSensor *sensor = [[ReanimatedSensor alloc] init:sensorType interval:interval setter:setter];
21
+ if ([sensor initialize]) {
22
+ NSNumber *sensorId = [_nextSensorId copy];
23
+ _nextSensorId = [NSNumber numberWithInt:[_nextSensorId intValue] + 1];
24
+ [_sensors setObject:sensor forKey:sensorId];
25
+ return [sensorId intValue];
26
+ } else {
27
+ return -1;
28
+ }
29
+ }
30
+
31
+ - (void)unregisterSensor:(int)sensorId
32
+ {
33
+ NSNumber *_sensorId = [NSNumber numberWithInt:sensorId];
34
+ if (_sensors[_sensorId] == nil) {
35
+ return;
36
+ }
37
+ [_sensors[_sensorId] cancel];
38
+ [_sensors removeObjectForKey:_sensorId];
39
+ }
40
+
41
+ @end
@@ -0,0 +1,7 @@
1
+ typedef NS_ENUM(NSUInteger, ReanimatedSensorType) {
2
+ ACCELEROMETER = 1,
3
+ GYROSCOPE = 2,
4
+ GRAVITY = 3,
5
+ MAGNETIC_FIELD = 4,
6
+ ROTATION_VECTOR = 5,
7
+ };