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

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