react-native-reanimated 3.0.0-rc.3 → 3.0.0-rc.4

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 (51) hide show
  1. package/Common/cpp/NativeModules/NativeReanimatedModule.cpp +5 -1
  2. package/Common/cpp/SharedItems/ShareableValue.cpp +0 -2
  3. package/RNReanimated.podspec +19 -85
  4. package/android/CMakeLists.txt +22 -21
  5. package/android/build.gradle +344 -56
  6. package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  7. package/android/src/main/cpp/AndroidErrorHandler.cpp +3 -4
  8. package/android/src/main/cpp/AndroidErrorHandler.h +1 -4
  9. package/android/src/main/java/com/swmansion/reanimated/{ReanimatedMessageQueueThread.java → ReanimatedMessageQueueThreadBase.java} +3 -8
  10. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ReanimatedUIManager.java +1 -1
  11. package/android/{rnVersionPatch/62 → src/reactNativeVersionPatch/UIImplementation/64/com/swmansion/reanimated}/layoutReanimation/ReanimatedUIImplementation.java +0 -0
  12. package/android/src/{main/java → reactNativeVersionPatch/UIImplementation/latest}/com/swmansion/reanimated/layoutReanimation/ReanimatedUIImplementation.java +0 -0
  13. package/android/src/reactNativeVersionPatch/messageQueueThread/67/com/swmansion/reanimated/ReanimatedMessageQueueThread.java +12 -0
  14. package/android/src/reactNativeVersionPatch/messageQueueThread/latest/com/swmansion/reanimated/ReanimatedMessageQueueThread.java +12 -0
  15. package/android/{rnVersionPatch/62 → src/reactNativeVersionPatch/nativeHierarchyManager/62/com/swmansion/reanimated}/layoutReanimation/ReanimatedNativeHierarchyManager.java +0 -0
  16. package/android/src/{main/java → reactNativeVersionPatch/nativeHierarchyManager/latest}/com/swmansion/reanimated/layoutReanimation/ReanimatedNativeHierarchyManager.java +0 -0
  17. package/ios/REAModule.mm +21 -2
  18. package/ios/keyboardObserver/REAKeyboardEventObserver.m +1 -1
  19. package/ios/native/REAMessageThread.mm +1 -1
  20. package/lib/commonjs/createAnimatedComponent.js +2 -5
  21. package/lib/commonjs/createAnimatedComponent.js.map +1 -1
  22. package/lib/commonjs/reanimated2/NativeMethods.js +66 -26
  23. package/lib/commonjs/reanimated2/NativeMethods.js.map +1 -1
  24. package/lib/commonjs/reanimated2/frameCallback/FrameCallbackRegistryUI.js.map +1 -1
  25. package/lib/commonjs/reanimated2/globals.d.js.map +1 -1
  26. package/lib/commonjs/reanimated2/hook/useScrollViewOffset.js +5 -3
  27. package/lib/commonjs/reanimated2/hook/useScrollViewOffset.js.map +1 -1
  28. package/lib/module/createAnimatedComponent.js +2 -5
  29. package/lib/module/createAnimatedComponent.js.map +1 -1
  30. package/lib/module/reanimated2/NativeMethods.js +67 -25
  31. package/lib/module/reanimated2/NativeMethods.js.map +1 -1
  32. package/lib/module/reanimated2/frameCallback/FrameCallbackRegistryUI.js.map +1 -1
  33. package/lib/module/reanimated2/globals.d.js.map +1 -1
  34. package/lib/module/reanimated2/hook/useScrollViewOffset.js +2 -1
  35. package/lib/module/reanimated2/hook/useScrollViewOffset.js.map +1 -1
  36. package/package.json +7 -5
  37. package/plugin.js +1 -1
  38. package/scripts/reanimated_utils.rb +77 -0
  39. package/src/createAnimatedComponent.tsx +2 -3
  40. package/src/reanimated2/NativeMethods.ts +85 -33
  41. package/src/reanimated2/frameCallback/FrameCallbackRegistryUI.ts +1 -1
  42. package/src/reanimated2/globals.d.ts +56 -14
  43. package/src/reanimated2/hook/useScrollViewOffset.ts +4 -3
  44. package/android/rnVersionPatch/63/layoutReanimation/ReanimatedUIImplementation.java +0 -68
  45. package/android/rnVersionPatch/64/layoutReanimation/ReanimatedUIImplementation.java +0 -68
  46. package/android/rnVersionPatch/65/.gitkeep +0 -0
  47. package/android/rnVersionPatch/66/.gitkeep +0 -0
  48. package/android/rnVersionPatch/67/.gitkeep +0 -0
  49. package/android/rnVersionPatch/68/.gitkeep +0 -0
  50. package/android/rnVersionPatch/backup/.gitkeep +0 -0
  51. package/android/src/main/java/com/swmansion/reanimated/AndroidErrorHandler.java +0 -8
@@ -1,10 +1,7 @@
1
1
  import com.android.Version
2
-
3
- import java.nio.file.Files
4
- import java.nio.file.Paths
5
- import java.nio.file.Path
6
2
  import org.apache.tools.ant.filters.ReplaceTokens
7
- import java.util.stream.Stream
3
+ import groovy.json.JsonSlurper
4
+ import java.nio.file.Paths
8
5
 
9
6
  /**
10
7
  * Finds the path of the installed npm package with the given name using Node's
@@ -45,6 +42,14 @@ def safeExtGet(prop, fallback) {
45
42
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
46
43
  }
47
44
 
45
+ def safeAppExtGet(prop, fallback) {
46
+ if (findProject(':app') == null) {
47
+ return fallback
48
+ }
49
+ def appProject = project(':app')
50
+ appProject?.ext?.has(prop) ? appProject.ext.get(prop) : fallback
51
+ }
52
+
48
53
  def resolveBuildType() {
49
54
  Gradle gradle = getGradle()
50
55
  String tskReqStr = gradle.getStartParameter().getTaskRequests()['args'].toString()
@@ -71,7 +76,7 @@ def resolveClientSideBuild() {
71
76
 
72
77
  def isDeveloperMode() {
73
78
  // developer mode, to run Example app
74
- return file("$projectDir/../node_modules/react-native/package.json").exists()
79
+ return safeAppExtGet("isReanimatedExampleApp", false) || System.getenv("REANIMATED_PACKAGE_BUILD") == "1"
75
80
  }
76
81
 
77
82
  def isNewArchitectureEnabled() {
@@ -83,10 +88,32 @@ def isNewArchitectureEnabled() {
83
88
  }
84
89
 
85
90
  def resolveReactNativeDirectory() {
91
+ def reactNativeLocation = safeAppExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
92
+ if (reactNativeLocation != null) {
93
+ return file(reactNativeLocation)
94
+ }
95
+
86
96
  if (isDeveloperMode()) {
87
97
  return file("$projectDir/../${getPlaygroundAppName()}/node_modules/react-native")
88
98
  }
89
- return file("$projectDir/../../react-native")
99
+
100
+ // monorepo workaround
101
+ // react-native can be hoisted or in project's own node_modules
102
+ def reactNativeFromProjectNodeModules = file("${rootProject.projectDir}/../node_modules/react-native")
103
+ if (reactNativeFromProjectNodeModules.exists()) {
104
+ return reactNativeFromProjectNodeModules
105
+ }
106
+
107
+ def reactNativeFromNodeModulesWithReanimated = file("${projectDir}/../../react-native")
108
+ if (reactNativeFromNodeModulesWithReanimated.exists()) {
109
+ return reactNativeFromNodeModulesWithReanimated
110
+ }
111
+
112
+ throw new Exception(
113
+ "[Reanimated] Unable to resolve react-native location in " +
114
+ "node_modules. You should project extension property (in app/build.gradle) " +
115
+ "`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
116
+ )
90
117
  }
91
118
 
92
119
  def getPlaygroundAppName() { // only for the development
@@ -113,20 +140,49 @@ def shouldAssertNoMultipleInstances() {
113
140
  }
114
141
  }
115
142
 
116
- def noMultipleInstancesAssertion() {
117
- // Assert there are no multiple installations of Reanimated
118
- Set<File> files = fileTree(rootDir.parent) {
143
+ def findReanimatedInstancesForPath(String path) {
144
+ return fileTree(path) {
119
145
  include "**/react-native-reanimated/package.json"
120
146
  exclude "**/.yarn/**"
147
+ exclude {{ file, attr -> attr.isSymbolicLink() }}
121
148
  }.files
149
+ }
122
150
 
151
+ def checkNoMultipleInstances() {
152
+ // Assert there are no multiple installations of Reanimated
153
+ Set<File> files
154
+ if (projectDir.path.contains(rootDir.parent)) {
155
+ // standard app
156
+ files = findReanimatedInstancesForPath(rootDir.parent + "/node_modules")
157
+ } else {
158
+ // monorepo
159
+ files = findReanimatedInstancesForPath(rootDir.parent + "/node_modules")
160
+ files.addAll(
161
+ findReanimatedInstancesForPath(file(projectDir.parent).parent)
162
+ )
163
+ }
123
164
  if (files.size() > 1) {
124
- String parsedLocation = files.stream().map({ File file -> "- " + file.toString().replace("/package.json", "") }).collect().join("\n")
125
- String exceptionMessage = "\nMultiple versions of Reanimated were detected. Only one instance of react-native-reanimated can be installed in a project. You need to resolve the conflict manually. Check out the documentation: https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/troubleshooting#multiple-versions-of-reanimated-were-detected \n\nConflict between: \n" + parsedLocation + "\n";
165
+ String parsedLocation = files.stream().map({
166
+ File file -> "- " + file.toString().replace("/package.json", "")
167
+ }).collect().join("\n")
168
+ String exceptionMessage = "\n[react-native-reanimated] Multiple versions of Reanimated " +
169
+ "were detected. Only one instance of react-native-reanimated can be installed in a " +
170
+ "project. You need to resolve the conflict manually. Check out the documentation: " +
171
+ "https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/" +
172
+ "troubleshooting#multiple-versions-of-reanimated-were-detected \n\nConflict " +
173
+ "between: \n" + parsedLocation + "\n";
126
174
  throw new Exception(exceptionMessage)
127
175
  }
128
176
  }
129
177
 
178
+ def getReanimatedVersion() {
179
+ def inputFile = file(projectDir.path + '/../package.json')
180
+ def json = new JsonSlurper().parseText(inputFile.text)
181
+ String reanimatedVersion = json.version
182
+ def (major, minor, patch) = reanimatedVersion.tokenize('.')
183
+ return major.toInteger()
184
+ }
185
+
130
186
  boolean CLIENT_SIDE_BUILD = resolveClientSideBuild()
131
187
  if (CLIENT_SIDE_BUILD) {
132
188
  configurations.maybeCreate("default")
@@ -144,6 +200,8 @@ def GLOG_VERSION = reactProperties.getProperty("GLOG_VERSION")
144
200
  def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME")
145
201
  def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.split("\\.")[1].toInteger()
146
202
  def FBJNI_VERSION = "0.3.0"
203
+ def REANIMATED_PACKAGE_BUILD = System.getenv("REANIMATED_PACKAGE_BUILD")
204
+ def REANIMATED_MAJOR_VERSION = getReanimatedVersion()
147
205
 
148
206
  // We download various C++ open-source dependencies into downloads.
149
207
  // We then copy both the downloaded code and our custom makefiles and headers into third-party-ndk.
@@ -154,13 +212,10 @@ def downloadsDir = customDownloadsDir ? new File(customDownloadsDir) : new File(
154
212
  def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
155
213
 
156
214
  def reactNativeThirdParty = new File("$reactNativeRootDir/ReactAndroid/src/main/jni/third-party")
215
+ def reactNativeAndroidDownloadDir = new File("$reactNativeRootDir/ReactAndroid/build/downloads")
157
216
 
158
217
  def _stackProtectorFlag = true
159
218
 
160
- def CMAKE_NODE_MODULES_DIR = CLIENT_SIDE_BUILD
161
- ? project.getProjectDir().getParentFile().getParent()
162
- : Paths.get(project.getProjectDir().getParent(), getPlaygroundAppName(), "node_modules").toString()
163
-
164
219
  def JS_RUNTIME = {
165
220
  // Returns the js runtime explicitly requested in the environment variable
166
221
  if (System.getenv("JS_RUNTIME")) {
@@ -180,14 +235,14 @@ def JS_RUNTIME = {
180
235
  def jsRuntimeDir = {
181
236
  if (JS_RUNTIME == "hermes") {
182
237
  if (REACT_NATIVE_MINOR_VERSION >= 69) {
183
- return Paths.get(CMAKE_NODE_MODULES_DIR, "react-native", "sdks", "hermes")
238
+ return Paths.get(reactNativeRootDir.path, "sdks", "hermes")
184
239
  } else {
185
- return Paths.get(CMAKE_NODE_MODULES_DIR, "hermes-engine")
240
+ return Paths.get(reactNativeRootDir.path, "..", "hermes-engine")
186
241
  }
187
242
  } else if (JS_RUNTIME == "v8") {
188
243
  return findProject(":react-native-v8").getProjectDir().getParent()
189
244
  } else {
190
- return Paths.get(CMAKE_NODE_MODULES_DIR, "react-native", "ReactCommon", "jsi")
245
+ return Paths.get(reactNativeRootDir.path, "ReactCommon", "jsi")
191
246
  }
192
247
  }.call()
193
248
 
@@ -196,6 +251,145 @@ def reactNativeArchitectures() {
196
251
  return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
197
252
  }
198
253
 
254
+ def detectAAR(Integer rnMinorVersion, String engine) { // Reanimated2 only
255
+ def rnMinorVersionCopy = rnMinorVersion
256
+ def aar = file("react-native-reanimated-${rnMinorVersionCopy}-${engine}.aar")
257
+
258
+ if (aar.exists()) {
259
+ println "AAR for react-native-reanimated has been found\n$aar"
260
+ return aar
261
+ } else {
262
+ while (!aar.exists() && rnMinorVersionCopy >= 63) {
263
+ rnMinorVersionCopy -= 1
264
+ aar = file("react-native-reanimated-${rnMinorVersionCopy}-${engine}.aar")
265
+ }
266
+
267
+ if (rnMinorVersionCopy < 63) {
268
+ println "No AAR for react-native-reanimated found. Attempting to build from source."
269
+ } else { // aar exists, but was build for lower react-native version
270
+ println "\n\n\n"
271
+ println "****************************************************************************************"
272
+ println "\n\n\n"
273
+ println "WARNING reanimated - no version-specific reanimated AAR for react-native version $minor found."
274
+ println "Falling back to AAR for react-native version $rnMinorVersionCopy."
275
+ println "The react-native JSI interface is not ABI-safe yet, this may result in crashes."
276
+ println "Please post a pull request to implement support for react-native version $minor to the reanimated repo."
277
+ println "Thanks!"
278
+ println "\n\n\n"
279
+ println "****************************************************************************************"
280
+
281
+ return aar
282
+ }
283
+ }
284
+ return null
285
+ }
286
+
287
+ def isUserDemandToBuildFromSource() { // Reanimated2 only
288
+ def buildFromSourceConf = false
289
+ rootProject.getSubprojects().forEach({project ->
290
+ if (project.plugins.hasPlugin("com.android.application")) {
291
+ if (
292
+ project.ext.has("reanimated")
293
+ && project.ext.reanimated.buildFromSource
294
+ ) {
295
+ buildFromSourceConf = true
296
+ }
297
+ }
298
+ })
299
+ return buildFromSourceConf
300
+ }
301
+
302
+ def shouldBuildFromSource(aar, jsRuntimeName) { // Reanimated2 only
303
+ if (jsRuntimeName == "v8") {
304
+ return true
305
+ }
306
+ else if (isDeveloperMode()) {
307
+ // Example app
308
+ return true
309
+ }
310
+ else if (isUserDemandToBuildFromSource()) {
311
+ // on user demand
312
+ return true
313
+ }
314
+ else if (aar != null) {
315
+ // when binary exist
316
+ return false
317
+ }
318
+ // when binary is not found
319
+ return true
320
+ }
321
+
322
+ def getTaskByPath(
323
+ project,
324
+ String appName,
325
+ String secondPart,
326
+ String flavorString,
327
+ String lastPart
328
+ ) { // Reanimated2 only
329
+ String pathName = "${appName}:${secondPart}${flavorString}${lastPart}"
330
+ Task task = project.getTasks().findByPath(pathName)
331
+ if (task != null) {
332
+ return task
333
+ }
334
+ pathName = "${appName}:${secondPart}${flavorString.capitalize()}${lastPart}"
335
+ return project.getTasks().findByPath(pathName)
336
+ }
337
+
338
+ def aar = detectAAR(REACT_NATIVE_MINOR_VERSION, JS_RUNTIME)
339
+ boolean BUILD_FROM_SOURCE = shouldBuildFromSource(aar, JS_RUNTIME)
340
+
341
+ if (!BUILD_FROM_SOURCE && !isNewArchitectureEnabled()) { // Reanimated2 only
342
+ if (REACT_NATIVE_MINOR_VERSION < 65) {
343
+ tasks.register("replaceSoTaskDebug", replaceSoTask)
344
+ tasks.register("replaceSoTaskRelease", replaceSoTask)
345
+ Task replaceSoTaskDebug = project.getTasks().findByPath(":react-native-reanimated:replaceSoTaskDebug")
346
+ Task replaceSoTaskRelease = project.getTasks().findByPath(":react-native-reanimated:replaceSoTaskRelease")
347
+
348
+ if (replaceSoTaskDebug != null && replaceSoTaskRelease != null) {
349
+ rootProject.getSubprojects().forEach({project ->
350
+ if (project.plugins.hasPlugin("com.android.application") && project.getProperties().get("android")) {
351
+ def projectProperties = project.getProperties()
352
+ def flavorString = getCurrentFlavor()
353
+ def reanimatedConf = projectProperties.get("reanimated")
354
+
355
+ if (
356
+ flavorString != "NOT-FOUND"
357
+ && (!reanimatedConf || (reanimatedConf && !reanimatedConf.get("enablePackagingOptions")))
358
+ ) {
359
+ replaceSoTask.appName = projectProperties.path
360
+ replaceSoTask.buildDir = projectProperties.buildDir
361
+ def appName = projectProperties.path
362
+
363
+ Task debugNativeLibsTask = getTaskByPath(project, appName, "merge", flavorString, "DebugNativeLibs")
364
+ Task debugDebugSymbolsTask = getTaskByPath(project, appName, "strip", flavorString, "DebugDebugSymbols")
365
+ Task releaseNativeLibsTask = getTaskByPath(project, appName, "merge", flavorString, "ReleaseNativeLibs")
366
+ Task releaseDebugSymbolsTask = getTaskByPath(project, appName, "strip", flavorString, "ReleaseDebugSymbols")
367
+ Task debugTask = getTaskByPath(project, appName, "package", flavorString, "Debug")
368
+ Task releaseTask = getTaskByPath(project, appName, "package", flavorString, "Release")
369
+
370
+ if (
371
+ debugNativeLibsTask != null && debugDebugSymbolsTask != null
372
+ && releaseNativeLibsTask != null && releaseDebugSymbolsTask != null
373
+ && debugTask != null && releaseTask != null
374
+ ) {
375
+ replaceSoTaskDebug.dependsOn(debugNativeLibsTask, debugDebugSymbolsTask)
376
+ debugTask.dependsOn(replaceSoTaskDebug)
377
+ replaceSoTaskRelease.dependsOn(releaseNativeLibsTask, releaseDebugSymbolsTask)
378
+ releaseTask.dependsOn(replaceSoTaskRelease)
379
+ }
380
+ }
381
+ }
382
+ })
383
+ }
384
+ }
385
+
386
+ artifacts.add("default", aar)
387
+ }
388
+
389
+ // end if already loaded aar
390
+ if (!BUILD_FROM_SOURCE) {
391
+ return
392
+ }
199
393
  // You need to have following folders in this directory:
200
394
  // - boost_1_63_0
201
395
  // - double-conversion-1.1.6
@@ -225,9 +419,9 @@ buildscript {
225
419
  }
226
420
  }
227
421
  dependencies {
228
- classpath "com.android.tools.build:gradle:4.2.2"
229
- classpath "de.undercouch:gradle-download-task:4.1.2"
230
- classpath "com.diffplug.spotless:spotless-plugin-gradle:5.15.0"
422
+ classpath "com.android.tools.build:gradle:7.3.0"
423
+ classpath "de.undercouch:gradle-download-task:5.0.1"
424
+ classpath "com.diffplug.spotless:spotless-plugin-gradle:6.11.0"
231
425
  }
232
426
  }
233
427
 
@@ -253,12 +447,13 @@ android {
253
447
  "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
254
448
  "-DANDROID_TOOLCHAIN=clang",
255
449
  "-DBOOST_VERSION=${BOOST_VERSION}",
256
- "-DNODE_MODULES_DIR=${CMAKE_NODE_MODULES_DIR}",
450
+ "-DREACT_NATIVE_DIR=${reactNativeRootDir.path}",
257
451
  "-DJS_RUNTIME=${JS_RUNTIME}",
258
452
  "-DJS_RUNTIME_DIR=${jsRuntimeDir}",
259
453
  "-DCLIENT_SIDE_BUILD=${CLIENT_SIDE_BUILD}",
260
454
  "-DIS_NEW_ARCHITECTURE_ENABLED=${isNewArchitectureEnabled()}",
261
- "-DPLAYGROUND_APP_NAME=${getPlaygroundAppName()}"
455
+ "-DPLAYGROUND_APP_NAME=${getPlaygroundAppName()}",
456
+ "-DREANIMATED_PACKAGE_BUILD=${REANIMATED_PACKAGE_BUILD}"
262
457
  abiFilters (*reactNativeArchitectures())
263
458
  _stackProtectorFlag ? (cppFlags("-fstack-protector-all")) : null
264
459
  }
@@ -299,6 +494,8 @@ android {
299
494
  packagingOptions {
300
495
  doNotStrip resolveBuildType() == 'debug' ? "**/**/*.so" : ''
301
496
  excludes = [
497
+ "META-INF",
498
+ "META-INF/**",
302
499
  "**/libc++_shared.so",
303
500
  "**/libfbjni.so",
304
501
  "**/libjsi.so",
@@ -335,27 +532,57 @@ android {
335
532
  sourceSets.main {
336
533
  java {
337
534
  if (isNewArchitectureEnabled()) {
338
- srcDirs += [
339
- "src/fabric/java",
340
- ]
535
+ srcDirs += "src/fabric/java"
536
+ } else {
537
+ srcDirs += "src/paper/java"
538
+ }
539
+
540
+ // messageQueueThread
541
+ if (REANIMATED_MAJOR_VERSION > 2) {
542
+ if (REACT_NATIVE_MINOR_VERSION <= 67) {
543
+ srcDirs += "src/reactNativeVersionPatch/messageQueueThread/67"
544
+ } else {
545
+ srcDirs += "src/reactNativeVersionPatch/messageQueueThread/latest"
546
+ }
547
+ }
548
+
549
+ // UIImplementation
550
+ if (REACT_NATIVE_MINOR_VERSION <= 64) {
551
+ srcDirs += "src/reactNativeVersionPatch/UIImplementation/64"
341
552
  } else {
342
- srcDirs += [
343
- "src/paper/java",
344
- ]
553
+ srcDirs += "src/reactNativeVersionPatch/UIImplementation/latest"
554
+ }
555
+
556
+ // nativeHierarchyManager
557
+ if (REACT_NATIVE_MINOR_VERSION <= 62) {
558
+ srcDirs += "src/reactNativeVersionPatch/nativeHierarchyManager/62"
559
+ } else {
560
+ srcDirs += "src/reactNativeVersionPatch/nativeHierarchyManager/latest"
345
561
  }
346
562
  }
347
563
  }
348
564
  }
349
565
 
350
- def assertionTask = task assertNoMultipleInstances {
566
+ def assertNoMultipleInstances = task assertNoMultipleInstancesTask {
351
567
  onlyIf { shouldAssertNoMultipleInstances() && CLIENT_SIDE_BUILD }
352
568
  doFirst {
353
- noMultipleInstancesAssertion()
569
+ checkNoMultipleInstances()
570
+ }
571
+ }
572
+
573
+ def assertNoReanimated2WithNewArchitecture = task assertNoReanimated2WithNewArchitectureTask {
574
+ onlyIf { isNewArchitectureEnabled() && REANIMATED_MAJOR_VERSION == 2 }
575
+ doFirst {
576
+ throw new Exception(
577
+ "\n[react-native-reanimated] Reanimated 2.x does not support Fabric. " +
578
+ "Please upgrade to 3.x to use Reanimated with the New Architecture. " +
579
+ "For details, see https://blog.swmansion.com/announcing-reanimated-3-16167428c5f7"
580
+ )
354
581
  }
355
582
  }
356
583
 
357
584
  tasks.preBuild {
358
- dependsOn assertionTask
585
+ dependsOn assertNoMultipleInstances, assertNoReanimated2WithNewArchitecture
359
586
  }
360
587
 
361
588
  task cleanCmakeCache() {
@@ -370,27 +597,67 @@ task printVersions {
370
597
  println "Gradle: ${project.gradle.gradleVersion}"
371
598
  }
372
599
 
373
- task Log {
374
- println("building Reanimated2")
600
+ task createNativeDepsDirectories() {
601
+ downloadsDir.mkdirs()
602
+ thirdPartyNdkDir.mkdirs()
375
603
  }
376
604
 
377
- task applyJavaPatches(type: Copy) {
378
- def patchDirectory = file("${projectDir}/rnVersionPatch/${REACT_NATIVE_MINOR_VERSION}")
379
- if (patchDirectory.exists()) {
380
- from ("${patchDirectory}") {
381
- include "**/*.java"
605
+ def resolveTaskFactory(String taskName, String artifactLocalName, File reactNativeAndroidDownloadDir, File reanimatedDownloadDir) {
606
+ return tasks.create(name: taskName, dependsOn: createNativeDepsDirectories, type: Copy) {
607
+ from reactNativeAndroidDownloadDir
608
+ include artifactLocalName
609
+ into reanimatedDownloadDir
610
+
611
+ onlyIf {
612
+ // First we check whether the file is already in our download directory
613
+ if (file("$reanimatedDownloadDir/$artifactLocalName").isFile()) {
614
+ return false
615
+ }
616
+
617
+ // If it is not the case we check whether it was downloaded by ReactAndroid project
618
+ if (file("$reactNativeAndroidDownloadDir/$artifactLocalName").isFile()) {
619
+ return true
620
+ }
621
+
622
+ return false
382
623
  }
383
- into ("${projectDir}/src/main/java/com/swmansion/reanimated")
384
624
  }
385
625
  }
386
626
 
387
- task createNativeDepsDirectories(dependsOn: applyJavaPatches) {
388
- downloadsDir.mkdirs()
389
- thirdPartyNdkDir.mkdirs()
627
+ Task resolveBoost = resolveTaskFactory("resolveBoost", "boost_${BOOST_VERSION}.tar.gz", reactNativeAndroidDownloadDir, downloadsDir)
628
+ Task resolveDoubleConversion = resolveTaskFactory(
629
+ "resolveDoubleConversion",
630
+ "double-conversion-${DOUBLE_CONVERSION_VERSION}.tar.gz",
631
+ reactNativeAndroidDownloadDir,
632
+ downloadsDir
633
+ )
634
+ Task resolveFolly = resolveTaskFactory("resolveFolly", "folly-${FOLLY_VERSION}.tar.gz", reactNativeAndroidDownloadDir, downloadsDir)
635
+ Task resolveGlog = resolveTaskFactory("resolveGlog", "glog-${GLOG_VERSION}.tar.gz", reactNativeAndroidDownloadDir, downloadsDir)
636
+
637
+ if (isNewArchitectureEnabled()) {
638
+ def reactNativeAndroidProject = findProject(":ReactAndroid")
639
+ if (reactNativeAndroidProject != null) {
640
+ reactNativeAndroidProject.afterEvaluate {
641
+ def resolveTasks = [resolveBoost, resolveGlog, resolveDoubleConversion, resolveFolly]
642
+ resolveTasks.forEach({ task ->
643
+ String reactAndroidDownloadTaskName = "download" + task.name.replace("resolve", "")
644
+ def reactAndroidDownloadTask = reactNativeAndroidProject.getTasks().findByName(reactAndroidDownloadTaskName)
645
+ if (reactAndroidDownloadTask != null) {
646
+ task.dependsOn(reactAndroidDownloadTask)
647
+ } else {
648
+ logger.warn("[Reanimated] Failed to find task named `$reactAndroidDownloadTaskName` in `:ReactAndroid` project." +
649
+ " Explicit dependency between it and $task.name task can not be set.")
650
+ }
651
+ })
652
+ }
653
+ } else {
654
+ throw new GradleScriptException("[Reanimated] Failed to find `:ReactAndroid` project. Explicit dependency between download tasks can not be set.")
655
+ }
390
656
  }
391
657
 
392
- task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
658
+ task downloadBoost(dependsOn: resolveBoost, type: Download) {
393
659
  def transformedVersion = BOOST_VERSION.replace("_", ".")
660
+ def artifactLocalName = "boost_${BOOST_VERSION}.tar.gz"
394
661
  def srcUrl = "https://boostorg.jfrog.io/artifactory/main/release/${transformedVersion}/source/boost_${BOOST_VERSION}.tar.gz"
395
662
  if (REACT_NATIVE_MINOR_VERSION < 69) {
396
663
  srcUrl = "https://github.com/react-native-community/boost-for-react-native/releases/download/v${transformedVersion}-0/boost_${BOOST_VERSION}.tar.gz"
@@ -398,7 +665,7 @@ task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
398
665
  src(srcUrl)
399
666
  onlyIfNewer(true)
400
667
  overwrite(false)
401
- dest(new File(downloadsDir, "boost_${BOOST_VERSION}.tar.gz"))
668
+ dest(new File(downloadsDir, artifactLocalName))
402
669
  }
403
670
 
404
671
  task prepareBoost(dependsOn: boostPath ? [] : [downloadBoost], type: Copy) {
@@ -412,7 +679,7 @@ task prepareBoost(dependsOn: boostPath ? [] : [downloadBoost], type: Copy) {
412
679
  }
413
680
  }
414
681
 
415
- task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
682
+ task downloadDoubleConversion(dependsOn: resolveDoubleConversion, type: Download) {
416
683
  src("https://github.com/google/double-conversion/archive/v${DOUBLE_CONVERSION_VERSION}.tar.gz")
417
684
  onlyIfNewer(true)
418
685
  overwrite(false)
@@ -428,7 +695,7 @@ task prepareDoubleConversion(dependsOn: dependenciesPath ? [] : [downloadDoubleC
428
695
  into("$thirdPartyNdkDir/double-conversion")
429
696
  }
430
697
 
431
- task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
698
+ task downloadFolly(dependsOn: resolveFolly, type: Download) {
432
699
  src("https://github.com/facebook/folly/archive/v${FOLLY_VERSION}.tar.gz")
433
700
  onlyIfNewer(true)
434
701
  overwrite(false)
@@ -447,7 +714,7 @@ task prepareFolly(dependsOn: dependenciesPath ? [] : [downloadFolly], type: Copy
447
714
  into("$thirdPartyNdkDir/folly")
448
715
  }
449
716
 
450
- task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
717
+ task downloadGlog(dependsOn: resolveGlog, type: Download) {
451
718
  src("https://github.com/google/glog/archive/v${GLOG_VERSION}.tar.gz")
452
719
  onlyIfNewer(true)
453
720
  overwrite(false)
@@ -531,7 +798,7 @@ if (REACT_NATIVE_MINOR_VERSION >= 69 && !isNewArchitectureEnabled()) {
531
798
  // We flatten the unzip as the tarball contains a `facebook-hermes-<SHA>`
532
799
  // folder at the top level.
533
800
  if (file.relativePath.segments.size() > 1) {
534
- file.relativePath = new org.gradle.api.file.RelativePath(!file.isDirectory(), file.relativePath.segments.drop(1))
801
+ file.relativePath = new RelativePath(!file.isDirectory(), file.relativePath.segments.drop(1))
535
802
  }
536
803
  }
537
804
  }
@@ -546,7 +813,12 @@ task prepareHermes() {
546
813
  }
547
814
 
548
815
  doLast {
549
- def hermesAAR = file("$reactNativeRootDir/android/com/facebook/react/hermes-engine/${REACT_NATIVE_VERSION}/hermes-engine-${REACT_NATIVE_VERSION}-${resolveBuildType()}.aar") // e.g. hermes-engine-0.70.0-rc.1-debug.aar
816
+ // e.g. hermes-engine-0.70.0-rc.1-debug.aar
817
+ def hermesAAR = file(
818
+ "$reactNativeRootDir/android/com/facebook/react/hermes-engine/" +
819
+ "${REACT_NATIVE_VERSION}/hermes-engine-${REACT_NATIVE_VERSION}-" +
820
+ "${resolveBuildType()}.aar"
821
+ )
550
822
  if (!hermesAAR.exists()) {
551
823
  throw new GradleScriptException("Could not find hermes-engine AAR", null)
552
824
  }
@@ -708,12 +980,23 @@ task downloadNdkBuildDependencies {
708
980
  dependsOn(downloadGlog)
709
981
  }
710
982
 
711
- task prepareThirdPartyNdkHeaders(dependsOn:[downloadNdkBuildDependencies, prepareBoost, prepareDoubleConversion, prepareFolly, prepareGlog, unpackReactNativeAAR]) {
712
- }
983
+ task prepareThirdPartyNdkHeaders(dependsOn:[
984
+ downloadNdkBuildDependencies,
985
+ prepareBoost,
986
+ prepareDoubleConversion,
987
+ prepareFolly,
988
+ prepareGlog,
989
+ unpackReactNativeAAR]
990
+ ) {}
713
991
 
714
992
  def nativeBuildDependsOn(dependsOnTask) {
715
- def buildTasks = tasks.findAll({ task ->
716
- !task.name.contains("Clean") && (task.name.contains("externalNative") || task.name.contains("CMake")) })
993
+ def buildTasks = tasks.findAll({ task -> (
994
+ !task.name.contains("Clean")
995
+ && (task.name.contains("externalNative")
996
+ || task.name.contains("CMake")
997
+ || task.name.contains("generateJsonModel")
998
+ )
999
+ ) })
717
1000
  buildTasks.forEach { task -> task.dependsOn(dependsOnTask) }
718
1001
  }
719
1002
 
@@ -741,12 +1024,17 @@ afterEvaluate {
741
1024
  def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
742
1025
  task.dependsOn(":react-native-v8:copy${buildType}JniLibsProjectOnly")
743
1026
  }
1027
+ } else if (JS_RUNTIME == "jsc") {
1028
+ extractAARHeaders.dependsOn(prepareJSC)
1029
+ extractSOFiles.dependsOn(prepareJSC)
1030
+ } else {
1031
+ throw GradleScriptException("Unknown JS runtime ${JS_RUNTIME}.")
744
1032
  }
745
1033
  }
746
1034
 
747
1035
  if (CLIENT_SIDE_BUILD) {
748
1036
  def aarDir = "${buildDir}/outputs"
749
- def aar = file("${aarDir}/android-${resolveBuildType()}.aar") // e.g. android-debug.aar
1037
+ aar = file("${aarDir}/android-${resolveBuildType()}.aar") // e.g. android-debug.aar
750
1038
  if (aar == null) {
751
1039
  throw GradleScriptException("AAR build failed. No AAR found in ${aarDir}.")
752
1040
  }
@@ -1,5 +1,5 @@
1
1
  distributionBase=GRADLE_USER_HOME
2
2
  distributionPath=wrapper/dists
3
- distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
3
+ distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
4
4
  zipStoreBase=GRADLE_USER_HOME
5
5
  zipStorePath=wrapper/dists
@@ -1,5 +1,6 @@
1
1
  #include "AndroidErrorHandler.h"
2
2
  #include <fbjni/fbjni.h>
3
+ #include <exception>
3
4
  #include <string>
4
5
  #include "Logger.h"
5
6
 
@@ -17,11 +18,9 @@ void AndroidErrorHandler::raiseSpec() {
17
18
  return;
18
19
  }
19
20
 
20
- static const auto cls = javaClassStatic();
21
- static auto method = cls->getStaticMethod<void(std::string)>("raise");
22
- method(cls, error->message);
23
-
21
+ // mark error as handled before this method throws exception
24
22
  this->error->handled = true;
23
+ throw std::runtime_error(this->error->message);
25
24
  }
26
25
 
27
26
  std::shared_ptr<Scheduler> AndroidErrorHandler::getScheduler() {
@@ -11,15 +11,12 @@
11
11
 
12
12
  namespace reanimated {
13
13
 
14
- class AndroidErrorHandler : public JavaClass<AndroidErrorHandler>,
15
- public ErrorHandler {
14
+ class AndroidErrorHandler : public ErrorHandler {
16
15
  std::shared_ptr<ErrorWrapper> error;
17
16
  std::shared_ptr<Scheduler> scheduler;
18
17
  void raiseSpec() override;
19
18
 
20
19
  public:
21
- static auto constexpr kJavaDescriptor =
22
- "Lcom/swmansion/reanimated/AndroidErrorHandler;";
23
20
  explicit AndroidErrorHandler(std::shared_ptr<Scheduler> scheduler);
24
21
  std::shared_ptr<Scheduler> getScheduler() override;
25
22
  std::shared_ptr<ErrorWrapper> getError() override;
@@ -14,10 +14,10 @@ import java.util.concurrent.Future;
14
14
  // The only method that has changed is `quitSynchronous()` (see comment above
15
15
  // function implementation for details).
16
16
  @DoNotStrip
17
- public class ReanimatedMessageQueueThread implements MessageQueueThread {
18
- private final MessageQueueThreadImpl messageQueueThread;
17
+ public abstract class ReanimatedMessageQueueThreadBase implements MessageQueueThread {
18
+ protected final MessageQueueThreadImpl messageQueueThread;
19
19
 
20
- public ReanimatedMessageQueueThread() {
20
+ public ReanimatedMessageQueueThreadBase() {
21
21
  messageQueueThread =
22
22
  MessageQueueThreadImpl.create(
23
23
  MessageQueueThreadSpec.mainThreadSpec(),
@@ -26,11 +26,6 @@ public class ReanimatedMessageQueueThread implements MessageQueueThread {
26
26
  });
27
27
  }
28
28
 
29
- @Override
30
- public boolean runOnQueue(Runnable runnable) {
31
- return messageQueueThread.runOnQueue(runnable);
32
- }
33
-
34
29
  @Override
35
30
  public <T> Future<T> callOnQueue(Callable<T> callable) {
36
31
  return messageQueueThread.callOnQueue(callable);