react-native 0.0.0-16bb2ae4f → 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 (616) 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/NativeAnimatedHelper.js +3 -3
  5. package/Libraries/BatchedBridge/MessageQueue.js +10 -10
  6. package/Libraries/Blob/FileReader.js +1 -1
  7. package/Libraries/Blob/React-RCTBlob.podspec +1 -1
  8. package/Libraries/Blob/URL.js +1 -1
  9. package/Libraries/Components/Button.js +3 -0
  10. package/Libraries/Components/DatePicker/DatePickerIOS.ios.js +3 -6
  11. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +4 -7
  12. package/Libraries/Components/ScrollView/ScrollView.js +14 -5
  13. package/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js +1 -0
  14. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +268 -252
  15. package/Libraries/Components/ScrollView/ScrollViewViewConfig.js +1 -0
  16. package/Libraries/Components/StatusBar/StatusBar.js +6 -14
  17. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +2 -3
  18. package/Libraries/Components/TextInput/AndroidTextInputViewConfig.js +1 -0
  19. package/Libraries/Components/TextInput/TextInput.js +27 -1
  20. package/Libraries/Components/TextInput/TextInputState.js +1 -1
  21. package/Libraries/Components/View/ViewAccessibility.js +1 -0
  22. package/Libraries/Core/ExceptionsManager.js +3 -1
  23. package/Libraries/Core/ReactNativeVersion.js +1 -1
  24. package/Libraries/Core/Timers/JSTimers.js +37 -28
  25. package/Libraries/Core/Timers/immediateShim.js +67 -0
  26. package/Libraries/Core/Timers/queueMicrotask.js +41 -0
  27. package/Libraries/Core/polyfillPromise.js +1 -1
  28. package/Libraries/Core/setUpBatchedBridge.js +1 -1
  29. package/Libraries/Core/setUpGlobals.js +2 -0
  30. package/Libraries/Core/setUpRegeneratorRuntime.js +25 -8
  31. package/Libraries/Core/setUpTimers.js +65 -6
  32. package/Libraries/DeprecatedPropTypes/DeprecatedTextInputPropTypes.js +1 -1
  33. package/Libraries/Image/Image.ios.js +6 -0
  34. package/Libraries/Image/ImageBackground.js +10 -8
  35. package/Libraries/Image/ImageProps.js +28 -0
  36. package/Libraries/Image/ImageSource.js +1 -1
  37. package/Libraries/Image/React-RCTImage.podspec +1 -1
  38. package/Libraries/LinkingIOS/React-RCTLinking.podspec +1 -1
  39. package/Libraries/Lists/FlatList.js +43 -26
  40. package/Libraries/Lists/VirtualizedList.js +3 -1
  41. package/Libraries/Lists/__flowtests__/SectionList-flowtest.js +4 -4
  42. package/Libraries/LogBox/Data/LogBoxData.js +18 -18
  43. package/Libraries/LogBox/UI/LogBoxImages/alert-triangle.png +0 -0
  44. package/Libraries/LogBox/UI/LogBoxImages/chevron-left.png +0 -0
  45. package/Libraries/LogBox/UI/LogBoxImages/chevron-right.png +0 -0
  46. package/Libraries/LogBox/UI/LogBoxImages/close.png +0 -0
  47. package/Libraries/LogBox/UI/LogBoxImages/loader.png +0 -0
  48. package/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m +0 -3
  49. package/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm +6 -3
  50. package/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.h +1 -2
  51. package/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.mm +17 -11
  52. package/Libraries/NativeAnimation/React-RCTAnimation.podspec +1 -1
  53. package/Libraries/Network/React-RCTNetwork.podspec +1 -1
  54. package/Libraries/Network/XMLHttpRequest.js +3 -1
  55. package/Libraries/NewAppScreen/components/logo.png +0 -0
  56. package/Libraries/Performance/QuickPerformanceLogger.js +2 -1
  57. package/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +2 -1
  58. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +2 -0
  59. package/Libraries/Pressability/Pressability.js +1 -0
  60. package/Libraries/Pressability/PressabilityPerformanceEventEmitter.js +1 -0
  61. package/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +0 -1
  62. package/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec +1 -1
  63. package/Libraries/ReactNative/AppRegistry.js +1 -1
  64. package/Libraries/ReactNative/PaperUIManager.js +1 -0
  65. package/Libraries/ReactNative/renderApplication.js +1 -1
  66. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +1 -2
  67. package/Libraries/Reliability/UserFlow.js +7 -0
  68. package/Libraries/Renderer/REVISION +1 -1
  69. package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +4485 -3842
  70. package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +2060 -1709
  71. package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +2148 -1796
  72. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +4264 -3695
  73. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +1303 -1063
  74. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +1374 -1139
  75. package/Libraries/Renderer/shims/ReactFabric.js +3 -1
  76. package/Libraries/Renderer/shims/ReactFeatureFlags.js +3 -1
  77. package/Libraries/Renderer/shims/ReactNative.js +3 -1
  78. package/Libraries/Renderer/shims/ReactNativeTypes.js +3 -1
  79. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +3 -1
  80. package/Libraries/Renderer/shims/createReactNativeComponentClass.js +3 -1
  81. package/Libraries/Settings/React-RCTSettings.podspec +1 -1
  82. package/Libraries/StyleSheet/normalizeColor.js +2 -2
  83. package/Libraries/Text/Text.js +11 -0
  84. package/Libraries/Text/TextInput/RCTBaseTextInputView.m +2 -12
  85. package/Libraries/Text/TextInput/RCTInputAccessoryViewContent.m +4 -11
  86. package/Libraries/Text/TextProps.js +1 -7
  87. package/Libraries/TurboModule/TurboModuleRegistry.js +1 -1
  88. package/Libraries/TypeSafety/RCTTypeSafety.podspec +1 -1
  89. package/Libraries/UTFSequence.js +1 -1
  90. package/Libraries/Utilities/Dimensions.js +9 -14
  91. package/Libraries/Utilities/FeatureDetection.js +31 -0
  92. package/Libraries/Utilities/HMRClient.js +10 -6
  93. package/Libraries/Utilities/MatrixMath.js +1 -1
  94. package/Libraries/Utilities/NativeDeviceInfo.js +1 -1
  95. package/Libraries/Utilities/deprecatedPropType.js +2 -2
  96. package/Libraries/Utilities/useWindowDimensions.js +7 -2
  97. package/Libraries/Vibration/React-RCTVibration.podspec +1 -1
  98. package/Libraries/vendor/emitter/_EventSubscriptionVendor.js +1 -1
  99. package/React/Base/RCTBridge+Private.h +8 -0
  100. package/React/Base/RCTBridge.h +13 -0
  101. package/React/Base/RCTBridge.m +30 -7
  102. package/React/Base/RCTBridgeModule.h +3 -12
  103. package/React/Base/RCTBundleURLProvider.h +26 -1
  104. package/React/Base/RCTBundleURLProvider.mm +79 -15
  105. package/React/Base/RCTConstants.h +6 -7
  106. package/React/Base/RCTConstants.m +12 -12
  107. package/React/Base/RCTConvert.h +1 -1
  108. package/React/Base/RCTConvert.m +1 -1
  109. package/React/Base/RCTCxxConvert.h +1 -1
  110. package/React/Base/RCTDefines.h +12 -3
  111. package/React/Base/RCTEventDispatcherProtocol.h +2 -0
  112. package/React/Base/RCTJSThread.h +29 -0
  113. package/React/Base/RCTJSThread.m +19 -0
  114. package/React/Base/RCTMultipartStreamReader.m +0 -2
  115. package/React/Base/RCTRootView.h +15 -0
  116. package/React/Base/RCTRootView.m +15 -0
  117. package/React/Base/RCTTouchHandler.m +4 -9
  118. package/React/Base/RCTUtils.h +3 -0
  119. package/React/Base/RCTUtils.m +14 -7
  120. package/React/Base/RCTVersion.m +1 -1
  121. package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h +11 -0
  122. package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +35 -1
  123. package/React/CoreModules/BUCK +3 -3
  124. package/React/CoreModules/RCTAccessibilityManager.mm +1 -1
  125. package/React/CoreModules/RCTActionSheetManager.mm +14 -5
  126. package/React/CoreModules/RCTAsyncLocalStorage.mm +4 -0
  127. package/React/CoreModules/RCTDevLoadingView.mm +5 -10
  128. package/React/CoreModules/RCTDevSettings.mm +12 -10
  129. package/React/CoreModules/RCTDevSplitBundleLoader.mm +1 -1
  130. package/React/CoreModules/RCTDeviceInfo.mm +4 -4
  131. package/React/CoreModules/RCTEventDispatcher.mm +5 -0
  132. package/React/CoreModules/RCTLogBox.mm +14 -10
  133. package/React/CoreModules/RCTPerfMonitor.mm +9 -4
  134. package/React/CoreModules/RCTRedBox.mm +1 -5
  135. package/React/CoreModules/React-CoreModules.podspec +1 -1
  136. package/React/CxxBridge/RCTCxxBridge.mm +18 -1
  137. package/React/DevSupport/RCTPackagerConnection.h +3 -0
  138. package/React/DevSupport/RCTPackagerConnection.mm +19 -8
  139. package/React/FBReactNativeSpec/FBReactNativeSpec.podspec +12 -4
  140. package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +1 -2
  141. package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +64 -62
  142. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +31 -11
  143. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.h +6 -0
  144. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +108 -4
  145. package/React/Fabric/Mounting/RCTComponentViewFactory.mm +1 -0
  146. package/React/Fabric/Mounting/RCTMountingManager.h +3 -0
  147. package/React/Fabric/Mounting/RCTMountingManager.mm +22 -3
  148. package/React/Fabric/Mounting/UIView+ComponentViewProtocol.h +2 -0
  149. package/React/Fabric/Mounting/UIView+ComponentViewProtocol.mm +12 -0
  150. package/React/Fabric/RCTConversions.h +3 -0
  151. package/React/Fabric/RCTScheduler.mm +12 -5
  152. package/React/Fabric/RCTSurfacePresenter.mm +6 -7
  153. package/React/Fabric/RCTSurfacePresenterBridgeAdapter.h +1 -1
  154. package/React/Fabric/RCTSurfaceRegistry.h +1 -1
  155. package/React/Fabric/RCTSurfaceTouchHandler.mm +6 -20
  156. package/React/Fabric/Surface/RCTFabricSurface.mm +3 -0
  157. package/React/Modules/RCTI18nUtil.h +14 -6
  158. package/React/Modules/RCTI18nUtil.m +1 -47
  159. package/React/Profiler/RCTProfileTrampoline-arm.S +1 -1
  160. package/React/Profiler/RCTProfileTrampoline-arm64.S +2 -2
  161. package/React/React-RCTFabric.podspec +1 -1
  162. package/React/Views/RCTFont.mm +54 -38
  163. package/React/Views/RCTModalHostView.h +1 -1
  164. package/React/Views/RCTModalHostView.m +16 -0
  165. package/React/Views/RCTModalHostViewManager.m +1 -0
  166. package/React/Views/RCTView.m +2 -7
  167. package/React/Views/RCTViewManager.m +4 -2
  168. package/React/Views/SafeAreaView/RCTSafeAreaView.m +1 -5
  169. package/React/Views/ScrollView/RCTScrollView.h +1 -0
  170. package/React/Views/ScrollView/RCTScrollView.m +111 -36
  171. package/React/Views/ScrollView/RCTScrollViewManager.m +1 -7
  172. package/React/Views/UIView+React.m +2 -11
  173. package/React-Core.podspec +1 -1
  174. package/ReactAndroid/Android-prebuilt.mk +8 -0
  175. package/ReactAndroid/README.md +1 -1
  176. package/ReactAndroid/build.gradle +12 -5
  177. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/BUCK +1 -1
  178. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppInstrumentationTestCase.java +1 -1
  179. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/idledetection/BUCK +1 -1
  180. package/ReactAndroid/src/androidTest/java/com/facebook/react/testing/rule/BUCK +5 -5
  181. package/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK +0 -1
  182. package/ReactAndroid/src/androidTest/java/com/facebook/react/tests/core/BUCK +5 -5
  183. package/ReactAndroid/src/androidTest/js/BUCK +26 -0
  184. package/ReactAndroid/src/androidTest/js/TestBundle.js +0 -7
  185. package/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/Android.mk +2 -2
  186. package/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/Android.mk +4 -4
  187. package/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutorFactory.java +1 -1
  188. package/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/RuntimeConfig.java +0 -6
  189. package/ReactAndroid/src/main/java/com/facebook/react/BUCK +1 -1
  190. package/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java +1 -0
  191. package/ReactAndroid/src/main/java/com/facebook/react/ReactAndroidHWInputDeviceHelper.java +2 -0
  192. package/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java +6 -2
  193. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +89 -44
  194. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java +28 -0
  195. package/ReactAndroid/src/main/java/com/facebook/react/ReactNativeHost.java +13 -0
  196. package/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +5 -4
  197. package/ReactAndroid/src/main/java/com/facebook/react/animated/BUCK +1 -1
  198. package/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +2 -2
  199. package/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java +4 -4
  200. package/ReactAndroid/src/main/java/com/facebook/react/bridge/BackgroundExecutor.java +3 -2
  201. package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java +4 -0
  202. package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +11 -0
  203. package/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java +37 -0
  204. package/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java +22 -0
  205. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +3 -6
  206. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContextBaseJavaModule.java +1 -1
  207. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactCxxErrorHandler.java +39 -0
  208. package/ReactAndroid/src/main/java/com/facebook/react/bridge/{ReactSoftException.java → ReactSoftExceptionLogger.java} +8 -3
  209. package/ReactAndroid/src/main/java/com/facebook/react/bridge/RuntimeScheduler.java +21 -0
  210. package/ReactAndroid/src/main/java/com/facebook/react/bridge/SoftAssertions.java +8 -7
  211. package/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java +10 -0
  212. package/ReactAndroid/src/main/java/com/facebook/react/common/BUCK +2 -2
  213. package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/BUCK +1 -1
  214. package/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +32 -4
  215. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK +1 -1
  216. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DefaultDevSupportManagerFactory.java +97 -0
  217. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java +9 -58
  218. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +14 -9
  219. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java +3 -72
  220. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/PackagerStatusCheck.java +100 -0
  221. package/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java +10 -0
  222. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricComponents.java +4 -3
  223. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java +1 -0
  224. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +64 -31
  225. package/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java +3 -3
  226. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk +2 -1
  227. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK +1 -1
  228. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +54 -10
  229. package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h +7 -1
  230. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java +14 -6
  231. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +4 -4
  232. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +40 -11
  233. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEvent.java +2 -2
  234. package/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/Android.mk +2 -2
  235. package/ReactAndroid/src/main/java/com/facebook/react/jstasks/HeadlessJsTaskContext.java +2 -2
  236. package/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/BUCK +1 -1
  237. package/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/BUCK +1 -1
  238. package/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/BUCK +1 -1
  239. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BUCK +1 -1
  240. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk +2 -2
  241. package/ReactAndroid/src/main/java/com/facebook/react/modules/bundleloader/BUCK +1 -1
  242. package/ReactAndroid/src/main/java/com/facebook/react/modules/camera/BUCK +1 -1
  243. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/BUCK +1 -1
  244. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/{JavaScriptTimerManager.java → JavaScriptTimerExecutor.java} +1 -1
  245. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java +7 -7
  246. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java +2 -2
  247. package/ReactAndroid/src/main/java/com/facebook/react/modules/debug/BUCK +1 -1
  248. package/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/BUCK +1 -1
  249. package/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java +10 -6
  250. package/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/BUCK +1 -1
  251. package/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/BUCK +1 -1
  252. package/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.java +7 -1
  253. package/ReactAndroid/src/main/java/com/facebook/react/modules/image/BUCK +1 -1
  254. package/ReactAndroid/src/main/java/com/facebook/react/modules/intent/BUCK +1 -1
  255. package/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java +23 -19
  256. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/BUCK +1 -1
  257. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/ForwardingCookieHandler.java +1 -4
  258. package/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/BUCK +1 -1
  259. package/ReactAndroid/src/main/java/com/facebook/react/modules/share/BUCK +1 -1
  260. package/ReactAndroid/src/main/java/com/facebook/react/modules/sound/BUCK +1 -1
  261. package/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/BUCK +1 -1
  262. package/ReactAndroid/src/main/java/com/facebook/react/modules/storage/BUCK +1 -1
  263. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK +2 -2
  264. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  265. package/ReactAndroid/src/main/java/com/facebook/react/modules/toast/BUCK +1 -1
  266. package/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/BUCK +1 -1
  267. package/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/BUCK +1 -1
  268. package/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/ReconnectingWebSocket.java +11 -9
  269. package/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK +0 -1
  270. package/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java +0 -5
  271. package/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +4 -2
  272. package/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp +39 -11
  273. package/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h +9 -2
  274. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java +7 -28
  275. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.java +1 -6
  276. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java +2 -2
  277. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactOverflowView.java +25 -0
  278. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java +162 -66
  279. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java +9 -9
  280. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +1 -0
  281. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +6 -5
  282. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.java +16 -1
  283. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java +12 -20
  284. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/LockFreeEventDispatcherImpl.java +2 -2
  285. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java +14 -13
  286. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java +21 -5
  287. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java +1 -1
  288. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/jni/BUCK +1 -1
  289. package/ReactAndroid/src/main/java/com/facebook/react/views/drawer/BUCK +1 -1
  290. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK +1 -1
  291. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +7 -11
  292. package/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/BUCK +1 -1
  293. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK +1 -0
  294. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +9 -1
  295. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +24 -1
  296. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java +2 -2
  297. package/ReactAndroid/src/main/java/com/facebook/react/views/slider/BUCK +1 -1
  298. package/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java +4 -7
  299. package/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/BUCK +1 -1
  300. package/ReactAndroid/src/main/java/com/facebook/react/views/switchview/BUCK +1 -1
  301. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java +0 -4
  302. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +23 -2
  303. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +8 -0
  304. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +20 -1
  305. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +31 -12
  306. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java +31 -11
  307. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK +1 -0
  308. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +14 -4
  309. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditTextInputConnectionWrapper.java +3 -0
  310. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +114 -62
  311. package/ReactAndroid/src/main/java/com/facebook/react/views/view/CanvasUtil.java +92 -0
  312. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java +39 -8
  313. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +24 -3
  314. package/ReactAndroid/src/main/jni/react/jni/Android.mk +5 -3
  315. package/ReactAndroid/src/main/jni/react/jni/BUCK +5 -2
  316. package/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +61 -0
  317. package/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +8 -0
  318. package/ReactAndroid/src/main/jni/react/jni/JReactCxxErrorHandler.cpp +18 -0
  319. package/ReactAndroid/src/main/jni/react/jni/JReactCxxErrorHandler.h +25 -0
  320. package/ReactAndroid/src/main/jni/react/jni/JReactSoftExceptionLogger.cpp +21 -0
  321. package/ReactAndroid/src/main/jni/react/jni/JReactSoftExceptionLogger.h +28 -0
  322. package/{ReactCommon/react/renderer/core/Constants.cpp → ReactAndroid/src/main/jni/react/jni/JRuntimeScheduler.cpp} +6 -8
  323. package/ReactAndroid/src/main/jni/react/jni/JRuntimeScheduler.h +30 -0
  324. package/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp +1 -1
  325. package/ReactAndroid/src/main/jni/third-party/libevent/Android.mk +0 -1
  326. package/ReactAndroid/src/main/third-party/android/androidx/BUCK +63 -2
  327. package/ReactAndroid/src/main/third-party/java/testing-support-lib/BUCK +0 -31
  328. package/ReactAndroid/src/test/java/com/facebook/react/bridge/ReactTestHelper.java +1 -0
  329. package/ReactAndroid/src/test/java/com/facebook/react/modules/BUCK +1 -0
  330. package/ReactAndroid/src/test/java/com/facebook/react/modules/deviceinfo/DeviceInfoModuleTest.java +168 -0
  331. package/ReactCommon/React-Fabric.podspec +10 -1
  332. package/ReactCommon/ReactCommon.podspec +2 -1
  333. package/ReactCommon/callinvoker/BUCK +2 -2
  334. package/ReactCommon/callinvoker/React-callinvoker.podspec +1 -1
  335. package/ReactCommon/cxxreact/Android.mk +2 -1
  336. package/ReactCommon/cxxreact/BUCK +1 -0
  337. package/ReactCommon/cxxreact/CxxNativeModule.cpp +28 -0
  338. package/ReactCommon/cxxreact/CxxNativeModule.h +9 -0
  339. package/ReactCommon/cxxreact/React-cxxreact.podspec +2 -1
  340. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  341. package/ReactCommon/hermes/React-hermes.podspec +1 -1
  342. package/ReactCommon/hermes/executor/Android.mk +4 -4
  343. package/ReactCommon/hermes/inspector/Android.mk +1 -2
  344. package/ReactCommon/hermes/inspector/tools/msggen/package.json +7 -4
  345. package/ReactCommon/hermes/inspector/tools/msggen/yarn.lock +13 -10
  346. package/ReactCommon/jsi/Android.mk +1 -1
  347. package/ReactCommon/jsi/BUCK +0 -2
  348. package/ReactCommon/jsi/React-jsi.podspec +1 -1
  349. package/ReactCommon/jsiexecutor/Android.mk +2 -2
  350. package/ReactCommon/jsiexecutor/React-jsiexecutor.podspec +1 -1
  351. package/ReactCommon/logger/Android.mk +23 -0
  352. package/ReactCommon/logger/BUCK +43 -0
  353. package/ReactCommon/logger/React-logger.podspec +40 -0
  354. package/ReactCommon/logger/react_native_log.cpp +52 -0
  355. package/ReactCommon/logger/react_native_log.h +33 -0
  356. package/ReactCommon/react/nativemodule/core/Android.mk +2 -2
  357. package/ReactCommon/react/nativemodule/core/ReactCommon/LongLivedObject.cpp +1 -0
  358. package/ReactCommon/react/nativemodule/core/ReactCommon/LongLivedObject.h +3 -2
  359. package/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp +46 -1
  360. package/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h +10 -0
  361. package/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleUtils.h +37 -1
  362. package/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp +24 -22
  363. package/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h +11 -8
  364. package/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.h +7 -5
  365. package/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm +51 -29
  366. package/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm +45 -34
  367. package/ReactCommon/react/nativemodule/samples/BUCK +2 -2
  368. package/ReactCommon/react/nativemodule/samples/platform/android/Android.mk +1 -1
  369. package/ReactCommon/react/renderer/animations/BUCK +1 -0
  370. package/ReactCommon/react/renderer/animations/LayoutAnimationCallbackWrapper.h +34 -0
  371. package/ReactCommon/react/renderer/animations/LayoutAnimationDriver.cpp +5 -27
  372. package/ReactCommon/react/renderer/animations/LayoutAnimationDriver.h +8 -14
  373. package/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp +920 -1136
  374. package/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h +80 -245
  375. package/ReactCommon/react/renderer/animations/conversions.h +212 -0
  376. package/ReactCommon/react/renderer/animations/primitives.h +104 -0
  377. package/ReactCommon/react/renderer/animations/tests/LayoutAnimationTest.cpp +9 -6
  378. package/ReactCommon/react/renderer/animations/utils.cpp +71 -0
  379. package/ReactCommon/react/renderer/animations/utils.h +80 -0
  380. package/ReactCommon/react/renderer/attributedstring/AttributedString.h +0 -1
  381. package/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.cpp +7 -3
  382. package/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h +12 -2
  383. package/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +7 -2
  384. package/ReactCommon/react/renderer/attributedstring/TextAttributes.h +3 -1
  385. package/ReactCommon/react/renderer/attributedstring/conversions.h +162 -11
  386. package/ReactCommon/react/renderer/attributedstring/primitives.h +34 -1
  387. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.cpp +2 -2
  388. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h +1 -0
  389. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp +10 -4
  390. package/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h +4 -1
  391. package/ReactCommon/react/renderer/componentregistry/componentNameByReactViewName.cpp +2 -1
  392. package/ReactCommon/react/renderer/components/image/Android.mk +1 -1
  393. package/ReactCommon/react/renderer/components/image/ImageProps.cpp +28 -9
  394. package/ReactCommon/react/renderer/components/image/ImageProps.h +5 -1
  395. package/ReactCommon/react/renderer/components/image/conversions.h +9 -2
  396. package/ReactCommon/react/renderer/components/inputaccessory/BUCK +1 -1
  397. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/BUCK +1 -1
  398. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.mm +0 -1
  399. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.cpp +2 -1
  400. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.h +2 -0
  401. package/ReactCommon/react/renderer/components/root/RootProps.cpp +12 -2
  402. package/ReactCommon/react/renderer/components/root/RootProps.h +6 -1
  403. package/ReactCommon/react/renderer/components/root/RootShadowNode.cpp +2 -1
  404. package/ReactCommon/react/renderer/components/root/RootShadowNode.h +2 -0
  405. package/ReactCommon/react/renderer/components/root/tests/RootShadowNodeTest.cpp +8 -4
  406. package/ReactCommon/react/renderer/components/safeareaview/BUCK +1 -1
  407. package/ReactCommon/react/renderer/components/scrollview/Android.mk +1 -1
  408. package/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +45 -4
  409. package/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h +5 -1
  410. package/ReactCommon/react/renderer/components/scrollview/conversions.h +5 -0
  411. package/ReactCommon/react/renderer/components/text/Android.mk +1 -1
  412. package/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +32 -0
  413. package/ReactCommon/react/renderer/components/text/BaseTextProps.h +5 -1
  414. package/ReactCommon/react/renderer/components/text/ParagraphComponentDescriptor.h +1 -16
  415. package/ReactCommon/react/renderer/components/text/ParagraphProps.cpp +10 -4
  416. package/ReactCommon/react/renderer/components/text/ParagraphProps.h +5 -1
  417. package/ReactCommon/react/renderer/components/text/RawTextProps.cpp +3 -2
  418. package/ReactCommon/react/renderer/components/text/RawTextProps.h +5 -1
  419. package/ReactCommon/react/renderer/components/text/RawTextShadowNode.h +0 -6
  420. package/ReactCommon/react/renderer/components/text/TextProps.cpp +6 -3
  421. package/ReactCommon/react/renderer/components/text/TextProps.h +5 -1
  422. package/ReactCommon/react/renderer/components/text/TextShadowNode.h +0 -6
  423. package/ReactCommon/react/renderer/components/textinput/Android.mk +1 -1
  424. package/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp +58 -91
  425. package/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputProps.h +10 -6
  426. package/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.cpp +46 -22
  427. package/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.h +6 -5
  428. package/ReactCommon/react/renderer/components/textinput/iostextinput/conversions.h +15 -3
  429. package/ReactCommon/react/renderer/components/textinput/iostextinput/primitives.h +6 -0
  430. package/ReactCommon/react/renderer/components/textinput/iostextinput/propsConversions.h +63 -2
  431. package/ReactCommon/react/renderer/components/unimplementedview/Android.mk +1 -1
  432. package/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.cpp +4 -2
  433. package/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.h +5 -2
  434. package/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewProps.h +1 -0
  435. package/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h +21 -0
  436. package/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp +24 -1
  437. package/ReactCommon/react/renderer/components/view/AccessibilityProps.h +3 -0
  438. package/ReactCommon/react/renderer/components/view/Android.mk +3 -2
  439. package/ReactCommon/react/renderer/components/view/BUCK +1 -0
  440. package/ReactCommon/react/renderer/components/view/Touch.h +1 -32
  441. package/ReactCommon/react/renderer/components/view/ViewComponentDescriptor.h +0 -22
  442. package/ReactCommon/react/renderer/components/view/ViewProps.cpp +62 -14
  443. package/ReactCommon/react/renderer/components/view/ViewProps.h +7 -1
  444. package/ReactCommon/react/renderer/components/view/ViewPropsInterpolation.h +2 -10
  445. package/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp +5 -4
  446. package/ReactCommon/react/renderer/components/view/ViewShadowNode.h +1 -1
  447. package/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +58 -33
  448. package/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h +2 -8
  449. package/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +3 -2
  450. package/ReactCommon/react/renderer/components/view/YogaStylableProps.h +2 -0
  451. package/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h +62 -8
  452. package/ReactCommon/react/renderer/components/view/conversions.h +57 -14
  453. package/ReactCommon/react/renderer/components/view/propsConversions.h +163 -28
  454. package/ReactCommon/react/renderer/components/view/tests/ViewTest.cpp +7 -2
  455. package/ReactCommon/react/renderer/core/Android.mk +1 -1
  456. package/ReactCommon/react/renderer/core/ComponentDescriptor.h +5 -2
  457. package/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h +19 -21
  458. package/ReactCommon/react/renderer/core/ConcreteShadowNode.h +4 -0
  459. package/ReactCommon/react/renderer/core/EventDispatcher.cpp +12 -31
  460. package/ReactCommon/react/renderer/core/EventDispatcher.h +1 -4
  461. package/ReactCommon/react/renderer/core/LayoutableShadowNode.h +0 -6
  462. package/ReactCommon/react/renderer/core/Props.cpp +10 -2
  463. package/ReactCommon/react/renderer/core/Props.h +6 -1
  464. package/ReactCommon/react/renderer/core/PropsParserContext.h +29 -0
  465. package/ReactCommon/react/renderer/core/RawProps.cpp +2 -1
  466. package/ReactCommon/react/renderer/core/RawProps.h +3 -1
  467. package/ReactCommon/react/renderer/core/RawPropsKey.cpp +10 -2
  468. package/ReactCommon/react/renderer/core/RawPropsParser.h +11 -2
  469. package/ReactCommon/react/renderer/core/ReactPrimitives.h +0 -2
  470. package/ReactCommon/react/renderer/core/ShadowNode.cpp +7 -10
  471. package/ReactCommon/react/renderer/core/ShadowNode.h +4 -0
  472. package/ReactCommon/react/renderer/core/ShadowNodeFamily.h +1 -0
  473. package/ReactCommon/react/renderer/core/ShadowNodeTraits.h +11 -1
  474. package/ReactCommon/react/renderer/core/propsConversions.h +18 -8
  475. package/ReactCommon/react/renderer/core/tests/ComponentDescriptorTest.cpp +16 -4
  476. package/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp +85 -20
  477. package/ReactCommon/react/renderer/core/tests/TestComponent.h +6 -2
  478. package/ReactCommon/react/renderer/graphics/Android.mk +5 -2
  479. package/ReactCommon/react/renderer/graphics/BUCK +12 -1
  480. package/ReactCommon/react/renderer/graphics/React-graphics.podspec +2 -1
  481. package/ReactCommon/react/renderer/graphics/Transform.cpp +1 -1
  482. package/ReactCommon/react/renderer/graphics/Transform.h +1 -1
  483. package/ReactCommon/react/renderer/graphics/conversions.h +34 -19
  484. package/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h +67 -0
  485. package/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h +29 -0
  486. package/ReactCommon/react/renderer/graphics/platform/ios/Color.h +42 -1
  487. package/ReactCommon/react/renderer/graphics/platform/ios/PlatformColorParser.h +34 -0
  488. package/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.h +12 -0
  489. package/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.mm +206 -0
  490. package/ReactCommon/react/renderer/imagemanager/BUCK +1 -1
  491. package/ReactCommon/react/renderer/imagemanager/platform/ios/RCTSyncImageManager.mm +1 -1
  492. package/ReactCommon/react/renderer/mapbuffer/BUCK +2 -2
  493. package/ReactCommon/react/renderer/mounting/Android.mk +2 -1
  494. package/ReactCommon/react/renderer/mounting/MountingOverrideDelegate.h +1 -1
  495. package/ReactCommon/react/renderer/mounting/ShadowTree.cpp +6 -2
  496. package/ReactCommon/react/renderer/mounting/ShadowTree.h +3 -1
  497. package/ReactCommon/react/renderer/mounting/ShadowViewMutation.cpp +12 -0
  498. package/ReactCommon/react/renderer/mounting/ShadowViewMutation.h +10 -1
  499. package/ReactCommon/react/renderer/mounting/tests/MountingTest.cpp +12 -1
  500. package/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp +8 -1
  501. package/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp +10 -3
  502. package/ReactCommon/react/renderer/runtimescheduler/Android.mk +2 -1
  503. package/ReactCommon/react/renderer/runtimescheduler/BUCK +1 -0
  504. package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp +10 -4
  505. package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h +9 -2
  506. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp +4 -2
  507. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h +4 -2
  508. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.cpp +30 -0
  509. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h +34 -0
  510. package/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerClock.h +4 -2
  511. package/ReactCommon/react/renderer/runtimescheduler/SchedulerPriority.h +4 -2
  512. package/ReactCommon/react/renderer/runtimescheduler/Task.cpp +11 -5
  513. package/ReactCommon/react/renderer/runtimescheduler/Task.h +5 -3
  514. package/ReactCommon/react/renderer/runtimescheduler/primitives.h +4 -2
  515. package/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +34 -0
  516. package/ReactCommon/react/renderer/{core/Constants.h → scheduler/InspectorData.h} +9 -8
  517. package/ReactCommon/react/renderer/scheduler/Scheduler.cpp +44 -29
  518. package/ReactCommon/react/renderer/scheduler/Scheduler.h +14 -0
  519. package/ReactCommon/react/renderer/scheduler/SurfaceHandler.cpp +49 -29
  520. package/ReactCommon/react/renderer/scheduler/SurfaceHandler.h +12 -4
  521. package/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp +1 -0
  522. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.h +2 -0
  523. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm +22 -0
  524. package/ReactCommon/react/renderer/timeline/BUCK +6 -6
  525. package/ReactCommon/react/renderer/uimanager/UIManager.cpp +34 -30
  526. package/ReactCommon/react/renderer/uimanager/UIManager.h +6 -3
  527. package/ReactCommon/react/renderer/uimanager/UIManagerAnimationDelegate.h +1 -1
  528. package/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +101 -108
  529. package/ReactCommon/react/renderer/uimanager/UIManagerBinding.h +4 -7
  530. package/ReactCommon/react/test_utils/BUCK +3 -0
  531. package/ReactCommon/react/test_utils/MockSurfaceHandler.h +25 -0
  532. package/ReactCommon/react/test_utils/shadowTreeGeneration.h +18 -4
  533. package/ReactCommon/react/utils/Android.mk +3 -1
  534. package/ReactCommon/react/utils/BUCK +1 -0
  535. package/ReactCommon/react/utils/ContextContainer.h +0 -27
  536. package/ReactCommon/reactperflogger/React-perflogger.podspec +1 -1
  537. package/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec +1 -1
  538. package/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h +12 -0
  539. package/android/com/facebook/react/react-native/{0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.aar → 0.0.0-18697adec/react-native-0.0.0-18697adec.aar} +0 -0
  540. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.md5 +1 -0
  541. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.sha1 +1 -0
  542. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.sha256 +1 -0
  543. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.aar.sha512 +1 -0
  544. package/android/com/facebook/react/react-native/{0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.module → 0.0.0-18697adec/react-native-0.0.0-18697adec.module} +30 -17
  545. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.md5 +1 -0
  546. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.sha1 +1 -0
  547. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.sha256 +1 -0
  548. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.module.sha512 +1 -0
  549. package/android/com/facebook/react/react-native/{0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.pom → 0.0.0-18697adec/react-native-0.0.0-18697adec.pom} +8 -2
  550. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.md5 +1 -0
  551. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.sha1 +1 -0
  552. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.sha256 +1 -0
  553. package/android/com/facebook/react/react-native/0.0.0-18697adec/react-native-0.0.0-18697adec.pom.sha512 +1 -0
  554. package/android/com/facebook/react/react-native/maven-metadata.xml +4 -4
  555. package/android/com/facebook/react/react-native/maven-metadata.xml.md5 +1 -1
  556. package/android/com/facebook/react/react-native/maven-metadata.xml.sha1 +1 -1
  557. package/android/com/facebook/react/react-native/maven-metadata.xml.sha256 +1 -1
  558. package/android/com/facebook/react/react-native/maven-metadata.xml.sha512 +1 -1
  559. package/flow/HermesInternalType.js +114 -0
  560. package/flow/global.js +68 -0
  561. package/index.js +37 -24
  562. package/jest/renderer.js +3 -7
  563. package/jest/setup.js +2 -1
  564. package/package.json +55 -16
  565. package/react.gradle +19 -13
  566. package/scripts/generate-specs-cli.js +20 -2
  567. package/scripts/ios-configure-glog.sh +4 -0
  568. package/scripts/react-native-xcode.sh +1 -1
  569. package/scripts/react_native_pods.rb +195 -38
  570. package/template/_flowconfig +1 -1
  571. package/template/android/app/build.gradle +2 -2
  572. package/template/android/build.gradle +1 -2
  573. package/template/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  574. package/template/android/gradle.properties +1 -1
  575. package/template/ios/HelloWorld.xcodeproj/project.pbxproj +2 -0
  576. package/template/ios/Podfile +1 -0
  577. package/template/package.json +3 -4
  578. package/third-party-podspecs/RCT-Folly.podspec +6 -3
  579. package/Libraries/BUCK +0 -26
  580. package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js +0 -87
  581. package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js +0 -30
  582. package/Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js +0 -30
  583. package/Libraries/Components/StaticContainer.react.js +0 -51
  584. package/Libraries/Components/StatusBar/StatusBarIOS.js +0 -38
  585. package/Libraries/Components/Touchable/ensurePositiveDelayProps.js +0 -25
  586. package/Libraries/Interaction/InteractionMixin.js +0 -54
  587. package/Libraries/ReactNative/queryLayoutByID.js +0 -58
  588. package/ReactAndroid/src/androidTest/java/com/facebook/react/tests/DatePickerDialogTestCase.java +0 -172
  589. package/ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js +0 -45
  590. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK +0 -27
  591. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogFragment.java +0 -137
  592. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java +0 -153
  593. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerMode.java +0 -15
  594. package/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DismissableDatePickerDialog.java +0 -117
  595. package/ReactAndroid/src/main/java/com/facebook/react/runtimescheduler/BUCK +0 -20
  596. package/ReactAndroid/src/main/java/com/facebook/react/runtimescheduler/RuntimeSchedulerManager.java +0 -39
  597. package/ReactAndroid/src/main/java/com/facebook/react/runtimescheduler/jni/Android.mk +0 -34
  598. package/ReactAndroid/src/main/java/com/facebook/react/runtimescheduler/jni/BUCK +0 -35
  599. package/ReactAndroid/src/main/java/com/facebook/react/runtimescheduler/jni/OnLoad.cpp +0 -15
  600. package/ReactAndroid/src/main/java/com/facebook/react/runtimescheduler/jni/RuntimeSchedulerManager.cpp +0 -46
  601. package/ReactAndroid/src/main/java/com/facebook/react/runtimescheduler/jni/RuntimeSchedulerManager.h +0 -40
  602. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.aar.md5 +0 -1
  603. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.aar.sha1 +0 -1
  604. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.aar.sha256 +0 -1
  605. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.aar.sha512 +0 -1
  606. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.module.md5 +0 -1
  607. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.module.sha1 +0 -1
  608. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.module.sha256 +0 -1
  609. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.module.sha512 +0 -1
  610. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.pom.md5 +0 -1
  611. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.pom.sha1 +0 -1
  612. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.pom.sha256 +0 -1
  613. package/android/com/facebook/react/react-native/0.0.0-16bb2ae4f/react-native-0.0.0-16bb2ae4f.pom.sha512 +0 -1
  614. package/scripts/generate-specs.sh +0 -100
  615. package/template/_editorconfig +0 -3
  616. package/template/_gitattributes +0 -3
@@ -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.
@@ -323,24 +151,9 @@ void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation(
323
151
  }
324
152
  }
325
153
 
326
- void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation(
327
- LayoutAnimation layoutAnimation) const {
328
- currentAnimation_ = better::optional<LayoutAnimation>{layoutAnimation};
329
- }
330
-
331
- void LayoutAnimationKeyFrameManager::setLayoutAnimationStatusDelegate(
332
- LayoutAnimationStatusDelegate *delegate) const {
333
- std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
334
- layoutAnimationStatusDelegate_ = delegate;
335
- }
336
-
337
- bool LayoutAnimationKeyFrameManager::shouldOverridePullTransaction() const {
338
- return shouldAnimateFrame();
339
- }
340
-
341
- void LayoutAnimationKeyFrameManager::stopSurface(SurfaceId surfaceId) {
342
- std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
343
- surfaceIdsToStop_.push_back(surfaceId);
154
+ void LayoutAnimationKeyFrameManager::setComponentDescriptorRegistry(
155
+ const SharedComponentDescriptorRegistry &componentDescriptorRegistry) {
156
+ componentDescriptorRegistry_ = componentDescriptorRegistry;
344
157
  }
345
158
 
346
159
  bool LayoutAnimationKeyFrameManager::shouldAnimateFrame() const {
@@ -348,599 +161,182 @@ bool LayoutAnimationKeyFrameManager::shouldAnimateFrame() const {
348
161
  return currentAnimation_ || !inflightAnimations_.empty();
349
162
  }
350
163
 
351
- static inline const float
352
- interpolateFloats(float coefficient, float oldValue, float newValue) {
353
- return oldValue + (newValue - oldValue) * coefficient;
164
+ void LayoutAnimationKeyFrameManager::stopSurface(SurfaceId surfaceId) {
165
+ std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
166
+ surfaceIdsToStop_.insert(surfaceId);
354
167
  }
355
168
 
356
- std::pair<double, double>
357
- LayoutAnimationKeyFrameManager::calculateAnimationProgress(
358
- uint64_t now,
359
- const LayoutAnimation &animation,
360
- const AnimationConfig &mutationConfig) const {
361
- if (mutationConfig.animationType == AnimationType::None) {
362
- return {1, 1};
363
- }
364
-
365
- uint64_t startTime = animation.startTime;
366
- uint64_t delay = mutationConfig.delay;
367
- uint64_t endTime = startTime + delay + mutationConfig.duration;
368
-
369
- static const float PI = 3.14159265358979323846;
370
-
371
- if (now >= endTime) {
372
- return {1, 1};
373
- }
374
- if (now < startTime + delay) {
375
- return {0, 0};
376
- }
169
+ #pragma mark - MountingOverrideDelegate methods
377
170
 
378
- double linearTimeProgression = 1 -
379
- (double)(endTime - delay - now) / (double)(endTime - animation.startTime);
380
-
381
- if (mutationConfig.animationType == AnimationType::Linear) {
382
- return {linearTimeProgression, linearTimeProgression};
383
- } else if (mutationConfig.animationType == AnimationType::EaseIn) {
384
- // This is an accelerator-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, pow(linearTimeProgression, 2.0)};
388
- } else if (mutationConfig.animationType == AnimationType::EaseOut) {
389
- // This is an decelerator-style interpolator.
390
- // In the future, this parameter (2.0) could be adjusted. This has been the
391
- // default for Classic RN forever.
392
- return {linearTimeProgression, 1.0 - pow(1 - linearTimeProgression, 2.0)};
393
- } else if (mutationConfig.animationType == AnimationType::EaseInEaseOut) {
394
- // This is a combination of accelerate+decelerate.
395
- // The animation starts and ends slowly, and speeds up in the middle.
396
- return {
397
- linearTimeProgression,
398
- cos((linearTimeProgression + 1.0) * PI) / 2 + 0.5};
399
- } else if (mutationConfig.animationType == AnimationType::Spring) {
400
- // Using mSpringDamping in this equation is not really the exact
401
- // mathematical springDamping, but a good approximation We need to replace
402
- // this equation with the right Factor that accounts for damping and
403
- // friction
404
- double damping = mutationConfig.springDamping;
405
- return {
406
- linearTimeProgression,
407
- (1 +
408
- pow(2, -10 * linearTimeProgression) *
409
- sin((linearTimeProgression - damping / 4) * PI * 2 / damping))};
410
- } else {
411
- return {linearTimeProgression, linearTimeProgression};
412
- }
171
+ bool LayoutAnimationKeyFrameManager::shouldOverridePullTransaction() const {
172
+ return shouldAnimateFrame();
413
173
  }
414
174
 
415
- void LayoutAnimationKeyFrameManager::
416
- adjustImmediateMutationIndicesForDelayedMutations(
417
- SurfaceId surfaceId,
418
- ShadowViewMutation &mutation,
419
- bool skipLastAnimation,
420
- bool lastAnimationOnly) const {
421
- bool isRemoveMutation = mutation.type == ShadowViewMutation::Type::Remove;
422
- react_native_assert(
423
- isRemoveMutation || mutation.type == ShadowViewMutation::Type::Insert);
424
-
425
- // TODO: turn all of this into a lambda and share code?
426
- if (mutation.mutatedViewIsVirtual()) {
427
- PrintMutationInstruction(
428
- "[IndexAdjustment] Not calling adjustImmediateMutationIndicesForDelayedMutations, is virtual, for:",
429
- mutation);
430
- return;
431
- }
432
-
433
- PrintMutationInstruction(
434
- "[IndexAdjustment] Calling adjustImmediateMutationIndicesForDelayedMutations for:",
435
- mutation);
436
-
437
- // First, collect all final mutations that could impact this immediate
438
- // mutation.
439
- std::vector<ShadowViewMutation *> candidateMutations{};
440
-
441
- for (auto inflightAnimationIt =
442
- inflightAnimations_.rbegin() + (skipLastAnimation ? 1 : 0);
443
- inflightAnimationIt != inflightAnimations_.rend();
444
- inflightAnimationIt++) {
445
- auto &inflightAnimation = *inflightAnimationIt;
446
- if (inflightAnimation.surfaceId != surfaceId) {
447
- continue;
448
- }
449
- if (inflightAnimation.completed) {
450
- continue;
451
- }
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_();
452
184
 
453
- for (auto it = inflightAnimation.keyFrames.begin();
454
- it != inflightAnimation.keyFrames.end();
455
- it++) {
456
- auto &animatedKeyFrame = *it;
185
+ bool inflightAnimationsExistInitially = !inflightAnimations_.empty();
186
+ deleteAnimationsForStoppedSurfaces();
457
187
 
458
- if (animatedKeyFrame.invalidated) {
459
- continue;
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;
460
197
  }
198
+ };
199
+ #endif
461
200
 
462
- // Detect if they're in the same view hierarchy, but not equivalent
463
- // We've already detected direct conflicts and removed them.
464
- if (animatedKeyFrame.parentView.tag != mutation.parentShadowView.tag) {
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) {
465
210
  continue;
466
211
  }
467
-
468
- for (auto &delayedMutation : animatedKeyFrame.finalMutationsForKeyFrame) {
469
- if (delayedMutation.type != ShadowViewMutation::Type::Remove) {
470
- continue;
471
- }
472
- if (delayedMutation.mutatedViewIsVirtual()) {
212
+ for (auto &keyframe : inflightAnimation.keyFrames) {
213
+ j++;
214
+ if (keyframe.invalidated) {
473
215
  continue;
474
216
  }
475
- if (delayedMutation.oldChildShadowView.tag ==
476
- (isRemoveMutation ? mutation.oldChildShadowView.tag
477
- : mutation.newChildShadowView.tag)) {
478
- continue;
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
+ }
479
227
  }
480
-
481
- PrintMutationInstructionRelative(
482
- "[IndexAdjustment] adjustImmediateMutationIndicesForDelayedMutations CANDIDATE for:",
483
- mutation,
484
- delayedMutation);
485
- candidateMutations.push_back(&delayedMutation);
486
228
  }
487
229
  }
230
+ LOG(ERROR) << "BEGINNING DONE DISPLAYING ONGOING inflightAnimations_!";
231
+ #endif
488
232
 
489
- if (lastAnimationOnly) {
490
- break;
233
+ PropsParserContext propsParserContext{surfaceId, *contextContainer_};
234
+
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);
251
+
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();
259
+ }
491
260
  }
492
- }
493
261
 
494
- // While the mutation keeps being affected, keep checking. We use the vector
495
- // so we only perform one adjustment per delayed mutation. See comments at
496
- // bottom of adjustDelayedMutationIndicesForMutation for further explanation.
497
- bool changed = true;
498
- int adjustedDelta = 0;
499
- while (changed) {
500
- changed = false;
501
- candidateMutations.erase(
502
- std::remove_if(
503
- candidateMutations.begin(),
504
- candidateMutations.end(),
505
- [&changed, &mutation, &adjustedDelta, &isRemoveMutation](
506
- ShadowViewMutation *candidateMutation) {
507
- bool indexConflicts =
508
- (candidateMutation->index < mutation.index ||
509
- (isRemoveMutation &&
510
- candidateMutation->index == mutation.index));
511
- if (indexConflicts) {
512
- mutation.index++;
513
- adjustedDelta++;
514
- changed = true;
515
- PrintMutationInstructionRelative(
516
- "[IndexAdjustment] adjustImmediateMutationIndicesForDelayedMutations: Adjusting mutation UPWARD",
517
- mutation,
518
- *candidateMutation);
519
- return true;
520
- }
521
- return false;
522
- }),
523
- candidateMutations.end());
524
- }
525
- }
526
-
527
- void LayoutAnimationKeyFrameManager::adjustDelayedMutationIndicesForMutation(
528
- SurfaceId surfaceId,
529
- ShadowViewMutation const &mutation,
530
- bool skipLastAnimation) const {
531
- bool isRemoveMutation = mutation.type == ShadowViewMutation::Type::Remove;
532
- bool isInsertMutation = mutation.type == ShadowViewMutation::Type::Insert;
533
- auto tag = isRemoveMutation ? mutation.oldChildShadowView.tag
534
- : mutation.newChildShadowView.tag;
535
- react_native_assert(isRemoveMutation || isInsertMutation);
536
-
537
- if (mutation.mutatedViewIsVirtual()) {
538
- PrintMutationInstruction(
539
- "[IndexAdjustment] Not calling adjustDelayedMutationIndicesForMutation, is virtual, for:",
540
- mutation);
541
- return;
542
- }
543
-
544
- // First, collect all final mutations that could impact this immediate
545
- // mutation.
546
- std::vector<ShadowViewMutation *> candidateMutations{};
547
-
548
- for (auto inflightAnimationIt =
549
- inflightAnimations_.rbegin() + (skipLastAnimation ? 1 : 0);
550
- inflightAnimationIt != inflightAnimations_.rend();
551
- inflightAnimationIt++) {
552
- auto &inflightAnimation = *inflightAnimationIt;
553
-
554
- if (inflightAnimation.surfaceId != surfaceId) {
555
- continue;
556
- }
557
- if (inflightAnimation.completed) {
558
- continue;
559
- }
560
-
561
- for (auto it = inflightAnimation.keyFrames.begin();
562
- it != inflightAnimation.keyFrames.end();
563
- it++) {
564
- auto &animatedKeyFrame = *it;
565
-
566
- if (animatedKeyFrame.invalidated) {
567
- continue;
568
- }
569
-
570
- // Detect if they're in the same view hierarchy, but not equivalent
571
- // (We've already detected direct conflicts and handled them above)
572
- if (animatedKeyFrame.parentView.tag != mutation.parentShadowView.tag) {
573
- continue;
574
- }
262
+ if (currentAnimation.hasValue()) {
263
+ LayoutAnimation animation = std::move(currentAnimation).value();
264
+ animation.surfaceId = surfaceId;
265
+ animation.startTime = now;
575
266
 
576
- for (auto &finalAnimationMutation :
577
- animatedKeyFrame.finalMutationsForKeyFrame) {
578
- if (finalAnimationMutation.oldChildShadowView.tag == tag) {
579
- continue;
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);
580
281
  }
581
-
582
- if (finalAnimationMutation.type != ShadowViewMutation::Type::Remove) {
583
- continue;
282
+ if (mutation.type == ShadowViewMutation::Type::Delete) {
283
+ deletedTags.insert(mutation.oldChildShadowView.tag);
584
284
  }
585
- if (finalAnimationMutation.mutatedViewIsVirtual()) {
586
- 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
+ }
587
290
  }
588
-
589
- PrintMutationInstructionRelative(
590
- "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: CANDIDATE:",
591
- mutation,
592
- finalAnimationMutation);
593
- candidateMutations.push_back(&finalAnimationMutation);
594
291
  }
595
- }
596
- }
597
-
598
- // Because the finalAnimations are not sorted in any way, it is possible to
599
- // have some sequence like:
600
- // * DELAYED REMOVE 10 from {TAG}
601
- // * DELAYED REMOVE 9 from {TAG}
602
- // * ...
603
- // * DELAYED REMOVE 5 from {TAG}
604
- // with mutation: INSERT 6/REMOVE 6. This would cause the first few mutations
605
- // to *not* be adjusted, even though they would be impacted by mutation or
606
- // vice-versa after later adjustments are applied. Therefore, we just keep
607
- // recursing while there are any changes. This isn't great, but is good enough
608
- // for now until we change these data-structures.
609
- bool changed = true;
610
- while (changed) {
611
- changed = false;
612
- candidateMutations.erase(
613
- std::remove_if(
614
- candidateMutations.begin(),
615
- candidateMutations.end(),
616
- [&mutation, &isRemoveMutation, &isInsertMutation, &changed](
617
- ShadowViewMutation *candidateMutation) {
618
- if (isRemoveMutation &&
619
- mutation.index <= candidateMutation->index) {
620
- candidateMutation->index--;
621
- changed = true;
622
- PrintMutationInstructionRelative(
623
- "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: Adjusting mutation DOWNWARD",
624
- mutation,
625
- *candidateMutation);
626
- return true;
627
- } else if (
628
- isInsertMutation &&
629
- mutation.index <= candidateMutation->index) {
630
- candidateMutation->index++;
631
- changed = true;
632
- PrintMutationInstructionRelative(
633
- "[IndexAdjustment] adjustDelayedMutationIndicesForMutation: Adjusting mutation UPWARD",
634
- mutation,
635
- *candidateMutation);
636
- return true;
637
- }
638
- return false;
639
- }),
640
- candidateMutations.end());
641
- }
642
- }
643
-
644
- void LayoutAnimationKeyFrameManager::getAndEraseConflictingAnimations(
645
- SurfaceId surfaceId,
646
- ShadowViewMutationList const &mutations,
647
- std::vector<AnimationKeyFrame> &conflictingAnimations) const {
648
- ShadowViewMutationList localConflictingMutations{};
649
- for (auto const &mutation : mutations) {
650
- bool mutationIsCreateOrDelete =
651
- mutation.type == ShadowViewMutation::Type::Create ||
652
- mutation.type == ShadowViewMutation::Type::Delete;
653
- auto const &baselineShadowView =
654
- (mutation.type == ShadowViewMutation::Type::Insert ||
655
- mutation.type == ShadowViewMutation::Type::Create)
656
- ? mutation.newChildShadowView
657
- : mutation.oldChildShadowView;
658
- auto baselineTag = baselineShadowView.tag;
659
292
 
660
- for (auto &inflightAnimation : inflightAnimations_) {
661
- if (inflightAnimation.surfaceId != surfaceId) {
662
- continue;
663
- }
664
- if (inflightAnimation.completed) {
665
- continue;
666
- }
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;
667
299
 
668
- for (auto it = inflightAnimation.keyFrames.begin();
669
- it != inflightAnimation.keyFrames.end();) {
670
- auto &animatedKeyFrame = *it;
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);
671
315
 
672
- if (animatedKeyFrame.invalidated) {
316
+ // Immediately execute any mutations on a root node
317
+ if (baselineShadowView.traits.check(
318
+ ShadowNodeTraits::Trait::RootNodeKind)) {
319
+ immediateMutations.push_back(mutation);
673
320
  continue;
674
321
  }
675
322
 
676
- // A conflict is when either: the animated node itself is mutated
677
- // directly; or, the parent of the node is created or deleted. In cases
678
- // of reparenting - say, the parent is deleted but the node was moved to
679
- // a different parent first - the reparenting (remove/insert) conflict
680
- // will be detected before we process the parent DELETE.
681
- // Parent deletion is important because deleting a parent recursively
682
- // deletes all children. If we previously deferred deletion of a child,
683
- // we need to force deletion/removal to happen immediately.
684
- bool conflicting = animatedKeyFrame.tag == baselineTag ||
685
- (mutationIsCreateOrDelete &&
686
- animatedKeyFrame.parentView.tag == baselineTag &&
687
- animatedKeyFrame.parentView.tag != 0);
688
-
689
- // Conflicting animation detected: if we're mutating a tag under
690
- // animation, or deleting the parent of a tag under animation, or
691
- // reparenting.
692
- if (conflicting) {
693
- animatedKeyFrame.invalidated = true;
694
-
695
- // We construct a list of all conflicting animations, whether or not
696
- // they have a "final mutation" to execute. This is important with,
697
- // for example, "insert" mutations where the final update needs to set
698
- // opacity to "1", even if there's no final ShadowNode update.
699
- // TODO: don't animate virtual views in the first place?
700
- bool isVirtual = false;
701
- for (const auto &finalMutationForKeyFrame :
702
- animatedKeyFrame.finalMutationsForKeyFrame) {
703
- isVirtual =
704
- isVirtual || finalMutationForKeyFrame.mutatedViewIsVirtual();
323
+ better::optional<ShadowViewMutation> executeMutationImmediately{};
705
324
 
706
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
707
- PrintMutationInstructionRelative(
708
- "Found mutation that conflicts with existing in-flight animation:",
709
- mutation,
710
- finalMutationForKeyFrame);
711
- #endif
712
- }
325
+ bool isRemoveReinserted =
326
+ mutation.type == ShadowViewMutation::Type::Remove &&
327
+ insertedTags.find(mutation.oldChildShadowView.tag) !=
328
+ insertedTags.end();
713
329
 
714
- conflictingAnimations.push_back(animatedKeyFrame);
715
- for (const auto &finalMutationForKeyFrame :
716
- animatedKeyFrame.finalMutationsForKeyFrame) {
717
- if (!isVirtual ||
718
- finalMutationForKeyFrame.type ==
719
- ShadowViewMutation::Type::Delete) {
720
- localConflictingMutations.push_back(finalMutationForKeyFrame);
721
- }
722
- }
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();
723
337
 
724
- // Delete from existing animation
725
- it = inflightAnimation.keyFrames.erase(it);
726
- } else {
727
- it++;
728
- }
729
- }
730
- }
731
- }
732
-
733
- // Recurse, in case conflicting mutations conflict with other existing
734
- // animations
735
- if (!localConflictingMutations.empty()) {
736
- getAndEraseConflictingAnimations(
737
- surfaceId, localConflictingMutations, conflictingAnimations);
738
- }
739
- }
740
-
741
- void LayoutAnimationKeyFrameManager::setClockNow(
742
- std::function<uint64_t()> now) {
743
- now_ = now;
744
- }
745
-
746
- better::optional<MountingTransaction>
747
- LayoutAnimationKeyFrameManager::pullTransaction(
748
- SurfaceId surfaceId,
749
- MountingTransaction::Number transactionNumber,
750
- TransactionTelemetry const &telemetry,
751
- ShadowViewMutationList mutations) const {
752
- // Current time in milliseconds
753
- uint64_t now = now_();
754
-
755
- bool inflightAnimationsExistInitially = !inflightAnimations_.empty();
756
-
757
- // Execute stopSurface on any ongoing animations
758
- if (inflightAnimationsExistInitially) {
759
- std::vector<SurfaceId> surfaceIdsToStop{};
760
- {
761
- std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
762
- surfaceIdsToStop = surfaceIdsToStop_;
763
- surfaceIdsToStop_ = {};
764
- }
765
-
766
- for (auto it = inflightAnimations_.begin();
767
- it != inflightAnimations_.end();) {
768
- const auto &animation = *it;
769
-
770
- if (std::find(
771
- surfaceIdsToStop.begin(),
772
- surfaceIdsToStop.end(),
773
- animation.surfaceId) != surfaceIdsToStop.end()) {
774
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
775
- LOG(ERROR)
776
- << "LayoutAnimations: stopping animation due to stopSurface on "
777
- << surfaceId;
778
- #endif
779
- it = inflightAnimations_.erase(it);
780
- } else {
781
- it++;
782
- }
783
- }
784
- }
785
-
786
- if (!mutations.empty()) {
787
- #ifdef RN_SHADOW_TREE_INTROSPECTION
788
- {
789
- std::stringstream ss(getDebugDescription(mutations, {}));
790
- std::string to;
791
- while (std::getline(ss, to, '\n')) {
792
- LOG(ERROR)
793
- << "LayoutAnimationKeyFrameManager.cpp: got mutation list: Line: "
794
- << to;
795
- }
796
- };
797
- #endif
798
-
799
- // DEBUG ONLY: list existing inflight animations
800
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
801
- LOG(ERROR) << "BEGINNING DISPLAYING ONGOING inflightAnimations_!";
802
- int i = 0;
803
- int j = 0;
804
- for (auto const &inflightAnimation : inflightAnimations_) {
805
- i++;
806
- j = 0;
807
- if (inflightAnimation.completed) {
808
- continue;
809
- }
810
- for (auto &keyframe : inflightAnimation.keyFrames) {
811
- j++;
812
- if (keyframe.invalidated) {
813
- continue;
814
- }
815
- for (const auto &finalMutationForKeyFrame :
816
- keyframe.finalMutationsForKeyFrame) {
817
- if (finalMutationForKeyFrame.mutatedViewIsVirtual()) {
818
- std::string msg = "Animation " + std::to_string(i) + " keyframe " +
819
- std::to_string(j) + ": Final Animation";
820
- PrintMutationInstruction(msg, finalMutationForKeyFrame);
821
- } else {
822
- LOG(ERROR) << "Animation " << i << " keyframe " << j
823
- << ": on tag: [" << keyframe.viewStart.tag << "]";
824
- }
825
- }
826
- }
827
- }
828
- LOG(ERROR) << "BEGINNING DONE DISPLAYING ONGOING inflightAnimations_!";
829
- #endif
830
-
831
- // What to do if we detect a conflict? Get current value and make
832
- // that the baseline of the next animation. Scale the remaining time
833
- // in the animation
834
- // Types of conflicts and how we handle them:
835
- // Update -> update: remove the previous update, make it the baseline of the
836
- // next update (with current progress) Update -> remove: same, with final
837
- // mutation being a remove Insert -> update: treat as update->update Insert
838
- // -> remove: same, as update->remove Remove -> update/insert: not possible
839
- // We just collect pairs here of <Mutation, AnimationConfig> and delete them
840
- // from active animations. If another animation is queued up from the
841
- // current mutations then these deleted mutations will serve as the baseline
842
- // for the next animation. If not, the current mutations are executed
843
- // immediately without issues.
844
- std::vector<AnimationKeyFrame> conflictingAnimations{};
845
- getAndEraseConflictingAnimations(
846
- surfaceId, mutations, conflictingAnimations);
847
-
848
- // Are we animating this list of mutations?
849
- better::optional<LayoutAnimation> currentAnimation{};
850
- {
851
- std::lock_guard<std::mutex> lock(currentAnimationMutex_);
852
- if (currentAnimation_) {
853
- currentAnimation = std::move(currentAnimation_);
854
- currentAnimation_ = {};
855
- }
856
- }
857
-
858
- if (currentAnimation) {
859
- LayoutAnimation animation = std::move(currentAnimation.value());
860
- currentAnimation = {};
861
- animation.surfaceId = surfaceId;
862
- animation.startTime = now;
863
-
864
- // Pre-process list to:
865
- // Catch remove+reinsert (reorders)
866
- // Catch delete+create (reparenting) (this should be optimized away at
867
- // the diffing level eventually?)
868
- // TODO: to prevent this step we could tag Remove/Insert mutations as
869
- // being moves on the Differ level, since we know that there? We could use
870
- // TinyMap here, but it's not exposed by Differentiator (yet).
871
- std::vector<Tag> insertedTags;
872
- std::vector<Tag> deletedTags;
873
- std::vector<Tag> reparentedTags; // tags that are deleted and recreated
874
- std::unordered_map<Tag, ShadowViewMutation> movedTags;
875
- for (const auto &mutation : mutations) {
876
- if (mutation.type == ShadowViewMutation::Type::Insert) {
877
- insertedTags.push_back(mutation.newChildShadowView.tag);
878
- }
879
- if (mutation.type == ShadowViewMutation::Type::Delete) {
880
- deletedTags.push_back(mutation.oldChildShadowView.tag);
881
- }
882
- if (mutation.type == ShadowViewMutation::Type::Create) {
883
- if (std::find(
884
- deletedTags.begin(),
885
- deletedTags.end(),
886
- mutation.newChildShadowView.tag) != deletedTags.end()) {
887
- reparentedTags.push_back(mutation.newChildShadowView.tag);
888
- }
889
- }
890
- }
891
-
892
- // Process mutations list into operations that can be sent to platform
893
- // immediately, and those that need to be animated Deletions, removals,
894
- // updates are delayed and animated. Creations and insertions are sent to
895
- // platform and then "animated in" with opacity updates. Upon completion,
896
- // removals and deletions are sent to platform
897
- ShadowViewMutation::List immediateMutations;
898
-
899
- // Remove operations that are actually moves should be copied to
900
- // "immediate mutations". The corresponding "insert" will also be executed
901
- // immediately and animated as an update.
902
- std::vector<AnimationKeyFrame> keyFramesToAnimate;
903
- std::vector<AnimationKeyFrame> movesToAnimate;
904
- auto const layoutAnimationConfig = animation.layoutAnimationConfig;
905
- for (auto const &mutation : mutations) {
906
- ShadowView baselineShadowView =
907
- (mutation.type == ShadowViewMutation::Type::Delete ||
908
- mutation.type == ShadowViewMutation::Type::Remove ||
909
- mutation.type == ShadowViewMutation::Type::Update
910
- ? mutation.oldChildShadowView
911
- : mutation.newChildShadowView);
912
- react_native_assert(baselineShadowView.tag > 0);
913
- bool haveComponentDescriptor =
914
- hasComponentDescriptorForShadowView(baselineShadowView);
915
-
916
- // Immediately execute any mutations on a root node
917
- if (baselineShadowView.traits.check(
918
- ShadowNodeTraits::Trait::RootNodeKind)) {
919
- immediateMutations.push_back(mutation);
920
- continue;
921
- }
922
-
923
- better::optional<ShadowViewMutation> executeMutationImmediately{};
924
-
925
- bool isRemoveReinserted =
926
- mutation.type == ShadowViewMutation::Type::Remove &&
927
- std::find(
928
- insertedTags.begin(),
929
- insertedTags.end(),
930
- mutation.oldChildShadowView.tag) != insertedTags.end();
931
-
932
- // Reparenting can result in a node being removed, inserted (moved) and
933
- // also deleted and created in the same frame, with the same props etc.
934
- // This should eventually be optimized out of the diffing algorithm, but
935
- // for now we detect reparenting and prevent the corresponding
936
- // Delete/Create instructions from being animated.
937
- bool isReparented = std::find(
938
- reparentedTags.begin(),
939
- reparentedTags.end(),
940
- baselineShadowView.tag) != reparentedTags.end();
941
-
942
- if (isRemoveReinserted) {
943
- movedTags.insert({mutation.oldChildShadowView.tag, mutation});
338
+ if (isRemoveReinserted) {
339
+ movedTags.insert({mutation.oldChildShadowView.tag, mutation});
944
340
  }
945
341
 
946
342
  // Inserts that follow a "remove" of the same tag should be treated as
@@ -970,16 +366,6 @@ LayoutAnimationKeyFrameManager::pullTransaction(
970
366
  bool haveConfiguration =
971
367
  mutationConfig.animationType != AnimationType::None;
972
368
 
973
- if (wasInsertedTagRemoved && haveConfiguration) {
974
- movesToAnimate.push_back(AnimationKeyFrame{
975
- {},
976
- AnimationConfigurationType::Update,
977
- mutation.newChildShadowView.tag,
978
- mutation.parentShadowView,
979
- movedIt->second.oldChildShadowView,
980
- mutation.newChildShadowView});
981
- }
982
-
983
369
  // Creates and inserts should also be executed immediately.
984
370
  // Mutations that would otherwise be animated, but have no
985
371
  // configuration, are also executed immediately.
@@ -1042,12 +428,11 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1042
428
  // that is being referenced by the REMOVE mutation.
1043
429
  if (keyframe.type == AnimationConfigurationType::Update &&
1044
430
  mutation.oldChildShadowView.tag > 0) {
1045
- executeMutationImmediately = ShadowViewMutation{
1046
- mutation.type,
1047
- mutation.parentShadowView,
1048
- keyframe.viewPrev,
1049
- {},
1050
- mutation.index};
431
+ executeMutationImmediately =
432
+ ShadowViewMutation::RemoveMutation(
433
+ mutation.parentShadowView,
434
+ keyframe.viewPrev,
435
+ mutation.index);
1051
436
  }
1052
437
  }
1053
438
  }
@@ -1082,15 +467,13 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1082
467
  haveComponentDescriptor) {
1083
468
  auto props =
1084
469
  getComponentDescriptorForShadowView(baselineShadowView)
1085
- .cloneProps(viewStart.props, {});
1086
-
1087
- // Dynamic cast, because - we don't know the type of this
1088
- // ShadowNode, it could be Image or Text or something else with
1089
- // different base props.
1090
- const auto viewProps =
1091
- dynamic_cast<const ViewProps *>(props.get());
1092
- if (viewProps != nullptr) {
1093
- const_cast<ViewProps *>(viewProps)->opacity = 0;
470
+ .cloneProps(propsParserContext, viewStart.props, {});
471
+
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;
1094
477
  }
1095
478
 
1096
479
  react_native_assert(props != nullptr);
@@ -1107,15 +490,12 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1107
490
  if ((isScaleX || isScaleY) && haveComponentDescriptor) {
1108
491
  auto props =
1109
492
  getComponentDescriptorForShadowView(baselineShadowView)
1110
- .cloneProps(viewStart.props, {});
1111
-
1112
- // Dynamic cast, because - we don't know the type of this
1113
- // ShadowNode, it could be Image or Text or something else with
1114
- // different base props.
1115
- const auto viewProps =
1116
- dynamic_cast<const ViewProps *>(props.get());
1117
- if (viewProps != nullptr) {
1118
- const_cast<ViewProps *>(viewProps)->transform =
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 =
1119
499
  Transform::Scale(isScaleX ? 0 : 1, isScaleY ? 0 : 1, 1);
1120
500
  }
1121
501
 
@@ -1130,14 +510,14 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1130
510
  mutation);
1131
511
 
1132
512
  keyFrame = AnimationKeyFrame{
1133
- {},
1134
- AnimationConfigurationType::Create,
1135
- tag,
1136
- parent,
1137
- viewStart,
1138
- viewFinal,
1139
- baselineShadowView,
1140
- 0};
513
+ /* .finalMutationsForKeyFrame = */ {},
514
+ /* .type = */ AnimationConfigurationType::Create,
515
+ /* .tag = */ tag,
516
+ /* .parentView = */ parent,
517
+ /* .viewStart = */ viewStart,
518
+ /* .viewEnd = */ viewFinal,
519
+ /* .viewPrev = */ baselineShadowView,
520
+ /* .initialProgress = */ 0};
1141
521
  } else if (mutation.type == ShadowViewMutation::Type::Delete) {
1142
522
  // This is just for assertion purposes.
1143
523
  // The NDEBUG check here is to satisfy the compiler in certain environments
@@ -1168,14 +548,14 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1168
548
  mutation);
1169
549
 
1170
550
  keyFrame = AnimationKeyFrame{
1171
- {mutation},
1172
- AnimationConfigurationType::Update,
1173
- tag,
1174
- parent,
1175
- viewStart,
1176
- viewFinal,
1177
- baselineShadowView,
1178
- 0};
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};
1179
559
  } else {
1180
560
  // This should just be "Remove" instructions that are not animated
1181
561
  // (either this is a "move", or there's a corresponding "Delete"
@@ -1210,15 +590,13 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1210
590
  haveComponentDescriptor) {
1211
591
  auto props =
1212
592
  getComponentDescriptorForShadowView(baselineShadowView)
1213
- .cloneProps(viewFinal.props, {});
1214
-
1215
- // Dynamic cast, because - we don't know the type of this
1216
- // ShadowNode, it could be Image or Text or something else with
1217
- // different base props.
1218
- const auto viewProps =
1219
- dynamic_cast<const ViewProps *>(props.get());
1220
- if (viewProps != nullptr) {
1221
- const_cast<ViewProps *>(viewProps)->opacity = 0;
593
+ .cloneProps(propsParserContext, viewFinal.props, {});
594
+
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;
1222
600
  }
1223
601
 
1224
602
  react_native_assert(props != nullptr);
@@ -1237,15 +615,13 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1237
615
  if ((isScaleX || isScaleY) && haveComponentDescriptor) {
1238
616
  auto props =
1239
617
  getComponentDescriptorForShadowView(baselineShadowView)
1240
- .cloneProps(viewFinal.props, {});
1241
-
1242
- // Dynamic cast, because - we don't know the type of this
1243
- // ShadowNode, it could be Image or Text or something else with
1244
- // different base props.
1245
- const auto viewProps =
1246
- dynamic_cast<const ViewProps *>(props.get());
1247
- if (viewProps != nullptr) {
1248
- const_cast<ViewProps *>(viewProps)->transform =
618
+ .cloneProps(propsParserContext, viewFinal.props, {});
619
+
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 =
1249
625
  Transform::Scale(isScaleX ? 0 : 1, isScaleY ? 0 : 1, 1);
1250
626
  }
1251
627
 
@@ -1260,14 +636,14 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1260
636
  mutation);
1261
637
 
1262
638
  keyFrame = AnimationKeyFrame{
1263
- {mutation, deleteMutation},
1264
- AnimationConfigurationType::Delete,
1265
- tag,
1266
- parent,
1267
- viewStart,
1268
- viewFinal,
1269
- baselineShadowView,
1270
- 0};
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};
1271
647
  } else {
1272
648
  PrintMutationInstruction(
1273
649
  "Executing Remove Immediately, due to reordering operation",
@@ -1406,7 +782,7 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1406
782
  // don't want to queue up any final UPDATE mutations here.
1407
783
  bool shouldGenerateSyntheticMutations =
1408
784
  keyFrame.generateFinalSyntheticMutations;
1409
- bool numFinalMutations = keyFrame.finalMutationsForKeyFrame.size();
785
+ auto numFinalMutations = keyFrame.finalMutationsForKeyFrame.size();
1410
786
  bool onlyMutationIsUpdate =
1411
787
  (numFinalMutations == 1 &&
1412
788
  keyFrame.finalMutationsForKeyFrame[0].type ==
@@ -1566,330 +942,738 @@ LayoutAnimationKeyFrameManager::pullTransaction(
1566
942
  "Conflict with non-animated mutation");
1567
943
  }
1568
944
 
1569
- // Make sure that all operations execute in the proper order.
1570
- // REMOVE operations with highest indices must operate first.
1571
- std::stable_sort(
1572
- finalMutationsForConflictingAnimations.begin(),
1573
- finalMutationsForConflictingAnimations.end(),
1574
- &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;
1329
+
1330
+ if (animatedKeyFrame.invalidated) {
1331
+ continue;
1332
+ }
1575
1333
 
1576
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1577
- LOG(ERROR)
1578
- << "No Animation: Adjust delayed mutations based on all finalMutationsForConflictingAnimations";
1579
- #endif
1580
- for (auto const &mutation : finalMutationsForConflictingAnimations) {
1581
- if (mutation.type == ShadowViewMutation::Type::Remove ||
1582
- mutation.type == ShadowViewMutation::Type::Insert) {
1583
- adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
1584
- }
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;
1585
1338
  }
1586
1339
 
1587
- // The ShadowTree layer doesn't realize that certain operations have
1588
- // been delayed, so we must adjust all Remove and Insert operations
1589
- // based on what else has been deferred, whether we are executing this
1590
- // immediately or later.
1591
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1592
- LOG(ERROR)
1593
- << "No Animation: Adjust mutations based on remaining delayed mutations / adjust delayed, based on each";
1594
- #endif
1595
- for (auto &mutation : mutations) {
1596
- if (mutation.type == ShadowViewMutation::Type::Remove ||
1597
- mutation.type == ShadowViewMutation::Type::Insert) {
1598
- adjustImmediateMutationIndicesForDelayedMutations(
1599
- surfaceId, mutation);
1600
- adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
1340
+ for (auto &delayedMutation : animatedKeyFrame.finalMutationsForKeyFrame) {
1341
+ if (delayedMutation.type != ShadowViewMutation::Type::Remove) {
1342
+ continue;
1343
+ }
1344
+ if (delayedMutation.mutatedViewIsVirtual()) {
1345
+ continue;
1346
+ }
1347
+ if (delayedMutation.oldChildShadowView.tag ==
1348
+ (isRemoveMutation ? mutation.oldChildShadowView.tag
1349
+ : mutation.newChildShadowView.tag)) {
1350
+ continue;
1601
1351
  }
1352
+
1353
+ PrintMutationInstructionRelative(
1354
+ "[IndexAdjustment] adjustImmediateMutationIndicesForDelayedMutations CANDIDATE for:",
1355
+ mutation,
1356
+ delayedMutation);
1357
+ candidateMutations.push_back(&delayedMutation);
1602
1358
  }
1359
+ }
1603
1360
 
1604
- // Append mutations to this list and swap - so that the final
1605
- // conflicting mutations happen before any other mutations
1606
- finalMutationsForConflictingAnimations.insert(
1607
- finalMutationsForConflictingAnimations.end(),
1608
- mutations.begin(),
1609
- mutations.end());
1610
- mutations = finalMutationsForConflictingAnimations;
1361
+ if (lastAnimationOnly) {
1362
+ break;
1611
1363
  }
1612
- } // if (mutations)
1364
+ }
1613
1365
 
1614
- // We never commit a different root or modify anything -
1615
- // we just send additional mutations to the mounting layer until the
1616
- // animations are finished and the mounting layer (view) represents exactly
1617
- // what is in the most recent shadow tree
1618
- // Add animation mutations to the end of our existing mutations list in this
1619
- // function.
1620
- ShadowViewMutationList mutationsForAnimation{};
1621
- 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
+ }
1622
1398
 
1623
- // If any delayed removes were executed, update remaining delayed keyframes
1624
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1625
- LOG(ERROR)
1626
- << "Adjust all delayed mutations based on final mutations generated by animation driver";
1627
- #endif
1628
- for (auto const &mutation : mutationsForAnimation) {
1629
- if (mutation.type == ShadowViewMutation::Type::Remove) {
1630
- adjustDelayedMutationIndicesForMutation(surfaceId, mutation);
1631
- }
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;
1632
1414
  }
1633
1415
 
1634
- mutations.insert(
1635
- mutations.end(),
1636
- mutationsForAnimation.begin(),
1637
- mutationsForAnimation.end());
1416
+ // First, collect all final mutations that could impact this immediate
1417
+ // mutation.
1418
+ std::vector<ShadowViewMutation *> candidateMutations{};
1638
1419
 
1639
- // DEBUG ONLY: list existing inflight animations
1640
- #ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
1641
- LOG(ERROR) << "FINISHING DISPLAYING ONGOING inflightAnimations_!";
1642
- int i = 0;
1643
- int j = 0;
1644
- for (auto const &inflightAnimation : inflightAnimations_) {
1645
- i++;
1646
- 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
+ }
1647
1429
  if (inflightAnimation.completed) {
1648
1430
  continue;
1649
1431
  }
1650
- for (auto &keyframe : inflightAnimation.keyFrames) {
1651
- j++;
1652
- 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) {
1653
1534
  continue;
1654
1535
  }
1655
- for (auto const &finalMutation : keyframe.finalMutationsForKeyFrame) {
1656
- if (!finalMutation.mutatedViewIsVirtual()) {
1657
- std::string msg = "Animation " + std::to_string(i) + " keyframe " +
1658
- std::to_string(j) + ": Final Animation";
1659
- PrintMutationInstruction(msg, finalMutation);
1660
- }
1536
+ if (inflightAnimation.completed) {
1537
+ continue;
1661
1538
  }
1662
- }
1663
- }
1664
- LOG(ERROR) << "FINISHING DONE DISPLAYING ONGOING inflightAnimations_!";
1665
- #endif
1666
1539
 
1667
- // Signal to delegate if all animations are complete, or if we were not
1668
- // animating anything and now some animation exists.
1669
- if (inflightAnimationsExistInitially && inflightAnimations_.empty()) {
1670
- std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
1671
- if (layoutAnimationStatusDelegate_ != nullptr) {
1672
- layoutAnimationStatusDelegate_->onAllAnimationsComplete();
1673
- }
1674
- } else if (
1675
- !inflightAnimationsExistInitially && !inflightAnimations_.empty()) {
1676
- std::lock_guard<std::mutex> lock(layoutAnimationStatusDelegateMutex_);
1677
- if (layoutAnimationStatusDelegate_ != nullptr) {
1678
- layoutAnimationStatusDelegate_->onAnimationStarted();
1679
- }
1680
- }
1540
+ for (auto it = inflightAnimation.keyFrames.begin();
1541
+ it != inflightAnimation.keyFrames.end();) {
1542
+ auto &animatedKeyFrame = *it;
1681
1543
 
1682
- return MountingTransaction{
1683
- surfaceId, transactionNumber, std::move(mutations), telemetry};
1684
- }
1544
+ if (animatedKeyFrame.invalidated) {
1545
+ continue;
1546
+ }
1685
1547
 
1686
- bool LayoutAnimationKeyFrameManager::hasComponentDescriptorForShadowView(
1687
- ShadowView const &shadowView) const {
1688
- return componentDescriptorRegistry_->hasComponentDescriptorAt(
1689
- shadowView.componentHandle);
1690
- }
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);
1691
1560
 
1692
- ComponentDescriptor const &
1693
- LayoutAnimationKeyFrameManager::getComponentDescriptorForShadowView(
1694
- ShadowView const &shadowView) const {
1695
- return componentDescriptorRegistry_->at(shadowView.componentHandle);
1696
- }
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;
1697
1566
 
1698
- void LayoutAnimationKeyFrameManager::setComponentDescriptorRegistry(
1699
- const SharedComponentDescriptorRegistry &componentDescriptorRegistry) {
1700
- componentDescriptorRegistry_ = componentDescriptorRegistry;
1701
- }
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();
1702
1577
 
1703
- /**
1704
- * Given a `progress` between 0 and 1, a mutation and LayoutAnimation config,
1705
- * return a ShadowView with mutated props and/or LayoutMetrics.
1706
- *
1707
- * @param progress
1708
- * @param layoutAnimation
1709
- * @param animatedMutation
1710
- * @return
1711
- */
1712
- ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView(
1713
- double progress,
1714
- ShadowView startingView,
1715
- ShadowView finalView) const {
1716
- react_native_assert(startingView.tag > 0);
1717
- react_native_assert(finalView.tag > 0);
1718
- if (!hasComponentDescriptorForShadowView(startingView)) {
1719
- LOG(ERROR) << "No ComponentDescriptor for ShadowView being animated: ["
1720
- << startingView.tag << "]";
1721
- react_native_assert(false);
1722
- return finalView;
1723
- }
1724
- ComponentDescriptor const &componentDescriptor =
1725
- 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
+ }
1726
1585
 
1727
- // Base the mutated view on the finalView, so that the following stay
1728
- // consistent:
1729
- // - state
1730
- // - eventEmitter
1731
- // For now, we do not allow interpolation of state. And we probably never
1732
- // will, so make sure we always keep the mounting layer consistent with the
1733
- // "final" state.
1734
- auto mutatedShadowView = ShadowView(finalView);
1735
- 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
+ }
1736
1595
 
1737
- react_native_assert(startingView.props != nullptr);
1738
- react_native_assert(finalView.props != nullptr);
1739
- if (startingView.props == nullptr || finalView.props == nullptr) {
1740
- return finalView;
1596
+ // Delete from existing animation
1597
+ it = inflightAnimation.keyFrames.erase(it);
1598
+ } else {
1599
+ it++;
1600
+ }
1601
+ }
1602
+ }
1741
1603
  }
1742
1604
 
1743
- // Animate opacity or scale/transform
1744
- mutatedShadowView.props = componentDescriptor.interpolateProps(
1745
- progress, startingView.props, finalView.props);
1746
- react_native_assert(mutatedShadowView.props != nullptr);
1747
- if (mutatedShadowView.props == nullptr) {
1748
- return finalView;
1605
+ // Recurse, in case conflicting mutations conflict with other existing
1606
+ // animations
1607
+ if (!localConflictingMutations.empty()) {
1608
+ getAndEraseConflictingAnimations(
1609
+ surfaceId, localConflictingMutations, conflictingAnimations);
1749
1610
  }
1750
-
1751
- // Interpolate LayoutMetrics
1752
- LayoutMetrics const &finalLayoutMetrics = finalView.layoutMetrics;
1753
- LayoutMetrics const &baselineLayoutMetrics = startingView.layoutMetrics;
1754
- LayoutMetrics interpolatedLayoutMetrics = finalLayoutMetrics;
1755
- interpolatedLayoutMetrics.frame.origin.x = interpolateFloats(
1756
- progress,
1757
- baselineLayoutMetrics.frame.origin.x,
1758
- finalLayoutMetrics.frame.origin.x);
1759
- interpolatedLayoutMetrics.frame.origin.y = interpolateFloats(
1760
- progress,
1761
- baselineLayoutMetrics.frame.origin.y,
1762
- finalLayoutMetrics.frame.origin.y);
1763
- interpolatedLayoutMetrics.frame.size.width = interpolateFloats(
1764
- progress,
1765
- baselineLayoutMetrics.frame.size.width,
1766
- finalLayoutMetrics.frame.size.width);
1767
- interpolatedLayoutMetrics.frame.size.height = interpolateFloats(
1768
- progress,
1769
- baselineLayoutMetrics.frame.size.height,
1770
- finalLayoutMetrics.frame.size.height);
1771
- mutatedShadowView.layoutMetrics = interpolatedLayoutMetrics;
1772
-
1773
- return mutatedShadowView;
1774
1611
  }
1775
1612
 
1776
- void LayoutAnimationKeyFrameManager::queueFinalMutationsForCompletedKeyFrame(
1777
- AnimationKeyFrame const &keyframe,
1778
- ShadowViewMutation::List &mutationsList,
1779
- bool interrupted,
1780
- std::string logPrefix) const {
1781
- if (keyframe.finalMutationsForKeyFrame.size() > 0) {
1782
- // TODO: modularize this segment, it is repeated 2x in KeyFrameManager
1783
- // as well.
1784
- ShadowView prev = keyframe.viewPrev;
1785
- for (auto const &finalMutation : keyframe.finalMutationsForKeyFrame) {
1786
- PrintMutationInstruction(
1787
- logPrefix + ": Queuing up Final Mutation:", finalMutation);
1788
- // Copy so that if something else mutates the inflight animations,
1789
- // it won't change this mutation after this point.
1790
- auto mutation = ShadowViewMutation{
1791
- finalMutation.type,
1792
- finalMutation.parentShadowView,
1793
- prev,
1794
- finalMutation.newChildShadowView,
1795
- finalMutation.index};
1796
- react_native_assert(mutation.oldChildShadowView.tag > 0);
1797
- react_native_assert(
1798
- mutation.newChildShadowView.tag > 0 ||
1799
- finalMutation.type == ShadowViewMutation::Remove ||
1800
- finalMutation.type == ShadowViewMutation::Delete);
1801
- mutationsList.push_back(mutation);
1802
- if (finalMutation.newChildShadowView.tag > 0) {
1803
- prev = finalMutation.newChildShadowView;
1804
- }
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();
1805
1624
  }
1806
- } else {
1807
- // If there's no final mutation associated, create a mutation that
1808
- // corresponds to the animation being 100% complete. This is
1809
- // important for, for example, INSERT mutations being animated from
1810
- // opacity 0 to 1. If the animation is interrupted we must force the
1811
- // View to be at opacity 1. For Android - since it passes along only
1812
- // deltas, not an entire bag of props - generate an "animation"
1813
- // frame corresponding to a final update for this view. Only then,
1814
- // generate an update that will cause the ShadowTree to be
1815
- // consistent with the Mounting layer by passing viewEnd,
1816
- // unmodified, to the mounting layer. This helps with, for example,
1817
- // opacity animations.
1818
- // This is necessary for INSERT (create) and UPDATE (update) mutations, but
1819
- // not REMOVE/DELETE mutations ("delete" animations).
1820
- if (interrupted) {
1821
- auto mutatedShadowView =
1822
- createInterpolatedShadowView(1, keyframe.viewStart, keyframe.viewEnd);
1823
- auto generatedPenultimateMutation = ShadowViewMutation::UpdateMutation(
1824
- keyframe.viewPrev, mutatedShadowView);
1825
- react_native_assert(
1826
- generatedPenultimateMutation.oldChildShadowView.tag > 0);
1827
- react_native_assert(
1828
- generatedPenultimateMutation.newChildShadowView.tag > 0);
1829
- PrintMutationInstruction(
1830
- "Queueing up penultimate mutation instruction - synthetic",
1831
- generatedPenultimateMutation);
1832
- mutationsList.push_back(generatedPenultimateMutation);
1833
1625
 
1834
- auto generatedMutation = ShadowViewMutation::UpdateMutation(
1835
- mutatedShadowView, keyframe.viewEnd);
1836
- react_native_assert(generatedMutation.oldChildShadowView.tag > 0);
1837
- react_native_assert(generatedMutation.newChildShadowView.tag > 0);
1838
- PrintMutationInstruction(
1839
- "Queueing up final mutation instruction - synthetic",
1840
- generatedMutation);
1841
- mutationsList.push_back(generatedMutation);
1842
- } else {
1843
- auto mutation = ShadowViewMutation{
1844
- ShadowViewMutation::Type::Update,
1845
- keyframe.parentView,
1846
- keyframe.viewPrev,
1847
- keyframe.viewEnd,
1848
- -1};
1849
- PrintMutationInstruction(
1850
- logPrefix +
1851
- "Animation Complete: Queuing up Final Synthetic Mutation:",
1852
- mutation);
1853
- react_native_assert(mutation.oldChildShadowView.tag > 0);
1854
- react_native_assert(mutation.newChildShadowView.tag > 0);
1855
- 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
+ }
1856
1641
  }
1857
1642
  }
1858
1643
  }
1859
1644
 
1860
- void LayoutAnimationKeyFrameManager::callCallback(
1861
- const LayoutAnimationCallbackWrapper &callback) const {
1862
- if (callback.readyForCleanup()) {
1645
+ void LayoutAnimationKeyFrameManager::simulateImagePropsMemoryAccess(
1646
+ ShadowViewMutationList const &mutations) const {
1647
+ if (!simulateImagePropsMemoryAccess_) {
1863
1648
  return;
1864
1649
  }
1865
-
1866
- // Callbacks can only be called once. Replace the callsite with an empty
1867
- // CallbackWrapper. We use a unique_ptr to avoid copying into the vector.
1868
- std::unique_ptr<LayoutAnimationCallbackWrapper> copiedCallback(
1869
- std::make_unique<LayoutAnimationCallbackWrapper>(callback));
1870
-
1871
- // Call the callback that is being retained in the vector
1872
- copiedCallback->call(runtimeExecutor_);
1873
-
1874
- // Protect with a mutex: this can be called on failure callbacks in the JS
1875
- // thread and success callbacks on the UI thread
1876
- {
1877
- std::lock_guard<std::mutex> lock(callbackWrappersPendingMutex_);
1878
-
1879
- // Clean any stale data in the retention vector
1880
- callbackWrappersPending_.erase(
1881
- std::remove_if(
1882
- callbackWrappersPending_.begin(),
1883
- callbackWrappersPending_.end(),
1884
- [](const std::unique_ptr<LayoutAnimationCallbackWrapper> &wrapper) {
1885
- return wrapper->readyForCleanup();
1886
- }),
1887
- callbackWrappersPending_.end());
1888
-
1889
- // Hold onto a reference to the callback, only while
1890
- // LayoutAnimationKeyFrameManager is alive and the callback hasn't
1891
- // completed yet.
1892
- 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
+ }
1893
1677
  }
1894
1678
  }
1895
1679