@react-native-ohos/react-native-reanimated 3.18.2-rc.2 → 4.0.1

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 (282) hide show
  1. package/compatibility.json +161 -0
  2. package/harmony/reanimated/BuildProfile.ets +1 -1
  3. package/harmony/reanimated/build-profile.json5 +18 -11
  4. package/harmony/reanimated/oh-package.json5 +12 -11
  5. package/harmony/reanimated/src/main/cpp/CMakeLists.txt +31 -40
  6. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.cpp +81 -86
  7. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h +46 -47
  8. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/InterpolatorRegistry.cpp +390 -0
  9. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/InterpolatorRegistry.h +16 -0
  10. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/definitions.h +30 -0
  11. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/filters/FilterOp.cpp +46 -0
  12. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/filters/FilterOp.h +23 -0
  13. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/Quaternion.cpp +53 -0
  14. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/Quaternion.h +21 -0
  15. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix.cpp +166 -0
  16. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix.h +71 -0
  17. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix2D.cpp +368 -0
  18. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix2D.h +53 -0
  19. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix3D.cpp +594 -0
  20. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix3D.h +67 -0
  21. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformOp.cpp +52 -0
  22. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformOp.h +26 -0
  23. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/vectors.cpp +156 -0
  24. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/vectors.h +76 -0
  25. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSAngle.cpp +94 -0
  26. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSAngle.h +33 -0
  27. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSBoolean.cpp +48 -0
  28. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSBoolean.h +31 -0
  29. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSColor.cpp +135 -0
  30. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSColor.h +61 -0
  31. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSDiscreteArray.cpp +100 -0
  32. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSDiscreteArray.h +45 -0
  33. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSKeyword.cpp +81 -0
  34. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSKeyword.h +53 -0
  35. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSLength.cpp +122 -0
  36. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSLength.h +38 -0
  37. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSNumber.cpp +82 -0
  38. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSNumber.h +63 -0
  39. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSValue.h +118 -0
  40. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSValueVariant.cpp +174 -0
  41. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSValueVariant.h +111 -0
  42. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSBoxShadow.cpp +196 -0
  43. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSBoxShadow.h +66 -0
  44. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSDropShadow.cpp +134 -0
  45. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSDropShadow.h +44 -0
  46. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSAnimationConfig.cpp +174 -0
  47. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSAnimationConfig.h +49 -0
  48. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSKeyframesConfig.cpp +45 -0
  49. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSKeyframesConfig.h +26 -0
  50. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSTransitionConfig.cpp +90 -0
  51. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSTransitionConfig.h +43 -0
  52. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/common.cpp +17 -0
  53. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/common.h +13 -0
  54. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSAnimation.cpp +127 -0
  55. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSAnimation.h +51 -0
  56. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSTransition.cpp +145 -0
  57. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSTransition.h +47 -0
  58. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/EasingFunctions.cpp +69 -0
  59. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/EasingFunctions.h +22 -0
  60. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/cubicBezier.cpp +66 -0
  61. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/cubicBezier.h +15 -0
  62. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/linear.cpp +28 -0
  63. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/linear.h +15 -0
  64. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/steps.cpp +13 -0
  65. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/steps.h +12 -0
  66. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/InterpolatorFactory.cpp +157 -0
  67. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/InterpolatorFactory.h +189 -0
  68. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.cpp +76 -0
  69. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.h +66 -0
  70. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/configs.h +20 -0
  71. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperation.cpp +136 -0
  72. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperation.h +40 -0
  73. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperationInterpolator.cpp +38 -0
  74. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperationInterpolator.h +24 -0
  75. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterStyleInterpolator.cpp +58 -0
  76. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterStyleInterpolator.h +24 -0
  77. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/blur.h +14 -0
  78. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/brightness.h +14 -0
  79. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/contrast.h +14 -0
  80. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/dropShadow.h +17 -0
  81. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/grayscale.h +14 -0
  82. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/hueRotate.h +14 -0
  83. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/invert.h +14 -0
  84. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/opacity.h +14 -0
  85. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/saturate.h +14 -0
  86. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/sepia.h +14 -0
  87. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/ArrayPropertiesInterpolator.cpp +95 -0
  88. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/ArrayPropertiesInterpolator.h +36 -0
  89. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.cpp +41 -0
  90. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.h +32 -0
  91. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/RecordPropertiesInterpolator.cpp +99 -0
  92. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/RecordPropertiesInterpolator.h +37 -0
  93. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/OperationsStyleInterpolator.cpp +308 -0
  94. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/OperationsStyleInterpolator.h +100 -0
  95. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperation.cpp +19 -0
  96. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperation.h +94 -0
  97. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperationInterpolator.cpp +18 -0
  98. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperationInterpolator.h +43 -0
  99. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/styles/AnimationStyleInterpolator.h +26 -0
  100. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.cpp +103 -0
  101. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.h +42 -0
  102. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperation.cpp +224 -0
  103. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperation.h +52 -0
  104. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.cpp +218 -0
  105. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.h +89 -0
  106. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformsStyleInterpolator.cpp +149 -0
  107. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformsStyleInterpolator.h +33 -0
  108. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/matrix.cpp +208 -0
  109. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/matrix.h +56 -0
  110. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/perspective.cpp +42 -0
  111. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/perspective.h +20 -0
  112. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/rotate.cpp +41 -0
  113. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/rotate.h +39 -0
  114. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/scale.cpp +28 -0
  115. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/scale.h +25 -0
  116. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/skew.cpp +14 -0
  117. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/skew.h +20 -0
  118. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/translate.cpp +39 -0
  119. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/translate.h +25 -0
  120. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.cpp +47 -0
  121. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.h +43 -0
  122. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/SimpleValueInterpolator.cpp +70 -0
  123. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/SimpleValueInterpolator.h +40 -0
  124. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.cpp +146 -0
  125. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.h +71 -0
  126. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.cpp +155 -0
  127. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.h +53 -0
  128. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/AnimationProgressProvider.cpp +170 -0
  129. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/AnimationProgressProvider.h +67 -0
  130. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/KeyframeProgressProvider.h +12 -0
  131. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/RawProgressProvider.cpp +41 -0
  132. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/RawProgressProvider.h +31 -0
  133. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/TransitionProgressProvider.cpp +193 -0
  134. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/TransitionProgressProvider.h +77 -0
  135. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSAnimationsRegistry.cpp +340 -0
  136. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSAnimationsRegistry.h +80 -0
  137. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSKeyframesRegistry.cpp +45 -0
  138. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSKeyframesRegistry.h +29 -0
  139. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.cpp +167 -0
  140. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.h +51 -0
  141. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/StaticPropsRegistry.cpp +61 -0
  142. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/StaticPropsRegistry.h +33 -0
  143. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGBrush.cpp +80 -0
  144. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGBrush.h +39 -0
  145. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGLength.cpp +93 -0
  146. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGLength.h +36 -0
  147. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.cpp +111 -0
  148. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.h +33 -0
  149. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/DelayedItemsManager.cpp +75 -0
  150. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/DelayedItemsManager.h +45 -0
  151. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/algorithms.cpp +12 -0
  152. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/algorithms.h +10 -0
  153. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/interpolators.cpp +36 -0
  154. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/interpolators.h +23 -0
  155. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/props.cpp +149 -0
  156. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/props.h +32 -0
  157. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.cpp +113 -101
  158. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.h +49 -51
  159. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitShadowNode.h +46 -49
  160. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +56 -96
  161. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +37 -33
  162. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ShadowTreeCloner.cpp +104 -95
  163. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ShadowTreeCloner.h +22 -29
  164. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp +72 -0
  165. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h +25 -0
  166. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.cpp +160 -0
  167. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.h +71 -0
  168. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistryManager.cpp +161 -0
  169. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistryManager.h +65 -0
  170. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationType.h +11 -9
  171. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.cpp +137 -232
  172. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h +82 -90
  173. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.cpp +79 -0
  174. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h +81 -0
  175. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp +864 -0
  176. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h +214 -0
  177. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/{LayoutAnimationsProxy.cpp → LayoutAnimationsProxy_Legacy.cpp} +897 -870
  178. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h +220 -0
  179. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.cpp +31 -91
  180. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.h +146 -176
  181. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/PropsDiffer.cpp +456 -0
  182. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/PropsDiffer.h +102 -0
  183. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/SharedTransitions.cpp +544 -0
  184. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/PropValueProcessor.cpp +119 -0
  185. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/PropValueProcessor.h +39 -0
  186. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +1380 -971
  187. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +230 -252
  188. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxySpec.cpp +183 -231
  189. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxySpec.h +93 -109
  190. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/RNRuntimeDecorator.cpp +54 -56
  191. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/RNRuntimeDecorator.h +28 -20
  192. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.cpp +58 -70
  193. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.h +31 -35
  194. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeatureFlags.cpp +18 -0
  195. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeatureFlags.h +44 -0
  196. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/PlatformDepMethodsHolder.h +67 -98
  197. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/ReanimatedSystraceSection.h +114 -135
  198. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/ReanimatedVersion.cpp +46 -0
  199. package/harmony/reanimated/src/main/cpp/Common/cpp/{worklets → reanimated}/Tools/ReanimatedVersion.h +18 -19
  200. package/harmony/reanimated/src/main/cpp/ReanimatedModule.cpp +63 -85
  201. package/harmony/reanimated/src/main/cpp/ReanimatedNodesManager.cpp +1 -0
  202. package/harmony/reanimated/src/main/cpp/ReanimatedPackage.cpp +0 -3
  203. package/harmony/reanimated/src/main/cpp/ReanimatedSensor.cpp +266 -0
  204. package/harmony/reanimated/src/main/cpp/ReanimatedSensor.h +36 -0
  205. package/harmony/reanimated/src/main/cpp/ReanimatedSensorContainer.cpp +36 -0
  206. package/harmony/reanimated/src/main/cpp/ReanimatedSensorContainer.h +23 -0
  207. package/harmony/reanimated/src/main/cpp/ReanimatedUIScheduler.h +3 -3
  208. package/harmony/reanimated/src/main/ets/ReanimatedModule.ts +5 -1
  209. package/harmony/reanimated/src/main/ets/ReanimatedPackage.ts +1 -4
  210. package/harmony/reanimated/src/main/module.json5 +12 -12
  211. package/harmony/reanimated/src/main/resources/base/element/color.json +7 -7
  212. package/harmony/reanimated/src/main/resources/base/element/string.json +15 -15
  213. package/harmony/reanimated/src/main/resources/base/profile/main_pages.json +5 -5
  214. package/harmony/reanimated/src/main/resources/en_US/element/string.json +15 -15
  215. package/harmony/reanimated/src/main/resources/zh_CN/element/string.json +15 -15
  216. package/harmony/reanimated/ts.ts +6 -6
  217. package/harmony/reanimated.har +0 -0
  218. package/package.json +69 -50
  219. package/scripts/deploy.js +191 -0
  220. package/scripts/set-reanimated-version.js +37 -0
  221. package/scripts/update-version.js +119 -0
  222. package/scripts/validate-react-native-version.js +46 -0
  223. package/scripts/validate-worklets-build.js +17 -0
  224. package/scripts/validate-worklets-version.js +84 -0
  225. package/scripts/worklets-version.json +4 -0
  226. package/LICENSE +0 -21
  227. package/README.OpenSource +0 -11
  228. package/README.md +0 -10
  229. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/PropsRegistry.cpp +0 -68
  230. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/PropsRegistry.h +0 -68
  231. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.h +0 -147
  232. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/CollectionUtils.h +0 -14
  233. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeaturesConfig.cpp +0 -5
  234. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeaturesConfig.h +0 -19
  235. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +0 -47
  236. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +0 -59
  237. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.cpp +0 -27
  238. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.h +0 -25
  239. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/EventHandlerRegistry.cpp +0 -94
  240. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/EventHandlerRegistry.h +0 -49
  241. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.cpp +0 -8
  242. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.h +0 -39
  243. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/SharedItems/Shareables.cpp +0 -326
  244. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/SharedItems/Shareables.h +0 -345
  245. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/AsyncQueue.cpp +0 -52
  246. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/AsyncQueue.h +0 -35
  247. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/Defs.h +0 -10
  248. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSISerializer.cpp +0 -342
  249. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSISerializer.h +0 -47
  250. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSLogger.cpp +0 -16
  251. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSLogger.h +0 -20
  252. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSScheduler.cpp +0 -20
  253. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSScheduler.h +0 -29
  254. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/PlatformLogger.h +0 -16
  255. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ReanimatedJSIUtils.cpp +0 -26
  256. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ReanimatedJSIUtils.h +0 -199
  257. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ReanimatedVersion.cpp +0 -95
  258. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/SingleInstanceChecker.h +0 -72
  259. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ThreadSafeQueue.h +0 -49
  260. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/UIScheduler.cpp +0 -20
  261. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/UIScheduler.h +0 -22
  262. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/WorkletEventHandler.cpp +0 -29
  263. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/WorkletEventHandler.h +0 -41
  264. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.cpp +0 -16
  265. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h +0 -19
  266. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedHermesRuntime.cpp +0 -112
  267. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedHermesRuntime.h +0 -127
  268. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedRuntime.cpp +0 -53
  269. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedRuntime.h +0 -22
  270. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/RuntimeInitialization.md +0 -191
  271. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +0 -173
  272. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +0 -90
  273. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeCollector.h +0 -36
  274. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +0 -189
  275. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +0 -22
  276. package/harmony/reanimated/src/main/cpp/ReanimatedLogger.cpp +0 -33
  277. package/harmony/reanimated/src/main/cpp/WorkletsModule.cpp +0 -61
  278. package/harmony/reanimated/src/main/cpp/WorkletsModule.h +0 -22
  279. package/harmony/reanimated/src/main/cpp/patches/AnimatedSensor/AnimatedSensorModule.cpp +0 -89
  280. package/harmony/reanimated/src/main/cpp/patches/Fabric/ShadowTreeCloner.cpp +0 -95
  281. package/harmony/reanimated/src/main/cpp/patches/NativeModules/ReanimatedModuleProxy.cpp +0 -964
  282. package/harmony/reanimated/src/main/ets/WorkletsModule.ts +0 -15
@@ -1,971 +1,1380 @@
1
- #include <jsi/jsi.h>
2
- #include <reanimated/NativeModules/ReanimatedModuleProxy.h>
3
- #include <reanimated/RuntimeDecorators/UIRuntimeDecorator.h>
4
- #include <reanimated/Tools/CollectionUtils.h>
5
- #include <reanimated/Tools/FeaturesConfig.h>
6
- #include <reanimated/Tools/ReanimatedSystraceSection.h>
7
- #include <unordered_map>
8
-
9
- #ifdef RCT_NEW_ARCH_ENABLED
10
- #include <reanimated/Fabric/ReanimatedCommitShadowNode.h>
11
- #include <reanimated/Fabric/ShadowTreeCloner.h>
12
- #endif // RCT_NEW_ARCH_ENABLED
13
-
14
- #include <worklets/Registries/EventHandlerRegistry.h>
15
- #include <worklets/SharedItems/Shareables.h>
16
- #include <worklets/Tools/AsyncQueue.h>
17
- #include <worklets/Tools/WorkletEventHandler.h>
18
-
19
- #ifdef __ANDROID__
20
- #include <fbjni/fbjni.h>
21
- #endif // __ANDROID__
22
-
23
- #ifdef RCT_NEW_ARCH_ENABLED
24
- #include <react/renderer/scheduler/Scheduler.h>
25
- #include <react/renderer/uimanager/UIManagerBinding.h>
26
- #include <react/renderer/uimanager/primitives.h>
27
- #endif // RCT_NEW_ARCH_ENABLED
28
-
29
- #include <functional>
30
- #include <utility>
31
-
32
- #ifdef RCT_NEW_ARCH_ENABLED
33
- #include <iomanip>
34
- #include <sstream>
35
- #include <string>
36
- #endif // RCT_NEW_ARCH_ENABLED
37
-
38
- namespace reanimated {
39
-
40
- ReanimatedModuleProxy::ReanimatedModuleProxy(
41
- const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy,
42
- jsi::Runtime &rnRuntime,
43
- const std::shared_ptr<CallInvoker> &jsCallInvoker,
44
- const PlatformDepMethodsHolder &platformDepMethodsHolder,
45
- const bool isBridgeless,
46
- const bool isReducedMotion)
47
- : ReanimatedModuleProxySpec(jsCallInvoker),
48
- isBridgeless_(isBridgeless),
49
- isReducedMotion_(isReducedMotion),
50
- workletsModuleProxy_(workletsModuleProxy),
51
- valueUnpackerCode_(workletsModuleProxy->getValueUnpackerCode()),
52
- uiWorkletRuntime_(std::make_shared<WorkletRuntime>(
53
- rnRuntime,
54
- workletsModuleProxy->getJSQueue(),
55
- workletsModuleProxy->getJSScheduler(),
56
- "Reanimated UI runtime",
57
- true /* supportsLocking */,
58
- valueUnpackerCode_)),
59
- eventHandlerRegistry_(std::make_unique<EventHandlerRegistry>()),
60
- requestRender_(platformDepMethodsHolder.requestRender),
61
- animatedSensorModule_(platformDepMethodsHolder),
62
- jsLogger_(
63
- std::make_shared<JSLogger>(workletsModuleProxy->getJSScheduler())),
64
- layoutAnimationsManager_(
65
- std::make_shared<LayoutAnimationsManager>(jsLogger_)),
66
- #ifdef RCT_NEW_ARCH_ENABLED
67
- propsRegistry_(std::make_shared<PropsRegistry>()),
68
- #else
69
- obtainPropFunction_(platformDepMethodsHolder.obtainPropFunction),
70
- configurePropsPlatformFunction_(
71
- platformDepMethodsHolder.configurePropsFunction),
72
- updatePropsFunction_(platformDepMethodsHolder.updatePropsFunction),
73
- #endif
74
- subscribeForKeyboardEventsFunction_(
75
- platformDepMethodsHolder.subscribeForKeyboardEvents),
76
- unsubscribeFromKeyboardEventsFunction_(
77
- platformDepMethodsHolder.unsubscribeFromKeyboardEvents) {
78
- }
79
-
80
- void ReanimatedModuleProxy::init(
81
- const PlatformDepMethodsHolder &platformDepMethodsHolder) {
82
- auto onRenderCallback = [weakThis =
83
- weak_from_this()](const double timestampMs) {
84
- auto strongThis = weakThis.lock();
85
- if (!strongThis) {
86
- return;
87
- }
88
-
89
- strongThis->renderRequested_ = false;
90
- strongThis->onRender(timestampMs);
91
- };
92
- onRenderCallback_ = std::move(onRenderCallback);
93
-
94
- auto requestAnimationFrame = [weakThis = weak_from_this()](
95
- jsi::Runtime &rt,
96
- const jsi::Value &callback) {
97
- auto strongThis = weakThis.lock();
98
- if (!strongThis) {
99
- return;
100
- }
101
-
102
- strongThis->requestAnimationFrame(rt, callback);
103
- };
104
-
105
- #ifdef RCT_NEW_ARCH_ENABLED
106
- auto updateProps = [weakThis = weak_from_this()](
107
- jsi::Runtime &rt, const jsi::Value &operations) {
108
- auto strongThis = weakThis.lock();
109
- if (!strongThis) {
110
- return;
111
- }
112
-
113
- strongThis->updateProps(rt, operations);
114
- };
115
-
116
- auto removeFromPropsRegistry = [weakThis = weak_from_this()](
117
- jsi::Runtime &rt,
118
- const jsi::Value &viewTags) {
119
- auto strongThis = weakThis.lock();
120
- if (!strongThis) {
121
- return;
122
- }
123
-
124
- strongThis->removeFromPropsRegistry(rt, viewTags);
125
- };
126
-
127
- auto measure = [weakThis = weak_from_this()](
128
- jsi::Runtime &rt,
129
- const jsi::Value &shadowNodeValue) -> jsi::Value {
130
- auto strongThis = weakThis.lock();
131
- if (!strongThis) {
132
- return jsi::Value::undefined();
133
- }
134
- return strongThis->measure(rt, shadowNodeValue);
135
- };
136
-
137
- auto dispatchCommand = [weakThis = weak_from_this()](
138
- jsi::Runtime &rt,
139
- const jsi::Value &shadowNodeValue,
140
- const jsi::Value &commandNameValue,
141
- const jsi::Value &argsValue) {
142
- auto strongThis = weakThis.lock();
143
- if (!strongThis) {
144
- return;
145
- }
146
-
147
- strongThis->dispatchCommand(
148
- rt, shadowNodeValue, commandNameValue, argsValue);
149
- };
150
- ProgressLayoutAnimationFunction progressLayoutAnimation =
151
- [weakThis = weak_from_this()](
152
- jsi::Runtime &rt, int tag, const jsi::Object &newStyle, bool) {
153
- auto strongThis = weakThis.lock();
154
- if (!strongThis) {
155
- return;
156
- }
157
-
158
- auto surfaceId =
159
- strongThis->layoutAnimationsProxy_->progressLayoutAnimation(
160
- tag, newStyle);
161
- if (!surfaceId) {
162
- return;
163
- }
164
- strongThis->uiManager_->getShadowTreeRegistry().visit(
165
- *surfaceId, [](const ShadowTree &shadowTree) {
166
- shadowTree.notifyDelegatesOfUpdates();
167
- });
168
- };
169
-
170
- EndLayoutAnimationFunction endLayoutAnimation =
171
- [weakThis = weak_from_this()](int tag, bool shouldRemove) {
172
- auto strongThis = weakThis.lock();
173
- if (!strongThis) {
174
- return;
175
- }
176
-
177
- auto surfaceId = strongThis->layoutAnimationsProxy_->endLayoutAnimation(
178
- tag, shouldRemove);
179
- if (!surfaceId) {
180
- return;
181
- }
182
-
183
- strongThis->uiManager_->getShadowTreeRegistry().visit(
184
- *surfaceId, [](const ShadowTree &shadowTree) {
185
- shadowTree.notifyDelegatesOfUpdates();
186
- });
187
- };
188
-
189
- auto obtainProp = [weakThis = weak_from_this()](
190
- jsi::Runtime &rt,
191
- const jsi::Value &shadowNodeWrapper,
192
- const jsi::Value &propName) {
193
- auto strongThis = weakThis.lock();
194
- if (!strongThis) {
195
- return jsi::String::createFromUtf8(rt, "");
196
- }
197
-
198
- return strongThis->obtainProp(rt, shadowNodeWrapper, propName);
199
- };
200
- #endif
201
-
202
- jsi::Runtime &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
203
- UIRuntimeDecorator::decorate(
204
- uiRuntime,
205
- #ifdef RCT_NEW_ARCH_ENABLED
206
- obtainProp,
207
- updateProps,
208
- measure,
209
- dispatchCommand,
210
- #else
211
- platformDepMethodsHolder.scrollToFunction,
212
- platformDepMethodsHolder.obtainPropFunction,
213
- platformDepMethodsHolder.updatePropsFunction,
214
- platformDepMethodsHolder.measureFunction,
215
- platformDepMethodsHolder.dispatchCommandFunction,
216
- #endif
217
- requestAnimationFrame,
218
- platformDepMethodsHolder.getAnimationTimestamp,
219
- platformDepMethodsHolder.setGestureStateFunction,
220
- #ifdef RCT_NEW_ARCH_ENABLED
221
- progressLayoutAnimation,
222
- endLayoutAnimation,
223
- #else
224
- platformDepMethodsHolder.progressLayoutAnimation,
225
- platformDepMethodsHolder.endLayoutAnimation,
226
- #endif
227
- platformDepMethodsHolder.maybeFlushUIUpdatesQueueFunction);
228
- }
229
-
230
- ReanimatedModuleProxy::~ReanimatedModuleProxy() {
231
- // event handler registry and frame callbacks store some JSI values from UI
232
- // runtime, so they have to go away before we tear down the runtime
233
- eventHandlerRegistry_.reset();
234
- frameCallbacks_.clear();
235
- #ifdef RCT_NEW_ARCH_ENABLED
236
- operationsInBatch_.clear();
237
- #endif // RCT_NEW_ARCH_ENABLED
238
- uiWorkletRuntime_.reset();
239
- }
240
-
241
- void ReanimatedModuleProxy::scheduleOnUI(
242
- jsi::Runtime &rt,
243
- const jsi::Value &worklet) {
244
- auto shareableWorklet = extractShareableOrThrow<ShareableWorklet>(
245
- rt, worklet, "[Reanimated] Only worklets can be scheduled to run on UI.");
246
- workletsModuleProxy_->getUIScheduler()->scheduleOnUI(
247
- [=, weakThis = weak_from_this()] {
248
- const auto strongThis = weakThis.lock();
249
- if (!strongThis) {
250
- return;
251
- }
252
- #if JS_RUNTIME_HERMES
253
- // JSI's scope defined here allows for JSI-objects to be cleared up
254
- // after each runtime loop. Within these loops we typically create some
255
- // temporary JSI objects and hence it allows for such objects to be
256
- // garbage collected much sooner. Apparently the scope API is only
257
- // supported on Hermes at the moment.
258
- const auto scope =
259
- jsi::Scope(strongThis->uiWorkletRuntime_->getJSIRuntime());
260
- #endif
261
- strongThis->uiWorkletRuntime_->runGuarded(shareableWorklet);
262
- });
263
- }
264
-
265
- jsi::Value ReanimatedModuleProxy::executeOnUIRuntimeSync(
266
- jsi::Runtime &rt,
267
- const jsi::Value &worklet) {
268
- return uiWorkletRuntime_->executeSync(rt, worklet);
269
- }
270
-
271
- jsi::Value ReanimatedModuleProxy::createWorkletRuntime(
272
- jsi::Runtime &rt,
273
- const jsi::Value &name,
274
- const jsi::Value &initializer) {
275
- auto workletRuntime = std::make_shared<WorkletRuntime>(
276
- rt,
277
- workletsModuleProxy_->getJSQueue(),
278
- workletsModuleProxy_->getJSScheduler(),
279
- name.asString(rt).utf8(rt),
280
- true /* supportsLocking */,
281
- valueUnpackerCode_);
282
- auto initializerShareable = extractShareableOrThrow<ShareableWorklet>(
283
- rt, initializer, "[Reanimated] Initializer must be a worklet.");
284
- workletRuntime->runGuarded(initializerShareable);
285
- return jsi::Object::createFromHostObject(rt, workletRuntime);
286
- }
287
-
288
- jsi::Value ReanimatedModuleProxy::scheduleOnRuntime(
289
- jsi::Runtime &rt,
290
- const jsi::Value &workletRuntimeValue,
291
- const jsi::Value &shareableWorkletValue) {
292
- reanimated::scheduleOnRuntime(rt, workletRuntimeValue, shareableWorkletValue);
293
- return jsi::Value::undefined();
294
- }
295
-
296
- jsi::Value ReanimatedModuleProxy::registerEventHandler(
297
- jsi::Runtime &rt,
298
- const jsi::Value &worklet,
299
- const jsi::Value &eventName,
300
- const jsi::Value &emitterReactTag) {
301
- static uint64_t NEXT_EVENT_HANDLER_ID = 1;
302
-
303
- uint64_t newRegistrationId = NEXT_EVENT_HANDLER_ID++;
304
- auto eventNameStr = eventName.asString(rt).utf8(rt);
305
- auto handlerShareable = extractShareableOrThrow<ShareableWorklet>(
306
- rt, worklet, "[Reanimated] Event handler must be a worklet.");
307
- int emitterReactTagInt = emitterReactTag.asNumber();
308
-
309
- workletsModuleProxy_->getUIScheduler()->scheduleOnUI(
310
- [=, weakThis = weak_from_this()]() {
311
- auto strongThis = weakThis.lock();
312
- if (!strongThis) {
313
- return;
314
- }
315
- auto handler = std::make_shared<WorkletEventHandler>(
316
- newRegistrationId,
317
- eventNameStr,
318
- emitterReactTagInt,
319
- handlerShareable);
320
- strongThis->eventHandlerRegistry_->registerEventHandler(
321
- std::move(handler));
322
- });
323
-
324
- return jsi::Value(static_cast<double>(newRegistrationId));
325
- }
326
-
327
- void ReanimatedModuleProxy::unregisterEventHandler(
328
- jsi::Runtime &,
329
- const jsi::Value &registrationId) {
330
- uint64_t id = registrationId.asNumber();
331
- workletsModuleProxy_->getUIScheduler()->scheduleOnUI(
332
- [=, weakThis = weak_from_this()]() {
333
- auto strongThis = weakThis.lock();
334
- if (!strongThis) {
335
- return;
336
- }
337
- strongThis->eventHandlerRegistry_->unregisterEventHandler(id);
338
- });
339
- }
340
-
341
- #ifdef RCT_NEW_ARCH_ENABLED
342
- static inline std::string intColorToHex(const int val) {
343
- std::stringstream
344
- invertedHexColorStream; // By default transparency is first, color second
345
- invertedHexColorStream << std::setfill('0') << std::setw(8) << std::hex
346
- << val;
347
-
348
- auto invertedHexColor = invertedHexColorStream.str();
349
- auto hexColor =
350
- "#" + invertedHexColor.substr(2, 6) + invertedHexColor.substr(0, 2);
351
-
352
- return hexColor;
353
- }
354
-
355
- std::string ReanimatedModuleProxy::obtainPropFromShadowNode(
356
- jsi::Runtime &rt,
357
- const std::string &propName,
358
- const ShadowNode::Shared &shadowNode) {
359
- auto newestCloneOfShadowNode =
360
- uiManager_->getNewestCloneOfShadowNode(*shadowNode);
361
-
362
- if (propName == "width" || propName == "height" || propName == "top" ||
363
- propName == "left") {
364
- // These props are calculated from frame
365
- auto layoutableShadowNode = dynamic_cast<LayoutableShadowNode const *>(
366
- newestCloneOfShadowNode.get());
367
- const auto &frame = layoutableShadowNode->layoutMetrics_.frame;
368
-
369
- if (propName == "width") {
370
- return std::to_string(frame.size.width);
371
- } else if (propName == "height") {
372
- return std::to_string(frame.size.height);
373
- } else if (propName == "top") {
374
- return std::to_string(frame.origin.y);
375
- } else if (propName == "left") {
376
- return std::to_string(frame.origin.x);
377
- }
378
- } else {
379
- // These props are calculated from viewProps
380
- auto props = newestCloneOfShadowNode->getProps();
381
- auto viewProps = std::static_pointer_cast<const ViewProps>(props);
382
- if (propName == "opacity") {
383
- return std::to_string(viewProps->opacity);
384
- } else if (propName == "zIndex") {
385
- if (viewProps->zIndex.has_value()) {
386
- return std::to_string(*viewProps->zIndex);
387
- }
388
- } else if (propName == "backgroundColor") {
389
- return intColorToHex(*viewProps->backgroundColor);
390
- }
391
- }
392
-
393
- throw std::runtime_error(std::string(
394
- "Getting property `" + propName +
395
- "` with function `getViewProp` is not supported"));
396
- }
397
-
398
- jsi::Value ReanimatedModuleProxy::getViewProp(
399
- jsi::Runtime &rnRuntime,
400
- const jsi::Value &shadowNodeWrapper,
401
- const jsi::Value &propName,
402
- const jsi::Value &callback) {
403
- const auto propNameStr = propName.asString(rnRuntime).utf8(rnRuntime);
404
- const auto funPtr = std::make_shared<jsi::Function>(
405
- callback.getObject(rnRuntime).asFunction(rnRuntime));
406
- const auto shadowNode = shadowNodeFromValue(rnRuntime, shadowNodeWrapper);
407
- workletsModuleProxy_->getUIScheduler()->scheduleOnUI(
408
- [=, weakThis = weak_from_this()]() {
409
- auto strongThis = weakThis.lock();
410
- if (!strongThis) {
411
- return;
412
- }
413
- jsi::Runtime &uiRuntime =
414
- strongThis->uiWorkletRuntime_->getJSIRuntime();
415
- const auto resultStr = strongThis->obtainPropFromShadowNode(
416
- uiRuntime, propNameStr, shadowNode);
417
-
418
- strongThis->workletsModuleProxy_->getJSScheduler()->scheduleOnJS(
419
- [=](jsi::Runtime &rnRuntime) {
420
- const auto resultValue =
421
- jsi::String::createFromUtf8(rnRuntime, resultStr);
422
- funPtr->call(rnRuntime, resultValue);
423
- });
424
- });
425
- return jsi::Value::undefined();
426
- }
427
-
428
- #else
429
-
430
- jsi::Value ReanimatedModuleProxy::getViewProp(
431
- jsi::Runtime &rnRuntime,
432
- const jsi::Value &viewTag,
433
- const jsi::Value &propName,
434
- const jsi::Value &callback) {
435
- const auto propNameStr = propName.asString(rnRuntime).utf8(rnRuntime);
436
- const auto funPtr = std::make_shared<jsi::Function>(
437
- callback.getObject(rnRuntime).asFunction(rnRuntime));
438
-
439
- const int viewTagInt = viewTag.asNumber();
440
-
441
- workletsModuleProxy_->getUIScheduler()->scheduleOnUI(
442
- [=, weakThis = weak_from_this()]
443
-
444
- () {
445
- auto strongThis = weakThis.lock();
446
- if (!strongThis) {
447
- return;
448
- }
449
- jsi::Runtime &uiRuntime =
450
- strongThis->uiWorkletRuntime_->getJSIRuntime();
451
- const jsi::Value propNameValue =
452
- jsi::String::createFromUtf8(uiRuntime, propNameStr);
453
- const auto resultValue = strongThis->obtainPropFunction_(
454
- uiRuntime, viewTagInt, propNameValue);
455
- const auto resultStr = resultValue.asString(uiRuntime).utf8(uiRuntime);
456
- const auto jsScheduler =
457
- strongThis->workletsModuleProxy_->getJSScheduler();
458
- jsScheduler->scheduleOnJS([=](jsi::Runtime &rnRuntime) {
459
- const auto resultValue =
460
- jsi::String::createFromUtf8(rnRuntime, resultStr);
461
- funPtr->call(rnRuntime, resultValue);
462
- });
463
- });
464
- return jsi::Value::undefined();
465
- }
466
-
467
- #endif
468
-
469
- jsi::Value ReanimatedModuleProxy::enableLayoutAnimations(
470
- jsi::Runtime &,
471
- const jsi::Value &config) {
472
- FeaturesConfig::setLayoutAnimationEnabled(config.getBool());
473
- return jsi::Value::undefined();
474
- }
475
-
476
- jsi::Value ReanimatedModuleProxy::configureProps(
477
- jsi::Runtime &rt,
478
- const jsi::Value &uiProps,
479
- const jsi::Value &nativeProps) {
480
- #ifdef RCT_NEW_ARCH_ENABLED
481
- auto uiPropsArray = uiProps.asObject(rt).asArray(rt);
482
- for (size_t i = 0; i < uiPropsArray.size(rt); ++i) {
483
- auto name = uiPropsArray.getValueAtIndex(rt, i).asString(rt).utf8(rt);
484
- animatablePropNames_.insert(name);
485
- }
486
- auto nativePropsArray = nativeProps.asObject(rt).asArray(rt);
487
- for (size_t i = 0; i < nativePropsArray.size(rt); ++i) {
488
- auto name = nativePropsArray.getValueAtIndex(rt, i).asString(rt).utf8(rt);
489
- animatablePropNames_.insert(name);
490
- }
491
- #else
492
- configurePropsPlatformFunction_(rt, uiProps, nativeProps);
493
- #endif // RCT_NEW_ARCH_ENABLED
494
-
495
- return jsi::Value::undefined();
496
- }
497
-
498
- jsi::Value ReanimatedModuleProxy::configureLayoutAnimationBatch(
499
- jsi::Runtime &rt,
500
- const jsi::Value &layoutAnimationsBatch) {
501
- auto array = layoutAnimationsBatch.asObject(rt).asArray(rt);
502
- size_t length = array.size(rt);
503
- std::vector<LayoutAnimationConfig> batch(length);
504
- for (int i = 0; i < length; i++) {
505
- auto item = array.getValueAtIndex(rt, i).asObject(rt);
506
- auto &batchItem = batch[i];
507
- batchItem.tag = item.getProperty(rt, "viewTag").asNumber();
508
- batchItem.type = static_cast<LayoutAnimationType>(
509
- item.getProperty(rt, "type").asNumber());
510
- auto config = item.getProperty(rt, "config");
511
- if (config.isUndefined()) {
512
- batchItem.config = nullptr;
513
- } else {
514
- batchItem.config = extractShareableOrThrow<ShareableObject>(
515
- rt,
516
- config,
517
- "[Reanimated] Layout animation config must be an object.");
518
- }
519
- if (batch[i].type != SHARED_ELEMENT_TRANSITION &&
520
- batch[i].type != SHARED_ELEMENT_TRANSITION_PROGRESS) {
521
- continue;
522
- }
523
- auto sharedTransitionTag = item.getProperty(rt, "sharedTransitionTag");
524
- if (sharedTransitionTag.isUndefined()) {
525
- batch[i].config = nullptr;
526
- } else {
527
- batch[i].sharedTransitionTag = sharedTransitionTag.asString(rt).utf8(rt);
528
- }
529
- }
530
- layoutAnimationsManager_->configureAnimationBatch(batch);
531
- return jsi::Value::undefined();
532
- }
533
-
534
- void ReanimatedModuleProxy::setShouldAnimateExiting(
535
- jsi::Runtime &rt,
536
- const jsi::Value &viewTag,
537
- const jsi::Value &shouldAnimate) {
538
- layoutAnimationsManager_->setShouldAnimateExiting(
539
- viewTag.asNumber(), shouldAnimate.getBool());
540
- }
541
-
542
- bool ReanimatedModuleProxy::isAnyHandlerWaitingForEvent(
543
- const std::string &eventName,
544
- const int emitterReactTag) {
545
- return eventHandlerRegistry_->isAnyHandlerWaitingForEvent(
546
- eventName, emitterReactTag);
547
- }
548
-
549
- void ReanimatedModuleProxy::requestAnimationFrame(
550
- jsi::Runtime &rt,
551
- const jsi::Value &callback) {
552
- frameCallbacks_.push_back(std::make_shared<jsi::Value>(rt, callback));
553
- maybeRequestRender();
554
- }
555
-
556
- void ReanimatedModuleProxy::maybeRequestRender() {
557
- if (!renderRequested_) {
558
- renderRequested_ = true;
559
- requestRender_(onRenderCallback_);
560
- }
561
- }
562
-
563
- void ReanimatedModuleProxy::onRender(double timestampMs) {
564
- auto callbacks = std::move(frameCallbacks_);
565
- frameCallbacks_.clear();
566
- jsi::Runtime &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
567
- jsi::Value timestamp{timestampMs};
568
- for (const auto &callback : callbacks) {
569
- runOnRuntimeGuarded(uiRuntime, *callback, timestamp);
570
- }
571
- }
572
-
573
- jsi::Value ReanimatedModuleProxy::registerSensor(
574
- jsi::Runtime &rt,
575
- const jsi::Value &sensorType,
576
- const jsi::Value &interval,
577
- const jsi::Value &iosReferenceFrame,
578
- const jsi::Value &sensorDataHandler) {
579
- return animatedSensorModule_.registerSensor(
580
- rt,
581
- uiWorkletRuntime_,
582
- sensorType,
583
- interval,
584
- iosReferenceFrame,
585
- sensorDataHandler);
586
- }
587
-
588
- void ReanimatedModuleProxy::unregisterSensor(
589
- jsi::Runtime &,
590
- const jsi::Value &sensorId) {
591
- animatedSensorModule_.unregisterSensor(sensorId);
592
- }
593
-
594
- void ReanimatedModuleProxy::cleanupSensors() {
595
- animatedSensorModule_.unregisterAllSensors();
596
- }
597
-
598
- #ifdef RCT_NEW_ARCH_ENABLED
599
-
600
- void ReanimatedModuleProxy::markNodeAsRemovable(
601
- jsi::Runtime &rt,
602
- const jsi::Value &shadowNodeWrapper) {
603
- auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
604
- propsRegistry_->markNodeAsRemovable(shadowNode);
605
- }
606
-
607
- void ReanimatedModuleProxy::unmarkNodeAsRemovable(
608
- jsi::Runtime &rt,
609
- const jsi::Value &viewTag) {
610
- propsRegistry_->unmarkNodeAsRemovable(viewTag.asNumber());
611
- }
612
-
613
- jsi::Value ReanimatedModuleProxy::filterNonAnimatableProps(
614
- jsi::Runtime &rt,
615
- const jsi::Value &props) {
616
- jsi::Object nonAnimatableProps(rt);
617
- bool hasAnyNonAnimatableProp = false;
618
- const jsi::Object &propsObject = props.asObject(rt);
619
- const jsi::Array &propNames = propsObject.getPropertyNames(rt);
620
- for (size_t i = 0; i < propNames.size(rt); ++i) {
621
- const std::string &propName =
622
- propNames.getValueAtIndex(rt, i).asString(rt).utf8(rt);
623
- if (!collection::contains(animatablePropNames_, propName)) {
624
- hasAnyNonAnimatableProp = true;
625
- const auto &propNameStr = propName.c_str();
626
- const jsi::Value &propValue = propsObject.getProperty(rt, propNameStr);
627
- nonAnimatableProps.setProperty(rt, propNameStr, propValue);
628
- }
629
- }
630
- if (!hasAnyNonAnimatableProp) {
631
- return jsi::Value::undefined();
632
- }
633
- return nonAnimatableProps;
634
- }
635
- #endif // RCT_NEW_ARCH_ENABLED
636
-
637
- bool ReanimatedModuleProxy::handleEvent(
638
- const std::string &eventName,
639
- const int emitterReactTag,
640
- const jsi::Value &payload,
641
- double currentTime) {
642
- eventHandlerRegistry_->processEvent(
643
- uiWorkletRuntime_, currentTime, eventName, emitterReactTag, payload);
644
-
645
- // TODO: return true if Reanimated successfully handled the event
646
- // to avoid sending it to JavaScript
647
- return false;
648
- }
649
-
650
- #ifdef RCT_NEW_ARCH_ENABLED
651
- bool ReanimatedModuleProxy::handleRawEvent(
652
- const RawEvent &rawEvent,
653
- double currentTime) {
654
- const EventTarget *eventTarget = rawEvent.eventTarget.get();
655
- if (eventTarget == nullptr) {
656
- // after app reload scrollView is unmounted and its content offset is set
657
- // to 0 and view is thrown into recycle pool setting content offset
658
- // triggers scroll event eventTarget is null though, because it's
659
- // unmounting we can just ignore this event, because it's an event on
660
- // unmounted component
661
- return false;
662
- }
663
-
664
- int tag = eventTarget->getTag();
665
- auto eventType = rawEvent.type;
666
- if (eventType.rfind("top", 0) == 0) {
667
- eventType = "on" + eventType.substr(3);
668
- }
669
- jsi::Runtime &rt = uiWorkletRuntime_->getJSIRuntime();
670
-
671
- if (!isAnyHandlerWaitingForEvent(eventType, tag)) {
672
- return false;
673
- }
674
-
675
- const auto &eventPayload = rawEvent.eventPayload;
676
- jsi::Value payload = eventPayload->asJSIValue(rt);
677
-
678
- auto res = handleEvent(eventType, tag, std::move(payload), currentTime);
679
- // TODO: we should call performOperations conditionally if event is handled
680
- // (res == true), but for now handleEvent always returns false. Thankfully,
681
- // performOperations does not trigger a lot of code if there is nothing to
682
- // be done so this is fine for now.
683
- performOperations();
684
- return res;
685
- }
686
-
687
- void ReanimatedModuleProxy::updateProps(
688
- jsi::Runtime &rt,
689
- const jsi::Value &operations) {
690
- auto array = operations.asObject(rt).asArray(rt);
691
- size_t length = array.size(rt);
692
- for (size_t i = 0; i < length; ++i) {
693
- auto item = array.getValueAtIndex(rt, i).asObject(rt);
694
- auto shadowNodeWrapper = item.getProperty(rt, "shadowNodeWrapper");
695
- auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
696
- const jsi::Value &updates = item.getProperty(rt, "updates");
697
- operationsInBatch_.emplace_back(
698
- shadowNode, std::make_unique<jsi::Value>(rt, updates));
699
- }
700
- }
701
-
702
- void ReanimatedModuleProxy::performOperations() {
703
- if (operationsInBatch_.empty() && tagsToRemove_.empty()) {
704
- // nothing to do
705
- return;
706
- }
707
-
708
- ReanimatedSystraceSection s("performOperations");
709
-
710
- auto copiedOperationsQueue = std::move(operationsInBatch_);
711
- operationsInBatch_.clear();
712
-
713
- jsi::Runtime &rt = uiWorkletRuntime_->getJSIRuntime();
714
-
715
- {
716
- auto lock = propsRegistry_->createLock();
717
-
718
- if (copiedOperationsQueue.size() > 0 &&
719
- propsRegistry_->shouldReanimatedSkipCommit()) {
720
- propsRegistry_->pleaseCommitAfterPause();
721
- }
722
-
723
- // remove recently unmounted ShadowNodes from PropsRegistry
724
- if (!tagsToRemove_.empty()) {
725
- for (auto tag : tagsToRemove_) {
726
- propsRegistry_->remove(tag);
727
- }
728
- tagsToRemove_.clear();
729
- }
730
-
731
- // Even if only non-layout props are changed, we need to store the update
732
- // in PropsRegistry anyway so that React doesn't overwrite it in the next
733
- // render. Currently, only opacity and transform are treated in a special
734
- // way but backgroundColor, shadowOpacity etc. would get overwritten (see
735
- // `_propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN`).
736
- for (const auto &[shadowNode, props] : copiedOperationsQueue) {
737
- propsRegistry_->update(shadowNode, dynamicFromValue(rt, *props));
738
- }
739
- }
740
-
741
- for (const auto &[shadowNode, props] : copiedOperationsQueue) {
742
- const jsi::Value &nonAnimatableProps = filterNonAnimatableProps(rt, *props);
743
- if (nonAnimatableProps.isUndefined()) {
744
- continue;
745
- }
746
- Tag viewTag = shadowNode->getTag();
747
- jsi::Value maybeJSPropsUpdater =
748
- rt.global().getProperty(rt, "updateJSProps");
749
- assert(
750
- maybeJSPropsUpdater.isObject() &&
751
- "[Reanimated] `updateJSProps` not found");
752
- jsi::Function jsPropsUpdater =
753
- maybeJSPropsUpdater.asObject(rt).asFunction(rt);
754
- jsPropsUpdater.call(rt, viewTag, nonAnimatableProps);
755
- }
756
-
757
- if (propsRegistry_->shouldReanimatedSkipCommit()) {
758
- // It may happen that `performOperations` is called on the UI thread
759
- // while React Native tries to commit a new tree on the JS thread.
760
- // In this case, we should skip the commit here and let React Native do
761
- // it. The commit will include the current values from PropsRegistry which
762
- // will be applied in ReanimatedCommitHook.
763
- return;
764
- }
765
-
766
- react_native_assert(uiManager_ != nullptr);
767
- const auto &shadowTreeRegistry = uiManager_->getShadowTreeRegistry();
768
-
769
- std::unordered_map<SurfaceId, PropsMap> propsMapBySurface;
770
-
771
- for (auto const &[shadowNode, props] : copiedOperationsQueue) {
772
- SurfaceId surfaceId = shadowNode->getSurfaceId();
773
- auto family = &shadowNode->getFamily();
774
- react_native_assert(family->getSurfaceId() == surfaceId);
775
- propsMapBySurface[surfaceId][family].emplace_back(rt, std::move(*props));
776
- }
777
-
778
- for (auto const &[surfaceId, propsMap] : propsMapBySurface) {
779
- shadowTreeRegistry.visit(surfaceId, [&](ShadowTree const &shadowTree) {
780
- shadowTree.commit(
781
- [&](RootShadowNode const &oldRootShadowNode)
782
- -> RootShadowNode::Unshared {
783
- if (propsRegistry_->shouldReanimatedSkipCommit()) {
784
- return nullptr;
785
- }
786
-
787
- auto rootNode =
788
- cloneShadowTreeWithNewProps(oldRootShadowNode, propsMap);
789
-
790
- // Mark the commit as Reanimated commit so that we can distinguish
791
- // it in ReanimatedCommitHook.
792
-
793
- auto reaShadowNode =
794
- std::reinterpret_pointer_cast<ReanimatedCommitShadowNode>(
795
- rootNode);
796
- reaShadowNode->setReanimatedCommitTrait();
797
-
798
- return rootNode;
799
- },
800
- {/* .enableStateReconciliation = */
801
- false,
802
- /* .mountSynchronously = */ true});
803
- });
804
- }
805
- }
806
-
807
- void ReanimatedModuleProxy::dispatchCommand(
808
- jsi::Runtime &rt,
809
- const jsi::Value &shadowNodeValue,
810
- const jsi::Value &commandNameValue,
811
- const jsi::Value &argsValue) {
812
- ShadowNode::Shared shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
813
- std::string commandName = stringFromValue(rt, commandNameValue);
814
- folly::dynamic args = commandArgsFromValue(rt, argsValue);
815
- const auto &scheduler = static_cast<Scheduler *>(uiManager_->getDelegate());
816
-
817
- if (!scheduler) {
818
- return;
819
- }
820
-
821
- const auto &schedulerDelegate = scheduler->getDelegate();
822
-
823
- if (schedulerDelegate) {
824
- const auto shadowView = ShadowView(*shadowNode);
825
- schedulerDelegate->schedulerDidDispatchCommand(
826
- shadowView, commandName, args);
827
- }
828
- }
829
-
830
- jsi::String ReanimatedModuleProxy::obtainProp(
831
- jsi::Runtime &rt,
832
- const jsi::Value &shadowNodeWrapper,
833
- const jsi::Value &propName) {
834
- jsi::Runtime &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
835
- const auto propNameStr = propName.asString(rt).utf8(rt);
836
- const auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
837
- const auto resultStr =
838
- obtainPropFromShadowNode(uiRuntime, propNameStr, shadowNode);
839
- return jsi::String::createFromUtf8(rt, resultStr);
840
- }
841
-
842
- jsi::Value ReanimatedModuleProxy::measure(
843
- jsi::Runtime &rt,
844
- const jsi::Value &shadowNodeValue) {
845
- // based on implementation from UIManagerBinding.cpp
846
-
847
- auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
848
- auto layoutMetrics = uiManager_->getRelativeLayoutMetrics(
849
- *shadowNode, nullptr, {/* .includeTransform = */ true});
850
-
851
- if (layoutMetrics == EmptyLayoutMetrics) {
852
- // Originally, in this case React Native returns `{0, 0, 0, 0, 0, 0}`,
853
- // most likely due to the type of measure callback function which accepts
854
- // just an array of numbers (not null). In Reanimated, `measure` returns
855
- // `MeasuredDimensions | null`.
856
- return jsi::Value::null();
857
- }
858
- auto newestCloneOfShadowNode =
859
- uiManager_->getNewestCloneOfShadowNode(*shadowNode);
860
-
861
- auto layoutableShadowNode =
862
- dynamic_cast<LayoutableShadowNode const *>(newestCloneOfShadowNode.get());
863
- facebook::react::Point originRelativeToParent =
864
- layoutableShadowNode != nullptr
865
- ? layoutableShadowNode->getLayoutMetrics().frame.origin
866
- : facebook::react::Point();
867
-
868
- auto frame = layoutMetrics.frame;
869
-
870
- jsi::Object result(rt);
871
- result.setProperty(
872
- rt, "x", jsi::Value(static_cast<double>(originRelativeToParent.x)));
873
- result.setProperty(
874
- rt, "y", jsi::Value(static_cast<double>(originRelativeToParent.y)));
875
- result.setProperty(
876
- rt, "width", jsi::Value(static_cast<double>(frame.size.width)));
877
- result.setProperty(
878
- rt, "height", jsi::Value(static_cast<double>(frame.size.height)));
879
- result.setProperty(
880
- rt, "pageX", jsi::Value(static_cast<double>(frame.origin.x)));
881
- result.setProperty(
882
- rt, "pageY", jsi::Value(static_cast<double>(frame.origin.y)));
883
- return result;
884
- }
885
-
886
- void ReanimatedModuleProxy::initializeFabric(
887
- const std::shared_ptr<UIManager> &uiManager) {
888
- uiManager_ = uiManager;
889
-
890
- initializeLayoutAnimationsProxy();
891
-
892
- mountHook_ =
893
- std::make_shared<ReanimatedMountHook>(propsRegistry_, uiManager_);
894
- commitHook_ = std::make_shared<ReanimatedCommitHook>(
895
- propsRegistry_, uiManager_, layoutAnimationsProxy_);
896
- }
897
-
898
- void ReanimatedModuleProxy::initializeLayoutAnimationsProxy() {
899
- uiManager_->setAnimationDelegate(nullptr);
900
- auto scheduler = reinterpret_cast<Scheduler *>(uiManager_->getDelegate());
901
- auto componentDescriptorRegistry =
902
- scheduler->getContextContainer()
903
- ->at<std::weak_ptr<const ComponentDescriptorRegistry>>(
904
- "ComponentDescriptorRegistry_DO_NOT_USE_PRETTY_PLEASE")
905
- .lock();
906
-
907
- if (componentDescriptorRegistry) {
908
- layoutAnimationsProxy_ = std::make_shared<LayoutAnimationsProxy>(
909
- layoutAnimationsManager_,
910
- componentDescriptorRegistry,
911
- scheduler->getContextContainer(),
912
- uiWorkletRuntime_->getJSIRuntime(),
913
- workletsModuleProxy_->getUIScheduler());
914
- }
915
- }
916
-
917
- #ifdef IS_REANIMATED_EXAMPLE_APP
918
-
919
- std::string format(bool b) {
920
- return b ? "✅" : "❌";
921
- }
922
-
923
- std::function<std::string()>
924
- ReanimatedModuleProxy::createRegistriesLeakCheck() {
925
- return [weakThis = weak_from_this()]() {
926
- auto strongThis = weakThis.lock();
927
- if (!strongThis) {
928
- return std::string("");
929
- }
930
-
931
- std::string result = "";
932
-
933
- result += "PropsRegistry: " + format(strongThis->propsRegistry_->isEmpty());
934
-
935
- return result;
936
- };
937
- }
938
-
939
- #endif // IS_REANIMATED_EXAMPLE_APP
940
-
941
- #endif // RCT_NEW_ARCH_ENABLED
942
-
943
- jsi::Value ReanimatedModuleProxy::subscribeForKeyboardEvents(
944
- jsi::Runtime &rt,
945
- const jsi::Value &handlerWorklet,
946
- const jsi::Value &isStatusBarTranslucent,
947
- const jsi::Value &isNavigationBarTranslucent) {
948
- auto shareableHandler = extractShareableOrThrow<ShareableWorklet>(
949
- rt,
950
- handlerWorklet,
951
- "[Reanimated] Keyboard event handler must be a worklet.");
952
- return subscribeForKeyboardEventsFunction_(
953
- [=, weakThis = weak_from_this()](int keyboardState, int height) {
954
- auto strongThis = weakThis.lock();
955
- if (!strongThis) {
956
- return;
957
- }
958
- strongThis->uiWorkletRuntime_->runGuarded(
959
- shareableHandler, jsi::Value(keyboardState), jsi::Value(height));
960
- },
961
- isStatusBarTranslucent.getBool(),
962
- isNavigationBarTranslucent.getBool());
963
- }
964
-
965
- void ReanimatedModuleProxy::unsubscribeFromKeyboardEvents(
966
- jsi::Runtime &,
967
- const jsi::Value &listenerId) {
968
- unsubscribeFromKeyboardEventsFunction_(listenerId.asNumber());
969
- }
970
-
971
- } // namespace reanimated
1
+ #include <jsi/jsi.h>
2
+ #include <reanimated/NativeModules/PropValueProcessor.h>
3
+ #include <reanimated/NativeModules/ReanimatedModuleProxy.h>
4
+ #include <reanimated/RuntimeDecorators/UIRuntimeDecorator.h>
5
+ #include <reanimated/Tools/FeatureFlags.h>
6
+ #include <reanimated/Tools/ReanimatedSystraceSection.h>
7
+
8
+ #include <worklets/Registries/EventHandlerRegistry.h>
9
+ #include <worklets/SharedItems/Serializable.h>
10
+ #include <worklets/Tools/WorkletEventHandler.h>
11
+
12
+ #ifdef __ANDROID__
13
+ #include <fbjni/fbjni.h>
14
+ #endif // __ANDROID__
15
+
16
+ #include <react/renderer/scheduler/Scheduler.h>
17
+ #include <react/renderer/uimanager/UIManagerBinding.h>
18
+ #include <reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h>
19
+ #include <reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h>
20
+
21
+ #include <functional>
22
+ #include <iomanip>
23
+ #include <memory>
24
+ #include <sstream>
25
+ #include <string>
26
+ #include <unordered_map>
27
+ #include <unordered_set>
28
+ #include <utility>
29
+ #include <vector>
30
+
31
+ namespace reanimated {
32
+
33
+ #if REACT_NATIVE_MINOR_VERSION >= 81
34
+ static inline std::shared_ptr<const ShadowNode> shadowNodeFromValue(
35
+ jsi::Runtime &rt,
36
+ const jsi::Value &shadowNodeWrapper) {
37
+ return Bridging<std::shared_ptr<const ShadowNode>>::fromJs(rt, shadowNodeWrapper);
38
+ }
39
+ #endif
40
+
41
+ ReanimatedModuleProxy::ReanimatedModuleProxy(
42
+ const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy,
43
+ jsi::Runtime &rnRuntime,
44
+ const std::shared_ptr<CallInvoker> &jsCallInvoker,
45
+ const PlatformDepMethodsHolder &platformDepMethodsHolder,
46
+ const bool isReducedMotion)
47
+ : ReanimatedModuleProxySpec(jsCallInvoker),
48
+ isReducedMotion_(isReducedMotion),
49
+ workletsModuleProxy_(workletsModuleProxy),
50
+ eventHandlerRegistry_(std::make_unique<EventHandlerRegistry>()),
51
+ requestRender_(platformDepMethodsHolder.requestRender),
52
+ animatedSensorModule_(platformDepMethodsHolder),
53
+ jsLogger_(std::make_shared<JSLogger>(workletsModuleProxy->getJSScheduler())),
54
+ layoutAnimationsManager_(std::make_shared<LayoutAnimationsManager>(jsLogger_)),
55
+ getAnimationTimestamp_(platformDepMethodsHolder.getAnimationTimestamp),
56
+ #ifdef __APPLE__
57
+ forceScreenSnapshot_(platformDepMethodsHolder.forceScreenSnapshotFunction),
58
+ #endif
59
+ animatedPropsRegistry_(std::make_shared<AnimatedPropsRegistry>()),
60
+ staticPropsRegistry_(std::make_shared<StaticPropsRegistry>()),
61
+ updatesRegistryManager_(std::make_shared<UpdatesRegistryManager>(staticPropsRegistry_)),
62
+ viewStylesRepository_(std::make_shared<ViewStylesRepository>(staticPropsRegistry_, animatedPropsRegistry_)),
63
+ cssAnimationKeyframesRegistry_(std::make_shared<CSSKeyframesRegistry>(viewStylesRepository_)),
64
+ cssAnimationsRegistry_(std::make_shared<CSSAnimationsRegistry>()),
65
+ cssTransitionsRegistry_(std::make_shared<CSSTransitionsRegistry>(staticPropsRegistry_, getAnimationTimestamp_)),
66
+ synchronouslyUpdateUIPropsFunction_(platformDepMethodsHolder.synchronouslyUpdateUIPropsFunction),
67
+ #ifdef ANDROID
68
+ filterUnmountedTagsFunction_(platformDepMethodsHolder.filterUnmountedTagsFunction),
69
+ #endif // ANDROID
70
+ subscribeForKeyboardEventsFunction_(platformDepMethodsHolder.subscribeForKeyboardEvents),
71
+ unsubscribeFromKeyboardEventsFunction_(platformDepMethodsHolder.unsubscribeFromKeyboardEvents) {
72
+ auto lock = updatesRegistryManager_->lock();
73
+ // Add registries in order of their priority (from the lowest to the
74
+ // highest)
75
+ // CSS transitions should be overriden by animated style animations;
76
+ // animated style animations should be overriden by CSS animations
77
+ updatesRegistryManager_->addRegistry(cssTransitionsRegistry_);
78
+ updatesRegistryManager_->addRegistry(animatedPropsRegistry_);
79
+ updatesRegistryManager_->addRegistry(cssAnimationsRegistry_);
80
+ }
81
+
82
+ void ReanimatedModuleProxy::init(const PlatformDepMethodsHolder &platformDepMethodsHolder) {
83
+ auto onRenderCallback = [weakThis = weak_from_this()](const double timestampMs) {
84
+ auto strongThis = weakThis.lock();
85
+ if (!strongThis) {
86
+ return;
87
+ }
88
+
89
+ strongThis->renderRequested_ = false;
90
+ strongThis->onRender(timestampMs);
91
+ };
92
+ onRenderCallback_ = std::move(onRenderCallback);
93
+
94
+ auto updateProps = [weakThis = weak_from_this()](jsi::Runtime &rt, const jsi::Value &operations) {
95
+ auto strongThis = weakThis.lock();
96
+ if (!strongThis) {
97
+ return;
98
+ }
99
+
100
+ const auto timestamp = strongThis->getAnimationTimestamp_();
101
+ strongThis->animatedPropsRegistry_->update(rt, operations, timestamp);
102
+ };
103
+
104
+ auto measure = [weakThis = weak_from_this()](jsi::Runtime &rt, const jsi::Value &shadowNodeValue) -> jsi::Value {
105
+ auto strongThis = weakThis.lock();
106
+ if (!strongThis) {
107
+ return jsi::Value::undefined();
108
+ }
109
+ return strongThis->measure(rt, shadowNodeValue);
110
+ };
111
+
112
+ auto dispatchCommand = [weakThis = weak_from_this()](
113
+ jsi::Runtime &rt,
114
+ const jsi::Value &shadowNodeValue,
115
+ const jsi::Value &commandNameValue,
116
+ const jsi::Value &argsValue) {
117
+ auto strongThis = weakThis.lock();
118
+ if (!strongThis) {
119
+ return;
120
+ }
121
+
122
+ strongThis->dispatchCommand(rt, shadowNodeValue, commandNameValue, argsValue);
123
+ };
124
+ ProgressLayoutAnimationFunction progressLayoutAnimation =
125
+ [weakThis = weak_from_this()](jsi::Runtime &rt, int tag, const jsi::Object &newStyle) {
126
+ auto strongThis = weakThis.lock();
127
+ if (!strongThis) {
128
+ return;
129
+ }
130
+ auto surfaceId = strongThis->layoutAnimationsProxy_->progressLayoutAnimation(tag, newStyle);
131
+ if (!surfaceId) {
132
+ return;
133
+ }
134
+ strongThis->layoutAnimationFlushRequests_.insert(*surfaceId);
135
+ };
136
+
137
+ auto requestLayoutAnimationRender = [weakThis = weak_from_this()](double) {
138
+ auto strongThis = weakThis.lock();
139
+ if (!strongThis) {
140
+ return;
141
+ }
142
+ strongThis->layoutAnimationRenderRequested_ = false;
143
+ };
144
+
145
+ EndLayoutAnimationFunction endLayoutAnimation = [weakThis = weak_from_this(), requestLayoutAnimationRender](
146
+ int tag, bool shouldRemove) {
147
+ auto strongThis = weakThis.lock();
148
+ if (!strongThis) {
149
+ return;
150
+ }
151
+
152
+ auto surfaceId = strongThis->layoutAnimationsProxy_->endLayoutAnimation(tag, shouldRemove);
153
+
154
+ if (!strongThis->layoutAnimationRenderRequested_) {
155
+ strongThis->layoutAnimationRenderRequested_ = true;
156
+ // if an animation has duration 0, performOperations would not get
157
+ // called for it so we call requestRender to have it called in the
158
+ // next frame
159
+ strongThis->requestRender_(requestLayoutAnimationRender);
160
+ }
161
+
162
+ if (!surfaceId) {
163
+ return;
164
+ }
165
+ strongThis->layoutAnimationFlushRequests_.insert(*surfaceId);
166
+ };
167
+
168
+ auto obtainProp = [weakThis = weak_from_this()](
169
+ jsi::Runtime &rt, const jsi::Value &shadowNodeWrapper, const jsi::Value &propName) {
170
+ auto strongThis = weakThis.lock();
171
+ if (!strongThis) {
172
+ return jsi::String::createFromUtf8(rt, "");
173
+ }
174
+
175
+ return strongThis->obtainProp(rt, shadowNodeWrapper, propName);
176
+ };
177
+
178
+ jsi::Runtime &uiRuntime = workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime();
179
+ UIRuntimeDecorator::decorate(
180
+ uiRuntime,
181
+ obtainProp,
182
+ updateProps,
183
+ measure,
184
+ dispatchCommand,
185
+ platformDepMethodsHolder.getAnimationTimestamp,
186
+ platformDepMethodsHolder.setGestureStateFunction,
187
+ progressLayoutAnimation,
188
+ endLayoutAnimation,
189
+ platformDepMethodsHolder.maybeFlushUIUpdatesQueueFunction);
190
+ }
191
+
192
+ ReanimatedModuleProxy::~ReanimatedModuleProxy() {
193
+ invalidate();
194
+ }
195
+
196
+ void ReanimatedModuleProxy::invalidate() {
197
+ // event handler registry and frame callbacks store some JSI values from UI
198
+ // runtime, so they have to go away before we tear down the runtime
199
+ eventHandlerRegistry_.reset();
200
+ }
201
+
202
+ jsi::Value ReanimatedModuleProxy::registerEventHandler(
203
+ jsi::Runtime &rt,
204
+ const jsi::Value &worklet,
205
+ const jsi::Value &eventName,
206
+ const jsi::Value &emitterReactTag) {
207
+ static uint64_t NEXT_EVENT_HANDLER_ID = 1;
208
+
209
+ uint64_t newRegistrationId = NEXT_EVENT_HANDLER_ID++;
210
+ auto eventNameStr = eventName.asString(rt).utf8(rt);
211
+ auto handlerSerializable = extractSerializableOrThrow<SerializableWorklet>(
212
+ rt, worklet, "[Reanimated] Event handler must be a serializable worklet.");
213
+ int emitterReactTagInt = emitterReactTag.asNumber();
214
+
215
+ workletsModuleProxy_->getUIScheduler()->scheduleOnUI([=, weakThis = weak_from_this()]() {
216
+ auto strongThis = weakThis.lock();
217
+ if (!strongThis) {
218
+ return;
219
+ }
220
+ auto handler =
221
+ std::make_shared<WorkletEventHandler>(newRegistrationId, eventNameStr, emitterReactTagInt, handlerSerializable);
222
+ strongThis->eventHandlerRegistry_->registerEventHandler(handler);
223
+ });
224
+
225
+ return jsi::Value(static_cast<double>(newRegistrationId));
226
+ }
227
+
228
+ void ReanimatedModuleProxy::unregisterEventHandler(jsi::Runtime &, const jsi::Value &registrationId) {
229
+ uint64_t id = registrationId.asNumber();
230
+ workletsModuleProxy_->getUIScheduler()->scheduleOnUI([=, weakThis = weak_from_this()]() {
231
+ auto strongThis = weakThis.lock();
232
+ if (!strongThis) {
233
+ return;
234
+ }
235
+ strongThis->eventHandlerRegistry_->unregisterEventHandler(id);
236
+ });
237
+ }
238
+
239
+ std::string ReanimatedModuleProxy::obtainPropFromShadowNode(
240
+ jsi::Runtime &rt,
241
+ const std::string &propName,
242
+ const std::shared_ptr<const ShadowNode> &shadowNode) {
243
+ auto newestCloneOfShadowNode = uiManager_->getNewestCloneOfShadowNode(*shadowNode);
244
+
245
+ return PropValueProcessor::processPropValue(propName, newestCloneOfShadowNode, rt);
246
+ }
247
+
248
+ jsi::Value ReanimatedModuleProxy::getViewProp(
249
+ jsi::Runtime &rnRuntime,
250
+ const jsi::Value &shadowNodeWrapper,
251
+ const jsi::Value &propName,
252
+ const jsi::Value &callback) {
253
+ const auto propNameStr = propName.asString(rnRuntime).utf8(rnRuntime);
254
+ const auto funPtr = std::make_shared<jsi::Function>(callback.getObject(rnRuntime).asFunction(rnRuntime));
255
+ const auto shadowNode = shadowNodeFromValue(rnRuntime, shadowNodeWrapper);
256
+ workletsModuleProxy_->getUIScheduler()->scheduleOnUI([=, weakThis = weak_from_this()]() {
257
+ auto strongThis = weakThis.lock();
258
+ if (!strongThis) {
259
+ return;
260
+ }
261
+ jsi::Runtime &uiRuntime = strongThis->workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime();
262
+ const auto resultStr = strongThis->obtainPropFromShadowNode(uiRuntime, propNameStr, shadowNode);
263
+
264
+ strongThis->workletsModuleProxy_->getJSScheduler()->scheduleOnJS([=](jsi::Runtime &rnRuntime) {
265
+ const auto resultValue = jsi::String::createFromUtf8(rnRuntime, resultStr);
266
+ funPtr->call(rnRuntime, resultValue);
267
+ });
268
+ });
269
+ return jsi::Value::undefined();
270
+ }
271
+
272
+ jsi::Value ReanimatedModuleProxy::getStaticFeatureFlag(jsi::Runtime &rt, const jsi::Value &name) {
273
+ return reanimated::StaticFeatureFlags::getFlag(name.asString(rt).utf8(rt));
274
+ }
275
+
276
+ jsi::Value
277
+ ReanimatedModuleProxy::setDynamicFeatureFlag(jsi::Runtime &rt, const jsi::Value &name, const jsi::Value &value) {
278
+ reanimated::DynamicFeatureFlags::setFlag(name.asString(rt).utf8(rt), value.asBool());
279
+ return jsi::Value::undefined();
280
+ }
281
+
282
+ jsi::Value ReanimatedModuleProxy::configureLayoutAnimationBatch(
283
+ jsi::Runtime &rt,
284
+ const jsi::Value &layoutAnimationsBatch) {
285
+ auto array = layoutAnimationsBatch.asObject(rt).asArray(rt);
286
+ size_t length = array.size(rt);
287
+ std::vector<LayoutAnimationConfig> batch(length);
288
+ for (int i = 0; i < length; i++) {
289
+ auto item = array.getValueAtIndex(rt, i).asObject(rt);
290
+ auto &batchItem = batch[i];
291
+ batchItem.tag = item.getProperty(rt, "viewTag").asNumber();
292
+ batchItem.type = static_cast<LayoutAnimationType>(item.getProperty(rt, "type").asNumber());
293
+ auto config = item.getProperty(rt, "config");
294
+ if (config.isUndefined()) {
295
+ batchItem.config = nullptr;
296
+ } else {
297
+ batchItem.config = extractSerializableOrThrow<SerializableObject>(
298
+ rt, config, "[Reanimated] Layout animation config must be an object.");
299
+ }
300
+ auto sharedTag = item.getProperty(rt, "sharedTransitionTag");
301
+ if (!sharedTag.isUndefined()) {
302
+ batchItem.sharedTransitionTag = sharedTag.asString(rt).utf8(rt);
303
+ }
304
+ }
305
+ layoutAnimationsManager_->configureAnimationBatch(batch);
306
+ return jsi::Value::undefined();
307
+ }
308
+
309
+ void ReanimatedModuleProxy::setShouldAnimateExiting(
310
+ jsi::Runtime &rt,
311
+ const jsi::Value &viewTag,
312
+ const jsi::Value &shouldAnimate) {
313
+ layoutAnimationsManager_->setShouldAnimateExiting(viewTag.asNumber(), shouldAnimate.getBool());
314
+ }
315
+
316
+ bool ReanimatedModuleProxy::isAnyHandlerWaitingForEvent(const std::string &eventName, const int emitterReactTag) {
317
+ return eventHandlerRegistry_->isAnyHandlerWaitingForEvent(eventName, emitterReactTag);
318
+ }
319
+
320
+ void ReanimatedModuleProxy::maybeRequestRender() {
321
+ if (!renderRequested_) {
322
+ renderRequested_ = true;
323
+ requestRender_(onRenderCallback_);
324
+ }
325
+ }
326
+
327
+ void ReanimatedModuleProxy::onRender(double timestampMs) {
328
+ ReanimatedSystraceSection s("ReanimatedModuleProxy::onRender");
329
+ // NOOP
330
+ }
331
+
332
+ jsi::Value ReanimatedModuleProxy::registerSensor(
333
+ jsi::Runtime &rt,
334
+ const jsi::Value &sensorType,
335
+ const jsi::Value &interval,
336
+ const jsi::Value &iosReferenceFrame,
337
+ const jsi::Value &sensorDataHandler) {
338
+ return animatedSensorModule_.registerSensor(
339
+ rt, workletsModuleProxy_->getUIWorkletRuntime(), sensorType, interval, iosReferenceFrame, sensorDataHandler);
340
+ }
341
+
342
+ void ReanimatedModuleProxy::unregisterSensor(jsi::Runtime &, const jsi::Value &sensorId) {
343
+ animatedSensorModule_.unregisterSensor(sensorId);
344
+ }
345
+
346
+ void ReanimatedModuleProxy::cleanupSensors() {
347
+ animatedSensorModule_.unregisterAllSensors();
348
+ }
349
+
350
+ void ReanimatedModuleProxy::setViewStyle(jsi::Runtime &rt, const jsi::Value &viewTag, const jsi::Value &viewStyle) {
351
+ const auto tag = viewTag.asNumber();
352
+ staticPropsRegistry_->set(rt, tag, viewStyle);
353
+ if (staticPropsRegistry_->hasObservers(tag)) {
354
+ maybeRunCSSLoop();
355
+ }
356
+ }
357
+
358
+ void ReanimatedModuleProxy::markNodeAsRemovable(jsi::Runtime &rt, const jsi::Value &shadowNodeWrapper) {
359
+ auto lock = updatesRegistryManager_->lock();
360
+ auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
361
+ updatesRegistryManager_->markNodeAsRemovable(shadowNode);
362
+ }
363
+
364
+ void ReanimatedModuleProxy::unmarkNodeAsRemovable(jsi::Runtime &rt, const jsi::Value &viewTag) {
365
+ auto lock = updatesRegistryManager_->lock();
366
+ updatesRegistryManager_->unmarkNodeAsRemovable(viewTag.asNumber());
367
+ }
368
+
369
+ void ReanimatedModuleProxy::registerCSSKeyframes(
370
+ jsi::Runtime &rt,
371
+ const jsi::Value &animationName,
372
+ const jsi::Value &viewName,
373
+ const jsi::Value &keyframesConfig) {
374
+ // Convert react view name to Fabric component name
375
+ const auto componentName = componentNameByReactViewName(viewName.asString(rt).utf8(rt));
376
+ cssAnimationKeyframesRegistry_->set(
377
+ animationName.asString(rt).utf8(rt),
378
+ componentName,
379
+ parseCSSAnimationKeyframesConfig(rt, keyframesConfig, componentName, viewStylesRepository_));
380
+ }
381
+
382
+ void ReanimatedModuleProxy::unregisterCSSKeyframes(
383
+ jsi::Runtime &rt,
384
+ const jsi::Value &animationName,
385
+ const jsi::Value &viewName) {
386
+ cssAnimationKeyframesRegistry_->remove(
387
+ animationName.asString(rt).utf8(rt), componentNameByReactViewName(viewName.asString(rt).utf8(rt)));
388
+ }
389
+
390
+ void ReanimatedModuleProxy::applyCSSAnimations(
391
+ jsi::Runtime &rt,
392
+ const jsi::Value &shadowNodeWrapper,
393
+ const jsi::Value &animationUpdates) {
394
+ auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
395
+ const auto timestamp = getCssTimestamp();
396
+ const auto updates = parseCSSAnimationUpdates(rt, animationUpdates);
397
+
398
+ CSSAnimationsMap newAnimations;
399
+
400
+ if (!updates.newAnimationSettings.empty()) {
401
+ // animationNames always exists when newAnimationSettings is not empty
402
+ const auto animationNames = updates.animationNames.value();
403
+ const auto animationNamesCount = animationNames.size();
404
+
405
+ for (const auto &[index, settings] : updates.newAnimationSettings) {
406
+ if (index >= animationNamesCount) {
407
+ throw std::invalid_argument("[Reanimated] index is out of bounds of animationNames");
408
+ }
409
+
410
+ const auto &animationName = animationNames[index];
411
+ const auto &keyframesConfig = cssAnimationKeyframesRegistry_->get(animationName, shadowNode->getComponentName());
412
+
413
+ newAnimations.emplace(
414
+ index, std::make_shared<CSSAnimation>(rt, shadowNode, animationName, keyframesConfig, settings, timestamp));
415
+ }
416
+ }
417
+
418
+ {
419
+ auto lock = cssAnimationsRegistry_->lock();
420
+ cssAnimationsRegistry_->apply(
421
+ rt, shadowNode, updates.animationNames, newAnimations, updates.settingsUpdates, timestamp);
422
+ }
423
+
424
+ maybeRunCSSLoop();
425
+ }
426
+
427
+ void ReanimatedModuleProxy::unregisterCSSAnimations(const jsi::Value &viewTag) {
428
+ auto lock = cssAnimationsRegistry_->lock();
429
+ cssAnimationsRegistry_->remove(viewTag.asNumber());
430
+ }
431
+
432
+ void ReanimatedModuleProxy::registerCSSTransition(
433
+ jsi::Runtime &rt,
434
+ const jsi::Value &shadowNodeWrapper,
435
+ const jsi::Value &transitionConfig) {
436
+ auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
437
+
438
+ auto transition = std::make_shared<CSSTransition>(
439
+ std::move(shadowNode), parseCSSTransitionConfig(rt, transitionConfig), viewStylesRepository_);
440
+
441
+ {
442
+ auto lock = cssTransitionsRegistry_->lock();
443
+ cssTransitionsRegistry_->add(transition);
444
+ }
445
+ maybeRunCSSLoop();
446
+ }
447
+
448
+ void ReanimatedModuleProxy::updateCSSTransition(
449
+ jsi::Runtime &rt,
450
+ const jsi::Value &viewTag,
451
+ const jsi::Value &configUpdates) {
452
+ auto lock = cssTransitionsRegistry_->lock();
453
+ cssTransitionsRegistry_->updateSettings(viewTag.asNumber(), parsePartialCSSTransitionConfig(rt, configUpdates));
454
+ maybeRunCSSLoop();
455
+ }
456
+
457
+ void ReanimatedModuleProxy::unregisterCSSTransition(jsi::Runtime &rt, const jsi::Value &viewTag) {
458
+ auto lock = cssTransitionsRegistry_->lock();
459
+ cssTransitionsRegistry_->remove(viewTag.asNumber());
460
+ }
461
+
462
+ jsi::Value ReanimatedModuleProxy::getSettledUpdates(jsi::Runtime &rt) {
463
+ react_native_assert(
464
+ StaticFeatureFlags::getFlag("FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS") &&
465
+ "getSettledUpdates requires FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS static feature flag to be enabled");
466
+
467
+ // TODO(future): use unified timestamp
468
+ const auto currentTimestamp = getAnimationTimestamp_();
469
+
470
+ const auto lock = animatedPropsRegistry_->lock();
471
+
472
+ // TODO: fix bug when threshold difference is smaller than 1 second
473
+ // TODO(future): flush updates from CSS animations and CSS transitions registries
474
+ animatedPropsRegistry_->removeUpdatesOlderThanTimestamp(currentTimestamp - 2000); // 2 seconds
475
+
476
+ // TODO(future): find a better way to obtain timestamp for removing updates
477
+ // TODO(future): move removing old updates to separate method
478
+ return animatedPropsRegistry_->getUpdatesOlderThanTimestamp(rt, currentTimestamp - 1000); // 1 second
479
+ }
480
+
481
+ bool ReanimatedModuleProxy::handleEvent(
482
+ const std::string &eventName,
483
+ const int emitterReactTag,
484
+ const jsi::Value &payload,
485
+ double currentTime) {
486
+ ReanimatedSystraceSection s("ReanimatedModuleProxy::handleEvent");
487
+
488
+ eventHandlerRegistry_->processEvent(
489
+ workletsModuleProxy_->getUIWorkletRuntime(), currentTime, eventName, emitterReactTag, payload);
490
+
491
+ // TODO: return true if Reanimated successfully handled the event
492
+ // to avoid sending it to JavaScript
493
+ return false;
494
+ }
495
+
496
+ bool ReanimatedModuleProxy::handleRawEvent(const RawEvent &rawEvent, double currentTime) {
497
+ ReanimatedSystraceSection s("ReanimatedModuleProxy::handleRawEvent");
498
+
499
+ const EventTarget *eventTarget = rawEvent.eventTarget.get();
500
+ if (eventTarget == nullptr) {
501
+ // after app reload scrollView is unmounted and its content offset is set
502
+ // to 0 and view is thrown into recycle pool setting content offset
503
+ // triggers scroll event eventTarget is null though, because it's
504
+ // unmounting we can just ignore this event, because it's an event on
505
+ // unmounted component
506
+ return false;
507
+ }
508
+
509
+ int tag = eventTarget->getTag();
510
+ auto eventType = rawEvent.type;
511
+ if (eventType.rfind("top", 0) == 0) {
512
+ eventType = "on" + eventType.substr(3);
513
+ }
514
+
515
+ if constexpr (StaticFeatureFlags::getFlag("ENABLE_SHARED_ELEMENT_TRANSITIONS")) {
516
+ if (eventType == "onTransitionProgress") {
517
+ jsi::Runtime &rt = workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime();
518
+ const auto &eventPayload = rawEvent.eventPayload;
519
+ jsi::Object payload = eventPayload->asJSIValue(rt).asObject(rt);
520
+ auto progress = payload.getProperty(rt, "progress").asNumber();
521
+ auto closing = static_cast<bool>(payload.getProperty(rt, "closing").asNumber());
522
+ auto goingForward = static_cast<bool>(payload.getProperty(rt, "goingForward").asNumber());
523
+
524
+ if (!layoutAnimationsProxy_) {
525
+ return false;
526
+ }
527
+ auto surfaceId = layoutAnimationsProxy_->onTransitionProgress(tag, progress, closing, goingForward);
528
+ if (!surfaceId) {
529
+ return false;
530
+ }
531
+ // TODO (future): enumerate -> visit
532
+ uiManager_->getShadowTreeRegistry().enumerate(
533
+ [](const ShadowTree &shadowTree, bool &) { shadowTree.notifyDelegatesOfUpdates(); });
534
+ return false;
535
+ } else if (eventType == "onGestureCancel") {
536
+ if (!layoutAnimationsProxy_) {
537
+ return false;
538
+ }
539
+ auto surfaceId = layoutAnimationsProxy_->onGestureCancel();
540
+ if (!surfaceId) {
541
+ return false;
542
+ }
543
+ // TODO (future): enumerate -> visit
544
+ uiManager_->getShadowTreeRegistry().enumerate(
545
+ [](const ShadowTree &shadowTree, bool &) { shadowTree.notifyDelegatesOfUpdates(); });
546
+ return false;
547
+ }
548
+ }
549
+
550
+ if (!isAnyHandlerWaitingForEvent(eventType, tag)) {
551
+ return false;
552
+ }
553
+
554
+ jsi::Runtime &rt = workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime();
555
+ const auto &eventPayload = rawEvent.eventPayload;
556
+ jsi::Value payload = eventPayload->asJSIValue(rt);
557
+
558
+ auto res = handleEvent(eventType, tag, payload, currentTime);
559
+ // TODO: we should call performOperations conditionally if event is handled
560
+ // (res == true), but for now handleEvent always returns false. Thankfully,
561
+ // performOperations does not trigger a lot of code if there is nothing to
562
+ // be done so this is fine for now.
563
+ performOperations(true);
564
+ return res;
565
+ }
566
+
567
+ void ReanimatedModuleProxy::cssLoopCallback(const double /*timestampMs*/) {
568
+ shouldUpdateCssAnimations_ = true;
569
+ if (cssAnimationsRegistry_->hasUpdates() || cssTransitionsRegistry_->hasUpdates()
570
+ #ifdef ANDROID
571
+ || updatesRegistryManager_->hasPropsToRevert()
572
+ #endif // ANDROID
573
+ ) {
574
+ requestRender_([weakThis = weak_from_this()](const double newTimestampMs) {
575
+ if (auto strongThis = weakThis.lock()) {
576
+ strongThis->cssLoopCallback(newTimestampMs);
577
+ }
578
+ });
579
+ } else {
580
+ cssLoopRunning_ = false;
581
+ }
582
+ }
583
+
584
+ void ReanimatedModuleProxy::maybeRunCSSLoop() {
585
+ if (cssLoopRunning_) {
586
+ return;
587
+ }
588
+
589
+ cssLoopRunning_ = true;
590
+
591
+ workletsModuleProxy_->getUIScheduler()->scheduleOnUI([weakThis = weak_from_this()]() {
592
+ auto strongThis = weakThis.lock();
593
+ if (!strongThis) {
594
+ return;
595
+ }
596
+ strongThis->requestRender_([weakThis](const double timestampMs) {
597
+ if (auto strongThis = weakThis.lock()) {
598
+ strongThis->cssLoopCallback(timestampMs);
599
+ }
600
+ });
601
+ });
602
+ }
603
+
604
+ double ReanimatedModuleProxy::getCssTimestamp() {
605
+ if (cssLoopRunning_) {
606
+ return currentCssTimestamp_;
607
+ }
608
+ currentCssTimestamp_ = getAnimationTimestamp_();
609
+ return currentCssTimestamp_;
610
+ }
611
+
612
+ void ReanimatedModuleProxy::performOperations(const bool isTriggeredByEvent) {
613
+ ReanimatedSystraceSection s("ReanimatedModuleProxy::performOperations");
614
+
615
+ if (!isTriggeredByEvent) {
616
+ auto flushRequestsCopy = std::move(layoutAnimationFlushRequests_);
617
+ for (const auto surfaceId : flushRequestsCopy) {
618
+ uiManager_->getShadowTreeRegistry().visit(
619
+ surfaceId, [](const ShadowTree &shadowTree) { shadowTree.notifyDelegatesOfUpdates(); });
620
+ }
621
+ }
622
+
623
+ jsi::Runtime &rt = workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime();
624
+
625
+ UpdatesBatch updatesBatch;
626
+ {
627
+ ReanimatedSystraceSection s2("ReanimatedModuleProxy::flushUpdates");
628
+
629
+ auto lock = updatesRegistryManager_->lock();
630
+
631
+ if (shouldUpdateCssAnimations_) {
632
+ currentCssTimestamp_ = getAnimationTimestamp_();
633
+ auto lock = cssTransitionsRegistry_->lock();
634
+ // Update CSS transitions and flush updates
635
+ cssTransitionsRegistry_->update(currentCssTimestamp_);
636
+ cssTransitionsRegistry_->flushUpdates(updatesBatch);
637
+ }
638
+
639
+ {
640
+ auto lock = animatedPropsRegistry_->lock();
641
+ // Flush all animated props updates
642
+ animatedPropsRegistry_->flushUpdates(updatesBatch);
643
+ }
644
+
645
+ if (shouldUpdateCssAnimations_) {
646
+ auto lock = cssAnimationsRegistry_->lock();
647
+ // Update CSS animations and flush updates
648
+ cssAnimationsRegistry_->update(currentCssTimestamp_);
649
+ cssAnimationsRegistry_->flushUpdates(updatesBatch);
650
+ }
651
+
652
+ shouldUpdateCssAnimations_ = false;
653
+
654
+ #ifdef ANDROID
655
+ if constexpr (
656
+ StaticFeatureFlags::getFlag("ANDROID_SYNCHRONOUSLY_UPDATE_UI_PROPS") &&
657
+ !StaticFeatureFlags::getFlag("ENABLE_SHARED_ELEMENT_TRANSITIONS")) {
658
+ static const std::unordered_set<std::string> synchronousProps = {
659
+ "opacity",
660
+ "elevation",
661
+ "zIndex",
662
+ // "shadowOpacity", // not supported on Android
663
+ // "shadowRadius", // not supported on Android
664
+ "backgroundColor",
665
+ // "color", // TODO: fix animating color of Animated.Text
666
+ "tintColor",
667
+ "borderRadius",
668
+ "borderTopLeftRadius",
669
+ "borderTopRightRadius",
670
+ "borderTopStartRadius",
671
+ "borderTopEndRadius",
672
+ "borderBottomLeftRadius",
673
+ "borderBottomRightRadius",
674
+ "borderBottomStartRadius",
675
+ "borderBottomEndRadius",
676
+ "borderStartStartRadius",
677
+ "borderStartEndRadius",
678
+ "borderEndStartRadius",
679
+ "borderEndEndRadius",
680
+ "borderColor",
681
+ "borderTopColor",
682
+ "borderBottomColor",
683
+ "borderLeftColor",
684
+ "borderRightColor",
685
+ "borderStartColor",
686
+ "borderEndColor",
687
+ "transform",
688
+ };
689
+
690
+ // NOTE: Keep in sync with NativeProxy.java
691
+ static constexpr auto CMD_START_OF_VIEW = 1;
692
+ static constexpr auto CMD_START_OF_TRANSFORM = 2;
693
+ static constexpr auto CMD_END_OF_TRANSFORM = 3;
694
+ static constexpr auto CMD_END_OF_VIEW = 4;
695
+
696
+ static constexpr auto CMD_OPACITY = 10;
697
+ static constexpr auto CMD_ELEVATION = 11;
698
+ static constexpr auto CMD_Z_INDEX = 12;
699
+ static constexpr auto CMD_SHADOW_OPACITY = 13;
700
+ static constexpr auto CMD_SHADOW_RADIUS = 14;
701
+ static constexpr auto CMD_BACKGROUND_COLOR = 15;
702
+ static constexpr auto CMD_COLOR = 16;
703
+ static constexpr auto CMD_TINT_COLOR = 17;
704
+
705
+ static constexpr auto CMD_BORDER_RADIUS = 20;
706
+ static constexpr auto CMD_BORDER_TOP_LEFT_RADIUS = 21;
707
+ static constexpr auto CMD_BORDER_TOP_RIGHT_RADIUS = 22;
708
+ static constexpr auto CMD_BORDER_TOP_START_RADIUS = 23;
709
+ static constexpr auto CMD_BORDER_TOP_END_RADIUS = 24;
710
+ static constexpr auto CMD_BORDER_BOTTOM_LEFT_RADIUS = 25;
711
+ static constexpr auto CMD_BORDER_BOTTOM_RIGHT_RADIUS = 26;
712
+ static constexpr auto CMD_BORDER_BOTTOM_START_RADIUS = 27;
713
+ static constexpr auto CMD_BORDER_BOTTOM_END_RADIUS = 28;
714
+ static constexpr auto CMD_BORDER_START_START_RADIUS = 29;
715
+ static constexpr auto CMD_BORDER_START_END_RADIUS = 30;
716
+ static constexpr auto CMD_BORDER_END_START_RADIUS = 31;
717
+ static constexpr auto CMD_BORDER_END_END_RADIUS = 32;
718
+
719
+ static constexpr auto CMD_BORDER_COLOR = 40;
720
+ static constexpr auto CMD_BORDER_TOP_COLOR = 41;
721
+ static constexpr auto CMD_BORDER_BOTTOM_COLOR = 42;
722
+ static constexpr auto CMD_BORDER_LEFT_COLOR = 43;
723
+ static constexpr auto CMD_BORDER_RIGHT_COLOR = 44;
724
+ static constexpr auto CMD_BORDER_START_COLOR = 45;
725
+ static constexpr auto CMD_BORDER_END_COLOR = 46;
726
+
727
+ static constexpr auto CMD_TRANSFORM_TRANSLATE_X = 100;
728
+ static constexpr auto CMD_TRANSFORM_TRANSLATE_Y = 101;
729
+ static constexpr auto CMD_TRANSFORM_SCALE = 102;
730
+ static constexpr auto CMD_TRANSFORM_SCALE_X = 103;
731
+ static constexpr auto CMD_TRANSFORM_SCALE_Y = 104;
732
+ static constexpr auto CMD_TRANSFORM_ROTATE = 105;
733
+ static constexpr auto CMD_TRANSFORM_ROTATE_X = 106;
734
+ static constexpr auto CMD_TRANSFORM_ROTATE_Y = 107;
735
+ static constexpr auto CMD_TRANSFORM_ROTATE_Z = 108;
736
+ static constexpr auto CMD_TRANSFORM_SKEW_X = 109;
737
+ static constexpr auto CMD_TRANSFORM_SKEW_Y = 110;
738
+ static constexpr auto CMD_TRANSFORM_MATRIX = 111;
739
+ static constexpr auto CMD_TRANSFORM_PERSPECTIVE = 112;
740
+
741
+ static constexpr auto CMD_UNIT_DEG = 200;
742
+ static constexpr auto CMD_UNIT_RAD = 201;
743
+ static constexpr auto CMD_UNIT_PX = 202;
744
+ static constexpr auto CMD_UNIT_PERCENT = 203;
745
+
746
+ const auto propNameToCommand = [](const std::string &name) {
747
+ if (name == "opacity")
748
+ return CMD_OPACITY;
749
+
750
+ if (name == "elevation")
751
+ return CMD_ELEVATION;
752
+
753
+ if (name == "zIndex")
754
+ return CMD_Z_INDEX;
755
+
756
+ if (name == "shadowOpacity")
757
+ return CMD_SHADOW_OPACITY;
758
+
759
+ if (name == "shadowRadius")
760
+ return CMD_SHADOW_RADIUS;
761
+
762
+ if (name == "backgroundColor")
763
+ return CMD_BACKGROUND_COLOR;
764
+
765
+ if (name == "color")
766
+ return CMD_COLOR;
767
+
768
+ if (name == "tintColor")
769
+ return CMD_TINT_COLOR;
770
+
771
+ if (name == "borderRadius")
772
+ return CMD_BORDER_RADIUS;
773
+
774
+ if (name == "borderTopLeftRadius")
775
+ return CMD_BORDER_TOP_LEFT_RADIUS;
776
+
777
+ if (name == "borderTopRightRadius")
778
+ return CMD_BORDER_TOP_RIGHT_RADIUS;
779
+
780
+ if (name == "borderTopStartRadius")
781
+ return CMD_BORDER_TOP_START_RADIUS;
782
+
783
+ if (name == "borderTopEndRadius")
784
+ return CMD_BORDER_TOP_END_RADIUS;
785
+
786
+ if (name == "borderBottomLeftRadius")
787
+ return CMD_BORDER_BOTTOM_LEFT_RADIUS;
788
+
789
+ if (name == "borderBottomRightRadius")
790
+ return CMD_BORDER_BOTTOM_RIGHT_RADIUS;
791
+
792
+ if (name == "borderBottomStartRadius")
793
+ return CMD_BORDER_BOTTOM_START_RADIUS;
794
+
795
+ if (name == "borderBottomEndRadius")
796
+ return CMD_BORDER_BOTTOM_END_RADIUS;
797
+
798
+ if (name == "borderStartStartRadius")
799
+ return CMD_BORDER_START_START_RADIUS;
800
+
801
+ if (name == "borderStartEndRadius")
802
+ return CMD_BORDER_START_END_RADIUS;
803
+
804
+ if (name == "borderEndStartRadius")
805
+ return CMD_BORDER_END_START_RADIUS;
806
+
807
+ if (name == "borderEndEndRadius")
808
+ return CMD_BORDER_END_END_RADIUS;
809
+
810
+ if (name == "borderColor")
811
+ return CMD_BORDER_COLOR;
812
+
813
+ if (name == "borderTopColor")
814
+ return CMD_BORDER_TOP_COLOR;
815
+
816
+ if (name == "borderBottomColor")
817
+ return CMD_BORDER_BOTTOM_COLOR;
818
+
819
+ if (name == "borderLeftColor")
820
+ return CMD_BORDER_LEFT_COLOR;
821
+
822
+ if (name == "borderRightColor")
823
+ return CMD_BORDER_RIGHT_COLOR;
824
+
825
+ if (name == "borderStartColor")
826
+ return CMD_BORDER_START_COLOR;
827
+
828
+ if (name == "borderEndColor")
829
+ return CMD_BORDER_END_COLOR;
830
+
831
+ if (name == "transform")
832
+ return CMD_START_OF_TRANSFORM; // TODO: use CMD_TRANSFORM?
833
+
834
+ throw std::runtime_error("[Reanimated] Unsupported style: " + name);
835
+ };
836
+
837
+ const auto transformNameToCommand = [](const std::string &name) {
838
+ if (name == "translateX")
839
+ return CMD_TRANSFORM_TRANSLATE_X;
840
+
841
+ if (name == "translateY")
842
+ return CMD_TRANSFORM_TRANSLATE_Y;
843
+
844
+ if (name == "scale")
845
+ return CMD_TRANSFORM_SCALE;
846
+
847
+ if (name == "scaleX")
848
+ return CMD_TRANSFORM_SCALE_X;
849
+
850
+ if (name == "scaleY")
851
+ return CMD_TRANSFORM_SCALE_Y;
852
+
853
+ if (name == "rotate")
854
+ return CMD_TRANSFORM_ROTATE;
855
+
856
+ if (name == "rotateX")
857
+ return CMD_TRANSFORM_ROTATE_X;
858
+
859
+ if (name == "rotateY")
860
+ return CMD_TRANSFORM_ROTATE_Y;
861
+
862
+ if (name == "rotateZ")
863
+ return CMD_TRANSFORM_ROTATE_Z;
864
+
865
+ if (name == "skewX")
866
+ return CMD_TRANSFORM_SKEW_X;
867
+
868
+ if (name == "skewY")
869
+ return CMD_TRANSFORM_SKEW_Y;
870
+
871
+ if (name == "matrix")
872
+ return CMD_TRANSFORM_MATRIX;
873
+
874
+ if (name == "perspective")
875
+ return CMD_TRANSFORM_PERSPECTIVE;
876
+
877
+ throw std::runtime_error("[Reanimated] Unsupported transform: " + name);
878
+ };
879
+
880
+ UpdatesBatch synchronousUpdatesBatch, shadowTreeUpdatesBatch;
881
+
882
+ for (const auto &[shadowNode, props] : updatesBatch) {
883
+ bool hasOnlySynchronousProps = true;
884
+ for (const auto &[key, value] : props.items()) {
885
+ const auto keyStr = key.asString();
886
+ if (!synchronousProps.contains(keyStr) ||
887
+ ((keyStr == "color" || keyStr.find("Color") != std::string::npos) && !value.isInt())) {
888
+ hasOnlySynchronousProps = false;
889
+ break;
890
+ }
891
+ }
892
+ if (hasOnlySynchronousProps) {
893
+ synchronousUpdatesBatch.emplace_back(shadowNode, props);
894
+ } else {
895
+ shadowTreeUpdatesBatch.emplace_back(shadowNode, props);
896
+ }
897
+ }
898
+
899
+ if (!synchronousUpdatesBatch.empty()) {
900
+ std::vector<int> intBuffer;
901
+ std::vector<double> doubleBuffer;
902
+ intBuffer.reserve(1024);
903
+ doubleBuffer.reserve(1024);
904
+
905
+ for (const auto &[shadowNode, props] : synchronousUpdatesBatch) {
906
+ intBuffer.push_back(CMD_START_OF_VIEW);
907
+ intBuffer.push_back(shadowNode->getTag());
908
+ for (const auto &[key, value] : props.items()) {
909
+ const auto command = propNameToCommand(key.getString());
910
+ switch (command) {
911
+ case CMD_OPACITY:
912
+ case CMD_ELEVATION:
913
+ case CMD_Z_INDEX:
914
+ case CMD_SHADOW_OPACITY:
915
+ case CMD_SHADOW_RADIUS:
916
+ intBuffer.push_back(command);
917
+ doubleBuffer.push_back(value.asDouble());
918
+ break;
919
+
920
+ case CMD_BACKGROUND_COLOR:
921
+ case CMD_COLOR:
922
+ case CMD_TINT_COLOR:
923
+ case CMD_BORDER_COLOR:
924
+ case CMD_BORDER_TOP_COLOR:
925
+ case CMD_BORDER_BOTTOM_COLOR:
926
+ case CMD_BORDER_LEFT_COLOR:
927
+ case CMD_BORDER_RIGHT_COLOR:
928
+ case CMD_BORDER_START_COLOR:
929
+ case CMD_BORDER_END_COLOR:
930
+ intBuffer.push_back(command);
931
+ intBuffer.push_back(value.asInt());
932
+ break;
933
+
934
+ case CMD_BORDER_RADIUS:
935
+ case CMD_BORDER_TOP_LEFT_RADIUS:
936
+ case CMD_BORDER_TOP_RIGHT_RADIUS:
937
+ case CMD_BORDER_TOP_START_RADIUS:
938
+ case CMD_BORDER_TOP_END_RADIUS:
939
+ case CMD_BORDER_BOTTOM_LEFT_RADIUS:
940
+ case CMD_BORDER_BOTTOM_RIGHT_RADIUS:
941
+ case CMD_BORDER_BOTTOM_START_RADIUS:
942
+ case CMD_BORDER_BOTTOM_END_RADIUS:
943
+ case CMD_BORDER_START_START_RADIUS:
944
+ case CMD_BORDER_START_END_RADIUS:
945
+ case CMD_BORDER_END_START_RADIUS:
946
+ case CMD_BORDER_END_END_RADIUS:
947
+ intBuffer.push_back(command);
948
+ if (value.isDouble()) {
949
+ intBuffer.push_back(CMD_UNIT_PX);
950
+ doubleBuffer.push_back(value.getDouble());
951
+ } else if (value.isString()) {
952
+ const auto &valueStr = value.getString();
953
+ if (!valueStr.ends_with("%")) {
954
+ throw std::runtime_error("[Reanimated] Border radius string must be a percentage");
955
+ }
956
+ intBuffer.push_back(CMD_UNIT_PERCENT);
957
+ doubleBuffer.push_back(std::stof(valueStr.substr(0, -1)));
958
+ } else {
959
+ throw std::runtime_error("[Reanimated] Border radius value must be either a number or a string");
960
+ }
961
+ break;
962
+
963
+ case CMD_START_OF_TRANSFORM:
964
+ intBuffer.push_back(command);
965
+ react_native_assert(value.isArray() && "[Reanimated] Transform value must be an array");
966
+ for (const auto &item : value) {
967
+ react_native_assert(item.isObject() && "[Reanimated] Transform array item must be an object");
968
+ react_native_assert(
969
+ item.size() == 1 && "[Reanimated] Transform array item must have exactly one key-value pair");
970
+ const auto transformCommand = transformNameToCommand(item.keys().begin()->getString());
971
+ const auto &transformValue = *item.values().begin();
972
+ switch (transformCommand) {
973
+ case CMD_TRANSFORM_SCALE:
974
+ case CMD_TRANSFORM_SCALE_X:
975
+ case CMD_TRANSFORM_SCALE_Y:
976
+ case CMD_TRANSFORM_PERSPECTIVE: {
977
+ intBuffer.push_back(transformCommand);
978
+ doubleBuffer.push_back(transformValue.asDouble());
979
+ break;
980
+ }
981
+
982
+ case CMD_TRANSFORM_TRANSLATE_X:
983
+ case CMD_TRANSFORM_TRANSLATE_Y: {
984
+ intBuffer.push_back(transformCommand);
985
+ if (transformValue.isDouble()) {
986
+ intBuffer.push_back(CMD_UNIT_PX);
987
+ doubleBuffer.push_back(transformValue.getDouble());
988
+ } else if (transformValue.isString()) {
989
+ const auto &transformValueStr = transformValue.getString();
990
+ if (!transformValueStr.ends_with("%")) {
991
+ throw std::runtime_error("[Reanimated] String translate must be a percentage");
992
+ }
993
+ intBuffer.push_back(CMD_UNIT_PERCENT);
994
+ doubleBuffer.push_back(std::stof(transformValueStr.substr(0, -1)));
995
+ } else {
996
+ throw std::runtime_error("[Reanimated] Translate value must be either a number or a string");
997
+ }
998
+ break;
999
+ }
1000
+
1001
+ case CMD_TRANSFORM_ROTATE:
1002
+ case CMD_TRANSFORM_ROTATE_X:
1003
+ case CMD_TRANSFORM_ROTATE_Y:
1004
+ case CMD_TRANSFORM_ROTATE_Z:
1005
+ case CMD_TRANSFORM_SKEW_X:
1006
+ case CMD_TRANSFORM_SKEW_Y: {
1007
+ const auto &transformValueStr = transformValue.getString();
1008
+ intBuffer.push_back(transformCommand);
1009
+ if (transformValueStr.ends_with("deg")) {
1010
+ intBuffer.push_back(CMD_UNIT_DEG);
1011
+ } else if (transformValueStr.ends_with("rad")) {
1012
+ intBuffer.push_back(CMD_UNIT_RAD);
1013
+ } else {
1014
+ throw std::runtime_error("[Reanimated] Unsupported rotation unit: " + transformValueStr);
1015
+ }
1016
+ doubleBuffer.push_back(std::stof(transformValueStr.substr(0, -3)));
1017
+ break;
1018
+ }
1019
+
1020
+ case CMD_TRANSFORM_MATRIX: {
1021
+ intBuffer.push_back(transformCommand);
1022
+ react_native_assert(transformValue.isArray() && "[Reanimated] Matrix must be an array");
1023
+ int size = transformValue.size();
1024
+ intBuffer.push_back(size);
1025
+ for (int i = 0; i < size; i++) {
1026
+ doubleBuffer.push_back(transformValue[i].asDouble());
1027
+ }
1028
+ break;
1029
+ }
1030
+ }
1031
+ }
1032
+ intBuffer.push_back(CMD_END_OF_TRANSFORM);
1033
+ break;
1034
+ }
1035
+ }
1036
+ intBuffer.push_back(CMD_END_OF_VIEW);
1037
+ }
1038
+ synchronouslyUpdateUIPropsFunction_(intBuffer, doubleBuffer);
1039
+ }
1040
+
1041
+ updatesBatch = std::move(shadowTreeUpdatesBatch);
1042
+ }
1043
+ #endif // ANDROID
1044
+
1045
+ #if __APPLE__
1046
+ if constexpr (
1047
+ StaticFeatureFlags::getFlag("IOS_SYNCHRONOUSLY_UPDATE_UI_PROPS") &&
1048
+ !StaticFeatureFlags::getFlag("ENABLE_SHARED_ELEMENT_TRANSITIONS")) {
1049
+ static const std::unordered_set<std::string> synchronousProps = {
1050
+ "opacity",
1051
+ "elevation",
1052
+ "zIndex",
1053
+ "shadowOpacity",
1054
+ "shadowRadius",
1055
+ "backgroundColor",
1056
+ // "color", // TODO: fix animating color of Animated.Text
1057
+ "tintColor",
1058
+ "borderRadius",
1059
+ "borderTopLeftRadius",
1060
+ "borderTopRightRadius",
1061
+ "borderTopStartRadius",
1062
+ "borderTopEndRadius",
1063
+ "borderBottomLeftRadius",
1064
+ "borderBottomRightRadius",
1065
+ "borderBottomStartRadius",
1066
+ "borderBottomEndRadius",
1067
+ "borderStartStartRadius",
1068
+ "borderStartEndRadius",
1069
+ "borderEndStartRadius",
1070
+ "borderEndEndRadius",
1071
+ "borderColor",
1072
+ "borderTopColor",
1073
+ "borderBottomColor",
1074
+ "borderLeftColor",
1075
+ "borderRightColor",
1076
+ "borderStartColor",
1077
+ "borderEndColor",
1078
+ "transform",
1079
+ };
1080
+
1081
+ UpdatesBatch synchronousUpdatesBatch, shadowTreeUpdatesBatch;
1082
+
1083
+ for (const auto &[shadowNode, props] : updatesBatch) {
1084
+ bool hasOnlySynchronousProps = true;
1085
+ for (const auto &key : props.keys()) {
1086
+ const auto keyStr = key.asString();
1087
+ if (!synchronousProps.contains(keyStr)) {
1088
+ hasOnlySynchronousProps = false;
1089
+ break;
1090
+ }
1091
+ }
1092
+ if (hasOnlySynchronousProps) {
1093
+ synchronousUpdatesBatch.emplace_back(shadowNode, props);
1094
+ } else {
1095
+ shadowTreeUpdatesBatch.emplace_back(shadowNode, props);
1096
+ }
1097
+ }
1098
+
1099
+ for (const auto &[shadowNode, props] : synchronousUpdatesBatch) {
1100
+ synchronouslyUpdateUIPropsFunction_(shadowNode->getTag(), props);
1101
+ }
1102
+
1103
+ updatesBatch = std::move(shadowTreeUpdatesBatch);
1104
+ }
1105
+ #endif // __APPLE__
1106
+
1107
+ if ((updatesBatch.size() > 0) && updatesRegistryManager_->shouldReanimatedSkipCommit()) {
1108
+ updatesRegistryManager_->pleaseCommitAfterPause();
1109
+ }
1110
+ }
1111
+
1112
+ if (updatesRegistryManager_->shouldReanimatedSkipCommit()) {
1113
+ // It may happen that `performOperations` is called on the UI thread
1114
+ // while React Native tries to commit a new tree on the JS thread.
1115
+ // In this case, we should skip the commit here and let React Native do
1116
+ // it. The commit will include the current values from the updates manager
1117
+ // which will be applied in ReanimatedCommitHook.
1118
+ return;
1119
+ }
1120
+
1121
+ commitUpdates(rt, updatesBatch);
1122
+
1123
+ // Clear the entire cache after the commit
1124
+ // (we don't know if the view is updated from outside of Reanimated
1125
+ // so we have to clear the entire cache)
1126
+ viewStylesRepository_->clearNodesCache();
1127
+ }
1128
+
1129
+ void ReanimatedModuleProxy::requestFlushRegistry() {
1130
+ requestRender_([weakThis = weak_from_this()](const double timestamp) {
1131
+ if (auto strongThis = weakThis.lock()) {
1132
+ strongThis->shouldFlushRegistry_ = true;
1133
+ }
1134
+ });
1135
+ }
1136
+
1137
+ void ReanimatedModuleProxy::commitUpdates(jsi::Runtime &rt, const UpdatesBatch &updatesBatch) {
1138
+ ReanimatedSystraceSection s("ReanimatedModuleProxy::commitUpdates");
1139
+ react_native_assert(uiManager_ != nullptr);
1140
+ const auto &shadowTreeRegistry = uiManager_->getShadowTreeRegistry();
1141
+
1142
+ std::unordered_map<SurfaceId, PropsMap> propsMapBySurface;
1143
+
1144
+ #ifdef ANDROID
1145
+ updatesRegistryManager_->collectPropsToRevertBySurface(propsMapBySurface);
1146
+ #endif
1147
+
1148
+ if (shouldFlushRegistry_) {
1149
+ shouldFlushRegistry_ = false;
1150
+ const auto propsMap = updatesRegistryManager_->collectProps();
1151
+ for (auto const &[family, props] : propsMap) {
1152
+ const auto surfaceId = family->getSurfaceId();
1153
+ auto &propsVector = propsMapBySurface[surfaceId][family];
1154
+ for (const auto &prop : props) {
1155
+ propsVector.emplace_back(prop);
1156
+ }
1157
+ }
1158
+ } else {
1159
+ for (auto const &[shadowNode, props] : updatesBatch) {
1160
+ SurfaceId surfaceId = shadowNode->getSurfaceId();
1161
+ auto family = &shadowNode->getFamily();
1162
+ react_native_assert(family->getSurfaceId() == surfaceId);
1163
+ propsMapBySurface[surfaceId][family].emplace_back(props);
1164
+ }
1165
+ }
1166
+
1167
+ for (const auto &entry : propsMapBySurface) {
1168
+ const SurfaceId surfaceId = entry.first;
1169
+ const PropsMap &propsMap = entry.second;
1170
+ shadowTreeRegistry.visit(surfaceId, [&](ShadowTree const &shadowTree) {
1171
+ const auto status = shadowTree.commit(
1172
+ [&](RootShadowNode const &oldRootShadowNode) -> RootShadowNode::Unshared {
1173
+ if (updatesRegistryManager_->shouldReanimatedSkipCommit()) {
1174
+ return nullptr;
1175
+ }
1176
+
1177
+ auto rootNode = cloneShadowTreeWithNewProps(oldRootShadowNode, propsMap);
1178
+
1179
+ // Mark the commit as Reanimated commit so that we can distinguish
1180
+ // it in ReanimatedCommitHook.
1181
+
1182
+ auto reaShadowNode = std::reinterpret_pointer_cast<ReanimatedCommitShadowNode>(rootNode);
1183
+ reaShadowNode->setReanimatedCommitTrait();
1184
+
1185
+ return rootNode;
1186
+ },
1187
+ {/* .enableStateReconciliation = */
1188
+ false,
1189
+ /* .mountSynchronously = */ true});
1190
+
1191
+ #ifdef ANDROID
1192
+ if (status == ShadowTree::CommitStatus::Succeeded) {
1193
+ updatesRegistryManager_->clearPropsToRevert(surfaceId);
1194
+ }
1195
+ #else
1196
+ (void)status;
1197
+ #endif
1198
+ });
1199
+ }
1200
+ }
1201
+
1202
+ void ReanimatedModuleProxy::dispatchCommand(
1203
+ jsi::Runtime &rt,
1204
+ const jsi::Value &shadowNodeValue,
1205
+ const jsi::Value &commandNameValue,
1206
+ const jsi::Value &argsValue) {
1207
+ const auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
1208
+ std::string commandName = stringFromValue(rt, commandNameValue);
1209
+ folly::dynamic args = commandArgsFromValue(rt, argsValue);
1210
+ const auto &scheduler = static_cast<Scheduler *>(uiManager_->getDelegate());
1211
+
1212
+ if (!scheduler) {
1213
+ return;
1214
+ }
1215
+
1216
+ const auto &schedulerDelegate = scheduler->getDelegate();
1217
+
1218
+ if (schedulerDelegate) {
1219
+ const auto shadowView = ShadowView(*shadowNode);
1220
+ schedulerDelegate->schedulerDidDispatchCommand(shadowView, commandName, args);
1221
+ }
1222
+ }
1223
+
1224
+ jsi::String
1225
+ ReanimatedModuleProxy::obtainProp(jsi::Runtime &rt, const jsi::Value &shadowNodeWrapper, const jsi::Value &propName) {
1226
+ jsi::Runtime &uiRuntime = workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime();
1227
+ const auto propNameStr = propName.asString(rt).utf8(rt);
1228
+ const auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
1229
+ const auto resultStr = obtainPropFromShadowNode(uiRuntime, propNameStr, shadowNode);
1230
+ return jsi::String::createFromUtf8(rt, resultStr);
1231
+ }
1232
+
1233
+ jsi::Value ReanimatedModuleProxy::measure(jsi::Runtime &rt, const jsi::Value &shadowNodeValue) {
1234
+ // based on implementation from UIManagerBinding.cpp
1235
+
1236
+ auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
1237
+ auto layoutMetrics = uiManager_->getRelativeLayoutMetrics(*shadowNode, nullptr, {/* .includeTransform = */ true});
1238
+
1239
+ if (layoutMetrics == EmptyLayoutMetrics) {
1240
+ // Originally, in this case React Native returns `{0, 0, 0, 0, 0, 0}`,
1241
+ // most likely due to the type of measure callback function which accepts
1242
+ // just an array of numbers (not null). In Reanimated, `measure` returns
1243
+ // `MeasuredDimensions | null`.
1244
+ return jsi::Value::null();
1245
+ }
1246
+ auto newestCloneOfShadowNode = uiManager_->getNewestCloneOfShadowNode(*shadowNode);
1247
+
1248
+ auto layoutableShadowNode = dynamic_cast<LayoutableShadowNode const *>(newestCloneOfShadowNode.get());
1249
+ facebook::react::Point originRelativeToParent = layoutableShadowNode != nullptr
1250
+ ? layoutableShadowNode->getLayoutMetrics().frame.origin
1251
+ : facebook::react::Point();
1252
+
1253
+ auto frame = layoutMetrics.frame;
1254
+
1255
+ jsi::Object result(rt);
1256
+ result.setProperty(rt, "x", jsi::Value(static_cast<double>(originRelativeToParent.x)));
1257
+ result.setProperty(rt, "y", jsi::Value(static_cast<double>(originRelativeToParent.y)));
1258
+ result.setProperty(rt, "width", jsi::Value(static_cast<double>(frame.size.width)));
1259
+ result.setProperty(rt, "height", jsi::Value(static_cast<double>(frame.size.height)));
1260
+ result.setProperty(rt, "pageX", jsi::Value(static_cast<double>(frame.origin.x)));
1261
+ result.setProperty(rt, "pageY", jsi::Value(static_cast<double>(frame.origin.y)));
1262
+ return result;
1263
+ }
1264
+
1265
+ void ReanimatedModuleProxy::initializeFabric(const std::shared_ptr<UIManager> &uiManager) {
1266
+ uiManager_ = uiManager;
1267
+ viewStylesRepository_->setUIManager(uiManager_);
1268
+
1269
+ initializeLayoutAnimationsProxy();
1270
+
1271
+ const std::function<void()> request = [weakThis = weak_from_this()]() {
1272
+ auto strongThis = weakThis.lock();
1273
+ if (!strongThis) {
1274
+ return;
1275
+ }
1276
+
1277
+ strongThis->requestFlushRegistry();
1278
+ };
1279
+ mountHook_ = std::make_shared<ReanimatedMountHook>(uiManager_, updatesRegistryManager_, request);
1280
+ commitHook_ = std::make_shared<ReanimatedCommitHook>(uiManager_, updatesRegistryManager_, layoutAnimationsProxy_);
1281
+ }
1282
+
1283
+ void ReanimatedModuleProxy::initializeLayoutAnimationsProxy() {
1284
+ auto scheduler = reinterpret_cast<Scheduler *>(uiManager_->getDelegate());
1285
+ auto componentDescriptorRegistry =
1286
+ scheduler->getContextContainer()
1287
+ ->at<std::weak_ptr<const ComponentDescriptorRegistry>>("ComponentDescriptorRegistry_DO_NOT_USE_PRETTY_PLEASE")
1288
+ .lock();
1289
+
1290
+ if (componentDescriptorRegistry) {
1291
+ if constexpr (StaticFeatureFlags::getFlag("ENABLE_SHARED_ELEMENT_TRANSITIONS")) {
1292
+ auto layoutAnimationsProxyExperimental = std::make_shared<LayoutAnimationsProxy_Experimental>(
1293
+ layoutAnimationsManager_,
1294
+ componentDescriptorRegistry,
1295
+ scheduler->getContextContainer(),
1296
+ workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime(),
1297
+ workletsModuleProxy_->getUIScheduler()
1298
+ #ifdef ANDROID
1299
+ ,
1300
+ filterUnmountedTagsFunction_,
1301
+ uiManager_,
1302
+ jsInvoker_
1303
+ #endif
1304
+ );
1305
+ #ifdef __APPLE__
1306
+ layoutAnimationsProxyExperimental->setForceScreenSnapshotFunction(forceScreenSnapshot_);
1307
+ #endif
1308
+ layoutAnimationsProxy_ = std::move(layoutAnimationsProxyExperimental);
1309
+ } else {
1310
+ auto layoutAnimationsProxyLegacy = std::make_shared<LayoutAnimationsProxy_Legacy>(
1311
+ layoutAnimationsManager_,
1312
+ componentDescriptorRegistry,
1313
+ scheduler->getContextContainer(),
1314
+ workletsModuleProxy_->getUIWorkletRuntime()->getJSIRuntime(),
1315
+ workletsModuleProxy_->getUIScheduler()
1316
+ #ifdef ANDROID
1317
+ ,
1318
+ filterUnmountedTagsFunction_,
1319
+ uiManager_,
1320
+ jsInvoker_
1321
+ #endif
1322
+ );
1323
+ // TODO (future): support in experimental
1324
+ uiManager_->setAnimationDelegate(layoutAnimationsProxyLegacy.get());
1325
+ layoutAnimationsProxy_ = std::move(layoutAnimationsProxyLegacy);
1326
+ }
1327
+ }
1328
+ }
1329
+
1330
+ #ifdef IS_REANIMATED_EXAMPLE_APP
1331
+
1332
+ std::string format(bool b) {
1333
+ return b ? "✅" : "❌";
1334
+ }
1335
+
1336
+ std::function<std::string()> ReanimatedModuleProxy::createRegistriesLeakCheck() {
1337
+ return [weakThis = weak_from_this()]() {
1338
+ auto strongThis = weakThis.lock();
1339
+ if (!strongThis) {
1340
+ return std::string("");
1341
+ }
1342
+
1343
+ std::string result = "";
1344
+
1345
+ result += "AnimatedPropsRegistry: " + format(strongThis->animatedPropsRegistry_->isEmpty());
1346
+ result += "\nCSSAnimationsRegistry: " + format(strongThis->cssAnimationsRegistry_->isEmpty());
1347
+ result += "\nCSSTransitionsRegistry: " + format(strongThis->cssTransitionsRegistry_->isEmpty());
1348
+ result += "\nStaticPropsRegistry: " + format(strongThis->staticPropsRegistry_->isEmpty()) + "\n";
1349
+
1350
+ return result;
1351
+ };
1352
+ }
1353
+
1354
+ #endif // IS_REANIMATED_EXAMPLE_APP
1355
+
1356
+ jsi::Value ReanimatedModuleProxy::subscribeForKeyboardEvents(
1357
+ jsi::Runtime &rt,
1358
+ const jsi::Value &handlerWorklet,
1359
+ const jsi::Value &isStatusBarTranslucent,
1360
+ const jsi::Value &isNavigationBarTranslucent) {
1361
+ auto serializableHandler = extractSerializableOrThrow<SerializableWorklet>(
1362
+ rt, handlerWorklet, "[Reanimated] Keyboard event handler must be a worklet.");
1363
+ return subscribeForKeyboardEventsFunction_(
1364
+ [=, weakThis = weak_from_this()](int keyboardState, int height) {
1365
+ auto strongThis = weakThis.lock();
1366
+ if (!strongThis) {
1367
+ return;
1368
+ }
1369
+ strongThis->workletsModuleProxy_->getUIWorkletRuntime()->runSync(
1370
+ serializableHandler, jsi::Value(keyboardState), jsi::Value(height));
1371
+ },
1372
+ isStatusBarTranslucent.getBool(),
1373
+ isNavigationBarTranslucent.getBool());
1374
+ }
1375
+
1376
+ void ReanimatedModuleProxy::unsubscribeFromKeyboardEvents(jsi::Runtime &, const jsi::Value &listenerId) {
1377
+ unsubscribeFromKeyboardEventsFunction_(listenerId.asNumber());
1378
+ }
1379
+
1380
+ } // namespace reanimated