react-native 0.0.0-17be3a003 → 0.0.0-18697adec

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 (993) hide show
  1. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +14 -1
  2. package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +2 -0
  3. package/Libraries/Animated/AnimatedEvent.js +23 -4
  4. package/Libraries/Animated/AnimatedImplementation.js +0 -2
  5. package/Libraries/Animated/AnimatedMock.js +1 -8
  6. package/Libraries/Animated/NativeAnimatedHelper.js +3 -3
  7. package/Libraries/Animated/animations/Animation.js +1 -0
  8. package/Libraries/Animated/animations/DecayAnimation.js +2 -0
  9. package/Libraries/Animated/animations/SpringAnimation.js +1 -0
  10. package/Libraries/Animated/animations/TimingAnimation.js +3 -0
  11. package/Libraries/Animated/createAnimatedComponent.js +6 -18
  12. package/Libraries/Animated/createAnimatedComponentInjection.js +48 -0
  13. package/Libraries/Animated/createAnimatedComponent_EXPERIMENTAL.js +48 -0
  14. package/Libraries/Animated/nodes/AnimatedProps.js +0 -1
  15. package/Libraries/Animated/nodes/AnimatedValue.js +20 -1
  16. package/Libraries/Animated/nodes/AnimatedWithChildren.js +1 -0
  17. package/Libraries/Animated/useAnimatedProps.js +211 -0
  18. package/Libraries/BatchedBridge/MessageQueue.js +15 -10
  19. package/Libraries/BatchedBridge/NativeModules.js +5 -1
  20. package/Libraries/Blob/FileReader.js +1 -1
  21. package/Libraries/Blob/RCTBlobManager.h +2 -1
  22. package/Libraries/Blob/RCTBlobManager.mm +1 -3
  23. package/Libraries/Blob/RCTBlobPlugins.mm +4 -3
  24. package/Libraries/Blob/React-RCTBlob.podspec +1 -1
  25. package/Libraries/Blob/URL.js +2 -2
  26. package/Libraries/BugReporting/BugReporting.js +2 -0
  27. package/Libraries/BugReporting/getReactData.js +1 -1
  28. package/Libraries/Components/ActivityIndicator/ActivityIndicator.js +4 -6
  29. package/Libraries/Components/Button.js +27 -12
  30. package/Libraries/Components/DatePicker/DatePickerIOS.android.js +4 -5
  31. package/Libraries/Components/DatePicker/DatePickerIOS.ios.js +50 -12
  32. package/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js +1 -0
  33. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +4 -7
  34. package/Libraries/Components/Keyboard/Keyboard.js +1 -1
  35. package/Libraries/Components/Keyboard/KeyboardAvoidingView.js +1 -1
  36. package/Libraries/Components/MaskedView/MaskedViewIOS.ios.js +3 -3
  37. package/Libraries/Components/Pressable/useAndroidRippleForView.js +18 -15
  38. package/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js +4 -5
  39. package/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js +2 -3
  40. package/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +2 -3
  41. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +2 -2
  42. package/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js +2 -2
  43. package/Libraries/Components/ScrollView/ScrollView.js +22 -5
  44. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +3 -2
  45. package/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js +2 -0
  46. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +3 -9
  47. package/Libraries/Components/ScrollView/ScrollViewViewConfig.js +2 -0
  48. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +4 -5
  49. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +14 -6
  50. package/Libraries/Components/Slider/Slider.js +19 -6
  51. package/Libraries/Components/StatusBar/StatusBar.js +10 -19
  52. package/Libraries/Components/Switch/Switch.js +98 -114
  53. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +9 -6
  54. package/Libraries/Components/TextInput/AndroidTextInputViewConfig.js +2 -1
  55. package/Libraries/Components/TextInput/InputAccessoryView.js +6 -6
  56. package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +5 -13
  57. package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +5 -13
  58. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +2 -2
  59. package/Libraries/Components/TextInput/TextInput.js +53 -19
  60. package/Libraries/Components/TextInput/TextInputState.js +1 -1
  61. package/Libraries/Components/Touchable/BoundingDimensions.js +1 -2
  62. package/Libraries/Components/Touchable/PooledClass.js +1 -2
  63. package/Libraries/Components/Touchable/Position.js +1 -2
  64. package/Libraries/Components/Touchable/Touchable.js +20 -6
  65. package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -1
  66. package/Libraries/Components/Touchable/TouchableOpacity.js +11 -2
  67. package/Libraries/Components/UnimplementedViews/UnimplementedView.js +2 -3
  68. package/Libraries/Components/View/ReactNativeStyleAttributes.js +133 -68
  69. package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -2
  70. package/Libraries/Components/View/ReactNativeViewViewConfig.js +1 -1
  71. package/Libraries/Components/View/ViewAccessibility.js +3 -0
  72. package/Libraries/Core/Devtools/parseErrorStack.js +0 -10
  73. package/Libraries/Core/Devtools/parseHermesStack.js +1 -1
  74. package/Libraries/Core/ExceptionsManager.js +51 -41
  75. package/Libraries/Core/ExtendedError.js +19 -0
  76. package/Libraries/Core/InitializeCore.js +1 -0
  77. package/Libraries/Core/ReactFiberErrorDialog.js +44 -34
  78. package/Libraries/Core/ReactNativeVersion.js +1 -1
  79. package/Libraries/Core/Timers/JSTimers.js +37 -28
  80. package/Libraries/Core/Timers/immediateShim.js +67 -0
  81. package/Libraries/Core/Timers/queueMicrotask.js +41 -0
  82. package/Libraries/Core/polyfillPromise.js +1 -1
  83. package/Libraries/Core/setUpBatchedBridge.js +1 -1
  84. package/Libraries/Core/setUpGlobals.js +2 -0
  85. package/Libraries/Core/setUpRegeneratorRuntime.js +25 -8
  86. package/Libraries/Core/setUpTimers.js +65 -6
  87. package/Libraries/DeprecatedPropTypes/DeprecatedImagePropType.android.js +131 -0
  88. package/Libraries/DeprecatedPropTypes/{DeprecatedImagePropType.js → DeprecatedImagePropType.ios.js} +0 -0
  89. package/Libraries/DeprecatedPropTypes/DeprecatedTextInputPropTypes.js +5 -5
  90. package/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js +2 -0
  91. package/Libraries/EventEmitter/NativeEventEmitter.js +22 -1
  92. package/Libraries/EventEmitter/RCTEventEmitter.js +5 -1
  93. package/Libraries/FBLazyVector/BUCK +5 -1
  94. package/Libraries/Image/Image.android.js +22 -131
  95. package/Libraries/Image/Image.ios.js +16 -8
  96. package/Libraries/Image/ImageBackground.js +10 -8
  97. package/Libraries/Image/ImageInjection.js +28 -0
  98. package/Libraries/Image/ImageProps.js +28 -0
  99. package/Libraries/Image/ImageSource.js +108 -65
  100. package/Libraries/Image/NativeImageLoaderIOS.js +2 -1
  101. package/Libraries/Image/RCTImageLoader.h +2 -2
  102. package/Libraries/Image/RCTImageLoader.mm +6 -6
  103. package/Libraries/Image/RCTImagePlugins.mm +4 -3
  104. package/Libraries/Image/React-RCTImage.podspec +1 -1
  105. package/Libraries/Inspector/Inspector.js +6 -0
  106. package/Libraries/Interaction/InteractionManager.js +3 -0
  107. package/Libraries/Interaction/PanResponder.js +1 -1
  108. package/Libraries/LinkingIOS/RCTLinkingPlugins.mm +4 -3
  109. package/Libraries/LinkingIOS/React-RCTLinking.podspec +1 -1
  110. package/Libraries/Lists/CellRenderMask.js +145 -0
  111. package/Libraries/Lists/FlatList.js +43 -26
  112. package/Libraries/Lists/VirtualizedList.js +14 -17
  113. package/Libraries/Lists/VirtualizedSectionList.js +159 -136
  114. package/Libraries/Lists/__flowtests__/SectionList-flowtest.js +4 -4
  115. package/Libraries/LogBox/Data/LogBoxData.js +21 -19
  116. package/Libraries/LogBox/LogBox.js +114 -47
  117. package/Libraries/LogBox/UI/LogBoxImages/alert-triangle.png +0 -0
  118. package/Libraries/LogBox/UI/LogBoxImages/chevron-left.png +0 -0
  119. package/Libraries/LogBox/UI/LogBoxImages/chevron-right.png +0 -0
  120. package/Libraries/LogBox/UI/LogBoxImages/close.png +0 -0
  121. package/Libraries/LogBox/UI/LogBoxImages/loader.png +0 -0
  122. package/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js +1 -0
  123. package/Libraries/Modal/Modal.js +8 -0
  124. package/Libraries/Modal/RCTModalHostViewNativeComponent.js +8 -2
  125. package/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m +0 -3
  126. package/Libraries/NativeAnimation/RCTAnimationPlugins.mm +4 -3
  127. package/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm +6 -3
  128. package/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h +1 -1
  129. package/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m +1 -1
  130. package/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.mm +32 -28
  131. package/Libraries/NativeAnimation/React-RCTAnimation.podspec +1 -1
  132. package/Libraries/Network/RCTHTTPRequestHandler.h +5 -0
  133. package/Libraries/Network/RCTHTTPRequestHandler.mm +19 -7
  134. package/Libraries/Network/RCTNetworkPlugins.mm +4 -3
  135. package/Libraries/Network/RCTNetworking.h +1 -1
  136. package/Libraries/Network/RCTNetworking.mm +3 -3
  137. package/Libraries/Network/React-RCTNetwork.podspec +1 -1
  138. package/Libraries/Network/XMLHttpRequest.js +4 -1
  139. package/Libraries/NewAppScreen/components/Header.js +1 -0
  140. package/Libraries/NewAppScreen/components/HermesBadge.js +4 -1
  141. package/Libraries/NewAppScreen/components/logo.png +0 -0
  142. package/Libraries/Performance/QuickPerformanceLogger.js +3 -1
  143. package/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +4 -1
  144. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +6 -0
  145. package/Libraries/Pressability/Pressability.js +1 -0
  146. package/Libraries/Pressability/PressabilityPerformanceEventEmitter.js +1 -0
  147. package/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +0 -1
  148. package/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm +4 -3
  149. package/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec +1 -1
  150. package/Libraries/RCTRequired/BUCK +4 -1
  151. package/Libraries/ReactNative/AppContainer.js +3 -8
  152. package/Libraries/ReactNative/AppRegistry.js +7 -2
  153. package/Libraries/ReactNative/DisplayMode.js +4 -5
  154. package/Libraries/ReactNative/DummyUIManager.js +7 -2
  155. package/Libraries/ReactNative/FabricUIManager.js +4 -3
  156. package/Libraries/ReactNative/I18nManager.js +12 -3
  157. package/Libraries/ReactNative/NativeUIManager.js +2 -1
  158. package/Libraries/ReactNative/PaperUIManager.js +3 -1
  159. package/Libraries/ReactNative/RootTag.js +2 -2
  160. package/Libraries/ReactNative/UIManager.js +2 -1
  161. package/Libraries/ReactNative/getCachedComponentWithDebugName.js +32 -0
  162. package/Libraries/ReactNative/renderApplication.js +12 -5
  163. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +2 -3
  164. package/Libraries/Reliability/UserFlow.js +7 -0
  165. package/Libraries/Renderer/REVISION +1 -1
  166. package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +6364 -5120
  167. package/Libraries/Renderer/implementations/ReactFabric-dev.js +7877 -6935
  168. package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +2488 -2118
  169. package/Libraries/Renderer/implementations/ReactFabric-prod.js +2112 -1937
  170. package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +2922 -2418
  171. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2568 -2244
  172. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +6086 -4942
  173. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +5736 -4864
  174. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +1624 -1394
  175. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +2275 -2120
  176. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +2279 -1921
  177. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +2565 -2259
  178. package/Libraries/Renderer/shims/ReactFabric.js +5 -4
  179. package/Libraries/Renderer/shims/ReactFeatureFlags.js +3 -1
  180. package/Libraries/Renderer/shims/ReactNative.js +3 -1
  181. package/Libraries/Renderer/shims/ReactNativeTypes.js +7 -4
  182. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +3 -1
  183. package/Libraries/Renderer/shims/createReactNativeComponentClass.js +3 -1
  184. package/Libraries/Settings/RCTSettingsPlugins.mm +4 -3
  185. package/Libraries/Settings/React-RCTSettings.podspec +1 -1
  186. package/Libraries/Settings/Settings.ios.js +4 -0
  187. package/Libraries/Storage/AsyncStorage.js +1 -0
  188. package/Libraries/StyleSheet/PlatformColorValueTypes.ios.js +16 -1
  189. package/Libraries/StyleSheet/PlatformColorValueTypesIOS.ios.js +8 -1
  190. package/Libraries/StyleSheet/PlatformColorValueTypesIOS.js +2 -0
  191. package/Libraries/StyleSheet/StyleSheet.js +3 -5
  192. package/Libraries/StyleSheet/normalizeColor.js +2 -2
  193. package/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.mm +1 -1
  194. package/Libraries/Text/Text.js +17 -0
  195. package/Libraries/Text/TextInput/RCTBaseTextInputView.m +10 -12
  196. package/Libraries/Text/TextInput/RCTInputAccessoryViewContent.m +4 -11
  197. package/Libraries/Text/TextProps.js +7 -7
  198. package/Libraries/TurboModule/RCTExport.js +1 -1
  199. package/Libraries/TurboModule/TurboModuleRegistry.js +1 -10
  200. package/Libraries/TypeSafety/RCTTypeSafety.podspec +1 -1
  201. package/Libraries/{Components/Picker/PickerAndroid.ios.js → Types/RootTagTypes.js} +2 -3
  202. package/Libraries/UTFSequence.js +1 -1
  203. package/Libraries/Utilities/Dimensions.js +9 -14
  204. package/Libraries/Utilities/FeatureDetection.js +31 -0
  205. package/Libraries/Utilities/HMRClient.js +15 -8
  206. package/Libraries/Utilities/MatrixMath.js +1 -1
  207. package/Libraries/Utilities/NativeDeviceInfo.js +1 -1
  208. package/Libraries/Utilities/PerformanceLoggerContext.js +8 -2
  209. package/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js +1 -0
  210. package/Libraries/Utilities/deprecatedPropType.js +2 -2
  211. package/Libraries/Utilities/useMergeRefs.js +44 -0
  212. package/Libraries/Utilities/useRefEffect.js +45 -0
  213. package/Libraries/Utilities/useWindowDimensions.js +7 -2
  214. package/Libraries/Vibration/RCTVibrationPlugins.mm +4 -3
  215. package/Libraries/Vibration/React-RCTVibration.podspec +1 -1
  216. package/Libraries/YellowBox/YellowBoxDeprecated.js +1 -0
  217. package/Libraries/promiseRejectionTrackingOptions.js +2 -0
  218. package/Libraries/vendor/emitter/_EventSubscriptionVendor.js +1 -1
  219. package/README.md +5 -5
  220. package/React/Base/RCTAssert.h +23 -13
  221. package/React/Base/RCTAssert.m +35 -9
  222. package/React/Base/RCTBridge+Private.h +8 -2
  223. package/React/Base/RCTBridge.h +19 -3
  224. package/React/Base/RCTBridge.m +33 -12
  225. package/React/Base/RCTBridgeModule.h +62 -12
  226. package/React/Base/RCTBundleManager.m +78 -0
  227. package/React/Base/RCTBundleURLProvider.h +36 -8
  228. package/React/Base/RCTBundleURLProvider.mm +91 -12
  229. package/React/Base/RCTCallableJSModules.m +47 -0
  230. package/React/Base/RCTConstants.h +6 -13
  231. package/React/Base/RCTConstants.m +12 -27
  232. package/React/Base/RCTConvert.h +1 -1
  233. package/React/Base/RCTConvert.m +31 -7
  234. package/React/Base/RCTCxxConvert.h +1 -1
  235. package/React/Base/RCTDefines.h +12 -3
  236. package/React/Base/RCTEventDispatcherProtocol.h +3 -2
  237. package/React/{Views/RCTPickerManager.h → Base/RCTInitializing.h} +4 -2
  238. package/React/Base/RCTJSThread.h +29 -0
  239. package/React/Base/RCTJSThread.m +19 -0
  240. package/React/Base/RCTModuleData.h +11 -3
  241. package/React/Base/RCTModuleData.mm +66 -1
  242. package/React/Base/RCTMultipartStreamReader.m +0 -2
  243. package/React/Base/RCTRootView.h +15 -0
  244. package/React/Base/RCTRootView.m +15 -0
  245. package/React/Base/RCTTouchHandler.m +4 -9
  246. package/React/Base/RCTUtils.h +3 -0
  247. package/React/Base/RCTUtils.m +14 -7
  248. package/React/Base/RCTVersion.m +1 -1
  249. package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h +12 -0
  250. package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +46 -2
  251. package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm +3 -0
  252. package/React/CoreModules/BUCK +4 -3
  253. package/React/CoreModules/CoreModulesPlugins.mm +4 -3
  254. package/React/CoreModules/RCTAccessibilityManager.mm +1 -1
  255. package/React/CoreModules/RCTActionSheetManager.mm +14 -5
  256. package/React/CoreModules/RCTAsyncLocalStorage.mm +4 -0
  257. package/React/CoreModules/RCTDevLoadingView.mm +10 -23
  258. package/React/CoreModules/RCTDevMenu.mm +22 -25
  259. package/React/CoreModules/RCTDevSettings.h +2 -1
  260. package/React/CoreModules/RCTDevSettings.mm +76 -75
  261. package/React/CoreModules/RCTDevSplitBundleLoader.mm +3 -8
  262. package/React/CoreModules/RCTDeviceInfo.mm +4 -5
  263. package/React/CoreModules/RCTEventDispatcher.h +2 -1
  264. package/React/CoreModules/RCTEventDispatcher.mm +17 -25
  265. package/React/CoreModules/RCTKeyboardObserver.mm +1 -1
  266. package/React/CoreModules/RCTLogBox.mm +14 -10
  267. package/React/CoreModules/RCTPerfMonitor.mm +9 -4
  268. package/React/CoreModules/RCTRedBox.mm +3 -12
  269. package/React/CoreModules/RCTSourceCode.mm +2 -1
  270. package/React/CoreModules/RCTTiming.h +2 -1
  271. package/React/CoreModules/RCTTiming.mm +1 -3
  272. package/React/CoreModules/React-CoreModules.podspec +1 -1
  273. package/React/CxxBridge/RCTCxxBridge.mm +81 -12
  274. package/React/CxxModule/RCTNativeModule.mm +3 -1
  275. package/React/DevSupport/RCTPackagerConnection.h +3 -0
  276. package/React/DevSupport/RCTPackagerConnection.mm +19 -8
  277. package/React/FBReactNativeSpec/FBReactNativeSpec.podspec +12 -4
  278. package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +3 -0
  279. package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h +3 -6
  280. package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +41 -26
  281. package/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.h +0 -1
  282. package/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.mm +0 -1
  283. package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +101 -85
  284. package/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h +7 -0
  285. package/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm +5 -1
  286. package/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm +12 -9
  287. package/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm +1 -0
  288. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +53 -17
  289. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.h +6 -0
  290. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +110 -8
  291. package/React/Fabric/Mounting/RCTComponentViewFactory.mm +1 -0
  292. package/React/Fabric/Mounting/RCTMountingManager.h +6 -1
  293. package/React/Fabric/Mounting/RCTMountingManager.mm +25 -4
  294. package/React/Fabric/Mounting/UIView+ComponentViewProtocol.h +2 -0
  295. package/React/Fabric/Mounting/UIView+ComponentViewProtocol.mm +12 -0
  296. package/React/Fabric/RCTConversions.h +3 -0
  297. package/React/Fabric/RCTScheduler.h +3 -1
  298. package/React/Fabric/RCTScheduler.mm +26 -8
  299. package/React/Fabric/RCTSurfacePresenter.mm +33 -33
  300. package/React/Fabric/RCTSurfacePresenterBridgeAdapter.h +4 -2
  301. package/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm +1 -1
  302. package/React/Fabric/RCTSurfaceRegistry.h +1 -1
  303. package/React/Fabric/RCTSurfaceTouchHandler.mm +6 -20
  304. package/React/Fabric/Surface/RCTFabricSurface.mm +3 -0
  305. package/React/Modules/RCTEventEmitter.h +1 -2
  306. package/React/Modules/RCTEventEmitter.m +8 -11
  307. package/React/Modules/RCTI18nUtil.h +14 -6
  308. package/React/Modules/RCTI18nUtil.m +1 -47
  309. package/React/Modules/RCTUIManager.m +2 -0
  310. package/React/Profiler/RCTProfileTrampoline-arm.S +1 -1
  311. package/React/Profiler/RCTProfileTrampoline-arm64.S +2 -2
  312. package/React/React-RCTFabric.podspec +3 -3
  313. package/React/Tests/Text/RCTParagraphComponentViewTests.mm +63 -0
  314. package/React/Views/RCTDatePickerManager.m +33 -0
  315. package/React/Views/RCTFont.mm +54 -38
  316. package/React/Views/RCTModalHostView.h +5 -1
  317. package/React/Views/RCTModalHostView.m +52 -20
  318. package/React/Views/RCTModalHostViewManager.m +5 -0
  319. package/React/Views/RCTModalManager.h +0 -7
  320. package/React/Views/RCTModalManager.m +0 -9
  321. package/React/Views/RCTView.h +7 -7
  322. package/React/Views/RCTView.m +32 -49
  323. package/React/Views/RCTViewManager.m +22 -4
  324. package/React/Views/SafeAreaView/RCTSafeAreaView.m +1 -5
  325. package/React/Views/ScrollView/RCTScrollView.h +1 -0
  326. package/React/Views/ScrollView/RCTScrollView.m +123 -36
  327. package/React/Views/ScrollView/RCTScrollViewManager.m +4 -7
  328. package/React/Views/UIView+React.m +2 -11
  329. package/React/third-party.xcconfig +1 -1
  330. package/React-Core.podspec +2 -2
  331. package/ReactAndroid/Android-prebuilt.mk +8 -0
  332. package/ReactAndroid/README.md +2 -2
  333. package/ReactAndroid/build.gradle +132 -20
  334. package/ReactAndroid/gradle.properties +7 -5
  335. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/BUCK +1 -1
  336. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppInstrumentationTestCase.java +1 -1
  337. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/idledetection/BUCK +1 -1
  338. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/rule/BUCK +5 -5
  339. package/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK +0 -2
  340. package/ReactAndroid/src/androidTest/java/com/facebook/react/tests/core/BUCK +5 -5
  341. package/ReactAndroid/src/androidTest/js/BUCK +26 -0
  342. package/ReactAndroid/src/androidTest/js/TestBundle.js +0 -12
  343. package/ReactAndroid/src/androidTest/js/UIManagerTestModule.js +7 -6
  344. package/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/Android.mk +2 -2
  345. package/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/Android.mk +4 -4
  346. package/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutorFactory.java +1 -1
  347. package/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/RuntimeConfig.java +0 -6
  348. package/ReactAndroid/src/main/java/com/facebook/proguard/annotations/BUCK +2 -2
  349. package/ReactAndroid/src/main/java/com/facebook/react/BUCK +1 -0
  350. package/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java +1 -0
  351. package/ReactAndroid/src/main/java/com/facebook/react/ReactAndroidHWInputDeviceHelper.java +5 -0
  352. package/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java +6 -2
  353. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +124 -66
  354. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java +28 -0
  355. package/ReactAndroid/src/main/java/com/facebook/react/ReactNativeHost.java +13 -0
  356. package/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +25 -3
  357. package/ReactAndroid/src/main/java/com/facebook/react/animated/BUCK +1 -1
  358. package/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +4 -7
  359. package/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java +5 -5
  360. package/ReactAndroid/src/main/java/com/facebook/react/bridge/BackgroundExecutor.java +3 -2
  361. package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java +4 -0
  362. package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +11 -1
  363. package/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java +37 -0
  364. package/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java +22 -0
  365. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +26 -6
  366. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContextBaseJavaModule.java +1 -1
  367. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactCxxErrorHandler.java +39 -0
  368. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java +3 -1
  369. package/ReactAndroid/src/main/java/com/facebook/react/bridge/{ReactSoftException.java → ReactSoftExceptionLogger.java} +8 -3
  370. package/ReactAndroid/src/main/java/com/facebook/react/bridge/RuntimeScheduler.java +21 -0
  371. package/ReactAndroid/src/main/java/com/facebook/react/bridge/SoftAssertions.java +8 -7
  372. package/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java +10 -0
  373. package/ReactAndroid/src/main/java/com/facebook/react/common/BUCK +2 -2
  374. package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/BUCK +3 -0
  375. package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java +7 -8
  376. package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBufferSoLoader.java +33 -0
  377. package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/BUCK +2 -1
  378. package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.cpp +23 -9
  379. package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.h +8 -5
  380. package/ReactAndroid/src/main/java/com/facebook/react/config/BUCK +2 -1
  381. package/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +54 -29
  382. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK +1 -1
  383. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java +275 -0
  384. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevSupportManagerFactory.java +97 -0
  385. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java +9 -58
  386. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +163 -328
  387. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java +3 -72
  388. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/PackagerStatusCheck.java +100 -0
  389. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/RedBoxHandler.java +1 -1
  390. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.java +1 -1
  391. package/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java +10 -0
  392. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricComponents.java +4 -3
  393. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java +8 -59
  394. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +154 -74
  395. package/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java +36 -1
  396. package/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java +14 -2
  397. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk +2 -2
  398. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.cpp +69 -0
  399. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.h +40 -0
  400. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK +1 -2
  401. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +171 -53
  402. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h +21 -2
  403. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp +0 -6
  404. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp +22 -2
  405. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h +4 -0
  406. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java +53 -7
  407. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +35 -13
  408. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +136 -35
  409. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java +3 -2
  410. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java +5 -5
  411. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEvent.java +2 -2
  412. package/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/Android.mk +2 -2
  413. package/ReactAndroid/src/main/java/com/facebook/react/jstasks/HeadlessJsTaskContext.java +2 -2
  414. package/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/BUCK +1 -1
  415. package/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/BUCK +1 -1
  416. package/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/BUCK +1 -1
  417. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BUCK +1 -1
  418. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobProvider.java +35 -7
  419. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk +2 -2
  420. package/ReactAndroid/src/main/java/com/facebook/react/modules/bundleloader/BUCK +1 -1
  421. package/ReactAndroid/src/main/java/com/facebook/react/modules/camera/BUCK +1 -1
  422. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/BUCK +1 -1
  423. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/{JavaScriptTimerManager.java → JavaScriptTimerExecutor.java} +1 -1
  424. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java +7 -7
  425. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java +2 -2
  426. package/ReactAndroid/src/main/java/com/facebook/react/modules/debug/BUCK +1 -1
  427. package/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/BUCK +1 -1
  428. package/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java +10 -6
  429. package/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/BUCK +1 -1
  430. package/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/BUCK +1 -1
  431. package/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.java +7 -1
  432. package/ReactAndroid/src/main/java/com/facebook/react/modules/image/BUCK +1 -1
  433. package/ReactAndroid/src/main/java/com/facebook/react/modules/intent/BUCK +1 -1
  434. package/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java +23 -19
  435. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/BUCK +1 -1
  436. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/ForwardingCookieHandler.java +1 -4
  437. package/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/BUCK +1 -1
  438. package/ReactAndroid/src/main/java/com/facebook/react/modules/share/BUCK +1 -1
  439. package/ReactAndroid/src/main/java/com/facebook/react/modules/sound/BUCK +1 -1
  440. package/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/BUCK +1 -1
  441. package/ReactAndroid/src/main/java/com/facebook/react/modules/storage/BUCK +1 -1
  442. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK +2 -2
  443. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  444. package/ReactAndroid/src/main/java/com/facebook/react/modules/toast/BUCK +1 -1
  445. package/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/BUCK +1 -1
  446. package/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/BUCK +1 -1
  447. package/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/ReconnectingWebSocket.java +11 -9
  448. package/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK +0 -2
  449. package/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java +0 -9
  450. package/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +4 -2
  451. package/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp +39 -11
  452. package/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h +9 -2
  453. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java +7 -28
  454. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java +14 -5
  455. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +2 -4
  456. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java +10 -13
  457. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.java +1 -6
  458. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java +11 -5
  459. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingProhibitedView.java +26 -0
  460. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroupHelper.java +5 -1
  461. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactOverflowView.java +25 -0
  462. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java +162 -66
  463. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +1 -4
  464. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java +28 -19
  465. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +10 -1
  466. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +6 -5
  467. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java +2 -3
  468. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.java +16 -1
  469. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java +53 -19
  470. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/LockFreeEventDispatcherImpl.java +236 -0
  471. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java +8 -0
  472. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java +20 -6
  473. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java +34 -5
  474. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java +1 -1
  475. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/interfaces/ViewProps.java +9 -2
  476. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/jni/BUCK +1 -1
  477. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/jni/ComponentNameResolverManager.cpp +2 -1
  478. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/jni/ComponentNameResolverManager.h +10 -15
  479. package/ReactAndroid/src/main/java/com/facebook/react/views/drawer/BUCK +1 -1
  480. package/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerClosedEvent.java +0 -6
  481. package/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerOpenedEvent.java +0 -6
  482. package/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerSlideEvent.java +0 -6
  483. package/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerStateChangedEvent.java +0 -6
  484. package/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java +10 -5
  485. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK +1 -1
  486. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java +6 -0
  487. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +7 -11
  488. package/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/BUCK +1 -1
  489. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK +1 -0
  490. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +17 -1
  491. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java +5 -0
  492. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +101 -8
  493. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java +18 -3
  494. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +5 -0
  495. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java +9 -7
  496. package/ReactAndroid/src/main/java/com/facebook/react/views/slider/BUCK +1 -1
  497. package/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderEvent.java +0 -5
  498. package/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java +4 -7
  499. package/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSlidingCompleteEvent.java +0 -5
  500. package/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/BUCK +1 -1
  501. package/ReactAndroid/src/main/java/com/facebook/react/views/switchview/BUCK +1 -1
  502. package/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchEvent.java +0 -6
  503. package/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java +3 -10
  504. package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java +6 -8
  505. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java +59 -44
  506. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java +0 -4
  507. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +31 -3
  508. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +19 -0
  509. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java +1 -1
  510. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java +41 -59
  511. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +20 -51
  512. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +39 -15
  513. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java +38 -10
  514. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TypefaceStyle.java +72 -0
  515. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK +1 -0
  516. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +16 -6
  517. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditTextInputConnectionWrapper.java +3 -0
  518. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +117 -62
  519. package/ReactAndroid/src/main/java/com/facebook/react/views/view/CanvasUtil.java +92 -0
  520. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java +39 -8
  521. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +49 -2
  522. package/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp +2 -7
  523. package/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJTypesVanilla.h +8 -4
  524. package/ReactAndroid/src/main/jni/react/jni/Android.mk +5 -3
  525. package/ReactAndroid/src/main/jni/react/jni/BUCK +5 -2
  526. package/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +61 -0
  527. package/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +8 -0
  528. package/ReactAndroid/src/main/jni/react/jni/JReactCxxErrorHandler.cpp +18 -0
  529. package/{ReactCommon/react/renderer/components/picker/iospicker/primitives.h → ReactAndroid/src/main/jni/react/jni/JReactCxxErrorHandler.h} +6 -10
  530. package/ReactAndroid/src/main/jni/react/jni/JReactSoftExceptionLogger.cpp +21 -0
  531. package/ReactAndroid/src/main/jni/react/jni/JReactSoftExceptionLogger.h +28 -0
  532. package/{ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDialogPickerComponentDescriptor.h → ReactAndroid/src/main/jni/react/jni/JRuntimeScheduler.cpp} +8 -7
  533. package/ReactAndroid/src/main/jni/react/jni/JRuntimeScheduler.h +30 -0
  534. package/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp +1 -1
  535. package/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h +1 -0
  536. package/ReactAndroid/src/main/jni/third-party/boost/Android.mk +7 -2
  537. package/ReactAndroid/src/main/jni/third-party/boost/asm/arm/jump_arm_aapcs_elf_gas.S +86 -0
  538. package/ReactAndroid/src/main/jni/third-party/boost/asm/arm/make_arm_aapcs_elf_gas.S +79 -0
  539. package/ReactAndroid/src/main/jni/third-party/boost/asm/arm/ontop_arm_aapcs_elf_gas.S +91 -0
  540. package/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/jump_arm64_aapcs_elf_gas.S +114 -0
  541. package/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/make_arm64_aapcs_elf_gas.S +85 -0
  542. package/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/ontop_arm64_aapcs_elf_gas.S +113 -0
  543. package/ReactAndroid/src/main/jni/third-party/boost/asm/x86/jump_i386_sysv_elf_gas.S +78 -0
  544. package/ReactAndroid/src/main/jni/third-party/boost/asm/x86/make_i386_sysv_elf_gas.S +106 -0
  545. package/ReactAndroid/src/main/jni/third-party/boost/asm/x86/ontop_i386_sysv_elf_gas.S +85 -0
  546. package/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/jump_x86_64_sysv_elf_gas.S +76 -0
  547. package/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/make_x86_64_sysv_elf_gas.S +81 -0
  548. package/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/ontop_x86_64_sysv_elf_gas.S +79 -0
  549. package/ReactAndroid/src/main/jni/third-party/fmt/Android.mk +15 -0
  550. package/ReactAndroid/src/main/jni/third-party/folly/Android.mk +36 -16
  551. package/ReactAndroid/src/main/jni/third-party/libevent/Android.mk +36 -0
  552. package/ReactAndroid/src/main/jni/third-party/libevent/evconfig-private.h +49 -0
  553. package/ReactAndroid/src/main/jni/third-party/libevent/event-config.h +340 -0
  554. package/ReactAndroid/src/main/libraries/fresco/fresco-react-native/BUCK +26 -26
  555. package/ReactAndroid/src/main/libraries/soloader/java/com/facebook/soloader/BUCK +5 -5
  556. package/ReactAndroid/src/main/res/devsupport/values/strings.xml +2 -1
  557. package/ReactAndroid/src/main/res/views/uimanager/values/strings_unlocalized.xml +0 -8
  558. package/ReactAndroid/src/main/third-party/android/androidx/BUCK +63 -2
  559. package/ReactAndroid/src/main/third-party/java/infer-annotations/BUCK +2 -2
  560. package/ReactAndroid/src/main/third-party/java/okhttp/BUCK +4 -4
  561. package/ReactAndroid/src/main/third-party/java/okio/BUCK +2 -2
  562. package/ReactAndroid/src/main/third-party/java/robolectric/{4.4/BUCK → BUCK} +0 -0
  563. package/ReactAndroid/src/main/third-party/java/testing-support-lib/BUCK +0 -31
  564. package/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java +2 -2
  565. package/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK +1 -1
  566. package/ReactAndroid/src/test/java/com/facebook/react/bridge/ReactTestHelper.java +1 -0
  567. package/ReactAndroid/src/test/java/com/facebook/react/modules/BUCK +1 -0
  568. package/ReactAndroid/src/test/java/com/facebook/react/modules/deviceinfo/DeviceInfoModuleTest.java +168 -0
  569. package/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.java +8 -0
  570. package/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.java +4 -0
  571. package/ReactCommon/React-Fabric.podspec +11 -11
  572. package/ReactCommon/ReactCommon.podspec +3 -2
  573. package/ReactCommon/callinvoker/BUCK +2 -2
  574. package/ReactCommon/callinvoker/React-callinvoker.podspec +1 -1
  575. package/ReactCommon/cxxreact/Android.mk +2 -1
  576. package/ReactCommon/cxxreact/BUCK +1 -3
  577. package/ReactCommon/cxxreact/CxxNativeModule.cpp +28 -0
  578. package/ReactCommon/cxxreact/CxxNativeModule.h +9 -0
  579. package/ReactCommon/cxxreact/Instance.cpp +21 -1
  580. package/ReactCommon/cxxreact/NativeToJsBridge.cpp +0 -21
  581. package/ReactCommon/cxxreact/NativeToJsBridge.h +0 -6
  582. package/ReactCommon/cxxreact/React-cxxreact.podspec +4 -3
  583. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  584. package/ReactCommon/hermes/React-hermes.podspec +4 -4
  585. package/ReactCommon/hermes/executor/Android.mk +4 -4
  586. package/ReactCommon/hermes/inspector/Android.mk +1 -2
  587. package/ReactCommon/hermes/inspector/chrome/Connection.cpp +74 -0
  588. package/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp +100 -1
  589. package/ReactCommon/hermes/inspector/chrome/MessageTypes.h +49 -1
  590. package/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp +81 -0
  591. package/ReactCommon/hermes/inspector/tools/message_types.txt +2 -0
  592. package/ReactCommon/hermes/inspector/tools/msggen/package.json +8 -5
  593. package/ReactCommon/hermes/inspector/tools/msggen/src/Property.js +1 -0
  594. package/ReactCommon/hermes/inspector/tools/msggen/yarn.lock +2246 -1419
  595. package/ReactCommon/jsi/Android.mk +1 -1
  596. package/ReactCommon/jsi/BUCK +0 -2
  597. package/ReactCommon/jsi/JSCRuntime.cpp +7 -0
  598. package/ReactCommon/jsi/React-jsi.podspec +3 -3
  599. package/ReactCommon/jsi/jsi/decorator.h +7 -0
  600. package/ReactCommon/jsi/jsi/jsi.h +29 -0
  601. package/ReactCommon/jsi/jsi/jsilib-posix.cpp +1 -11
  602. package/ReactCommon/jsiexecutor/Android.mk +2 -2
  603. package/ReactCommon/jsiexecutor/React-jsiexecutor.podspec +2 -2
  604. package/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp +35 -2
  605. package/ReactCommon/logger/Android.mk +23 -0
  606. package/ReactCommon/logger/BUCK +43 -0
  607. package/ReactCommon/logger/React-logger.podspec +40 -0
  608. package/ReactCommon/logger/react_native_log.cpp +52 -0
  609. package/ReactCommon/logger/react_native_log.h +33 -0
  610. package/ReactCommon/react/nativemodule/core/Android.mk +2 -2
  611. package/ReactCommon/react/nativemodule/core/ReactCommon/LongLivedObject.cpp +1 -0
  612. package/ReactCommon/react/nativemodule/core/ReactCommon/LongLivedObject.h +3 -2
  613. package/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp +46 -1
  614. package/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h +10 -0
  615. package/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleUtils.h +37 -1
  616. package/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp +24 -22
  617. package/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h +11 -8
  618. package/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.h +7 -17
  619. package/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm +73 -40
  620. package/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.h +0 -1
  621. package/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm +111 -107
  622. package/ReactCommon/react/nativemodule/samples/BUCK +2 -2
  623. package/ReactCommon/react/nativemodule/samples/platform/android/Android.mk +1 -1
  624. package/ReactCommon/react/nativemodule/samples/platform/ios/RCTSampleTurboModule.mm +0 -2
  625. package/ReactCommon/react/renderer/animations/BUCK +2 -0
  626. package/ReactCommon/react/renderer/animations/LayoutAnimationCallbackWrapper.h +34 -0
  627. package/ReactCommon/react/renderer/animations/LayoutAnimationDriver.cpp +5 -27
  628. package/ReactCommon/react/renderer/animations/LayoutAnimationDriver.h +8 -14
  629. package/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp +1231 -1401
  630. package/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h +90 -241
  631. package/ReactCommon/react/renderer/animations/conversions.h +212 -0
  632. package/ReactCommon/react/renderer/animations/primitives.h +104 -0
  633. package/ReactCommon/react/renderer/animations/tests/LayoutAnimationTest.cpp +544 -0
  634. package/ReactCommon/react/renderer/animations/utils.cpp +71 -0
  635. package/ReactCommon/react/renderer/animations/utils.h +80 -0
  636. package/ReactCommon/react/renderer/attributedstring/AttributedString.h +0 -1
  637. package/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp +7 -3
  638. package/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h +12 -2
  639. package/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +7 -2
  640. package/ReactCommon/react/renderer/attributedstring/TextAttributes.h +3 -1
  641. package/ReactCommon/react/renderer/attributedstring/conversions.h +162 -11
  642. package/ReactCommon/react/renderer/attributedstring/primitives.h +34 -1
  643. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.cpp +2 -2
  644. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h +1 -0
  645. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp +12 -6
  646. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h +4 -1
  647. package/ReactCommon/react/renderer/componentregistry/componentNameByReactViewName.cpp +2 -1
  648. package/ReactCommon/react/renderer/components/image/Android.mk +1 -1
  649. package/ReactCommon/react/renderer/components/image/ImageProps.cpp +28 -9
  650. package/ReactCommon/react/renderer/components/image/ImageProps.h +5 -1
  651. package/ReactCommon/react/renderer/components/image/conversions.h +9 -2
  652. package/ReactCommon/react/renderer/components/inputaccessory/BUCK +1 -1
  653. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/BUCK +1 -1
  654. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.mm +0 -1
  655. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.cpp +2 -1
  656. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.h +2 -0
  657. package/ReactCommon/react/renderer/components/root/BUCK +1 -0
  658. package/ReactCommon/react/renderer/components/root/RootProps.cpp +12 -2
  659. package/ReactCommon/react/renderer/components/root/RootProps.h +6 -1
  660. package/ReactCommon/react/renderer/components/root/RootShadowNode.cpp +7 -1
  661. package/ReactCommon/react/renderer/components/root/RootShadowNode.h +2 -0
  662. package/ReactCommon/react/renderer/components/root/tests/RootShadowNodeTest.cpp +35 -3
  663. package/ReactCommon/react/renderer/components/safeareaview/BUCK +1 -1
  664. package/ReactCommon/react/renderer/components/scrollview/Android.mk +1 -1
  665. package/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +54 -4
  666. package/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h +10 -5
  667. package/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp +4 -3
  668. package/ReactCommon/react/renderer/components/scrollview/ScrollViewState.h +5 -2
  669. package/ReactCommon/react/renderer/components/scrollview/conversions.h +5 -0
  670. package/ReactCommon/react/renderer/components/text/Android.mk +1 -1
  671. package/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +32 -0
  672. package/ReactCommon/react/renderer/components/text/BaseTextProps.h +5 -1
  673. package/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp +2 -3
  674. package/ReactCommon/react/renderer/components/text/ParagraphComponentDescriptor.h +1 -16
  675. package/ReactCommon/react/renderer/components/text/ParagraphProps.cpp +10 -4
  676. package/ReactCommon/react/renderer/components/text/ParagraphProps.h +5 -1
  677. package/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp +3 -3
  678. package/ReactCommon/react/renderer/components/text/RawTextProps.cpp +3 -2
  679. package/ReactCommon/react/renderer/components/text/RawTextProps.h +5 -1
  680. package/ReactCommon/react/renderer/components/text/RawTextShadowNode.h +36 -2
  681. package/ReactCommon/react/renderer/components/text/TextProps.cpp +6 -3
  682. package/ReactCommon/react/renderer/components/text/TextProps.h +5 -1
  683. package/ReactCommon/react/renderer/components/text/TextShadowNode.h +23 -0
  684. package/ReactCommon/react/renderer/components/textinput/Android.mk +1 -1
  685. package/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp +58 -91
  686. package/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.h +10 -6
  687. package/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.cpp +46 -22
  688. package/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.h +6 -5
  689. package/ReactCommon/react/renderer/components/textinput/iostextinput/conversions.h +19 -7
  690. package/ReactCommon/react/renderer/components/textinput/iostextinput/primitives.h +6 -0
  691. package/ReactCommon/react/renderer/components/textinput/iostextinput/propsConversions.h +63 -2
  692. package/ReactCommon/react/renderer/components/unimplementedview/Android.mk +1 -1
  693. package/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.cpp +4 -2
  694. package/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.h +5 -2
  695. package/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewProps.h +1 -0
  696. package/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h +28 -0
  697. package/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp +24 -1
  698. package/ReactCommon/react/renderer/components/view/AccessibilityProps.h +4 -1
  699. package/ReactCommon/react/renderer/components/view/Android.mk +3 -2
  700. package/ReactCommon/react/renderer/components/view/BUCK +1 -0
  701. package/ReactCommon/react/renderer/components/view/Touch.h +1 -32
  702. package/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp +19 -5
  703. package/ReactCommon/react/renderer/components/view/TouchEventEmitter.h +2 -1
  704. package/ReactCommon/react/renderer/components/view/ViewComponentDescriptor.h +0 -22
  705. package/ReactCommon/react/renderer/components/view/ViewEventEmitter.cpp +1 -1
  706. package/ReactCommon/react/renderer/components/view/ViewProps.cpp +62 -14
  707. package/ReactCommon/react/renderer/components/view/ViewProps.h +7 -1
  708. package/ReactCommon/react/renderer/components/view/ViewPropsInterpolation.h +5 -10
  709. package/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp +5 -12
  710. package/ReactCommon/react/renderer/components/view/ViewShadowNode.h +1 -1
  711. package/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +58 -33
  712. package/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h +2 -8
  713. package/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +3 -2
  714. package/ReactCommon/react/renderer/components/view/YogaStylableProps.h +2 -0
  715. package/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h +78 -7
  716. package/ReactCommon/react/renderer/components/view/conversions.h +57 -14
  717. package/ReactCommon/react/renderer/components/view/primitives.h +5 -4
  718. package/ReactCommon/react/renderer/components/view/propsConversions.h +163 -28
  719. package/ReactCommon/react/renderer/components/view/tests/ViewTest.cpp +7 -2
  720. package/ReactCommon/react/renderer/core/Android.mk +1 -1
  721. package/ReactCommon/react/renderer/core/BUCK +1 -0
  722. package/ReactCommon/react/renderer/core/BatchedEventQueue.cpp +2 -34
  723. package/ReactCommon/react/renderer/core/BatchedEventQueue.h +2 -9
  724. package/ReactCommon/react/renderer/core/ComponentDescriptor.h +5 -2
  725. package/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h +19 -21
  726. package/ReactCommon/react/renderer/core/ConcreteShadowNode.h +4 -0
  727. package/ReactCommon/react/renderer/core/EventDispatcher.cpp +9 -15
  728. package/ReactCommon/react/renderer/core/EventDispatcher.h +5 -10
  729. package/ReactCommon/react/renderer/core/EventEmitter.cpp +22 -12
  730. package/ReactCommon/react/renderer/core/EventEmitter.h +7 -2
  731. package/ReactCommon/react/renderer/core/EventPipe.h +2 -0
  732. package/ReactCommon/react/renderer/core/EventPriority.h +1 -1
  733. package/ReactCommon/react/renderer/core/EventQueue.cpp +39 -36
  734. package/ReactCommon/react/renderer/core/EventQueue.h +14 -8
  735. package/ReactCommon/react/renderer/core/EventQueueProcessor.cpp +82 -0
  736. package/ReactCommon/react/renderer/core/EventQueueProcessor.h +36 -0
  737. package/ReactCommon/react/renderer/core/LayoutConstraints.h +6 -0
  738. package/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp +1 -1
  739. package/ReactCommon/react/renderer/core/LayoutableShadowNode.h +0 -6
  740. package/ReactCommon/react/renderer/core/Props.cpp +10 -2
  741. package/ReactCommon/react/renderer/core/Props.h +6 -1
  742. package/ReactCommon/react/renderer/core/PropsParserContext.h +29 -0
  743. package/ReactCommon/react/renderer/core/RawEvent.cpp +4 -2
  744. package/ReactCommon/react/renderer/core/RawEvent.h +40 -3
  745. package/ReactCommon/react/renderer/core/RawProps.cpp +2 -1
  746. package/ReactCommon/react/renderer/core/RawProps.h +3 -1
  747. package/ReactCommon/react/renderer/core/RawPropsKey.cpp +10 -2
  748. package/ReactCommon/react/renderer/core/RawPropsKeyMap.cpp +1 -1
  749. package/ReactCommon/react/renderer/core/RawPropsParser.cpp +1 -1
  750. package/ReactCommon/react/renderer/core/RawPropsParser.h +11 -2
  751. package/ReactCommon/react/renderer/core/ReactEventPriority.h +43 -0
  752. package/ReactCommon/react/renderer/core/ReactPrimitives.h +0 -2
  753. package/ReactCommon/react/renderer/core/ShadowNode.cpp +9 -12
  754. package/ReactCommon/react/renderer/core/ShadowNode.h +4 -0
  755. package/ReactCommon/react/renderer/core/ShadowNodeFamily.h +1 -0
  756. package/ReactCommon/react/renderer/core/ShadowNodeTraits.h +17 -1
  757. package/ReactCommon/react/renderer/core/propsConversions.h +19 -9
  758. package/ReactCommon/react/renderer/core/tests/ComponentDescriptorTest.cpp +16 -4
  759. package/ReactCommon/react/renderer/core/tests/ConcreteShadowNodeTest.cpp +1 -1
  760. package/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp +134 -0
  761. package/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp +97 -29
  762. package/ReactCommon/react/renderer/core/tests/TestComponent.h +6 -2
  763. package/ReactCommon/react/renderer/core/tests/traitCastTest.cpp +31 -0
  764. package/ReactCommon/react/renderer/debug/DebugStringConvertible.h +9 -9
  765. package/ReactCommon/react/renderer/graphics/Android.mk +5 -2
  766. package/ReactCommon/react/renderer/graphics/BUCK +12 -1
  767. package/ReactCommon/react/renderer/graphics/React-graphics.podspec +3 -2
  768. package/ReactCommon/react/renderer/graphics/Transform.cpp +2 -2
  769. package/ReactCommon/react/renderer/graphics/Transform.h +1 -1
  770. package/ReactCommon/react/renderer/graphics/conversions.h +34 -19
  771. package/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h +67 -0
  772. package/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.cpp +8 -0
  773. package/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h +1 -0
  774. package/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h +29 -0
  775. package/ReactCommon/react/renderer/graphics/platform/ios/Color.cpp +8 -0
  776. package/ReactCommon/react/renderer/graphics/platform/ios/Color.h +43 -1
  777. package/ReactCommon/react/renderer/graphics/platform/ios/PlatformColorParser.h +34 -0
  778. package/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.h +12 -0
  779. package/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.mm +206 -0
  780. package/ReactCommon/react/renderer/imagemanager/BUCK +1 -1
  781. package/ReactCommon/react/renderer/imagemanager/platform/ios/RCTSyncImageManager.mm +1 -1
  782. package/ReactCommon/react/renderer/leakchecker/LeakChecker.cpp +6 -9
  783. package/ReactCommon/react/renderer/leakchecker/LeakChecker.h +1 -4
  784. package/ReactCommon/react/renderer/mapbuffer/BUCK +2 -2
  785. package/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp +34 -31
  786. package/ReactCommon/react/renderer/mapbuffer/MapBuffer.h +10 -9
  787. package/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp +50 -35
  788. package/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h +13 -13
  789. package/ReactCommon/react/renderer/mapbuffer/primitives.h +18 -19
  790. package/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp +13 -1
  791. package/ReactCommon/react/renderer/mounting/Android.mk +2 -1
  792. package/ReactCommon/react/renderer/mounting/BUCK +1 -0
  793. package/ReactCommon/react/renderer/mounting/Differentiator.cpp +392 -519
  794. package/ReactCommon/react/renderer/mounting/Differentiator.h +1 -2
  795. package/ReactCommon/react/renderer/mounting/MountingCoordinator.cpp +1 -7
  796. package/ReactCommon/react/renderer/mounting/MountingCoordinator.h +0 -4
  797. package/ReactCommon/react/renderer/mounting/MountingOverrideDelegate.h +1 -1
  798. package/ReactCommon/react/renderer/mounting/ShadowTree.cpp +7 -5
  799. package/ReactCommon/react/renderer/mounting/ShadowTree.h +2 -1
  800. package/ReactCommon/react/renderer/mounting/ShadowView.cpp +2 -0
  801. package/ReactCommon/react/renderer/mounting/ShadowView.h +2 -1
  802. package/ReactCommon/react/renderer/mounting/ShadowViewMutation.cpp +12 -0
  803. package/ReactCommon/react/renderer/mounting/ShadowViewMutation.h +10 -1
  804. package/ReactCommon/react/renderer/mounting/StubViewTree.cpp +10 -3
  805. package/ReactCommon/react/renderer/mounting/TelemetryController.cpp +1 -1
  806. package/ReactCommon/react/renderer/mounting/stubs.cpp +3 -3
  807. package/ReactCommon/react/renderer/mounting/tests/MountingTest.cpp +23 -22
  808. package/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp +49 -10
  809. package/ReactCommon/react/renderer/mounting/tests/StackingContextTest.cpp +2 -2
  810. package/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp +6 -3
  811. package/ReactCommon/react/renderer/runtimescheduler/Android.mk +2 -1
  812. package/ReactCommon/react/renderer/runtimescheduler/BUCK +1 -0
  813. package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp +78 -16
  814. package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h +60 -8
  815. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp +17 -7
  816. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h +8 -5
  817. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.cpp +30 -0
  818. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h +34 -0
  819. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerClock.h +4 -2
  820. package/ReactCommon/react/renderer/runtimescheduler/SchedulerPriority.h +4 -2
  821. package/ReactCommon/react/renderer/runtimescheduler/Task.cpp +20 -25
  822. package/ReactCommon/react/renderer/runtimescheduler/Task.h +16 -15
  823. package/ReactCommon/react/renderer/runtimescheduler/primitives.h +4 -2
  824. package/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +297 -11
  825. package/ReactCommon/react/renderer/runtimescheduler/tests/StubQueue.h +6 -0
  826. package/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp +13 -12
  827. package/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.h +4 -4
  828. package/ReactCommon/react/renderer/{components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDialogPickerShadowNode.cpp → scheduler/InspectorData.h} +10 -2
  829. package/ReactCommon/react/renderer/scheduler/Scheduler.cpp +64 -40
  830. package/ReactCommon/react/renderer/scheduler/Scheduler.h +18 -3
  831. package/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h +9 -1
  832. package/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h +1 -6
  833. package/ReactCommon/react/renderer/scheduler/SurfaceHandler.cpp +49 -35
  834. package/ReactCommon/react/renderer/scheduler/SurfaceHandler.h +12 -12
  835. package/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp +1 -0
  836. package/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.cpp +11 -4
  837. package/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.h +4 -1
  838. package/ReactCommon/react/renderer/telemetry/BUCK +1 -0
  839. package/ReactCommon/react/renderer/telemetry/tests/TransactionTelemetryTest.cpp +1 -19
  840. package/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp +5 -5
  841. package/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.cpp +2 -1
  842. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.h +2 -0
  843. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm +22 -0
  844. package/ReactCommon/react/renderer/timeline/BUCK +6 -6
  845. package/ReactCommon/react/renderer/uimanager/UIManager.cpp +32 -28
  846. package/ReactCommon/react/renderer/uimanager/UIManager.h +3 -4
  847. package/ReactCommon/react/renderer/uimanager/UIManagerAnimationDelegate.h +1 -1
  848. package/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +61 -17
  849. package/ReactCommon/react/renderer/uimanager/UIManagerBinding.h +13 -1
  850. package/ReactCommon/react/renderer/uimanager/UIManagerDelegate.h +10 -2
  851. package/ReactCommon/react/{renderer/components/picker/iospicker → test_utils}/BUCK +12 -14
  852. package/ReactCommon/react/{renderer/mounting/tests → test_utils}/Entropy.h +0 -0
  853. package/ReactCommon/react/test_utils/MockClock.h +29 -0
  854. package/ReactCommon/react/{renderer/core/Constants.h → test_utils/MockSurfaceHandler.h} +9 -7
  855. package/ReactCommon/react/{renderer/mounting/tests → test_utils}/shadowTreeGeneration.h +18 -4
  856. package/ReactCommon/react/utils/Android.mk +3 -1
  857. package/ReactCommon/react/utils/BUCK +1 -0
  858. package/ReactCommon/react/utils/ContextContainer.h +0 -27
  859. package/ReactCommon/reactperflogger/React-perflogger.podspec +1 -1
  860. package/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec +1 -1
  861. package/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h +12 -0
  862. package/ReactCommon/yoga/yoga/Yoga.cpp +2 -6
  863. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar +0 -0
  864. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.md5 +1 -0
  865. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.sha1 +1 -0
  866. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.sha256 +1 -0
  867. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.sha512 +1 -0
  868. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module +272 -0
  869. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.md5 +1 -0
  870. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.sha1 +1 -0
  871. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.sha256 +1 -0
  872. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.sha512 +1 -0
  873. package/android/com/facebook/react/react-native/{0.0.0-17be3a003/react-native-0.0.0-17be3a003.pom → 0.0.0-18697adec/react-native-0.0.0-18697adec.pom} +22 -11
  874. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.md5 +1 -0
  875. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.sha1 +1 -0
  876. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.sha256 +1 -0
  877. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.sha512 +1 -0
  878. package/android/com/facebook/react/react-native/maven-metadata.xml +4 -3
  879. package/android/com/facebook/react/react-native/maven-metadata.xml.md5 +1 -1
  880. package/android/com/facebook/react/react-native/maven-metadata.xml.sha1 +1 -1
  881. package/android/com/facebook/react/react-native/maven-metadata.xml.sha256 +1 -0
  882. package/android/com/facebook/react/react-native/maven-metadata.xml.sha512 +1 -0
  883. package/flow/HermesInternalType.js +114 -0
  884. package/flow/global.js +68 -0
  885. package/flow-typed/npm/react-test-renderer_v16.x.x.js +79 -0
  886. package/index.js +67 -42
  887. package/jest/preprocessor.js +75 -7
  888. package/jest/renderer.js +3 -7
  889. package/jest/setup.js +3 -2
  890. package/package.json +59 -20
  891. package/react.gradle +22 -22
  892. package/scripts/find-node.sh +6 -0
  893. package/scripts/generate-specs-cli.js +20 -2
  894. package/scripts/ios-configure-glog.sh +4 -0
  895. package/scripts/react-native-xcode.sh +5 -1
  896. package/scripts/react_native_pods.rb +213 -43
  897. package/template/_flowconfig +3 -4
  898. package/template/_gitignore +1 -0
  899. package/template/android/app/build.gradle +12 -7
  900. package/template/android/app/src/main/res/values/styles.xml +0 -1
  901. package/template/android/build.gradle +5 -6
  902. package/template/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  903. package/template/android/gradle.properties +1 -1
  904. package/template/ios/HelloWorld.xcodeproj/project.pbxproj +2 -0
  905. package/template/ios/Podfile +1 -0
  906. package/template/package.json +3 -4
  907. package/third-party-podspecs/RCT-Folly.podspec +31 -11
  908. package/third-party-podspecs/boost.podspec +23 -0
  909. package/Libraries/BUCK +0 -24
  910. package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js +0 -87
  911. package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js +0 -30
  912. package/Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js +0 -30
  913. package/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js +0 -83
  914. package/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js +0 -82
  915. package/Libraries/Components/Picker/Picker.js +0 -169
  916. package/Libraries/Components/Picker/PickerAndroid.android.js +0 -143
  917. package/Libraries/Components/Picker/PickerIOS.android.js +0 -14
  918. package/Libraries/Components/Picker/PickerIOS.ios.js +0 -162
  919. package/Libraries/Components/Picker/RCTPickerNativeComponent.js +0 -86
  920. package/Libraries/Components/ScrollView/ScrollViewStickyHeaderInjection.js +0 -17
  921. package/Libraries/Components/StaticContainer.react.js +0 -51
  922. package/Libraries/Components/StatusBar/StatusBarIOS.js +0 -38
  923. package/Libraries/Components/Switch/SwitchInjection.js +0 -17
  924. package/Libraries/Components/Touchable/ensurePositiveDelayProps.js +0 -26
  925. package/Libraries/Interaction/InteractionMixin.js +0 -53
  926. package/Libraries/Lists/VirtualizedListInjection.js +0 -15
  927. package/Libraries/Lists/VirtualizedSectionListInjection.js +0 -17
  928. package/Libraries/ReactNative/queryLayoutByID.js +0 -58
  929. package/Libraries/StyleSheet/StyleSheetValidation.js +0 -100
  930. package/Libraries/Text/TextInjection.js +0 -15
  931. package/Libraries/Utilities/registerGeneratedViewConfig.js +0 -34
  932. package/React/Base/RCTBundleHolderModule.h +0 -16
  933. package/React/Base/RCTJSInvokerModule.h +0 -18
  934. package/React/Fabric/Mounting/ComponentViews/Picker/RCTPickerComponentView.h +0 -19
  935. package/React/Fabric/Mounting/ComponentViews/Picker/RCTPickerComponentView.mm +0 -206
  936. package/React/Views/RCTPicker.h +0 -23
  937. package/React/Views/RCTPicker.m +0 -122
  938. package/React/Views/RCTPickerManager.m +0 -59
  939. package/ReactAndroid/release.gradle +0 -87
  940. package/ReactAndroid/src/androidTest/java/com/facebook/react/tests/DatePickerDialogTestCase.java +0 -172
  941. package/ReactAndroid/src/androidTest/java/com/facebook/react/tests/ReactPickerTestCase.java +0 -196
  942. package/ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js +0 -45
  943. package/ReactAndroid/src/androidTest/js/PickerAndroidTestModule.js +0 -89
  944. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java +0 -82
  945. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK +0 -27
  946. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogFragment.java +0 -137
  947. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java +0 -147
  948. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerMode.java +0 -15
  949. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DismissableDatePickerDialog.java +0 -117
  950. package/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/AndroidDialogPickerManagerDelegate.java +0 -48
  951. package/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/AndroidDialogPickerManagerInterface.java +0 -23
  952. package/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/AndroidDropdownPickerManagerDelegate.java +0 -48
  953. package/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/AndroidDropdownPickerManagerInterface.java +0 -22
  954. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/BUCK +0 -30
  955. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactDialogPickerManager.java +0 -51
  956. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactDropdownPickerManager.java +0 -50
  957. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPicker.java +0 -196
  958. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerAdapter.java +0 -95
  959. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerItem.java +0 -43
  960. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java +0 -99
  961. package/ReactAndroid/src/main/java/com/facebook/react/views/picker/events/PickerItemSelectEvent.java +0 -42
  962. package/ReactCommon/react/renderer/components/picker/Android.mk +0 -37
  963. package/ReactCommon/react/renderer/components/picker/BUCK +0 -98
  964. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDialogPickerEventEmitter.cpp +0 -23
  965. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDialogPickerEventEmitter.h +0 -27
  966. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDialogPickerProps.cpp +0 -28
  967. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDialogPickerProps.h +0 -77
  968. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDialogPickerShadowNode.h +0 -29
  969. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDropdownPickerComponentDescriptor.h +0 -21
  970. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDropdownPickerEventEmitter.cpp +0 -23
  971. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDropdownPickerEventEmitter.h +0 -27
  972. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDropdownPickerProps.cpp +0 -28
  973. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDropdownPickerProps.h +0 -77
  974. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDropdownPickerShadowNode.cpp +0 -17
  975. package/ReactCommon/react/renderer/components/picker/androidpicker/react/renderer/components/androidpicker/AndroidDropdownPickerShadowNode.h +0 -29
  976. package/ReactCommon/react/renderer/components/picker/iospicker/PickerComponentDescriptor.h +0 -26
  977. package/ReactCommon/react/renderer/components/picker/iospicker/PickerEventEmitter.cpp +0 -23
  978. package/ReactCommon/react/renderer/components/picker/iospicker/PickerEventEmitter.h +0 -28
  979. package/ReactCommon/react/renderer/components/picker/iospicker/PickerProps.cpp +0 -46
  980. package/ReactCommon/react/renderer/components/picker/iospicker/PickerProps.h +0 -36
  981. package/ReactCommon/react/renderer/components/picker/iospicker/PickerShadowNode.cpp +0 -16
  982. package/ReactCommon/react/renderer/components/picker/iospicker/PickerShadowNode.h +0 -33
  983. package/ReactCommon/react/renderer/components/picker/iospicker/PickerState.h +0 -19
  984. package/ReactCommon/react/renderer/components/picker/iospicker/conversions.h +0 -48
  985. package/ReactCommon/react/renderer/core/Constants.cpp +0 -24
  986. package/ReactCommon/react/renderer/mounting/DifferentiatorFlatteningClassic.cpp +0 -1564
  987. package/ReactCommon/react/renderer/mounting/DifferentiatorFlatteningClassic.h +0 -45
  988. package/android/com/facebook/react/react-native/0.0.0-17be3a003/react-native-0.0.0-17be3a003.aar +0 -0
  989. package/android/com/facebook/react/react-native/0.0.0-17be3a003/react-native-0.0.0-17be3a003.aar.md5 +0 -1
  990. package/android/com/facebook/react/react-native/0.0.0-17be3a003/react-native-0.0.0-17be3a003.aar.sha1 +0 -1
  991. package/android/com/facebook/react/react-native/0.0.0-17be3a003/react-native-0.0.0-17be3a003.pom.md5 +0 -1
  992. package/android/com/facebook/react/react-native/0.0.0-17be3a003/react-native-0.0.0-17be3a003.pom.sha1 +0 -1
  993. package/scripts/generate-specs.sh +0 -100
@@ -8,25 +8,24 @@
8
8
  #include "LayoutAnimationKeyFrameManager.h"
9
9
 
10
10
  #include <algorithm>
11
- #include <chrono>
12
11
 
13
12
  #include <react/debug/flags.h>
14
13
  #include <react/debug/react_native_assert.h>
15
14
 
15
+ #include <logger/react_native_log.h>
16
+ #include <react/renderer/animations/conversions.h>
17
+ #include <react/renderer/animations/utils.h>
16
18
  #include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
17
- #include <react/renderer/components/root/RootShadowNode.h>
19
+ #include <react/renderer/components/image/ImageProps.h>
18
20
  #include <react/renderer/components/view/ViewProps.h>
19
21
  #include <react/renderer/core/ComponentDescriptor.h>
20
22
  #include <react/renderer/core/LayoutMetrics.h>
21
- #include <react/renderer/core/LayoutableShadowNode.h>
22
23
  #include <react/renderer/core/Props.h>
24
+ #include <react/renderer/core/PropsParserContext.h>
23
25
  #include <react/renderer/core/RawValue.h>
24
26
  #include <react/renderer/mounting/MountingCoordinator.h>
25
- #include <react/renderer/mounting/ShadowViewMutation.h>
26
-
27
- #include <react/renderer/mounting/Differentiator.h>
28
- #include <react/renderer/mounting/ShadowTreeRevision.h>
29
27
  #include <react/renderer/mounting/ShadowView.h>
28
+ #include <react/renderer/mounting/ShadowViewMutation.h>
30
29
 
31
30
  #include <glog/logging.h>
32
31
 
@@ -74,6 +73,7 @@ void PrintMutationInstruction(
74
73
  return stream;
75
74
  }(LOG(ERROR));
76
75
  }
76
+
77
77
  void PrintMutationInstructionRelative(
78
78
  std::string message,
79
79
  ShadowViewMutation const &mutation,
@@ -85,199 +85,27 @@ void PrintMutationInstructionRelative(
85
85
  }
86
86
  #endif
87
87
 
88
- static better::optional<AnimationType> parseAnimationType(std::string param) {
89
- if (param == "spring") {
90
- return AnimationType::Spring;
91
- }
92
- if (param == "linear") {
93
- return AnimationType::Linear;
94
- }
95
- if (param == "easeInEaseOut") {
96
- return AnimationType::EaseInEaseOut;
97
- }
98
- if (param == "easeIn") {
99
- return AnimationType::EaseIn;
100
- }
101
- if (param == "easeOut") {
102
- return AnimationType::EaseOut;
103
- }
104
- if (param == "keyboard") {
105
- return AnimationType::Keyboard;
106
- }
107
-
108
- LOG(ERROR) << "Error parsing animation type: " << param;
109
- return {};
110
- }
111
-
112
- static better::optional<AnimationProperty> parseAnimationProperty(
113
- std::string param) {
114
- if (param == "opacity") {
115
- return AnimationProperty::Opacity;
116
- }
117
- if (param == "scaleX") {
118
- return AnimationProperty::ScaleX;
119
- }
120
- if (param == "scaleY") {
121
- return AnimationProperty::ScaleY;
122
- }
123
- if (param == "scaleXY") {
124
- return AnimationProperty::ScaleXY;
125
- }
126
-
127
- LOG(ERROR) << "Error parsing animation property: " << param;
128
- return {};
129
- }
130
-
131
- static better::optional<AnimationConfig> parseAnimationConfig(
132
- folly::dynamic const &config,
133
- double defaultDuration,
134
- bool parsePropertyType) {
135
- if (config.empty() || !config.isObject()) {
136
- return AnimationConfig{
137
- AnimationType::Linear,
138
- AnimationProperty::NotApplicable,
139
- defaultDuration,
140
- 0,
141
- 0,
142
- 0};
143
- }
144
-
145
- auto const typeIt = config.find("type");
146
- if (typeIt == config.items().end()) {
147
- LOG(ERROR) << "Error parsing animation config: could not find field `type`";
148
- return {};
149
- }
150
- auto const animationTypeParam = typeIt->second;
151
- if (animationTypeParam.empty() || !animationTypeParam.isString()) {
152
- LOG(ERROR)
153
- << "Error parsing animation config: could not unwrap field `type`";
154
- return {};
155
- }
156
- const auto animationType = parseAnimationType(animationTypeParam.asString());
157
- if (!animationType) {
158
- LOG(ERROR)
159
- << "Error parsing animation config: could not parse field `type`";
160
- return {};
161
- }
162
-
163
- AnimationProperty animationProperty = AnimationProperty::NotApplicable;
164
- if (parsePropertyType) {
165
- auto const propertyIt = config.find("property");
166
- if (propertyIt == config.items().end()) {
167
- LOG(ERROR)
168
- << "Error parsing animation config: could not find field `property`";
169
- return {};
170
- }
171
- auto const animationPropertyParam = propertyIt->second;
172
- if (animationPropertyParam.empty() || !animationPropertyParam.isString()) {
173
- LOG(ERROR)
174
- << "Error parsing animation config: could not unwrap field `property`";
175
- return {};
176
- }
177
- const auto animationPropertyParsed =
178
- parseAnimationProperty(animationPropertyParam.asString());
179
- if (!animationPropertyParsed) {
180
- LOG(ERROR)
181
- << "Error parsing animation config: could not parse field `property`";
182
- return {};
183
- }
184
- animationProperty = *animationPropertyParsed;
185
- }
186
-
187
- double duration = defaultDuration;
188
- double delay = 0;
189
- double springDamping = 0.5;
190
- double initialVelocity = 0;
191
-
192
- auto const durationIt = config.find("duration");
193
- if (durationIt != config.items().end()) {
194
- if (durationIt->second.isDouble()) {
195
- duration = durationIt->second.asDouble();
196
- } else {
197
- LOG(ERROR)
198
- << "Error parsing animation config: field `duration` must be a number";
199
- return {};
200
- }
201
- }
202
-
203
- auto const delayIt = config.find("delay");
204
- if (delayIt != config.items().end()) {
205
- if (delayIt->second.isDouble()) {
206
- delay = delayIt->second.asDouble();
207
- } else {
208
- LOG(ERROR)
209
- << "Error parsing animation config: field `delay` must be a number";
210
- return {};
211
- }
212
- }
213
-
214
- auto const springDampingIt = config.find("springDamping");
215
- if (springDampingIt != config.items().end() &&
216
- springDampingIt->second.isDouble()) {
217
- if (springDampingIt->second.isDouble()) {
218
- springDamping = springDampingIt->second.asDouble();
219
- } else {
220
- LOG(ERROR)
221
- << "Error parsing animation config: field `springDamping` must be a number";
222
- return {};
223
- }
224
- }
225
-
226
- auto const initialVelocityIt = config.find("initialVelocity");
227
- if (initialVelocityIt != config.items().end()) {
228
- if (initialVelocityIt->second.isDouble()) {
229
- initialVelocity = initialVelocityIt->second.asDouble();
230
- } else {
231
- LOG(ERROR)
232
- << "Error parsing animation config: field `initialVelocity` must be a number";
233
- return {};
234
- }
235
- }
236
-
237
- return better::optional<AnimationConfig>(AnimationConfig{
238
- *animationType,
239
- animationProperty,
240
- duration,
241
- delay,
242
- springDamping,
243
- initialVelocity});
88
+ static inline float
89
+ interpolateFloats(float coefficient, float oldValue, float newValue) {
90
+ return oldValue + (newValue - oldValue) * coefficient;
244
91
  }
245
92
 
246
- // Parse animation config from JS
247
- static better::optional<LayoutAnimationConfig> parseLayoutAnimationConfig(
248
- folly::dynamic const &config) {
249
- if (config.empty() || !config.isObject()) {
250
- return {};
251
- }
252
-
253
- const auto durationIt = config.find("duration");
254
- if (durationIt == config.items().end() || !durationIt->second.isDouble()) {
255
- return {};
256
- }
257
- const double duration = durationIt->second.asDouble();
258
-
259
- const auto createConfigIt = config.find("create");
260
- const auto createConfig = createConfigIt == config.items().end()
261
- ? better::optional<AnimationConfig>(AnimationConfig{})
262
- : parseAnimationConfig(createConfigIt->second, duration, true);
263
-
264
- const auto updateConfigIt = config.find("update");
265
- const auto updateConfig = updateConfigIt == config.items().end()
266
- ? better::optional<AnimationConfig>(AnimationConfig{})
267
- : parseAnimationConfig(updateConfigIt->second, duration, false);
93
+ #pragma mark -
268
94
 
269
- const auto deleteConfigIt = config.find("delete");
270
- const auto deleteConfig = deleteConfigIt == config.items().end()
271
- ? better::optional<AnimationConfig>(AnimationConfig{})
272
- : parseAnimationConfig(deleteConfigIt->second, duration, true);
95
+ LayoutAnimationKeyFrameManager::LayoutAnimationKeyFrameManager(
96
+ RuntimeExecutor runtimeExecutor,
97
+ ContextContainer::Shared &contextContainer,
98
+ LayoutAnimationStatusDelegate *delegate)
99
+ : runtimeExecutor_(runtimeExecutor),
100
+ contextContainer_(contextContainer),
101
+ layoutAnimationStatusDelegate_(delegate),
102
+ now_([]() {
103
+ return std::chrono::duration_cast<std::chrono::milliseconds>(
104
+ std::chrono::high_resolution_clock::now().time_since_epoch())
105
+ .count();
106
+ }) {}
273
107
 
274
- if (!createConfig || !updateConfig || !deleteConfig) {
275
- return {};
276
- }
277
-
278
- return better::optional<LayoutAnimationConfig>(LayoutAnimationConfig{
279
- duration, *createConfig, *updateConfig, *deleteConfig});
280
- }
108
+ #pragma mark UIManagerAnimationDelegate methods
281
109
 
282
110
  /**
283
111
  * Globally configure next LayoutAnimation.
@@ -307,14 +135,14 @@ void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation(
307
135
  if (layoutAnimationConfig) {
308
136
  std::lock_guard<std::mutex> lock(currentAnimationMutex_);
309
137
 
310
- currentAnimation_ = better::optional<LayoutAnimation>{LayoutAnimation{
138
+ uiManagerDidConfigureNextLayoutAnimation(LayoutAnimation{
311
139
  -1,
312
140
  0,
313
141
  false,
314
142
  *layoutAnimationConfig,
315
143
  successCallback,
316
144
  failureCallback,
317
- {}}};
145
+ {}});
318
146
  } else {
319
147
  LOG(ERROR) << "Parsing LayoutAnimationConfig failed: "
320
148
  << (folly::dynamic)config;
@@ -323,19 +151,9 @@ void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation(
323
151
  }
324
152
  }
325
153
 
326
- void LayoutAnimationKeyFrameManager::setLayoutAnimationStatusDelegate(
327
- LayoutAnimationStatusDelegate *delegate) const {
328
- std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
329
- layoutAnimationStatusDelegate_ = delegate;
330
- }
331
-
332
- bool LayoutAnimationKeyFrameManager::shouldOverridePullTransaction() const {
333
- return shouldAnimateFrame();
334
- }
335
-
336
- void LayoutAnimationKeyFrameManager::stopSurface(SurfaceId surfaceId) {
337
- std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
338
- surfaceIdsToStop_.push_back(surfaceId);
154
+ void LayoutAnimationKeyFrameManager::setComponentDescriptorRegistry(
155
+ const SharedComponentDescriptorRegistry &componentDescriptorRegistry) {
156
+ componentDescriptorRegistry_ = componentDescriptorRegistry;
339
157
  }
340
158
 
341
159
  bool LayoutAnimationKeyFrameManager::shouldAnimateFrame() const {
@@ -343,980 +161,582 @@ bool LayoutAnimationKeyFrameManager::shouldAnimateFrame() const {
343
161
  return currentAnimation_ || !inflightAnimations_.empty();
344
162
  }
345
163
 
346
- static inline const float
347
- interpolateFloats(float coefficient, float oldValue, float newValue) {
348
- return oldValue + (newValue - oldValue) * coefficient;
164
+ void LayoutAnimationKeyFrameManager::stopSurface(SurfaceId surfaceId) {
165
+ std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
166
+ surfaceIdsToStop_.insert(surfaceId);
349
167
  }
350
168
 
351
- std::pair<double, double>
352
- LayoutAnimationKeyFrameManager::calculateAnimationProgress(
353
- uint64_t now,
354
- const LayoutAnimation &animation,
355
- const AnimationConfig &mutationConfig) const {
356
- if (mutationConfig.animationType == AnimationType::None) {
357
- return {1, 1};
358
- }
359
-
360
- uint64_t startTime = animation.startTime;
361
- uint64_t delay = mutationConfig.delay;
362
- uint64_t endTime = startTime + delay + mutationConfig.duration;
169
+ #pragma mark - MountingOverrideDelegate methods
363
170
 
364
- static const float PI = 3.14159265358979323846;
365
-
366
- if (now >= endTime) {
367
- return {1, 1};
368
- }
369
- if (now < startTime + delay) {
370
- return {0, 0};
371
- }
372
-
373
- double linearTimeProgression = 1 -
374
- (double)(endTime - delay - now) / (double)(endTime - animation.startTime);
375
-
376
- if (mutationConfig.animationType == AnimationType::Linear) {
377
- return {linearTimeProgression, linearTimeProgression};
378
- } else if (mutationConfig.animationType == AnimationType::EaseIn) {
379
- // This is an accelerator-style interpolator.
380
- // In the future, this parameter (2.0) could be adjusted. This has been the
381
- // default for Classic RN forever.
382
- return {linearTimeProgression, pow(linearTimeProgression, 2.0)};
383
- } else if (mutationConfig.animationType == AnimationType::EaseOut) {
384
- // This is an decelerator-style interpolator.
385
- // In the future, this parameter (2.0) could be adjusted. This has been the
386
- // default for Classic RN forever.
387
- return {linearTimeProgression, 1.0 - pow(1 - linearTimeProgression, 2.0)};
388
- } else if (mutationConfig.animationType == AnimationType::EaseInEaseOut) {
389
- // This is a combination of accelerate+decelerate.
390
- // The animation starts and ends slowly, and speeds up in the middle.
391
- return {
392
- linearTimeProgression,
393
- cos((linearTimeProgression + 1.0) * PI) / 2 + 0.5};
394
- } else if (mutationConfig.animationType == AnimationType::Spring) {
395
- // Using mSpringDamping in this equation is not really the exact
396
- // mathematical springDamping, but a good approximation We need to replace
397
- // this equation with the right Factor that accounts for damping and
398
- // friction
399
- double damping = mutationConfig.springDamping;
400
- return {
401
- linearTimeProgression,
402
- (1 +
403
- pow(2, -10 * linearTimeProgression) *
404
- sin((linearTimeProgression - damping / 4) * PI * 2 / damping))};
405
- } else {
406
- return {linearTimeProgression, linearTimeProgression};
407
- }
171
+ bool LayoutAnimationKeyFrameManager::shouldOverridePullTransaction() const {
172
+ return shouldAnimateFrame();
408
173
  }
409
174
 
410
- void LayoutAnimationKeyFrameManager::
411
- adjustImmediateMutationIndicesForDelayedMutations(
412
- SurfaceId surfaceId,
413
- ShadowViewMutation &mutation,
414
- bool skipLastAnimation,
415
- bool lastAnimationOnly) const {
416
- bool isRemoveMutation = mutation.type == ShadowViewMutation::Type::Remove;
417
- react_native_assert(
418
- isRemoveMutation || mutation.type == ShadowViewMutation::Type::Insert);
419
-
420
- // TODO: turn all of this into a lambda and share code?
421
- if (mutation.mutatedViewIsVirtual()) {
422
- PrintMutationInstruction(
423
- "[IndexAdjustment] Not calling adjustImmediateMutationIndicesForDelayedMutations, is virtual, for:",
424
- mutation);
425
- return;
426
- }
175
+ better::optional<MountingTransaction>
176
+ LayoutAnimationKeyFrameManager::pullTransaction(
177
+ SurfaceId surfaceId,
178
+ MountingTransaction::Number transactionNumber,
179
+ TransactionTelemetry const &telemetry,
180
+ ShadowViewMutationList mutations) const {
181
+ simulateImagePropsMemoryAccess(mutations);
182
+ // Current time in milliseconds
183
+ uint64_t now = now_();
427
184
 
428
- PrintMutationInstruction(
429
- "[IndexAdjustment] Calling adjustImmediateMutationIndicesForDelayedMutations for:",
430
- mutation);
185
+ bool inflightAnimationsExistInitially = !inflightAnimations_.empty();
186
+ deleteAnimationsForStoppedSurfaces();
431
187
 
432
- // First, collect all final mutations that could impact this immediate
433
- // mutation.
434
- std::vector<ShadowViewMutation *> candidateMutations{};
188
+ if (!mutations.empty()) {
189
+ #ifdef RN_SHADOW_TREE_INTROSPECTION
190
+ {
191
+ std::stringstream ss(getDebugDescription(mutations, {}));
192
+ std::string to;
193
+ while (std::getline(ss, to, '\n')) {
194
+ LOG(ERROR)
195
+ << "LayoutAnimationKeyFrameManager.cpp: got mutation list: Line: "
196
+ << to;
197
+ }
198
+ };
199
+ #endif
435
200
 
436
- for (auto inflightAnimationIt =
437
- inflightAnimations_.rbegin() + (skipLastAnimation ? 1 : 0);
438
- inflightAnimationIt != inflightAnimations_.rend();
439
- inflightAnimationIt++) {
440
- auto &inflightAnimation = *inflightAnimationIt;
441
- if (inflightAnimation.surfaceId != surfaceId) {
442
- continue;
443
- }
444
- if (inflightAnimation.completed) {
445
- continue;
201
+ // DEBUG ONLY: list existing inflight animations
202
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
203
+ LOG(ERROR) << "BEGINNING DISPLAYING ONGOING inflightAnimations_!";
204
+ int i = 0;
205
+ int j = 0;
206
+ for (auto const &inflightAnimation : inflightAnimations_) {
207
+ i++;
208
+ j = 0;
209
+ if (inflightAnimation.completed) {
210
+ continue;
211
+ }
212
+ for (auto &keyframe : inflightAnimation.keyFrames) {
213
+ j++;
214
+ if (keyframe.invalidated) {
215
+ continue;
216
+ }
217
+ for (const auto &finalMutationForKeyFrame :
218
+ keyframe.finalMutationsForKeyFrame) {
219
+ if (finalMutationForKeyFrame.mutatedViewIsVirtual()) {
220
+ std::string msg = "Animation " + std::to_string(i) + " keyframe " +
221
+ std::to_string(j) + ": Final Animation";
222
+ PrintMutationInstruction(msg, finalMutationForKeyFrame);
223
+ } else {
224
+ LOG(ERROR) << "Animation " << i << " keyframe " << j
225
+ << ": on tag: [" << keyframe.viewStart.tag << "]";
226
+ }
227
+ }
228
+ }
446
229
  }
230
+ LOG(ERROR) << "BEGINNING DONE DISPLAYING ONGOING inflightAnimations_!";
231
+ #endif
447
232
 
448
- for (auto it = inflightAnimation.keyFrames.begin();
449
- it != inflightAnimation.keyFrames.end();
450
- it++) {
451
- auto &animatedKeyFrame = *it;
233
+ PropsParserContext propsParserContext{surfaceId, *contextContainer_};
452
234
 
453
- if (animatedKeyFrame.invalidated) {
454
- continue;
455
- }
235
+ // What to do if we detect a conflict? Get current value and make
236
+ // that the baseline of the next animation. Scale the remaining time
237
+ // in the animation
238
+ // Types of conflicts and how we handle them:
239
+ // Update -> update: remove the previous update, make it the baseline of the
240
+ // next update (with current progress) Update -> remove: same, with final
241
+ // mutation being a remove Insert -> update: treat as update->update Insert
242
+ // -> remove: same, as update->remove Remove -> update/insert: not possible
243
+ // We just collect pairs here of <Mutation, AnimationConfig> and delete them
244
+ // from active animations. If another animation is queued up from the
245
+ // current mutations then these deleted mutations will serve as the baseline
246
+ // for the next animation. If not, the current mutations are executed
247
+ // immediately without issues.
248
+ std::vector<AnimationKeyFrame> conflictingAnimations{};
249
+ getAndEraseConflictingAnimations(
250
+ surfaceId, mutations, conflictingAnimations);
456
251
 
457
- // Detect if they're in the same view hierarchy, but not equivalent
458
- // We've already detected direct conflicts and removed them.
459
- if (animatedKeyFrame.parentView.tag != mutation.parentShadowView.tag) {
460
- continue;
252
+ // Are we animating this list of mutations?
253
+ better::optional<LayoutAnimation> currentAnimation{};
254
+ {
255
+ std::lock_guard<std::mutex> lock(currentAnimationMutex_);
256
+ if (currentAnimation_) {
257
+ currentAnimation = std::move(currentAnimation_);
258
+ currentAnimation_.reset();
461
259
  }
260
+ }
462
261
 
463
- for (auto &delayedMutation : animatedKeyFrame.finalMutationsForKeyFrame) {
464
- if (delayedMutation.type != ShadowViewMutation::Type::Remove) {
465
- continue;
262
+ if (currentAnimation.hasValue()) {
263
+ LayoutAnimation animation = std::move(currentAnimation).value();
264
+ animation.surfaceId = surfaceId;
265
+ animation.startTime = now;
266
+
267
+ // Pre-process list to:
268
+ // Catch remove+reinsert (reorders)
269
+ // Catch delete+create (reparenting) (this should be optimized away at
270
+ // the diffing level eventually?)
271
+ // TODO: to prevent this step we could tag Remove/Insert mutations as
272
+ // being moves on the Differ level, since we know that there? We could use
273
+ // TinyMap here, but it's not exposed by Differentiator (yet).
274
+ better::set<Tag> insertedTags;
275
+ better::set<Tag> deletedTags;
276
+ better::set<Tag> reparentedTags; // tags that are deleted and recreated
277
+ std::unordered_map<Tag, ShadowViewMutation> movedTags;
278
+ for (const auto &mutation : mutations) {
279
+ if (mutation.type == ShadowViewMutation::Type::Insert) {
280
+ insertedTags.insert(mutation.newChildShadowView.tag);
466
281
  }
467
- if (delayedMutation.mutatedViewIsVirtual()) {
468
- continue;
282
+ if (mutation.type == ShadowViewMutation::Type::Delete) {
283
+ deletedTags.insert(mutation.oldChildShadowView.tag);
469
284
  }
470
- if (delayedMutation.oldChildShadowView.tag ==
471
- (isRemoveMutation ? mutation.oldChildShadowView.tag
472
- : mutation.newChildShadowView.tag)) {
473
- continue;
285
+ if (mutation.type == ShadowViewMutation::Type::Create) {
286
+ if (deletedTags.find(mutation.newChildShadowView.tag) !=
287
+ deletedTags.end()) {
288
+ reparentedTags.insert(mutation.newChildShadowView.tag);
289
+ }
474
290
  }
475
-
476
- PrintMutationInstructionRelative(
477
- "[IndexAdjustment] adjustImmediateMutationIndicesForDelayedMutations CANDIDATE for:",
478
- mutation,
479
- delayedMutation);
480
- candidateMutations.push_back(&delayedMutation);
481
291
  }
482
- }
483
292
 
484
- if (lastAnimationOnly) {
485
- break;
486
- }
487
- }
293
+ // Process mutations list into operations that can be sent to platform
294
+ // immediately, and those that need to be animated Deletions, removals,
295
+ // updates are delayed and animated. Creations and insertions are sent to
296
+ // platform and then "animated in" with opacity updates. Upon completion,
297
+ // removals and deletions are sent to platform
298
+ ShadowViewMutation::List immediateMutations;
488
299
 
489
- // While the mutation keeps being affected, keep checking. We use the vector
490
- // so we only perform one adjustment per delayed mutation. See comments at
491
- // bottom of adjustDelayedMutationIndicesForMutation for further explanation.
492
- bool changed = true;
493
- int adjustedDelta = 0;
494
- while (changed) {
495
- changed = false;
496
- candidateMutations.erase(
497
- std::remove_if(
498
- candidateMutations.begin(),
499
- candidateMutations.end(),
500
- [&changed, &mutation, &adjustedDelta, &isRemoveMutation](
501
- ShadowViewMutation *candidateMutation) {
502
- bool indexConflicts =
503
- (candidateMutation->index < mutation.index ||
504
- (isRemoveMutation &&
505
- candidateMutation->index == mutation.index));
506
- if (indexConflicts) {
507
- mutation.index++;
508
- adjustedDelta++;
509
- changed = true;
510
- PrintMutationInstructionRelative(
511
- "[IndexAdjustment] adjustImmediateMutationIndicesForDelayedMutations: Adjusting mutation UPWARD",
512
- mutation,
513
- *candidateMutation);
514
- return true;
515
- }
516
- return false;
517
- }),
518
- candidateMutations.end());
519
- }
520
- }
521
-
522
- void LayoutAnimationKeyFrameManager::adjustDelayedMutationIndicesForMutation(
523
- SurfaceId surfaceId,
524
- ShadowViewMutation const &mutation,
525
- bool skipLastAnimation) const {
526
- bool isRemoveMutation = mutation.type == ShadowViewMutation::Type::Remove;
527
- bool isInsertMutation = mutation.type == ShadowViewMutation::Type::Insert;
528
- auto tag = isRemoveMutation ? mutation.oldChildShadowView.tag
529
- : mutation.newChildShadowView.tag;
530
- react_native_assert(isRemoveMutation || isInsertMutation);
300
+ // Remove operations that are actually moves should be copied to
301
+ // "immediate mutations". The corresponding "insert" will also be executed
302
+ // immediately and animated as an update.
303
+ std::vector<AnimationKeyFrame> keyFramesToAnimate;
304
+ auto const layoutAnimationConfig = animation.layoutAnimationConfig;
305
+ for (auto const &mutation : mutations) {
306
+ ShadowView baselineShadowView =
307
+ (mutation.type == ShadowViewMutation::Type::Delete ||
308
+ mutation.type == ShadowViewMutation::Type::Remove ||
309
+ mutation.type == ShadowViewMutation::Type::Update
310
+ ? mutation.oldChildShadowView
311
+ : mutation.newChildShadowView);
312
+ react_native_assert(baselineShadowView.tag > 0);
313
+ bool haveComponentDescriptor =
314
+ hasComponentDescriptorForShadowView(baselineShadowView);
531
315
 
532
- if (mutation.mutatedViewIsVirtual()) {
533
- PrintMutationInstruction(
534
- "[IndexAdjustment] Not calling adjustDelayedMutationIndicesForMutation, is virtual, for:",
535
- mutation);
536
- return;
537
- }
316
+ // Immediately execute any mutations on a root node
317
+ if (baselineShadowView.traits.check(
318
+ ShadowNodeTraits::Trait::RootNodeKind)) {
319
+ immediateMutations.push_back(mutation);
320
+ continue;
321
+ }
538
322
 
539
- // First, collect all final mutations that could impact this immediate
540
- // mutation.
541
- std::vector<ShadowViewMutation *> candidateMutations{};
323
+ better::optional<ShadowViewMutation> executeMutationImmediately{};
542
324
 
543
- for (auto inflightAnimationIt =
544
- inflightAnimations_.rbegin() + (skipLastAnimation ? 1 : 0);
545
- inflightAnimationIt != inflightAnimations_.rend();
546
- inflightAnimationIt++) {
547
- auto &inflightAnimation = *inflightAnimationIt;
325
+ bool isRemoveReinserted =
326
+ mutation.type == ShadowViewMutation::Type::Remove &&
327
+ insertedTags.find(mutation.oldChildShadowView.tag) !=
328
+ insertedTags.end();
548
329
 
549
- if (inflightAnimation.surfaceId != surfaceId) {
550
- continue;
551
- }
552
- if (inflightAnimation.completed) {
553
- continue;
554
- }
330
+ // Reparenting can result in a node being removed, inserted (moved) and
331
+ // also deleted and created in the same frame, with the same props etc.
332
+ // This should eventually be optimized out of the diffing algorithm, but
333
+ // for now we detect reparenting and prevent the corresponding
334
+ // Delete/Create instructions from being animated.
335
+ bool isReparented =
336
+ reparentedTags.find(baselineShadowView.tag) != reparentedTags.end();
555
337
 
556
- for (auto it = inflightAnimation.keyFrames.begin();
557
- it != inflightAnimation.keyFrames.end();
558
- it++) {
559
- auto &animatedKeyFrame = *it;
338
+ if (isRemoveReinserted) {
339
+ movedTags.insert({mutation.oldChildShadowView.tag, mutation});
340
+ }
560
341
 
561
- if (animatedKeyFrame.invalidated) {
562
- continue;
563
- }
342
+ // Inserts that follow a "remove" of the same tag should be treated as
343
+ // an update (move) animation.
344
+ bool wasInsertedTagRemoved = false;
345
+ auto movedIt = movedTags.end();
346
+ if (mutation.type == ShadowViewMutation::Type::Insert) {
347
+ // If this is a move, we actually don't want to copy this insert
348
+ // instruction to animated instructions - we want to
349
+ // generate an Update mutation for Remove+Insert pairs to animate
350
+ // the layout.
351
+ // The corresponding Remove and Insert instructions will instead
352
+ // be treated as "immediate" instructions.
353
+ movedIt = movedTags.find(mutation.newChildShadowView.tag);
354
+ wasInsertedTagRemoved = movedIt != movedTags.end();
355
+ }
564
356
 
565
- // Detect if they're in the same view hierarchy, but not equivalent
566
- // (We've already detected direct conflicts and handled them above)
567
- if (animatedKeyFrame.parentView.tag != mutation.parentShadowView.tag) {
568
- continue;
569
- }
357
+ auto const &mutationConfig =
358
+ (mutation.type == ShadowViewMutation::Type::Delete ||
359
+ (mutation.type == ShadowViewMutation::Type::Remove &&
360
+ !wasInsertedTagRemoved)
361
+ ? layoutAnimationConfig.deleteConfig
362
+ : (mutation.type == ShadowViewMutation::Type::Insert &&
363
+ !wasInsertedTagRemoved
364
+ ? layoutAnimationConfig.createConfig
365
+ : layoutAnimationConfig.updateConfig));
366
+ bool haveConfiguration =
367
+ mutationConfig.animationType != AnimationType::None;
570
368
 
571
- for (auto &finalAnimationMutation :
572
- animatedKeyFrame.finalMutationsForKeyFrame) {
573
- if (finalAnimationMutation.oldChildShadowView.tag == tag) {
574
- continue;
575
- }
369
+ // Creates and inserts should also be executed immediately.
370
+ // Mutations that would otherwise be animated, but have no
371
+ // configuration, are also executed immediately.
372
+ if (isRemoveReinserted || !haveConfiguration || isReparented ||
373
+ mutation.type == ShadowViewMutation::Type::Create ||
374
+ mutation.type == ShadowViewMutation::Type::Insert) {
375
+ executeMutationImmediately = mutation;
576
376
 
577
- if (finalAnimationMutation.type != ShadowViewMutation::Type::Remove) {
578
- continue;
579
- }
580
- if (finalAnimationMutation.mutatedViewIsVirtual()) {
581
- continue;
582
- }
377
+ // It is possible, especially in the case of "moves", that we have a
378
+ // sequence of operations like:
379
+ // UPDATE X
380
+ // REMOVE X
381
+ // INSERT X
382
+ // In these cases, we will have queued up an animation for the UPDATE
383
+ // and delayed its execution; the REMOVE and INSERT will be executed
384
+ // first; and then the UPDATE will be animating to/from ShadowViews
385
+ // that are out-of-sync with what's on the mounting layer. Thus, for
386
+ // any UPDATE animations already queued up for this tag, we adjust the
387
+ // "previous" ShadowView.
388
+ if (mutation.type == ShadowViewMutation::Type::Insert) {
389
+ for (auto &keyframe : keyFramesToAnimate) {
390
+ if (keyframe.tag == baselineShadowView.tag) {
391
+ // If there's already an animation queued up, followed by this
392
+ // Insert, it *must* be an Update mutation animation. Other
393
+ // sequences should not be possible.
394
+ react_native_assert(
395
+ keyframe.type == AnimationConfigurationType::Update);
583
396
 
584
- PrintMutationInstructionRelative(
585
- "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: CANDIDATE:",
586
- mutation,
587
- finalAnimationMutation);
588
- candidateMutations.push_back(&finalAnimationMutation);
589
- }
590
- }
591
- }
397
+ // The mutation is an "insert", so it must have a
398
+ // "newChildShadowView"
399
+ react_native_assert(mutation.newChildShadowView.tag > 0);
592
400
 
593
- // Because the finalAnimations are not sorted in any way, it is possible to
594
- // have some sequence like:
595
- // * DELAYED REMOVE 10 from {TAG}
596
- // * DELAYED REMOVE 9 from {TAG}
597
- // * ...
598
- // * DELAYED REMOVE 5 from {TAG}
599
- // with mutation: INSERT 6/REMOVE 6. This would cause the first few mutations
600
- // to *not* be adjusted, even though they would be impacted by mutation or
601
- // vice-versa after later adjustments are applied. Therefore, we just keep
602
- // recursing while there are any changes. This isn't great, but is good enough
603
- // for now until we change these data-structures.
604
- bool changed = true;
605
- while (changed) {
606
- changed = false;
607
- candidateMutations.erase(
608
- std::remove_if(
609
- candidateMutations.begin(),
610
- candidateMutations.end(),
611
- [&mutation, &isRemoveMutation, &isInsertMutation, &changed](
612
- ShadowViewMutation *candidateMutation) {
613
- if (isRemoveMutation &&
614
- mutation.index <= candidateMutation->index) {
615
- candidateMutation->index--;
616
- changed = true;
617
- PrintMutationInstructionRelative(
618
- "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: Adjusting mutation DOWNWARD",
619
- mutation,
620
- *candidateMutation);
621
- return true;
622
- } else if (
623
- isInsertMutation &&
624
- mutation.index <= candidateMutation->index) {
625
- candidateMutation->index++;
626
- changed = true;
627
- PrintMutationInstructionRelative(
628
- "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: Adjusting mutation UPWARD",
629
- mutation,
630
- *candidateMutation);
631
- return true;
401
+ // Those asserts don't run in prod. If there's some edge-case
402
+ // that we haven't caught yet, we'd crash in debug; make sure we
403
+ // don't mutate the prevView in prod.
404
+ if (keyframe.type == AnimationConfigurationType::Update &&
405
+ mutation.newChildShadowView.tag > 0) {
406
+ keyframe.viewPrev = mutation.newChildShadowView;
407
+ }
632
408
  }
633
- return false;
634
- }),
635
- candidateMutations.end());
636
- }
637
- }
638
-
639
- void LayoutAnimationKeyFrameManager::getAndEraseConflictingAnimations(
640
- SurfaceId surfaceId,
641
- ShadowViewMutationList const &mutations,
642
- std::vector<AnimationKeyFrame> &conflictingAnimations) const {
643
- ShadowViewMutationList localConflictingMutations{};
644
- for (auto const &mutation : mutations) {
645
- bool mutationIsCreateOrDelete =
646
- mutation.type == ShadowViewMutation::Type::Create ||
647
- mutation.type == ShadowViewMutation::Type::Delete;
648
- auto const &baselineShadowView =
649
- (mutation.type == ShadowViewMutation::Type::Insert ||
650
- mutation.type == ShadowViewMutation::Type::Create)
651
- ? mutation.newChildShadowView
652
- : mutation.oldChildShadowView;
653
- auto baselineTag = baselineShadowView.tag;
409
+ }
410
+ } else if (mutation.type == ShadowViewMutation::Type::Remove) {
411
+ for (auto &keyframe : keyFramesToAnimate) {
412
+ if (keyframe.tag == baselineShadowView.tag) {
413
+ // If there's already an animation queued up, followed by this
414
+ // Insert, it *must* be an Update mutation animation. Other
415
+ // sequences should not be possible.
416
+ react_native_assert(
417
+ keyframe.type == AnimationConfigurationType::Update);
654
418
 
655
- for (auto &inflightAnimation : inflightAnimations_) {
656
- if (inflightAnimation.surfaceId != surfaceId) {
657
- continue;
658
- }
659
- if (inflightAnimation.completed) {
660
- continue;
661
- }
419
+ // The mutation is a "remove", so it must have a
420
+ // "oldChildShadowView"
421
+ react_native_assert(mutation.oldChildShadowView.tag > 0);
662
422
 
663
- for (auto it = inflightAnimation.keyFrames.begin();
664
- it != inflightAnimation.keyFrames.end();) {
665
- auto &animatedKeyFrame = *it;
666
-
667
- if (animatedKeyFrame.invalidated) {
668
- continue;
423
+ // Those asserts don't run in prod. If there's some edge-case
424
+ // that we haven't caught yet, we'd crash in debug; make sure we
425
+ // don't mutate the prevView in prod.
426
+ // Since normally the UPDATE would have been executed first and
427
+ // now it's deferred, we need to change the `oldChildShadowView`
428
+ // that is being referenced by the REMOVE mutation.
429
+ if (keyframe.type == AnimationConfigurationType::Update &&
430
+ mutation.oldChildShadowView.tag > 0) {
431
+ executeMutationImmediately =
432
+ ShadowViewMutation::RemoveMutation(
433
+ mutation.parentShadowView,
434
+ keyframe.viewPrev,
435
+ mutation.index);
436
+ }
437
+ }
438
+ }
439
+ }
669
440
  }
670
441
 
671
- // A conflict is when either: the animated node itself is mutated
672
- // directly; or, the parent of the node is created or deleted. In cases
673
- // of reparenting - say, the parent is deleted but the node was moved to
674
- // a different parent first - the reparenting (remove/insert) conflict
675
- // will be detected before we process the parent DELETE.
676
- // Parent deletion is important because deleting a parent recursively
677
- // deletes all children. If we previously deferred deletion of a child,
678
- // we need to force deletion/removal to happen immediately.
679
- bool conflicting = animatedKeyFrame.tag == baselineTag ||
680
- (mutationIsCreateOrDelete &&
681
- animatedKeyFrame.parentView.tag == baselineTag &&
682
- animatedKeyFrame.parentView.tag != 0);
683
-
684
- // Conflicting animation detected: if we're mutating a tag under
685
- // animation, or deleting the parent of a tag under animation, or
686
- // reparenting.
687
- if (conflicting) {
688
- animatedKeyFrame.invalidated = true;
442
+ // Deletes, non-move inserts, updates get animated
443
+ if (!wasInsertedTagRemoved && !isRemoveReinserted && !isReparented &&
444
+ haveConfiguration &&
445
+ mutation.type != ShadowViewMutation::Type::Create) {
446
+ ShadowView viewStart = ShadowView(
447
+ mutation.type == ShadowViewMutation::Type::Insert
448
+ ? mutation.newChildShadowView
449
+ : mutation.oldChildShadowView);
450
+ react_native_assert(viewStart.tag > 0);
451
+ ShadowView viewFinal = ShadowView(
452
+ mutation.type == ShadowViewMutation::Type::Update
453
+ ? mutation.newChildShadowView
454
+ : viewStart);
455
+ react_native_assert(viewFinal.tag > 0);
456
+ ShadowView parent = mutation.parentShadowView;
457
+ react_native_assert(
458
+ parent.tag > 0 ||
459
+ mutation.type == ShadowViewMutation::Type::Update ||
460
+ mutation.type == ShadowViewMutation::Type::Delete);
461
+ Tag tag = viewStart.tag;
689
462
 
690
- // We construct a list of all conflicting animations, whether or not
691
- // they have a "final mutation" to execute. This is important with,
692
- // for example, "insert" mutations where the final update needs to set
693
- // opacity to "1", even if there's no final ShadowNode update.
694
- // TODO: don't animate virtual views in the first place?
695
- bool isVirtual = false;
696
- for (const auto &finalMutationForKeyFrame :
697
- animatedKeyFrame.finalMutationsForKeyFrame) {
698
- isVirtual =
699
- isVirtual || finalMutationForKeyFrame.mutatedViewIsVirtual();
463
+ AnimationKeyFrame keyFrame{};
464
+ if (mutation.type == ShadowViewMutation::Type::Insert) {
465
+ if (mutationConfig.animationProperty ==
466
+ AnimationProperty::Opacity &&
467
+ haveComponentDescriptor) {
468
+ auto props =
469
+ getComponentDescriptorForShadowView(baselineShadowView)
470
+ .cloneProps(propsParserContext, viewStart.props, {});
700
471
 
701
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
702
- PrintMutationInstructionRelative(
703
- "Found mutation that conflicts with existing in-flight animation:",
704
- mutation,
705
- finalMutationForKeyFrame);
706
- #endif
707
- }
472
+ if (baselineShadowView.traits.check(
473
+ ShadowNodeTraits::Trait::ViewKind)) {
474
+ auto const &viewProps =
475
+ *std::static_pointer_cast<ViewProps const>(props);
476
+ const_cast<ViewProps &>(viewProps).opacity = 0;
477
+ }
708
478
 
709
- conflictingAnimations.push_back(animatedKeyFrame);
710
- for (const auto &finalMutationForKeyFrame :
711
- animatedKeyFrame.finalMutationsForKeyFrame) {
712
- if (!isVirtual ||
713
- finalMutationForKeyFrame.type ==
714
- ShadowViewMutation::Type::Delete) {
715
- localConflictingMutations.push_back(finalMutationForKeyFrame);
479
+ react_native_assert(props != nullptr);
480
+ if (props != nullptr) {
481
+ viewStart.props = props;
482
+ }
716
483
  }
717
- }
484
+ bool isScaleX =
485
+ mutationConfig.animationProperty == AnimationProperty::ScaleX ||
486
+ mutationConfig.animationProperty == AnimationProperty::ScaleXY;
487
+ bool isScaleY =
488
+ mutationConfig.animationProperty == AnimationProperty::ScaleY ||
489
+ mutationConfig.animationProperty == AnimationProperty::ScaleXY;
490
+ if ((isScaleX || isScaleY) && haveComponentDescriptor) {
491
+ auto props =
492
+ getComponentDescriptorForShadowView(baselineShadowView)
493
+ .cloneProps(propsParserContext, viewStart.props, {});
494
+ if (baselineShadowView.traits.check(
495
+ ShadowNodeTraits::Trait::ViewKind)) {
496
+ auto const &viewProps =
497
+ *std::static_pointer_cast<ViewProps const>(props);
498
+ const_cast<ViewProps &>(viewProps).transform =
499
+ Transform::Scale(isScaleX ? 0 : 1, isScaleY ? 0 : 1, 1);
500
+ }
718
501
 
719
- // Delete from existing animation
720
- it = inflightAnimation.keyFrames.erase(it);
721
- } else {
722
- it++;
723
- }
724
- }
725
- }
726
- }
502
+ react_native_assert(props != nullptr);
503
+ if (props != nullptr) {
504
+ viewStart.props = props;
505
+ }
506
+ }
727
507
 
728
- // Recurse, in case conflicting mutations conflict with other existing
729
- // animations
730
- if (!localConflictingMutations.empty()) {
731
- getAndEraseConflictingAnimations(
732
- surfaceId, localConflictingMutations, conflictingAnimations);
733
- }
734
- }
508
+ PrintMutationInstruction(
509
+ "Setting up animation KeyFrame for INSERT mutation (Create animation)",
510
+ mutation);
735
511
 
736
- better::optional<MountingTransaction>
737
- LayoutAnimationKeyFrameManager::pullTransaction(
738
- SurfaceId surfaceId,
739
- MountingTransaction::Number transactionNumber,
740
- TransactionTelemetry const &telemetry,
741
- ShadowViewMutationList mutations) const {
742
- // Current time in milliseconds
743
- uint64_t now =
744
- std::chrono::duration_cast<std::chrono::milliseconds>(
745
- std::chrono::high_resolution_clock::now().time_since_epoch())
746
- .count();
512
+ keyFrame = AnimationKeyFrame{
513
+ /* .finalMutationsForKeyFrame = */ {},
514
+ /* .type = */ AnimationConfigurationType::Create,
515
+ /* .tag = */ tag,
516
+ /* .parentView = */ parent,
517
+ /* .viewStart = */ viewStart,
518
+ /* .viewEnd = */ viewFinal,
519
+ /* .viewPrev = */ baselineShadowView,
520
+ /* .initialProgress = */ 0};
521
+ } else if (mutation.type == ShadowViewMutation::Type::Delete) {
522
+ // This is just for assertion purposes.
523
+ // The NDEBUG check here is to satisfy the compiler in certain environments
524
+ // complaining about correspondingRemoveIt being unused.
525
+ #ifdef REACT_NATIVE_DEBUG
526
+ #ifndef NDEBUG
527
+ // This block is temporarily disabled to fix some internal builds.
528
+ // In some build configurations, we get a compiler error that
529
+ // `correspondingRemoveIt` is unused.
530
+ /* Tag deleteTag = mutation.oldChildShadowView.tag;
531
+ auto correspondingRemoveIt = std::find_if(
532
+ mutations.begin(),
533
+ mutations.end(),
534
+ [&deleteTag](auto &mutation) {
535
+ return mutation.type == ShadowViewMutation::Type::Remove &&
536
+ mutation.oldChildShadowView.tag == deleteTag;
537
+ });
538
+ react_native_assert(correspondingRemoveIt != mutations.end());
539
+ */
540
+ #endif
541
+ #endif
542
+ continue;
543
+ } else if (mutation.type == ShadowViewMutation::Type::Update) {
544
+ viewFinal = ShadowView(mutation.newChildShadowView);
747
545
 
748
- bool inflightAnimationsExistInitially = !inflightAnimations_.empty();
546
+ PrintMutationInstruction(
547
+ "Setting up animation KeyFrame for UPDATE mutation (Update animation)",
548
+ mutation);
749
549
 
750
- // Execute stopSurface on any ongoing animations
751
- if (inflightAnimationsExistInitially) {
752
- std::vector<SurfaceId> surfaceIdsToStop{};
753
- {
754
- std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
755
- surfaceIdsToStop = surfaceIdsToStop_;
756
- surfaceIdsToStop_ = {};
757
- }
550
+ keyFrame = AnimationKeyFrame{
551
+ /* .finalMutationsForKeyFrame = */ {mutation},
552
+ /* .type = */ AnimationConfigurationType::Update,
553
+ /* .tag = */ tag,
554
+ /* .parentView = */ parent,
555
+ /* .viewStart = */ viewStart,
556
+ /* .viewEnd = */ viewFinal,
557
+ /* .viewPrev = */ baselineShadowView,
558
+ /* .initialProgress = */ 0};
559
+ } else {
560
+ // This should just be "Remove" instructions that are not animated
561
+ // (either this is a "move", or there's a corresponding "Delete"
562
+ // that is animated).
563
+ react_native_assert(
564
+ mutation.type == ShadowViewMutation::Type::Remove);
758
565
 
759
- for (auto it = inflightAnimations_.begin();
760
- it != inflightAnimations_.end();) {
761
- const auto &animation = *it;
566
+ Tag removeTag = mutation.oldChildShadowView.tag;
567
+ auto correspondingInsertIt = std::find_if(
568
+ mutations.begin(),
569
+ mutations.end(),
570
+ [&removeTag](auto &mutation) {
571
+ return mutation.type == ShadowViewMutation::Type::Insert &&
572
+ mutation.newChildShadowView.tag == removeTag;
573
+ });
574
+ if (correspondingInsertIt == mutations.end()) {
575
+ // This is a REMOVE not paired with an INSERT (move), so it must
576
+ // be paired with a DELETE.
577
+ auto correspondingDeleteIt = std::find_if(
578
+ mutations.begin(),
579
+ mutations.end(),
580
+ [&removeTag](auto &mutation) {
581
+ return mutation.type == ShadowViewMutation::Type::Delete &&
582
+ mutation.oldChildShadowView.tag == removeTag;
583
+ });
584
+ react_native_assert(correspondingDeleteIt != mutations.end());
762
585
 
763
- if (std::find(
764
- surfaceIdsToStop.begin(),
765
- surfaceIdsToStop.end(),
766
- animation.surfaceId) != surfaceIdsToStop.end()) {
767
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
768
- LOG(ERROR)
769
- << "LayoutAnimations: stopping animation due to stopSurface on "
770
- << surfaceId;
771
- #endif
772
- it = inflightAnimations_.erase(it);
773
- } else {
774
- it++;
775
- }
776
- }
777
- }
586
+ auto deleteMutation = *correspondingDeleteIt;
778
587
 
779
- if (!mutations.empty()) {
780
- #ifdef RN_SHADOW_TREE_INTROSPECTION
781
- {
782
- std::stringstream ss(getDebugDescription(mutations, {}));
783
- std::string to;
784
- while (std::getline(ss, to, '\n')) {
785
- LOG(ERROR)
786
- << "LayoutAnimationKeyFrameManager.cpp: got mutation list: Line: "
787
- << to;
788
- }
789
- };
790
- #endif
588
+ if (mutationConfig.animationProperty ==
589
+ AnimationProperty::Opacity &&
590
+ haveComponentDescriptor) {
591
+ auto props =
592
+ getComponentDescriptorForShadowView(baselineShadowView)
593
+ .cloneProps(propsParserContext, viewFinal.props, {});
791
594
 
792
- // DEBUG ONLY: list existing inflight animations
793
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
794
- LOG(ERROR) << "BEGINNING DISPLAYING ONGOING inflightAnimations_!";
795
- int i = 0;
796
- int j = 0;
797
- for (auto const &inflightAnimation : inflightAnimations_) {
798
- i++;
799
- j = 0;
800
- if (inflightAnimation.completed) {
801
- continue;
802
- }
803
- for (auto &keyframe : inflightAnimation.keyFrames) {
804
- j++;
805
- if (keyframe.invalidated) {
806
- continue;
807
- }
808
- for (const auto &finalMutationForKeyFrame :
809
- keyframe.finalMutationsForKeyFrame) {
810
- if (finalMutationForKeyFrame.mutatedViewIsVirtual()) {
811
- std::string msg = "Animation " + std::to_string(i) + " keyframe " +
812
- std::to_string(j) + ": Final Animation";
813
- PrintMutationInstruction(msg, finalMutationForKeyFrame);
814
- } else {
815
- LOG(ERROR) << "Animation " << i << " keyframe " << j
816
- << ": on tag: [" << keyframe.viewStart.tag << "]";
817
- }
818
- }
819
- }
820
- }
821
- LOG(ERROR) << "BEGINNING DONE DISPLAYING ONGOING inflightAnimations_!";
822
- #endif
595
+ if (baselineShadowView.traits.check(
596
+ ShadowNodeTraits::Trait::ViewKind)) {
597
+ auto const &viewProps =
598
+ *std::static_pointer_cast<ViewProps const>(props);
599
+ const_cast<ViewProps &>(viewProps).opacity = 0;
600
+ }
823
601
 
824
- // What to do if we detect a conflict? Get current value and make
825
- // that the baseline of the next animation. Scale the remaining time
826
- // in the animation
827
- // Types of conflicts and how we handle them:
828
- // Update -> update: remove the previous update, make it the baseline of the
829
- // next update (with current progress) Update -> remove: same, with final
830
- // mutation being a remove Insert -> update: treat as update->update Insert
831
- // -> remove: same, as update->remove Remove -> update/insert: not possible
832
- // We just collect pairs here of <Mutation, AnimationConfig> and delete them
833
- // from active animations. If another animation is queued up from the
834
- // current mutations then these deleted mutations will serve as the baseline
835
- // for the next animation. If not, the current mutations are executed
836
- // immediately without issues.
837
- std::vector<AnimationKeyFrame> conflictingAnimations{};
838
- getAndEraseConflictingAnimations(
839
- surfaceId, mutations, conflictingAnimations);
602
+ react_native_assert(props != nullptr);
603
+ if (props != nullptr) {
604
+ viewFinal.props = props;
605
+ }
606
+ }
607
+ bool isScaleX = mutationConfig.animationProperty ==
608
+ AnimationProperty::ScaleX ||
609
+ mutationConfig.animationProperty ==
610
+ AnimationProperty::ScaleXY;
611
+ bool isScaleY = mutationConfig.animationProperty ==
612
+ AnimationProperty::ScaleY ||
613
+ mutationConfig.animationProperty ==
614
+ AnimationProperty::ScaleXY;
615
+ if ((isScaleX || isScaleY) && haveComponentDescriptor) {
616
+ auto props =
617
+ getComponentDescriptorForShadowView(baselineShadowView)
618
+ .cloneProps(propsParserContext, viewFinal.props, {});
840
619
 
841
- // Are we animating this list of mutations?
842
- better::optional<LayoutAnimation> currentAnimation{};
843
- {
844
- std::lock_guard<std::mutex> lock(currentAnimationMutex_);
845
- if (currentAnimation_) {
846
- currentAnimation = std::move(currentAnimation_);
847
- currentAnimation_ = {};
848
- }
849
- }
620
+ if (baselineShadowView.traits.check(
621
+ ShadowNodeTraits::Trait::ViewKind)) {
622
+ auto const &viewProps =
623
+ *std::static_pointer_cast<ViewProps const>(props);
624
+ const_cast<ViewProps &>(viewProps).transform =
625
+ Transform::Scale(isScaleX ? 0 : 1, isScaleY ? 0 : 1, 1);
626
+ }
850
627
 
851
- if (currentAnimation) {
852
- LayoutAnimation animation = std::move(currentAnimation.value());
853
- currentAnimation = {};
854
- animation.surfaceId = surfaceId;
855
- animation.startTime = now;
628
+ react_native_assert(props != nullptr);
629
+ if (props != nullptr) {
630
+ viewFinal.props = props;
631
+ }
632
+ }
856
633
 
857
- // Pre-process list to:
858
- // Catch remove+reinsert (reorders)
859
- // Catch delete+create (reparenting) (this should be optimized away at
860
- // the diffing level eventually?)
861
- // TODO: to prevent this step we could tag Remove/Insert mutations as
862
- // being moves on the Differ level, since we know that there? We could use
863
- // TinyMap here, but it's not exposed by Differentiator (yet).
864
- std::vector<Tag> insertedTags;
865
- std::vector<Tag> deletedTags;
866
- std::vector<Tag> reparentedTags; // tags that are deleted and recreated
867
- std::unordered_map<Tag, ShadowViewMutation> movedTags;
868
- for (const auto &mutation : mutations) {
869
- if (mutation.type == ShadowViewMutation::Type::Insert) {
870
- insertedTags.push_back(mutation.newChildShadowView.tag);
871
- }
872
- if (mutation.type == ShadowViewMutation::Type::Delete) {
873
- deletedTags.push_back(mutation.oldChildShadowView.tag);
874
- }
875
- if (mutation.type == ShadowViewMutation::Type::Create) {
876
- if (std::find(
877
- deletedTags.begin(),
878
- deletedTags.end(),
879
- mutation.newChildShadowView.tag) != deletedTags.end()) {
880
- reparentedTags.push_back(mutation.newChildShadowView.tag);
634
+ PrintMutationInstruction(
635
+ "Setting up animation KeyFrame for REMOVE mutation (Delete animation)",
636
+ mutation);
637
+
638
+ keyFrame = AnimationKeyFrame{
639
+ /* .finalMutationsForKeyFrame */ {mutation, deleteMutation},
640
+ /* .type */ AnimationConfigurationType::Delete,
641
+ /* .tag */ tag,
642
+ /* .parentView */ parent,
643
+ /* .viewStart */ viewStart,
644
+ /* .viewEnd */ viewFinal,
645
+ /* .viewPrev */ baselineShadowView,
646
+ /* .initialProgress */ 0};
647
+ } else {
648
+ PrintMutationInstruction(
649
+ "Executing Remove Immediately, due to reordering operation",
650
+ mutation);
651
+ immediateMutations.push_back(mutation);
652
+ continue;
653
+ }
881
654
  }
882
- }
883
- }
884
655
 
885
- // Process mutations list into operations that can be sent to platform
886
- // immediately, and those that need to be animated Deletions, removals,
887
- // updates are delayed and animated. Creations and insertions are sent to
888
- // platform and then "animated in" with opacity updates. Upon completion,
889
- // removals and deletions are sent to platform
890
- ShadowViewMutation::List immediateMutations;
656
+ // Handle conflicting animations
657
+ for (auto &conflictingKeyFrame : conflictingAnimations) {
658
+ auto const &conflictingMutationBaselineShadowView =
659
+ conflictingKeyFrame.viewStart;
891
660
 
892
- // Remove operations that are actually moves should be copied to
893
- // "immediate mutations". The corresponding "insert" will also be executed
894
- // immediately and animated as an update.
895
- std::vector<AnimationKeyFrame> keyFramesToAnimate;
896
- std::vector<AnimationKeyFrame> movesToAnimate;
897
- auto const layoutAnimationConfig = animation.layoutAnimationConfig;
898
- for (auto const &mutation : mutations) {
899
- ShadowView baselineShadowView =
900
- (mutation.type == ShadowViewMutation::Type::Delete ||
901
- mutation.type == ShadowViewMutation::Type::Remove ||
902
- mutation.type == ShadowViewMutation::Type::Update
903
- ? mutation.oldChildShadowView
904
- : mutation.newChildShadowView);
905
- react_native_assert(baselineShadowView.tag > 0);
906
- bool haveComponentDescriptor =
907
- hasComponentDescriptorForShadowView(baselineShadowView);
661
+ // We've found a conflict.
662
+ if (conflictingMutationBaselineShadowView.tag == tag) {
663
+ conflictingKeyFrame.generateFinalSyntheticMutations = false;
908
664
 
909
- bool executeMutationImmediately = false;
665
+ // Do NOT update viewStart for a CREATE animation.
666
+ if (keyFrame.type == AnimationConfigurationType::Create) {
667
+ break;
668
+ }
910
669
 
911
- bool isRemoveReinserted =
912
- mutation.type == ShadowViewMutation::Type::Remove &&
913
- std::find(
914
- insertedTags.begin(),
915
- insertedTags.end(),
916
- mutation.oldChildShadowView.tag) != insertedTags.end();
670
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
671
+ LOG(ERROR)
672
+ << "Due to conflict, replacing 'viewStart' of animated keyframe: ["
673
+ << conflictingKeyFrame.viewPrev.tag << "] with ##"
674
+ << std::hash<ShadowView>{}(conflictingKeyFrame.viewPrev);
675
+ #endif
676
+ // Pick a Prop or layout property, depending on the current
677
+ // animation configuration. Figure out how much progress we've
678
+ // already made in the current animation, and start the animation
679
+ // from this point.
680
+ keyFrame.viewPrev = conflictingKeyFrame.viewPrev;
681
+ keyFrame.viewStart = conflictingKeyFrame.viewPrev;
682
+ react_native_assert(keyFrame.viewStart.tag > 0);
683
+ keyFrame.initialProgress = 0;
917
684
 
918
- // Reparenting can result in a node being removed, inserted (moved) and
919
- // also deleted and created in the same frame, with the same props etc.
920
- // This should eventually be optimized out of the diffing algorithm, but
921
- // for now we detect reparenting and prevent the corresponding
922
- // Delete/Create instructions from being animated.
923
- bool isReparented = std::find(
924
- reparentedTags.begin(),
925
- reparentedTags.end(),
926
- baselineShadowView.tag) != reparentedTags.end();
685
+ // We're guaranteed that a tag only has one animation associated
686
+ // with it, so we can break here. If we support multiple
687
+ // animations and animation curves over the same tag in the
688
+ // future, this will need to be modified to support that.
689
+ break;
690
+ }
691
+ }
927
692
 
928
- if (isRemoveReinserted) {
929
- movedTags.insert({mutation.oldChildShadowView.tag, mutation});
693
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
694
+ LOG(ERROR) << "Checking validity of keyframe: ["
695
+ << keyFrame.viewStart.tag << "] [" << keyFrame.viewEnd.tag
696
+ << "] [" << keyFrame.viewPrev.tag
697
+ << "] animation type: " << (int)keyFrame.type;
698
+ #endif
699
+ react_native_assert(keyFrame.viewStart.tag > 0);
700
+ react_native_assert(keyFrame.viewEnd.tag > 0);
701
+ react_native_assert(keyFrame.viewPrev.tag > 0);
702
+ keyFramesToAnimate.push_back(keyFrame);
930
703
  }
931
704
 
932
- // Inserts that follow a "remove" of the same tag should be treated as
933
- // an update (move) animation.
934
- bool wasInsertedTagRemoved = false;
935
- auto movedIt = movedTags.end();
936
- if (mutation.type == ShadowViewMutation::Type::Insert) {
937
- // If this is a move, we actually don't want to copy this insert
938
- // instruction to animated instructions - we want to
939
- // generate an Update mutation for Remove+Insert pairs to animate
940
- // the layout.
941
- // The corresponding Remove and Insert instructions will instead
942
- // be treated as "immediate" instructions.
943
- movedIt = movedTags.find(mutation.newChildShadowView.tag);
944
- wasInsertedTagRemoved = movedIt != movedTags.end();
705
+ if (executeMutationImmediately.hasValue()) {
706
+ PrintMutationInstruction(
707
+ "Queue Up For Immediate Execution", *executeMutationImmediately);
708
+ immediateMutations.push_back(*executeMutationImmediately);
945
709
  }
710
+ }
946
711
 
947
- auto const &mutationConfig =
948
- (mutation.type == ShadowViewMutation::Type::Delete ||
949
- (mutation.type == ShadowViewMutation::Type::Remove &&
950
- !wasInsertedTagRemoved)
951
- ? layoutAnimationConfig.deleteConfig
952
- : (mutation.type == ShadowViewMutation::Type::Insert &&
953
- !wasInsertedTagRemoved
954
- ? layoutAnimationConfig.createConfig
955
- : layoutAnimationConfig.updateConfig));
956
- bool haveConfiguration =
957
- mutationConfig.animationType != AnimationType::None;
958
-
959
- if (wasInsertedTagRemoved && haveConfiguration) {
960
- movesToAnimate.push_back(AnimationKeyFrame{
961
- {},
962
- AnimationConfigurationType::Update,
963
- mutation.newChildShadowView.tag,
964
- mutation.parentShadowView,
965
- movedIt->second.oldChildShadowView,
966
- mutation.newChildShadowView});
712
+ #ifdef RN_SHADOW_TREE_INTROSPECTION
713
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
714
+ {
715
+ int idx = 0;
716
+ for (auto &mutation : immediateMutations) {
717
+ PrintMutationInstruction(
718
+ std::string("IMMEDIATE list: ") + std::to_string(idx) + "/" +
719
+ std::to_string(immediateMutations.size()),
720
+ mutation);
721
+ idx++;
967
722
  }
723
+ }
968
724
 
969
- // Creates and inserts should also be executed immediately.
970
- // Mutations that would otherwise be animated, but have no
971
- // configuration, are also executed immediately.
972
- if (isRemoveReinserted || !haveConfiguration || isReparented ||
973
- mutation.type == ShadowViewMutation::Type::Create ||
974
- mutation.type == ShadowViewMutation::Type::Insert) {
975
- executeMutationImmediately = true;
976
-
977
- // It is possible, especially in the case of "moves", that we have a
978
- // sequence of operations like:
979
- // UPDATE X
980
- // REMOVE X
981
- // INSERT X
982
- // In these cases, we will have queued up an animation for the UPDATE
983
- // and delayed its execution; the REMOVE and INSERT will be executed
984
- // first; and then the UPDATE will be animating to/from ShadowViews
985
- // that are out-of-sync with what's on the mounting layer. Thus, for
986
- // any UPDATE animations already queued up for this tag, we adjust the
987
- // "previous" ShadowView.
988
- if (mutation.type == ShadowViewMutation::Type::Insert) {
989
- for (auto &keyframe : keyFramesToAnimate) {
990
- if (keyframe.tag == baselineShadowView.tag) {
991
- // If there's already an animation queued up, followed by this
992
- // Insert, it *must* be an Update mutation animation. Other
993
- // sequences should not be possible.
994
- react_native_assert(
995
- keyframe.type == AnimationConfigurationType::Update);
996
-
997
- // The mutation is an "insert", so it must have a
998
- // "newChildShadowView"
999
- react_native_assert(mutation.newChildShadowView.tag > 0);
1000
-
1001
- // Those asserts don't run in prod. If there's some edge-case
1002
- // that we haven't caught yet, we'd crash in debug; make sure we
1003
- // don't mutate the prevView in prod.
1004
- if (keyframe.type == AnimationConfigurationType::Update &&
1005
- mutation.newChildShadowView.tag > 0) {
1006
- keyframe.viewPrev = mutation.newChildShadowView;
1007
- }
1008
- }
1009
- }
725
+ {
726
+ int idx = 0;
727
+ for (const auto &keyframe : keyFramesToAnimate) {
728
+ for (const auto &finalMutationForKeyFrame :
729
+ keyframe.finalMutationsForKeyFrame) {
730
+ PrintMutationInstruction(
731
+ std::string("FINAL list: ") + std::to_string(idx) + "/" +
732
+ std::to_string(keyFramesToAnimate.size()),
733
+ finalMutationForKeyFrame);
1010
734
  }
735
+ idx++;
1011
736
  }
1012
-
1013
- // Deletes, non-move inserts, updates get animated
1014
- if (!wasInsertedTagRemoved && !isRemoveReinserted && !isReparented &&
1015
- haveConfiguration &&
1016
- mutation.type != ShadowViewMutation::Type::Create) {
1017
- ShadowView viewStart = ShadowView(
1018
- mutation.type == ShadowViewMutation::Type::Insert
1019
- ? mutation.newChildShadowView
1020
- : mutation.oldChildShadowView);
1021
- react_native_assert(viewStart.tag > 0);
1022
- ShadowView viewFinal = ShadowView(
1023
- mutation.type == ShadowViewMutation::Type::Update
1024
- ? mutation.newChildShadowView
1025
- : viewStart);
1026
- react_native_assert(viewFinal.tag > 0);
1027
- ShadowView parent = mutation.parentShadowView;
1028
- react_native_assert(
1029
- parent.tag > 0 ||
1030
- mutation.type == ShadowViewMutation::Type::Update ||
1031
- mutation.type == ShadowViewMutation::Type::Delete);
1032
- Tag tag = viewStart.tag;
1033
-
1034
- AnimationKeyFrame keyFrame{};
1035
- if (mutation.type == ShadowViewMutation::Type::Insert) {
1036
- if (mutationConfig.animationProperty ==
1037
- AnimationProperty::Opacity &&
1038
- haveComponentDescriptor) {
1039
- auto props =
1040
- getComponentDescriptorForShadowView(baselineShadowView)
1041
- .cloneProps(viewStart.props, {});
1042
-
1043
- // Dynamic cast, because - we don't know the type of this
1044
- // ShadowNode, it could be Image or Text or something else with
1045
- // different base props.
1046
- const auto viewProps =
1047
- dynamic_cast<const ViewProps *>(props.get());
1048
- if (viewProps != nullptr) {
1049
- const_cast<ViewProps *>(viewProps)->opacity = 0;
1050
- }
1051
-
1052
- react_native_assert(props != nullptr);
1053
- if (props != nullptr) {
1054
- viewStart.props = props;
1055
- }
1056
- }
1057
- bool isScaleX =
1058
- mutationConfig.animationProperty == AnimationProperty::ScaleX ||
1059
- mutationConfig.animationProperty == AnimationProperty::ScaleXY;
1060
- bool isScaleY =
1061
- mutationConfig.animationProperty == AnimationProperty::ScaleY ||
1062
- mutationConfig.animationProperty == AnimationProperty::ScaleXY;
1063
- if ((isScaleX || isScaleY) && haveComponentDescriptor) {
1064
- auto props =
1065
- getComponentDescriptorForShadowView(baselineShadowView)
1066
- .cloneProps(viewStart.props, {});
1067
-
1068
- // Dynamic cast, because - we don't know the type of this
1069
- // ShadowNode, it could be Image or Text or something else with
1070
- // different base props.
1071
- const auto viewProps =
1072
- dynamic_cast<const ViewProps *>(props.get());
1073
- if (viewProps != nullptr) {
1074
- const_cast<ViewProps *>(viewProps)->transform =
1075
- Transform::Scale(isScaleX ? 0 : 1, isScaleY ? 0 : 1, 1);
1076
- }
1077
-
1078
- react_native_assert(props != nullptr);
1079
- if (props != nullptr) {
1080
- viewStart.props = props;
1081
- }
1082
- }
1083
-
1084
- PrintMutationInstruction(
1085
- "Setting up animation KeyFrame for INSERT mutation (Create animation)",
1086
- mutation);
1087
-
1088
- keyFrame = AnimationKeyFrame{
1089
- {},
1090
- AnimationConfigurationType::Create,
1091
- tag,
1092
- parent,
1093
- viewStart,
1094
- viewFinal,
1095
- baselineShadowView,
1096
- 0};
1097
- } else if (mutation.type == ShadowViewMutation::Type::Delete) {
1098
- // This is just for assertion purposes.
1099
- // The NDEBUG check here is to satisfy the compiler in certain environments
1100
- // complaining about correspondingRemoveIt being unused.
1101
- #ifdef REACT_NATIVE_DEBUG
1102
- #ifndef NDEBUG
1103
- // This block is temporarily disabled to fix some internal builds.
1104
- // In some build configurations, we get a compiler error that
1105
- // `correspondingRemoveIt` is unused.
1106
- /* Tag deleteTag = mutation.oldChildShadowView.tag;
1107
- auto correspondingRemoveIt = std::find_if(
1108
- mutations.begin(),
1109
- mutations.end(),
1110
- [&deleteTag](auto &mutation) {
1111
- return mutation.type == ShadowViewMutation::Type::Remove &&
1112
- mutation.oldChildShadowView.tag == deleteTag;
1113
- });
1114
- react_native_assert(correspondingRemoveIt != mutations.end());
1115
- */
1116
- #endif
1117
- #endif
1118
- continue;
1119
- } else if (mutation.type == ShadowViewMutation::Type::Update) {
1120
- viewFinal = ShadowView(mutation.newChildShadowView);
1121
-
1122
- PrintMutationInstruction(
1123
- "Setting up animation KeyFrame for UPDATE mutation (Update animation)",
1124
- mutation);
1125
-
1126
- keyFrame = AnimationKeyFrame{
1127
- {mutation},
1128
- AnimationConfigurationType::Update,
1129
- tag,
1130
- parent,
1131
- viewStart,
1132
- viewFinal,
1133
- baselineShadowView,
1134
- 0};
1135
- } else {
1136
- // This should just be "Remove" instructions that are not animated
1137
- // (either this is a "move", or there's a corresponding "Delete"
1138
- // that is animated).
1139
- react_native_assert(
1140
- mutation.type == ShadowViewMutation::Type::Remove);
1141
-
1142
- Tag removeTag = mutation.oldChildShadowView.tag;
1143
- auto correspondingInsertIt = std::find_if(
1144
- mutations.begin(),
1145
- mutations.end(),
1146
- [&removeTag](auto &mutation) {
1147
- return mutation.type == ShadowViewMutation::Type::Insert &&
1148
- mutation.newChildShadowView.tag == removeTag;
1149
- });
1150
- if (correspondingInsertIt == mutations.end()) {
1151
- // This is a REMOVE not paired with an INSERT (move), so it must
1152
- // be paired with a DELETE.
1153
- auto correspondingDeleteIt = std::find_if(
1154
- mutations.begin(),
1155
- mutations.end(),
1156
- [&removeTag](auto &mutation) {
1157
- return mutation.type == ShadowViewMutation::Type::Delete &&
1158
- mutation.oldChildShadowView.tag == removeTag;
1159
- });
1160
- react_native_assert(correspondingDeleteIt != mutations.end());
1161
-
1162
- auto deleteMutation = *correspondingDeleteIt;
1163
-
1164
- if (mutationConfig.animationProperty ==
1165
- AnimationProperty::Opacity &&
1166
- haveComponentDescriptor) {
1167
- auto props =
1168
- getComponentDescriptorForShadowView(baselineShadowView)
1169
- .cloneProps(viewFinal.props, {});
1170
-
1171
- // Dynamic cast, because - we don't know the type of this
1172
- // ShadowNode, it could be Image or Text or something else with
1173
- // different base props.
1174
- const auto viewProps =
1175
- dynamic_cast<const ViewProps *>(props.get());
1176
- if (viewProps != nullptr) {
1177
- const_cast<ViewProps *>(viewProps)->opacity = 0;
1178
- }
1179
-
1180
- react_native_assert(props != nullptr);
1181
- if (props != nullptr) {
1182
- viewFinal.props = props;
1183
- }
1184
- }
1185
- bool isScaleX = mutationConfig.animationProperty ==
1186
- AnimationProperty::ScaleX ||
1187
- mutationConfig.animationProperty ==
1188
- AnimationProperty::ScaleXY;
1189
- bool isScaleY = mutationConfig.animationProperty ==
1190
- AnimationProperty::ScaleY ||
1191
- mutationConfig.animationProperty ==
1192
- AnimationProperty::ScaleXY;
1193
- if ((isScaleX || isScaleY) && haveComponentDescriptor) {
1194
- auto props =
1195
- getComponentDescriptorForShadowView(baselineShadowView)
1196
- .cloneProps(viewFinal.props, {});
1197
-
1198
- // Dynamic cast, because - we don't know the type of this
1199
- // ShadowNode, it could be Image or Text or something else with
1200
- // different base props.
1201
- const auto viewProps =
1202
- dynamic_cast<const ViewProps *>(props.get());
1203
- if (viewProps != nullptr) {
1204
- const_cast<ViewProps *>(viewProps)->transform =
1205
- Transform::Scale(isScaleX ? 0 : 1, isScaleY ? 0 : 1, 1);
1206
- }
1207
-
1208
- react_native_assert(props != nullptr);
1209
- if (props != nullptr) {
1210
- viewFinal.props = props;
1211
- }
1212
- }
1213
-
1214
- PrintMutationInstruction(
1215
- "Setting up animation KeyFrame for REMOVE mutation (Delete animation)",
1216
- mutation);
1217
-
1218
- keyFrame = AnimationKeyFrame{
1219
- {mutation, deleteMutation},
1220
- AnimationConfigurationType::Delete,
1221
- tag,
1222
- parent,
1223
- viewStart,
1224
- viewFinal,
1225
- baselineShadowView,
1226
- 0};
1227
- } else {
1228
- PrintMutationInstruction(
1229
- "Executing Remove Immediately, due to reordering operation",
1230
- mutation);
1231
- immediateMutations.push_back(mutation);
1232
- continue;
1233
- }
1234
- }
1235
-
1236
- // Handle conflicting animations
1237
- for (auto &conflictingKeyFrame : conflictingAnimations) {
1238
- auto const &conflictingMutationBaselineShadowView =
1239
- conflictingKeyFrame.viewStart;
1240
-
1241
- // We've found a conflict.
1242
- if (conflictingMutationBaselineShadowView.tag == tag) {
1243
- conflictingKeyFrame.generateFinalSyntheticMutations = false;
1244
-
1245
- // Do NOT update viewStart for a CREATE animation.
1246
- if (keyFrame.type == AnimationConfigurationType::Create) {
1247
- break;
1248
- }
1249
-
1250
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1251
- LOG(ERROR)
1252
- << "Due to conflict, replacing 'viewStart' of animated keyframe: ["
1253
- << conflictingKeyFrame.viewPrev.tag << "] with ##"
1254
- << std::hash<ShadowView>{}(conflictingKeyFrame.viewPrev);
1255
- #endif
1256
- // Pick a Prop or layout property, depending on the current
1257
- // animation configuration. Figure out how much progress we've
1258
- // already made in the current animation, and start the animation
1259
- // from this point.
1260
- keyFrame.viewPrev = conflictingKeyFrame.viewPrev;
1261
- keyFrame.viewStart = conflictingKeyFrame.viewPrev;
1262
- react_native_assert(keyFrame.viewStart.tag > 0);
1263
- keyFrame.initialProgress = 0;
1264
-
1265
- // We're guaranteed that a tag only has one animation associated
1266
- // with it, so we can break here. If we support multiple
1267
- // animations and animation curves over the same tag in the
1268
- // future, this will need to be modified to support that.
1269
- break;
1270
- }
1271
- }
1272
-
1273
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1274
- LOG(ERROR) << "Checking validity of keyframe: ["
1275
- << keyFrame.viewStart.tag << "] [" << keyFrame.viewEnd.tag
1276
- << "] [" << keyFrame.viewPrev.tag
1277
- << "] animation type: " << (int)keyFrame.type;
1278
- #endif
1279
- react_native_assert(keyFrame.viewStart.tag > 0);
1280
- react_native_assert(keyFrame.viewEnd.tag > 0);
1281
- react_native_assert(keyFrame.viewPrev.tag > 0);
1282
- keyFramesToAnimate.push_back(keyFrame);
1283
- }
1284
-
1285
- if (executeMutationImmediately) {
1286
- PrintMutationInstruction(
1287
- "Queue Up Animation For Immediate Execution", mutation);
1288
- immediateMutations.push_back(mutation);
1289
- }
1290
- }
1291
-
1292
- #ifdef RN_SHADOW_TREE_INTROSPECTION
1293
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1294
- {
1295
- int idx = 0;
1296
- for (auto &mutation : immediateMutations) {
1297
- PrintMutationInstruction(
1298
- std::string("IMMEDIATE list: ") + std::to_string(idx) + "/" +
1299
- std::to_string(immediateMutations.size()),
1300
- mutation);
1301
- idx++;
1302
- }
1303
- }
1304
-
1305
- {
1306
- int idx = 0;
1307
- for (const auto &keyframe : keyFramesToAnimate) {
1308
- for (const auto &finalMutationForKeyFrame :
1309
- keyframe.finalMutationsForKeyFrame) {
1310
- PrintMutationInstruction(
1311
- std::string("FINAL list: ") + std::to_string(idx) + "/" +
1312
- std::to_string(keyFramesToAnimate.size()),
1313
- finalMutationForKeyFrame);
1314
- }
1315
- idx++;
1316
- }
1317
- }
1318
- #endif
1319
- #endif
737
+ }
738
+ #endif
739
+ #endif
1320
740
 
1321
741
  auto finalConflictingMutations = ShadowViewMutationList{};
1322
742
  for (auto &keyFrame : conflictingAnimations) {
@@ -1362,7 +782,7 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1362
782
  // don't want to queue up any final UPDATE mutations here.
1363
783
  bool shouldGenerateSyntheticMutations =
1364
784
  keyFrame.generateFinalSyntheticMutations;
1365
- bool numFinalMutations = keyFrame.finalMutationsForKeyFrame.size();
785
+ auto numFinalMutations = keyFrame.finalMutationsForKeyFrame.size();
1366
786
  bool onlyMutationIsUpdate =
1367
787
  (numFinalMutations == 1 &&
1368
788
  keyFrame.finalMutationsForKeyFrame[0].type ==
@@ -1522,328 +942,738 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1522
942
  "Conflict with non-animated mutation");
1523
943
  }
1524
944
 
1525
- // Make sure that all operations execute in the proper order.
1526
- // REMOVE operations with highest indices must operate first.
1527
- std::stable_sort(
1528
- finalMutationsForConflictingAnimations.begin(),
1529
- finalMutationsForConflictingAnimations.end(),
1530
- &shouldFirstComeBeforeSecondMutation);
945
+ // Make sure that all operations execute in the proper order.
946
+ // REMOVE operations with highest indices must operate first.
947
+ std::stable_sort(
948
+ finalMutationsForConflictingAnimations.begin(),
949
+ finalMutationsForConflictingAnimations.end(),
950
+ &shouldFirstComeBeforeSecondMutation);
951
+
952
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
953
+ LOG(ERROR)
954
+ << "No Animation: Adjust delayed mutations based on all finalMutationsForConflictingAnimations";
955
+ #endif
956
+ for (auto const &mutation : finalMutationsForConflictingAnimations) {
957
+ if (mutation.type == ShadowViewMutation::Type::Remove ||
958
+ mutation.type == ShadowViewMutation::Type::Insert) {
959
+ adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
960
+ }
961
+ }
962
+
963
+ // The ShadowTree layer doesn't realize that certain operations have
964
+ // been delayed, so we must adjust all Remove and Insert operations
965
+ // based on what else has been deferred, whether we are executing this
966
+ // immediately or later.
967
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
968
+ LOG(ERROR)
969
+ << "No Animation: Adjust mutations based on remaining delayed mutations / adjust delayed, based on each";
970
+ #endif
971
+ for (auto &mutation : mutations) {
972
+ if (mutation.type == ShadowViewMutation::Type::Remove ||
973
+ mutation.type == ShadowViewMutation::Type::Insert) {
974
+ adjustImmediateMutationIndicesForDelayedMutations(
975
+ surfaceId, mutation);
976
+ adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
977
+ }
978
+ }
979
+
980
+ // Append mutations to this list and swap - so that the final
981
+ // conflicting mutations happen before any other mutations
982
+ finalMutationsForConflictingAnimations.insert(
983
+ finalMutationsForConflictingAnimations.end(),
984
+ mutations.begin(),
985
+ mutations.end());
986
+ mutations = finalMutationsForConflictingAnimations;
987
+ }
988
+ } // if (mutations)
989
+
990
+ // We never commit a different root or modify anything -
991
+ // we just send additional mutations to the mounting layer until the
992
+ // animations are finished and the mounting layer (view) represents exactly
993
+ // what is in the most recent shadow tree
994
+ // Add animation mutations to the end of our existing mutations list in this
995
+ // function.
996
+ ShadowViewMutationList mutationsForAnimation{};
997
+ animationMutationsForFrame(surfaceId, mutationsForAnimation, now);
998
+
999
+ // If any delayed removes were executed, update remaining delayed keyframes
1000
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1001
+ LOG(ERROR)
1002
+ << "Adjust all delayed mutations based on final mutations generated by animation driver";
1003
+ #endif
1004
+ for (auto const &mutation : mutationsForAnimation) {
1005
+ if (mutation.type == ShadowViewMutation::Type::Remove) {
1006
+ adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
1007
+ }
1008
+ }
1009
+
1010
+ mutations.insert(
1011
+ mutations.end(),
1012
+ mutationsForAnimation.begin(),
1013
+ mutationsForAnimation.end());
1014
+
1015
+ // DEBUG ONLY: list existing inflight animations
1016
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1017
+ LOG(ERROR) << "FINISHING DISPLAYING ONGOING inflightAnimations_!";
1018
+ int i = 0;
1019
+ int j = 0;
1020
+ for (auto const &inflightAnimation : inflightAnimations_) {
1021
+ i++;
1022
+ j = 0;
1023
+ if (inflightAnimation.completed) {
1024
+ continue;
1025
+ }
1026
+ for (auto &keyframe : inflightAnimation.keyFrames) {
1027
+ j++;
1028
+ if (keyframe.invalidated) {
1029
+ continue;
1030
+ }
1031
+ for (auto const &finalMutation : keyframe.finalMutationsForKeyFrame) {
1032
+ if (!finalMutation.mutatedViewIsVirtual()) {
1033
+ std::string msg = "Animation " + std::to_string(i) + " keyframe " +
1034
+ std::to_string(j) + ": Final Animation";
1035
+ PrintMutationInstruction(msg, finalMutation);
1036
+ }
1037
+ }
1038
+ }
1039
+ }
1040
+ LOG(ERROR) << "FINISHING DONE DISPLAYING ONGOING inflightAnimations_!";
1041
+ #endif
1042
+
1043
+ // Signal to delegate if all animations are complete, or if we were not
1044
+ // animating anything and now some animation exists.
1045
+ if (inflightAnimationsExistInitially && inflightAnimations_.empty()) {
1046
+ std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
1047
+ if (layoutAnimationStatusDelegate_ != nullptr) {
1048
+ layoutAnimationStatusDelegate_->onAllAnimationsComplete();
1049
+ }
1050
+ } else if (
1051
+ !inflightAnimationsExistInitially && !inflightAnimations_.empty()) {
1052
+ std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
1053
+ if (layoutAnimationStatusDelegate_ != nullptr) {
1054
+ layoutAnimationStatusDelegate_->onAnimationStarted();
1055
+ }
1056
+ }
1057
+
1058
+ simulateImagePropsMemoryAccess(mutations);
1059
+
1060
+ return MountingTransaction{
1061
+ surfaceId, transactionNumber, std::move(mutations), telemetry};
1062
+ }
1063
+
1064
+ void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation(
1065
+ LayoutAnimation layoutAnimation) const {
1066
+ currentAnimation_ = better::optional<LayoutAnimation>{layoutAnimation};
1067
+ }
1068
+
1069
+ void LayoutAnimationKeyFrameManager::setLayoutAnimationStatusDelegate(
1070
+ LayoutAnimationStatusDelegate *delegate) const {
1071
+ std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
1072
+ layoutAnimationStatusDelegate_ = delegate;
1073
+ }
1074
+
1075
+ void LayoutAnimationKeyFrameManager::setClockNow(
1076
+ std::function<uint64_t()> now) {
1077
+ now_ = now;
1078
+ }
1079
+
1080
+ void LayoutAnimationKeyFrameManager::enableSkipInvalidatedKeyFrames() {
1081
+ skipInvalidatedKeyFrames_ = true;
1082
+ }
1083
+
1084
+ void LayoutAnimationKeyFrameManager::enableCrashOnMissingComponentDescriptor() {
1085
+ crashOnMissingComponentDescriptor_ = true;
1086
+ }
1087
+
1088
+ void LayoutAnimationKeyFrameManager::enableSimulateImagePropsMemoryAccess() {
1089
+ simulateImagePropsMemoryAccess_ = true;
1090
+ }
1091
+
1092
+ #pragma mark - Protected
1093
+
1094
+ bool LayoutAnimationKeyFrameManager::hasComponentDescriptorForShadowView(
1095
+ ShadowView const &shadowView) const {
1096
+ auto hasComponentDescriptor =
1097
+ componentDescriptorRegistry_->hasComponentDescriptorAt(
1098
+ shadowView.componentHandle);
1099
+
1100
+ if (crashOnMissingComponentDescriptor_ && !hasComponentDescriptor) {
1101
+ LOG(FATAL) << "Component descriptor with handle: "
1102
+ << shadowView.componentHandle
1103
+ << " doesn't exist. The component name: "
1104
+ << shadowView.componentName;
1105
+ }
1106
+
1107
+ return hasComponentDescriptor;
1108
+ }
1109
+
1110
+ ComponentDescriptor const &
1111
+ LayoutAnimationKeyFrameManager::getComponentDescriptorForShadowView(
1112
+ ShadowView const &shadowView) const {
1113
+ return componentDescriptorRegistry_->at(shadowView.componentHandle);
1114
+ }
1115
+
1116
+ ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView(
1117
+ double progress,
1118
+ ShadowView const &startingView,
1119
+ ShadowView const &finalView) const {
1120
+ react_native_assert(startingView.tag > 0);
1121
+ react_native_assert(finalView.tag > 0);
1122
+ if (!hasComponentDescriptorForShadowView(startingView)) {
1123
+ LOG(ERROR) << "No ComponentDescriptor for ShadowView being animated: ["
1124
+ << startingView.tag << "]";
1125
+ react_native_assert(false);
1126
+ return finalView;
1127
+ }
1128
+
1129
+ ComponentDescriptor const &componentDescriptor =
1130
+ getComponentDescriptorForShadowView(startingView);
1131
+
1132
+ // Base the mutated view on the finalView, so that the following stay
1133
+ // consistent:
1134
+ // - state
1135
+ // - eventEmitter
1136
+ // For now, we do not allow interpolation of state. And we probably never
1137
+ // will, so make sure we always keep the mounting layer consistent with the
1138
+ // "final" state.
1139
+ auto mutatedShadowView = ShadowView(finalView);
1140
+ react_native_assert(mutatedShadowView.tag > 0);
1141
+
1142
+ react_native_assert(startingView.props != nullptr);
1143
+ react_native_assert(finalView.props != nullptr);
1144
+ if (startingView.props == nullptr || finalView.props == nullptr) {
1145
+ return finalView;
1146
+ }
1147
+
1148
+ // Animate opacity or scale/transform
1149
+ PropsParserContext propsParserContext{
1150
+ finalView.surfaceId, *contextContainer_};
1151
+ mutatedShadowView.props = componentDescriptor.interpolateProps(
1152
+ propsParserContext, progress, startingView.props, finalView.props);
1153
+ react_native_assert(mutatedShadowView.props != nullptr);
1154
+ if (mutatedShadowView.props == nullptr) {
1155
+ return finalView;
1156
+ }
1157
+
1158
+ // Interpolate LayoutMetrics
1159
+ LayoutMetrics const &finalLayoutMetrics = finalView.layoutMetrics;
1160
+ LayoutMetrics const &baselineLayoutMetrics = startingView.layoutMetrics;
1161
+ LayoutMetrics interpolatedLayoutMetrics = finalLayoutMetrics;
1162
+ interpolatedLayoutMetrics.frame.origin.x = interpolateFloats(
1163
+ progress,
1164
+ baselineLayoutMetrics.frame.origin.x,
1165
+ finalLayoutMetrics.frame.origin.x);
1166
+ interpolatedLayoutMetrics.frame.origin.y = interpolateFloats(
1167
+ progress,
1168
+ baselineLayoutMetrics.frame.origin.y,
1169
+ finalLayoutMetrics.frame.origin.y);
1170
+ interpolatedLayoutMetrics.frame.size.width = interpolateFloats(
1171
+ progress,
1172
+ baselineLayoutMetrics.frame.size.width,
1173
+ finalLayoutMetrics.frame.size.width);
1174
+ interpolatedLayoutMetrics.frame.size.height = interpolateFloats(
1175
+ progress,
1176
+ baselineLayoutMetrics.frame.size.height,
1177
+ finalLayoutMetrics.frame.size.height);
1178
+ mutatedShadowView.layoutMetrics = interpolatedLayoutMetrics;
1179
+
1180
+ return mutatedShadowView;
1181
+ }
1182
+
1183
+ void LayoutAnimationKeyFrameManager::callCallback(
1184
+ LayoutAnimationCallbackWrapper const &callback) const {
1185
+ runtimeExecutor_(
1186
+ [callback](jsi::Runtime &runtime) { callback.call(runtime); });
1187
+ }
1188
+
1189
+ void LayoutAnimationKeyFrameManager::queueFinalMutationsForCompletedKeyFrame(
1190
+ AnimationKeyFrame const &keyframe,
1191
+ ShadowViewMutation::List &mutationsList,
1192
+ bool interrupted,
1193
+ const std::string &logPrefix) const {
1194
+ if (skipInvalidatedKeyFrames_ && keyframe.invalidated) {
1195
+ return;
1196
+ }
1197
+ if (keyframe.finalMutationsForKeyFrame.size() > 0) {
1198
+ // TODO: modularize this segment, it is repeated 2x in KeyFrameManager
1199
+ // as well.
1200
+ ShadowView prev = keyframe.viewPrev;
1201
+ for (auto const &finalMutation : keyframe.finalMutationsForKeyFrame) {
1202
+ PrintMutationInstruction(
1203
+ logPrefix + ": Queuing up Final Mutation:", finalMutation);
1204
+ // Copy so that if something else mutates the inflight animations,
1205
+ // it won't change this mutation after this point.
1206
+ switch (finalMutation.type) {
1207
+ // For CREATE/INSERT this will contain CREATE, INSERT in that order.
1208
+ // For REMOVE/DELETE, same.
1209
+ case ShadowViewMutation::Type::Create:
1210
+ mutationsList.push_back(ShadowViewMutation::CreateMutation(
1211
+ finalMutation.newChildShadowView));
1212
+ break;
1213
+ case ShadowViewMutation::Type::Delete:
1214
+ mutationsList.push_back(ShadowViewMutation::DeleteMutation(prev));
1215
+ break;
1216
+ case ShadowViewMutation::Type::Insert:
1217
+ mutationsList.push_back(ShadowViewMutation::InsertMutation(
1218
+ finalMutation.parentShadowView,
1219
+ finalMutation.newChildShadowView,
1220
+ finalMutation.index));
1221
+ break;
1222
+ case ShadowViewMutation::Type::Remove:
1223
+ mutationsList.push_back(ShadowViewMutation::RemoveMutation(
1224
+ finalMutation.parentShadowView, prev, finalMutation.index));
1225
+ break;
1226
+ case ShadowViewMutation::Type::Update:
1227
+ mutationsList.push_back(ShadowViewMutation::UpdateMutation(
1228
+ prev, finalMutation.newChildShadowView));
1229
+ break;
1230
+ }
1231
+ if (finalMutation.newChildShadowView.tag > 0) {
1232
+ prev = finalMutation.newChildShadowView;
1233
+ }
1234
+ }
1235
+ } else {
1236
+ // If there's no final mutation associated, create a mutation that
1237
+ // corresponds to the animation being 100% complete. This is
1238
+ // important for, for example, INSERT mutations being animated from
1239
+ // opacity 0 to 1. If the animation is interrupted we must force the
1240
+ // View to be at opacity 1. For Android - since it passes along only
1241
+ // deltas, not an entire bag of props - generate an "animation"
1242
+ // frame corresponding to a final update for this view. Only then,
1243
+ // generate an update that will cause the ShadowTree to be
1244
+ // consistent with the Mounting layer by passing viewEnd,
1245
+ // unmodified, to the mounting layer. This helps with, for example,
1246
+ // opacity animations.
1247
+ // This is necessary for INSERT (create) and UPDATE (update) mutations, but
1248
+ // not REMOVE/DELETE mutations ("delete" animations).
1249
+ if (interrupted) {
1250
+ auto mutatedShadowView =
1251
+ createInterpolatedShadowView(1, keyframe.viewStart, keyframe.viewEnd);
1252
+ auto generatedPenultimateMutation = ShadowViewMutation::UpdateMutation(
1253
+ keyframe.viewPrev, mutatedShadowView);
1254
+ react_native_assert(
1255
+ generatedPenultimateMutation.oldChildShadowView.tag > 0);
1256
+ react_native_assert(
1257
+ generatedPenultimateMutation.newChildShadowView.tag > 0);
1258
+ PrintMutationInstruction(
1259
+ "Queueing up penultimate mutation instruction - synthetic",
1260
+ generatedPenultimateMutation);
1261
+ mutationsList.push_back(generatedPenultimateMutation);
1262
+
1263
+ auto generatedMutation = ShadowViewMutation::UpdateMutation(
1264
+ mutatedShadowView, keyframe.viewEnd);
1265
+ react_native_assert(generatedMutation.oldChildShadowView.tag > 0);
1266
+ react_native_assert(generatedMutation.newChildShadowView.tag > 0);
1267
+ PrintMutationInstruction(
1268
+ "Queueing up final mutation instruction - synthetic",
1269
+ generatedMutation);
1270
+ mutationsList.push_back(generatedMutation);
1271
+ } else {
1272
+ auto mutation = ShadowViewMutation::UpdateMutation(
1273
+ keyframe.viewPrev, keyframe.viewEnd);
1274
+ PrintMutationInstruction(
1275
+ logPrefix +
1276
+ "Animation Complete: Queuing up Final Synthetic Mutation:",
1277
+ mutation);
1278
+ react_native_assert(mutation.oldChildShadowView.tag > 0);
1279
+ react_native_assert(mutation.newChildShadowView.tag > 0);
1280
+ mutationsList.push_back(std::move(mutation));
1281
+ }
1282
+ }
1283
+ }
1284
+
1285
+ #pragma mark - Private
1286
+
1287
+ void LayoutAnimationKeyFrameManager::
1288
+ adjustImmediateMutationIndicesForDelayedMutations(
1289
+ SurfaceId surfaceId,
1290
+ ShadowViewMutation &mutation,
1291
+ bool skipLastAnimation,
1292
+ bool lastAnimationOnly) const {
1293
+ bool isRemoveMutation = mutation.type == ShadowViewMutation::Type::Remove;
1294
+ react_native_assert(
1295
+ isRemoveMutation || mutation.type == ShadowViewMutation::Type::Insert);
1296
+
1297
+ // TODO: turn all of this into a lambda and share code?
1298
+ if (mutation.mutatedViewIsVirtual()) {
1299
+ PrintMutationInstruction(
1300
+ "[IndexAdjustment] Not calling adjustImmediateMutationIndicesForDelayedMutations, is virtual, for:",
1301
+ mutation);
1302
+ return;
1303
+ }
1304
+
1305
+ PrintMutationInstruction(
1306
+ "[IndexAdjustment] Calling adjustImmediateMutationIndicesForDelayedMutations for:",
1307
+ mutation);
1308
+
1309
+ // First, collect all final mutations that could impact this immediate
1310
+ // mutation.
1311
+ std::vector<ShadowViewMutation *> candidateMutations{};
1312
+
1313
+ for (auto inflightAnimationIt =
1314
+ inflightAnimations_.rbegin() + (skipLastAnimation ? 1 : 0);
1315
+ inflightAnimationIt != inflightAnimations_.rend();
1316
+ inflightAnimationIt++) {
1317
+ auto &inflightAnimation = *inflightAnimationIt;
1318
+ if (inflightAnimation.surfaceId != surfaceId) {
1319
+ continue;
1320
+ }
1321
+ if (inflightAnimation.completed) {
1322
+ continue;
1323
+ }
1324
+
1325
+ for (auto it = inflightAnimation.keyFrames.begin();
1326
+ it != inflightAnimation.keyFrames.end();
1327
+ it++) {
1328
+ auto &animatedKeyFrame = *it;
1531
1329
 
1532
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1533
- LOG(ERROR)
1534
- << "No Animation: Adjust delayed mutations based on all finalMutationsForConflictingAnimations";
1535
- #endif
1536
- for (auto const &mutation : finalMutationsForConflictingAnimations) {
1537
- if (mutation.type == ShadowViewMutation::Type::Remove ||
1538
- mutation.type == ShadowViewMutation::Type::Insert) {
1539
- adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
1540
- }
1330
+ if (animatedKeyFrame.invalidated) {
1331
+ continue;
1541
1332
  }
1542
1333
 
1543
- // The ShadowTree layer doesn't realize that certain operations have
1544
- // been delayed, so we must adjust all Remove and Insert operations
1545
- // based on what else has been deferred, whether we are executing this
1546
- // immediately or later.
1547
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1548
- LOG(ERROR)
1549
- << "No Animation: Adjust mutations based on remaining delayed mutations / adjust delayed, based on each";
1550
- #endif
1551
- for (auto &mutation : mutations) {
1552
- if (mutation.type == ShadowViewMutation::Type::Remove ||
1553
- mutation.type == ShadowViewMutation::Type::Insert) {
1554
- adjustImmediateMutationIndicesForDelayedMutations(
1555
- surfaceId, mutation);
1556
- adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
1334
+ // Detect if they're in the same view hierarchy, but not equivalent
1335
+ // We've already detected direct conflicts and removed them.
1336
+ if (animatedKeyFrame.parentView.tag != mutation.parentShadowView.tag) {
1337
+ continue;
1338
+ }
1339
+
1340
+ for (auto &delayedMutation : animatedKeyFrame.finalMutationsForKeyFrame) {
1341
+ if (delayedMutation.type != ShadowViewMutation::Type::Remove) {
1342
+ continue;
1343
+ }
1344
+ if (delayedMutation.mutatedViewIsVirtual()) {
1345
+ continue;
1557
1346
  }
1347
+ if (delayedMutation.oldChildShadowView.tag ==
1348
+ (isRemoveMutation ? mutation.oldChildShadowView.tag
1349
+ : mutation.newChildShadowView.tag)) {
1350
+ continue;
1351
+ }
1352
+
1353
+ PrintMutationInstructionRelative(
1354
+ "[IndexAdjustment] adjustImmediateMutationIndicesForDelayedMutations CANDIDATE for:",
1355
+ mutation,
1356
+ delayedMutation);
1357
+ candidateMutations.push_back(&delayedMutation);
1558
1358
  }
1359
+ }
1559
1360
 
1560
- // Append mutations to this list and swap - so that the final
1561
- // conflicting mutations happen before any other mutations
1562
- finalMutationsForConflictingAnimations.insert(
1563
- finalMutationsForConflictingAnimations.end(),
1564
- mutations.begin(),
1565
- mutations.end());
1566
- mutations = finalMutationsForConflictingAnimations;
1361
+ if (lastAnimationOnly) {
1362
+ break;
1567
1363
  }
1568
- } // if (mutations)
1364
+ }
1569
1365
 
1570
- // We never commit a different root or modify anything -
1571
- // we just send additional mutations to the mounting layer until the
1572
- // animations are finished and the mounting layer (view) represents exactly
1573
- // what is in the most recent shadow tree
1574
- // Add animation mutations to the end of our existing mutations list in this
1575
- // function.
1576
- ShadowViewMutationList mutationsForAnimation{};
1577
- animationMutationsForFrame(surfaceId, mutationsForAnimation, now);
1366
+ // While the mutation keeps being affected, keep checking. We use the vector
1367
+ // so we only perform one adjustment per delayed mutation. See comments at
1368
+ // bottom of adjustDelayedMutationIndicesForMutation for further explanation.
1369
+ bool changed = true;
1370
+ int adjustedDelta = 0;
1371
+ while (changed) {
1372
+ changed = false;
1373
+ candidateMutations.erase(
1374
+ std::remove_if(
1375
+ candidateMutations.begin(),
1376
+ candidateMutations.end(),
1377
+ [&changed, &mutation, &adjustedDelta, &isRemoveMutation](
1378
+ ShadowViewMutation *candidateMutation) {
1379
+ bool indexConflicts =
1380
+ (candidateMutation->index < mutation.index ||
1381
+ (isRemoveMutation &&
1382
+ candidateMutation->index == mutation.index));
1383
+ if (indexConflicts) {
1384
+ mutation.index++;
1385
+ adjustedDelta++;
1386
+ changed = true;
1387
+ PrintMutationInstructionRelative(
1388
+ "[IndexAdjustment] adjustImmediateMutationIndicesForDelayedMutations: Adjusting mutation UPWARD",
1389
+ mutation,
1390
+ *candidateMutation);
1391
+ return true;
1392
+ }
1393
+ return false;
1394
+ }),
1395
+ candidateMutations.end());
1396
+ }
1397
+ }
1578
1398
 
1579
- // If any delayed removes were executed, update remaining delayed keyframes
1580
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1581
- LOG(ERROR)
1582
- << "Adjust all delayed mutations based on final mutations generated by animation driver";
1583
- #endif
1584
- for (auto const &mutation : mutationsForAnimation) {
1585
- if (mutation.type == ShadowViewMutation::Type::Remove) {
1586
- adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
1587
- }
1399
+ void LayoutAnimationKeyFrameManager::adjustDelayedMutationIndicesForMutation(
1400
+ SurfaceId surfaceId,
1401
+ ShadowViewMutation const &mutation,
1402
+ bool skipLastAnimation) const {
1403
+ bool isRemoveMutation = mutation.type == ShadowViewMutation::Type::Remove;
1404
+ bool isInsertMutation = mutation.type == ShadowViewMutation::Type::Insert;
1405
+ auto tag = isRemoveMutation ? mutation.oldChildShadowView.tag
1406
+ : mutation.newChildShadowView.tag;
1407
+ react_native_assert(isRemoveMutation || isInsertMutation);
1408
+
1409
+ if (mutation.mutatedViewIsVirtual()) {
1410
+ PrintMutationInstruction(
1411
+ "[IndexAdjustment] Not calling adjustDelayedMutationIndicesForMutation, is virtual, for:",
1412
+ mutation);
1413
+ return;
1588
1414
  }
1589
1415
 
1590
- mutations.insert(
1591
- mutations.end(),
1592
- mutationsForAnimation.begin(),
1593
- mutationsForAnimation.end());
1416
+ // First, collect all final mutations that could impact this immediate
1417
+ // mutation.
1418
+ std::vector<ShadowViewMutation *> candidateMutations{};
1594
1419
 
1595
- // DEBUG ONLY: list existing inflight animations
1596
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1597
- LOG(ERROR) << "FINISHING DISPLAYING ONGOING inflightAnimations_!";
1598
- int i = 0;
1599
- int j = 0;
1600
- for (auto const &inflightAnimation : inflightAnimations_) {
1601
- i++;
1602
- j = 0;
1420
+ for (auto inflightAnimationIt =
1421
+ inflightAnimations_.rbegin() + (skipLastAnimation ? 1 : 0);
1422
+ inflightAnimationIt != inflightAnimations_.rend();
1423
+ inflightAnimationIt++) {
1424
+ auto &inflightAnimation = *inflightAnimationIt;
1425
+
1426
+ if (inflightAnimation.surfaceId != surfaceId) {
1427
+ continue;
1428
+ }
1603
1429
  if (inflightAnimation.completed) {
1604
1430
  continue;
1605
1431
  }
1606
- for (auto &keyframe : inflightAnimation.keyFrames) {
1607
- j++;
1608
- if (keyframe.invalidated) {
1432
+
1433
+ for (auto it = inflightAnimation.keyFrames.begin();
1434
+ it != inflightAnimation.keyFrames.end();
1435
+ it++) {
1436
+ auto &animatedKeyFrame = *it;
1437
+
1438
+ if (animatedKeyFrame.invalidated) {
1439
+ continue;
1440
+ }
1441
+
1442
+ // Detect if they're in the same view hierarchy, but not equivalent
1443
+ // (We've already detected direct conflicts and handled them above)
1444
+ if (animatedKeyFrame.parentView.tag != mutation.parentShadowView.tag) {
1445
+ continue;
1446
+ }
1447
+
1448
+ for (auto &finalAnimationMutation :
1449
+ animatedKeyFrame.finalMutationsForKeyFrame) {
1450
+ if (finalAnimationMutation.oldChildShadowView.tag == tag) {
1451
+ continue;
1452
+ }
1453
+
1454
+ if (finalAnimationMutation.type != ShadowViewMutation::Type::Remove) {
1455
+ continue;
1456
+ }
1457
+ if (finalAnimationMutation.mutatedViewIsVirtual()) {
1458
+ continue;
1459
+ }
1460
+
1461
+ PrintMutationInstructionRelative(
1462
+ "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: CANDIDATE:",
1463
+ mutation,
1464
+ finalAnimationMutation);
1465
+ candidateMutations.push_back(&finalAnimationMutation);
1466
+ }
1467
+ }
1468
+ }
1469
+
1470
+ // Because the finalAnimations are not sorted in any way, it is possible to
1471
+ // have some sequence like:
1472
+ // * DELAYED REMOVE 10 from {TAG}
1473
+ // * DELAYED REMOVE 9 from {TAG}
1474
+ // * ...
1475
+ // * DELAYED REMOVE 5 from {TAG}
1476
+ // with mutation: INSERT 6/REMOVE 6. This would cause the first few mutations
1477
+ // to *not* be adjusted, even though they would be impacted by mutation or
1478
+ // vice-versa after later adjustments are applied. Therefore, we just keep
1479
+ // recursing while there are any changes. This isn't great, but is good enough
1480
+ // for now until we change these data-structures.
1481
+ bool changed = true;
1482
+ while (changed) {
1483
+ changed = false;
1484
+ candidateMutations.erase(
1485
+ std::remove_if(
1486
+ candidateMutations.begin(),
1487
+ candidateMutations.end(),
1488
+ [&mutation, &isRemoveMutation, &isInsertMutation, &changed](
1489
+ ShadowViewMutation *candidateMutation) {
1490
+ if (isRemoveMutation &&
1491
+ mutation.index <= candidateMutation->index) {
1492
+ candidateMutation->index--;
1493
+ changed = true;
1494
+ PrintMutationInstructionRelative(
1495
+ "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: Adjusting mutation DOWNWARD",
1496
+ mutation,
1497
+ *candidateMutation);
1498
+ return true;
1499
+ } else if (
1500
+ isInsertMutation &&
1501
+ mutation.index <= candidateMutation->index) {
1502
+ candidateMutation->index++;
1503
+ changed = true;
1504
+ PrintMutationInstructionRelative(
1505
+ "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: Adjusting mutation UPWARD",
1506
+ mutation,
1507
+ *candidateMutation);
1508
+ return true;
1509
+ }
1510
+ return false;
1511
+ }),
1512
+ candidateMutations.end());
1513
+ }
1514
+ }
1515
+
1516
+ void LayoutAnimationKeyFrameManager::getAndEraseConflictingAnimations(
1517
+ SurfaceId surfaceId,
1518
+ ShadowViewMutationList const &mutations,
1519
+ std::vector<AnimationKeyFrame> &conflictingAnimations) const {
1520
+ ShadowViewMutationList localConflictingMutations{};
1521
+ for (auto const &mutation : mutations) {
1522
+ bool mutationIsCreateOrDelete =
1523
+ mutation.type == ShadowViewMutation::Type::Create ||
1524
+ mutation.type == ShadowViewMutation::Type::Delete;
1525
+ auto const &baselineShadowView =
1526
+ (mutation.type == ShadowViewMutation::Type::Insert ||
1527
+ mutation.type == ShadowViewMutation::Type::Create)
1528
+ ? mutation.newChildShadowView
1529
+ : mutation.oldChildShadowView;
1530
+ auto baselineTag = baselineShadowView.tag;
1531
+
1532
+ for (auto &inflightAnimation : inflightAnimations_) {
1533
+ if (inflightAnimation.surfaceId != surfaceId) {
1609
1534
  continue;
1610
1535
  }
1611
- for (auto const &finalMutation : keyframe.finalMutationsForKeyFrame) {
1612
- if (!finalMutation.mutatedViewIsVirtual()) {
1613
- std::string msg = "Animation " + std::to_string(i) + " keyframe " +
1614
- std::to_string(j) + ": Final Animation";
1615
- PrintMutationInstruction(msg, finalMutation);
1616
- }
1536
+ if (inflightAnimation.completed) {
1537
+ continue;
1617
1538
  }
1618
- }
1619
- }
1620
- LOG(ERROR) << "FINISHING DONE DISPLAYING ONGOING inflightAnimations_!";
1621
- #endif
1622
1539
 
1623
- // Signal to delegate if all animations are complete, or if we were not
1624
- // animating anything and now some animation exists.
1625
- if (inflightAnimationsExistInitially && inflightAnimations_.empty()) {
1626
- std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
1627
- if (layoutAnimationStatusDelegate_ != nullptr) {
1628
- layoutAnimationStatusDelegate_->onAllAnimationsComplete();
1629
- }
1630
- } else if (
1631
- !inflightAnimationsExistInitially && !inflightAnimations_.empty()) {
1632
- std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
1633
- if (layoutAnimationStatusDelegate_ != nullptr) {
1634
- layoutAnimationStatusDelegate_->onAnimationStarted();
1635
- }
1636
- }
1540
+ for (auto it = inflightAnimation.keyFrames.begin();
1541
+ it != inflightAnimation.keyFrames.end();) {
1542
+ auto &animatedKeyFrame = *it;
1637
1543
 
1638
- return MountingTransaction{
1639
- surfaceId, transactionNumber, std::move(mutations), telemetry};
1640
- }
1544
+ if (animatedKeyFrame.invalidated) {
1545
+ continue;
1546
+ }
1641
1547
 
1642
- bool LayoutAnimationKeyFrameManager::hasComponentDescriptorForShadowView(
1643
- ShadowView const &shadowView) const {
1644
- return componentDescriptorRegistry_->hasComponentDescriptorAt(
1645
- shadowView.componentHandle);
1646
- }
1548
+ // A conflict is when either: the animated node itself is mutated
1549
+ // directly; or, the parent of the node is created or deleted. In cases
1550
+ // of reparenting - say, the parent is deleted but the node was moved to
1551
+ // a different parent first - the reparenting (remove/insert) conflict
1552
+ // will be detected before we process the parent DELETE.
1553
+ // Parent deletion is important because deleting a parent recursively
1554
+ // deletes all children. If we previously deferred deletion of a child,
1555
+ // we need to force deletion/removal to happen immediately.
1556
+ bool conflicting = animatedKeyFrame.tag == baselineTag ||
1557
+ (mutationIsCreateOrDelete &&
1558
+ animatedKeyFrame.parentView.tag == baselineTag &&
1559
+ animatedKeyFrame.parentView.tag != 0);
1647
1560
 
1648
- ComponentDescriptor const &
1649
- LayoutAnimationKeyFrameManager::getComponentDescriptorForShadowView(
1650
- ShadowView const &shadowView) const {
1651
- return componentDescriptorRegistry_->at(shadowView.componentHandle);
1652
- }
1561
+ // Conflicting animation detected: if we're mutating a tag under
1562
+ // animation, or deleting the parent of a tag under animation, or
1563
+ // reparenting.
1564
+ if (conflicting) {
1565
+ animatedKeyFrame.invalidated = true;
1653
1566
 
1654
- void LayoutAnimationKeyFrameManager::setComponentDescriptorRegistry(
1655
- const SharedComponentDescriptorRegistry &componentDescriptorRegistry) {
1656
- componentDescriptorRegistry_ = componentDescriptorRegistry;
1657
- }
1567
+ // We construct a list of all conflicting animations, whether or not
1568
+ // they have a "final mutation" to execute. This is important with,
1569
+ // for example, "insert" mutations where the final update needs to set
1570
+ // opacity to "1", even if there's no final ShadowNode update.
1571
+ // TODO: don't animate virtual views in the first place?
1572
+ bool isVirtual = false;
1573
+ for (const auto &finalMutationForKeyFrame :
1574
+ animatedKeyFrame.finalMutationsForKeyFrame) {
1575
+ isVirtual =
1576
+ isVirtual || finalMutationForKeyFrame.mutatedViewIsVirtual();
1658
1577
 
1659
- /**
1660
- * Given a `progress` between 0 and 1, a mutation and LayoutAnimation config,
1661
- * return a ShadowView with mutated props and/or LayoutMetrics.
1662
- *
1663
- * @param progress
1664
- * @param layoutAnimation
1665
- * @param animatedMutation
1666
- * @return
1667
- */
1668
- ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView(
1669
- double progress,
1670
- ShadowView startingView,
1671
- ShadowView finalView) const {
1672
- react_native_assert(startingView.tag > 0);
1673
- react_native_assert(finalView.tag > 0);
1674
- if (!hasComponentDescriptorForShadowView(startingView)) {
1675
- react_native_assert(false);
1676
- return finalView;
1677
- }
1678
- ComponentDescriptor const &componentDescriptor =
1679
- getComponentDescriptorForShadowView(startingView);
1578
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1579
+ PrintMutationInstructionRelative(
1580
+ "Found mutation that conflicts with existing in-flight animation:",
1581
+ mutation,
1582
+ finalMutationForKeyFrame);
1583
+ #endif
1584
+ }
1680
1585
 
1681
- // Base the mutated view on the finalView, so that the following stay
1682
- // consistent:
1683
- // - state
1684
- // - eventEmitter
1685
- // For now, we do not allow interpolation of state. And we probably never
1686
- // will, so make sure we always keep the mounting layer consistent with the
1687
- // "final" state.
1688
- auto mutatedShadowView = ShadowView(finalView);
1689
- react_native_assert(mutatedShadowView.tag > 0);
1586
+ conflictingAnimations.push_back(animatedKeyFrame);
1587
+ for (const auto &finalMutationForKeyFrame :
1588
+ animatedKeyFrame.finalMutationsForKeyFrame) {
1589
+ if (!isVirtual ||
1590
+ finalMutationForKeyFrame.type ==
1591
+ ShadowViewMutation::Type::Delete) {
1592
+ localConflictingMutations.push_back(finalMutationForKeyFrame);
1593
+ }
1594
+ }
1690
1595
 
1691
- react_native_assert(startingView.props != nullptr);
1692
- react_native_assert(finalView.props != nullptr);
1693
- if (startingView.props == nullptr || finalView.props == nullptr) {
1694
- return finalView;
1596
+ // Delete from existing animation
1597
+ it = inflightAnimation.keyFrames.erase(it);
1598
+ } else {
1599
+ it++;
1600
+ }
1601
+ }
1602
+ }
1695
1603
  }
1696
1604
 
1697
- // Animate opacity or scale/transform
1698
- mutatedShadowView.props = componentDescriptor.interpolateProps(
1699
- progress, startingView.props, finalView.props);
1700
- react_native_assert(mutatedShadowView.props != nullptr);
1701
- if (mutatedShadowView.props == nullptr) {
1702
- return finalView;
1605
+ // Recurse, in case conflicting mutations conflict with other existing
1606
+ // animations
1607
+ if (!localConflictingMutations.empty()) {
1608
+ getAndEraseConflictingAnimations(
1609
+ surfaceId, localConflictingMutations, conflictingAnimations);
1703
1610
  }
1704
-
1705
- // Interpolate LayoutMetrics
1706
- LayoutMetrics const &finalLayoutMetrics = finalView.layoutMetrics;
1707
- LayoutMetrics const &baselineLayoutMetrics = startingView.layoutMetrics;
1708
- LayoutMetrics interpolatedLayoutMetrics = finalLayoutMetrics;
1709
- interpolatedLayoutMetrics.frame.origin.x = interpolateFloats(
1710
- progress,
1711
- baselineLayoutMetrics.frame.origin.x,
1712
- finalLayoutMetrics.frame.origin.x);
1713
- interpolatedLayoutMetrics.frame.origin.y = interpolateFloats(
1714
- progress,
1715
- baselineLayoutMetrics.frame.origin.y,
1716
- finalLayoutMetrics.frame.origin.y);
1717
- interpolatedLayoutMetrics.frame.size.width = interpolateFloats(
1718
- progress,
1719
- baselineLayoutMetrics.frame.size.width,
1720
- finalLayoutMetrics.frame.size.width);
1721
- interpolatedLayoutMetrics.frame.size.height = interpolateFloats(
1722
- progress,
1723
- baselineLayoutMetrics.frame.size.height,
1724
- finalLayoutMetrics.frame.size.height);
1725
- mutatedShadowView.layoutMetrics = interpolatedLayoutMetrics;
1726
-
1727
- return mutatedShadowView;
1728
1611
  }
1729
1612
 
1730
- void LayoutAnimationKeyFrameManager::queueFinalMutationsForCompletedKeyFrame(
1731
- AnimationKeyFrame const &keyframe,
1732
- ShadowViewMutation::List &mutationsList,
1733
- bool interrupted,
1734
- std::string logPrefix) const {
1735
- if (keyframe.finalMutationsForKeyFrame.size() > 0) {
1736
- // TODO: modularize this segment, it is repeated 2x in KeyFrameManager
1737
- // as well.
1738
- ShadowView prev = keyframe.viewPrev;
1739
- for (auto const &finalMutation : keyframe.finalMutationsForKeyFrame) {
1740
- PrintMutationInstruction(
1741
- logPrefix + ": Queuing up Final Mutation:", finalMutation);
1742
- // Copy so that if something else mutates the inflight animations,
1743
- // it won't change this mutation after this point.
1744
- auto mutation = ShadowViewMutation{
1745
- finalMutation.type,
1746
- finalMutation.parentShadowView,
1747
- prev,
1748
- finalMutation.newChildShadowView,
1749
- finalMutation.index};
1750
- react_native_assert(mutation.oldChildShadowView.tag > 0);
1751
- react_native_assert(
1752
- mutation.newChildShadowView.tag > 0 ||
1753
- finalMutation.type == ShadowViewMutation::Remove ||
1754
- finalMutation.type == ShadowViewMutation::Delete);
1755
- mutationsList.push_back(mutation);
1756
- if (finalMutation.newChildShadowView.tag > 0) {
1757
- prev = finalMutation.newChildShadowView;
1758
- }
1613
+ void LayoutAnimationKeyFrameManager::deleteAnimationsForStoppedSurfaces()
1614
+ const {
1615
+ bool inflightAnimationsExistInitially = !inflightAnimations_.empty();
1616
+
1617
+ // Execute stopSurface on any ongoing animations
1618
+ if (inflightAnimationsExistInitially) {
1619
+ better::set<SurfaceId> surfaceIdsToStop{};
1620
+ {
1621
+ std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
1622
+ surfaceIdsToStop = surfaceIdsToStop_;
1623
+ surfaceIdsToStop_.clear();
1759
1624
  }
1760
- } else {
1761
- // If there's no final mutation associated, create a mutation that
1762
- // corresponds to the animation being 100% complete. This is
1763
- // important for, for example, INSERT mutations being animated from
1764
- // opacity 0 to 1. If the animation is interrupted we must force the
1765
- // View to be at opacity 1. For Android - since it passes along only
1766
- // deltas, not an entire bag of props - generate an "animation"
1767
- // frame corresponding to a final update for this view. Only then,
1768
- // generate an update that will cause the ShadowTree to be
1769
- // consistent with the Mounting layer by passing viewEnd,
1770
- // unmodified, to the mounting layer. This helps with, for example,
1771
- // opacity animations.
1772
- // This is necessary for INSERT (create) and UPDATE (update) mutations, but
1773
- // not REMOVE/DELETE mutations ("delete" animations).
1774
- if (interrupted) {
1775
- auto mutatedShadowView =
1776
- createInterpolatedShadowView(1, keyframe.viewStart, keyframe.viewEnd);
1777
- auto generatedPenultimateMutation = ShadowViewMutation::UpdateMutation(
1778
- keyframe.viewPrev, mutatedShadowView);
1779
- react_native_assert(
1780
- generatedPenultimateMutation.oldChildShadowView.tag > 0);
1781
- react_native_assert(
1782
- generatedPenultimateMutation.newChildShadowView.tag > 0);
1783
- PrintMutationInstruction(
1784
- "Queueing up penultimate mutation instruction - synthetic",
1785
- generatedPenultimateMutation);
1786
- mutationsList.push_back(generatedPenultimateMutation);
1787
1625
 
1788
- auto generatedMutation = ShadowViewMutation::UpdateMutation(
1789
- mutatedShadowView, keyframe.viewEnd);
1790
- react_native_assert(generatedMutation.oldChildShadowView.tag > 0);
1791
- react_native_assert(generatedMutation.newChildShadowView.tag > 0);
1792
- PrintMutationInstruction(
1793
- "Queueing up final mutation instruction - synthetic",
1794
- generatedMutation);
1795
- mutationsList.push_back(generatedMutation);
1796
- } else {
1797
- auto mutation = ShadowViewMutation{
1798
- ShadowViewMutation::Type::Update,
1799
- keyframe.parentView,
1800
- keyframe.viewPrev,
1801
- keyframe.viewEnd,
1802
- -1};
1803
- PrintMutationInstruction(
1804
- logPrefix +
1805
- "Animation Complete: Queuing up Final Synthetic Mutation:",
1806
- mutation);
1807
- react_native_assert(mutation.oldChildShadowView.tag > 0);
1808
- react_native_assert(mutation.newChildShadowView.tag > 0);
1809
- mutationsList.push_back(mutation);
1626
+ for (auto it = inflightAnimations_.begin();
1627
+ it != inflightAnimations_.end();) {
1628
+ const auto &animation = *it;
1629
+
1630
+ #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1631
+ LOG(ERROR)
1632
+ << "LayoutAnimations: stopping animation due to stopSurface on "
1633
+ << surfaceId;
1634
+ #endif
1635
+ if (surfaceIdsToStop.find(animation.surfaceId) !=
1636
+ surfaceIdsToStop.end()) {
1637
+ it = inflightAnimations_.erase(it);
1638
+ } else {
1639
+ it++;
1640
+ }
1810
1641
  }
1811
1642
  }
1812
1643
  }
1813
1644
 
1814
- void LayoutAnimationKeyFrameManager::callCallback(
1815
- const LayoutAnimationCallbackWrapper &callback) const {
1816
- if (callback.readyForCleanup()) {
1645
+ void LayoutAnimationKeyFrameManager::simulateImagePropsMemoryAccess(
1646
+ ShadowViewMutationList const &mutations) const {
1647
+ if (!simulateImagePropsMemoryAccess_) {
1817
1648
  return;
1818
1649
  }
1819
-
1820
- // Callbacks can only be called once. Replace the callsite with an empty
1821
- // CallbackWrapper. We use a unique_ptr to avoid copying into the vector.
1822
- std::unique_ptr<LayoutAnimationCallbackWrapper> copiedCallback(
1823
- std::make_unique<LayoutAnimationCallbackWrapper>(callback));
1824
-
1825
- // Call the callback that is being retained in the vector
1826
- copiedCallback->call(runtimeExecutor_);
1827
-
1828
- // Protect with a mutex: this can be called on failure callbacks in the JS
1829
- // thread and success callbacks on the UI thread
1830
- {
1831
- std::lock_guard<std::mutex> lock(callbackWrappersPendingMutex_);
1832
-
1833
- // Clean any stale data in the retention vector
1834
- callbackWrappersPending_.erase(
1835
- std::remove_if(
1836
- callbackWrappersPending_.begin(),
1837
- callbackWrappersPending_.end(),
1838
- [](const std::unique_ptr<LayoutAnimationCallbackWrapper> &wrapper) {
1839
- return wrapper->readyForCleanup();
1840
- }),
1841
- callbackWrappersPending_.end());
1842
-
1843
- // Hold onto a reference to the callback, only while
1844
- // LayoutAnimationKeyFrameManager is alive and the callback hasn't
1845
- // completed yet.
1846
- callbackWrappersPending_.push_back(std::move(copiedCallback));
1650
+ for (auto const &mutation : mutations) {
1651
+ if (mutation.type != ShadowViewMutation::Type::Insert) {
1652
+ continue;
1653
+ }
1654
+ if (strcmp(mutation.newChildShadowView.componentName, "Image") == 0) {
1655
+ auto const &imageProps = *std::static_pointer_cast<ImageProps const>(
1656
+ mutation.newChildShadowView.props);
1657
+ int temp = 0;
1658
+ switch (imageProps.resizeMode) {
1659
+ case ImageResizeMode::Cover:
1660
+ temp = 1;
1661
+ break;
1662
+ case ImageResizeMode::Contain:
1663
+ temp = 2;
1664
+ break;
1665
+ case ImageResizeMode::Stretch:
1666
+ temp = 3;
1667
+ break;
1668
+ case ImageResizeMode::Center:
1669
+ temp = 4;
1670
+ break;
1671
+ case ImageResizeMode::Repeat:
1672
+ temp = 5;
1673
+ break;
1674
+ }
1675
+ (void)temp;
1676
+ }
1847
1677
  }
1848
1678
  }
1849
1679