react-native-worklets 0.10.2 → 0.10.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.
@@ -9,11 +9,40 @@
9
9
  #include <thread>
10
10
  #include <utility>
11
11
 
12
+ #if __APPLE__
13
+ extern "C" {
14
+ void *objc_autoreleasePoolPush(void);
15
+ void objc_autoreleasePoolPop(void *pool);
16
+ }
17
+ #endif // __APPLE__
18
+
12
19
  namespace worklets {
13
20
 
14
21
  using namespace facebook;
15
22
 
23
+ #if __APPLE__
24
+ namespace {
25
+
26
+ class ScopedAutoreleasePool {
27
+ public:
28
+ ScopedAutoreleasePool() : pool_(objc_autoreleasePoolPush()) {}
29
+ ~ScopedAutoreleasePool() {
30
+ objc_autoreleasePoolPop(pool_);
31
+ }
32
+ ScopedAutoreleasePool(const ScopedAutoreleasePool &) = delete;
33
+ ScopedAutoreleasePool &operator=(const ScopedAutoreleasePool &) = delete;
34
+
35
+ private:
36
+ void *const pool_;
37
+ };
38
+
39
+ } // namespace
40
+ #endif // __APPLE__
41
+
16
42
  void AsyncQueueImpl::runLoop(const std::shared_ptr<AsyncQueueState> &state) {
43
+ #if __APPLE__
44
+ const ScopedAutoreleasePool threadAutoreleasePool;
45
+ #endif // __APPLE__
17
46
  while (state->running) {
18
47
  std::unique_lock<std::mutex> lock(state->mutex);
19
48
  state->cv.wait(lock, [state] { return !state->queue.empty() || !state->running; });
@@ -26,6 +55,9 @@ void AsyncQueueImpl::runLoop(const std::shared_ptr<AsyncQueueState> &state) {
26
55
  auto job = std::move(state->queue.front());
27
56
  state->queue.pop();
28
57
  lock.unlock();
58
+ #if __APPLE__
59
+ const ScopedAutoreleasePool autoreleasePool;
60
+ #endif // __APPLE__
29
61
  job();
30
62
  }
31
63
  }
@@ -14,7 +14,6 @@ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
14
14
  import com.facebook.soloader.SoLoader
15
15
  import com.swmansion.worklets.runloop.AnimationFrameCallback
16
16
  import com.swmansion.worklets.runloop.AnimationFrameQueue
17
- import java.util.concurrent.atomic.AtomicBoolean
18
17
 
19
18
  @Suppress("KotlinJniMissingFunction")
20
19
  @ReactModule(name = WorkletsModule.NAME)
@@ -50,7 +49,8 @@ class WorkletsModule(
50
49
  * Invalidating concurrently could be fatal. It shouldn't happen in a normal flow, but it doesn't
51
50
  * cost us much to add synchronization for extra safety.
52
51
  */
53
- private val mInvalidated = AtomicBoolean(false)
52
+ private val mInvalidationLock = Any()
53
+ private var mInvalidated = false
54
54
 
55
55
  @OptIn(FrameworkAPI::class)
56
56
  private external fun initHybrid(
@@ -161,9 +161,17 @@ class WorkletsModule(
161
161
  return mSlowAnimationsEnabled
162
162
  }
163
163
 
164
+ override fun initialize() {
165
+ reactApplicationContext.addLifecycleEventListener(this)
166
+ }
167
+
164
168
  override fun invalidate() {
165
- if (mInvalidated.getAndSet(true)) {
166
- return
169
+ synchronized(mInvalidationLock) {
170
+ if (mInvalidated) {
171
+ return
172
+ }
173
+ mInvalidated = true
174
+ reactApplicationContext.removeLifecycleEventListener(this)
167
175
  }
168
176
  if (mHybridData != null && mHybridData!!.isValid) {
169
177
  invalidateCpp()
@@ -176,11 +184,21 @@ class WorkletsModule(
176
184
  private external fun startCpp()
177
185
 
178
186
  override fun onHostResume() {
179
- mAnimationFrameQueue.resume()
187
+ synchronized(mInvalidationLock) {
188
+ if (mInvalidated) {
189
+ return
190
+ }
191
+ mAnimationFrameQueue.resume()
192
+ }
180
193
  }
181
194
 
182
195
  override fun onHostPause() {
183
- mAnimationFrameQueue.pause()
196
+ synchronized(mInvalidationLock) {
197
+ if (mInvalidated) {
198
+ return
199
+ }
200
+ mAnimationFrameQueue.pause()
201
+ }
184
202
  }
185
203
 
186
204
  override fun onHostDestroy() {}
@@ -11,7 +11,6 @@ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
11
11
  import com.facebook.soloader.SoLoader
12
12
  import com.swmansion.worklets.runloop.AnimationFrameCallback
13
13
  import com.swmansion.worklets.runloop.AnimationFrameQueue
14
- import java.util.concurrent.atomic.AtomicBoolean
15
14
 
16
15
  @Suppress("KotlinJniMissingFunction")
17
16
  @ReactModule(name = WorkletsModule.NAME)
@@ -46,7 +45,8 @@ class WorkletsModule(
46
45
  * Invalidating concurrently could be fatal. It shouldn't happen in a normal flow, but it doesn't
47
46
  * cost us much to add synchronization for extra safety.
48
47
  */
49
- private val mInvalidated = AtomicBoolean(false)
48
+ private val mInvalidationLock = Any()
49
+ private var mInvalidated = false
50
50
 
51
51
  @OptIn(FrameworkAPI::class)
52
52
  private external fun initHybrid(
@@ -117,9 +117,17 @@ class WorkletsModule(
117
117
  return mSlowAnimationsEnabled
118
118
  }
119
119
 
120
+ override fun initialize() {
121
+ reactApplicationContext.addLifecycleEventListener(this)
122
+ }
123
+
120
124
  override fun invalidate() {
121
- if (mInvalidated.getAndSet(true)) {
122
- return
125
+ synchronized(mInvalidationLock) {
126
+ if (mInvalidated) {
127
+ return
128
+ }
129
+ mInvalidated = true
130
+ reactApplicationContext.removeLifecycleEventListener(this)
123
131
  }
124
132
  if (mHybridData != null && mHybridData!!.isValid) {
125
133
  invalidateCpp()
@@ -132,11 +140,21 @@ class WorkletsModule(
132
140
  private external fun startCpp()
133
141
 
134
142
  override fun onHostResume() {
135
- mAnimationFrameQueue.resume()
143
+ synchronized(mInvalidationLock) {
144
+ if (mInvalidated) {
145
+ return
146
+ }
147
+ mAnimationFrameQueue.resume()
148
+ }
136
149
  }
137
150
 
138
151
  override fun onHostPause() {
139
- mAnimationFrameQueue.pause()
152
+ synchronized(mInvalidationLock) {
153
+ if (mInvalidated) {
154
+ return
155
+ }
156
+ mAnimationFrameQueue.pause()
157
+ }
140
158
  }
141
159
 
142
160
  override fun onHostDestroy() {}
@@ -5,5 +5,5 @@
5
5
  * version used to build the native part of the library in runtime. Remember to
6
6
  * keep this in sync with the version declared in `package.json`
7
7
  */
8
- export const jsVersion = '0.10.2';
8
+ export const jsVersion = '0.10.4';
9
9
  //# sourceMappingURL=jsVersion.js.map
@@ -3,5 +3,5 @@
3
3
  * version used to build the native part of the library in runtime. Remember to
4
4
  * keep this in sync with the version declared in `package.json`
5
5
  */
6
- export declare const jsVersion = "0.10.2";
6
+ export declare const jsVersion = "0.10.4";
7
7
  //# sourceMappingURL=jsVersion.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-worklets",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "The React Native multithreading library",
5
5
  "keywords": [
6
6
  "react-native",
package/plugin/index.js CHANGED
@@ -414,6 +414,7 @@ var require_globals = __commonJS({
414
414
  exports2.isGeneratedWorkletFile = isGeneratedWorkletFile;
415
415
  exports2.initializeGlobals = initializeGlobals;
416
416
  exports2.addCustomGlobals = addCustomGlobals;
417
+ var assert_1 = require("assert");
417
418
  var path_1 = __importDefault(require("path"));
418
419
  var autoworkletization_12 = require_autoworkletization();
419
420
  var types_12 = require_types();
@@ -555,7 +556,8 @@ var require_globals = __commonJS({
555
556
  addCustomGlobals(state);
556
557
  }
557
558
  const userImportForwarding = state.opts.importForwarding;
558
- state.opts.importForwarding = {
559
+ (0, assert_1.strict)(state.importForwarding === void 0, "state.importForwarding should be undefined at this point");
560
+ state.importForwarding = {
559
561
  relativePaths: [
560
562
  ...defaultAllowedPaths,
561
563
  ...(_a = userImportForwarding === null || userImportForwarding === void 0 ? void 0 : userImportForwarding.relativePaths) !== null && _a !== void 0 ? _a : []
@@ -614,7 +616,7 @@ var require_imports = __commonJS({
614
616
  var _a;
615
617
  if (nodePath.get("callee").isIdentifier({ name: "require" }) && ((_a = nodePath.get("arguments")[0]) === null || _a === void 0 ? void 0 : _a.isStringLiteral())) {
616
618
  const requiredModule = nodePath.get("arguments")[0];
617
- if (requiredModule.node.value.startsWith(".") && canForwardRelativeImport(state.file.opts.filename || "", state.opts.importForwarding.relativePaths)) {
619
+ if (requiredModule.node.value.startsWith(".") && canForwardRelativeImport(state.file.opts.filename || "", state.importForwarding.relativePaths)) {
618
620
  requiredModule.replaceWith(createImportPathLiteral(requiredModule.node.value, state));
619
621
  }
620
622
  }
@@ -711,13 +713,13 @@ var require_closure = __commonJS({
711
713
  scope = scope.parent;
712
714
  }
713
715
  if (state.opts.bundleMode && (0, imports_1.isImport)(binding)) {
714
- if ((0, imports_1.isImportRelative)(binding) && (0, imports_1.canForwardRelativeImport)(state.filename, state.opts.importForwarding.relativePaths)) {
716
+ if ((0, imports_1.isImportRelative)(binding) && (0, imports_1.canForwardRelativeImport)(state.filename, state.importForwarding.relativePaths)) {
715
717
  capturedNames.add(name);
716
718
  relativeBindingsToImport.add(binding);
717
719
  return;
718
720
  }
719
721
  const source = binding.path.parentPath.node.source.value;
720
- if ((0, imports_1.canForwardModuleImport)(source, state.opts.importForwarding.moduleNames)) {
722
+ if ((0, imports_1.canForwardModuleImport)(source, state.importForwarding.moduleNames)) {
721
723
  capturedNames.add(name);
722
724
  moduleBindingsToImport.add(binding);
723
725
  return;
@@ -5,4 +5,4 @@
5
5
  * version used to build the native part of the library in runtime. Remember to
6
6
  * keep this in sync with the version declared in `package.json`
7
7
  */
8
- export const jsVersion = '0.10.2';
8
+ export const jsVersion = '0.10.4';